Skip to content

Commit bee9304

Browse files
committed
Add status to snippetsFilter (#2536)
Add Status to SnippetsFilter Problem: Users want to be have information about the status of the snippetFilters. Solution: Add status details to snippetFilters.
1 parent ac3e9b9 commit bee9304

File tree

6 files changed

+241
-1
lines changed

6 files changed

+241
-1
lines changed

internal/mode/static/handler.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,12 +255,18 @@ 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)
258259

259-
reqs := make([]frameworkStatus.UpdateRequest, 0, len(gcReqs)+len(routeReqs)+len(polReqs)+len(ngfPolReqs))
260+
reqs := make(
261+
[]frameworkStatus.UpdateRequest,
262+
0,
263+
len(gcReqs)+len(routeReqs)+len(polReqs)+len(ngfPolReqs)+len(snippetsFilterReqs),
264+
)
260265
reqs = append(reqs, gcReqs...)
261266
reqs = append(reqs, routeReqs...)
262267
reqs = append(reqs, polReqs...)
263268
reqs = append(reqs, ngfPolReqs...)
269+
reqs = append(reqs, snippetsFilterReqs...)
264270

265271
h.cfg.statusUpdater.UpdateGroup(ctx, groupAllExceptGateways, reqs...)
266272

internal/mode/static/state/conditions/conditions.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,3 +744,14 @@ func NewSnippetsFilterInvalid(msg string) conditions.Condition {
744744
Message: msg,
745745
}
746746
}
747+
748+
// NewSnippetsFilterAccepted returns a Condition that indicates that the SnippetsFilter is accepted because it is
749+
// valid.
750+
func NewSnippetsFilterAccepted() conditions.Condition {
751+
return conditions.Condition{
752+
Type: string(ngfAPI.SnippetsFilterConditionTypeAccepted),
753+
Status: metav1.ConditionTrue,
754+
Reason: string(ngfAPI.SnippetsFilterConditionReasonAccepted),
755+
Message: "SnippetsFilter is accepted",
756+
}
757+
}

internal/mode/static/status/prepare_requests.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,38 @@ func PrepareBackendTLSPolicyRequests(
409409
return reqs
410410
}
411411

412+
// PrepareSnippetsFilterRequests prepares status UpdateRequests for the given SnippetsFilters.
413+
func PrepareSnippetsFilterRequests(
414+
snippetsFilters map[types.NamespacedName]*graph.SnippetsFilter,
415+
transitionTime metav1.Time,
416+
) []frameworkStatus.UpdateRequest {
417+
reqs := make([]frameworkStatus.UpdateRequest, 0, len(snippetsFilters))
418+
419+
for nsname, snippetsFilter := range snippetsFilters {
420+
allConds := make([]conditions.Condition, 0, len(snippetsFilter.Conditions)+1)
421+
422+
// The order of conditions matters here.
423+
// We add the default condition first, followed by the snippetsFilter conditions.
424+
// DeduplicateConditions will ensure the last condition wins.
425+
allConds = append(allConds, staticConds.NewSnippetsFilterAccepted())
426+
allConds = append(allConds, snippetsFilter.Conditions...)
427+
428+
conds := conditions.DeduplicateConditions(allConds)
429+
apiConds := conditions.ConvertConditions(conds, snippetsFilter.Source.GetGeneration(), transitionTime)
430+
status := ngfAPI.SnippetsFilterStatus{
431+
Conditions: apiConds,
432+
}
433+
434+
reqs = append(reqs, frameworkStatus.UpdateRequest{
435+
NsName: nsname,
436+
ResourceType: snippetsFilter.Source,
437+
Setter: newSnippetsFilterStatusSetter(status),
438+
})
439+
}
440+
441+
return reqs
442+
}
443+
412444
// ControlPlaneUpdateResult describes the result of a control plane update.
413445
type ControlPlaneUpdateResult struct {
414446
// Error is the error that occurred during the update.

internal/mode/static/status/prepare_requests_test.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,3 +1782,122 @@ func TestBuildNGFPolicyStatuses(t *testing.T) {
17821782
})
17831783
}
17841784
}
1785+
1786+
func TestBuildSnippetsFilterStatuses(t *testing.T) {
1787+
transitionTime := helpers.PrepareTimeForFakeClient(metav1.Now())
1788+
1789+
validSnippetsFilter := &graph.SnippetsFilter{
1790+
Source: &ngfAPI.SnippetsFilter{
1791+
ObjectMeta: metav1.ObjectMeta{
1792+
Name: "valid-snippet",
1793+
Namespace: "test",
1794+
Generation: 1,
1795+
},
1796+
Spec: ngfAPI.SnippetsFilterSpec{
1797+
Snippets: []ngfAPI.Snippet{
1798+
{
1799+
Context: ngfAPI.NginxContextHTTP,
1800+
Value: "proxy_buffer on;",
1801+
},
1802+
},
1803+
},
1804+
},
1805+
Valid: true,
1806+
}
1807+
1808+
invalidSnippetsFilter := &graph.SnippetsFilter{
1809+
Source: &ngfAPI.SnippetsFilter{
1810+
ObjectMeta: metav1.ObjectMeta{
1811+
Name: "invalid-snippet",
1812+
Namespace: "test",
1813+
Generation: 1,
1814+
},
1815+
},
1816+
Conditions: []conditions.Condition{staticConds.NewSnippetsFilterInvalid("invalid snippetsFilter")},
1817+
Valid: false,
1818+
}
1819+
1820+
tests := []struct {
1821+
snippetsFilters map[types.NamespacedName]*graph.SnippetsFilter
1822+
expected map[types.NamespacedName]ngfAPI.SnippetsFilterStatus
1823+
name string
1824+
expectedReqs int
1825+
}{
1826+
{
1827+
name: "nil snippetsFilters",
1828+
expectedReqs: 0,
1829+
expected: map[types.NamespacedName]ngfAPI.SnippetsFilterStatus{},
1830+
},
1831+
{
1832+
name: "valid snippetsFilter",
1833+
snippetsFilters: map[types.NamespacedName]*graph.SnippetsFilter{
1834+
{Namespace: "test", Name: "valid-snippet"}: validSnippetsFilter,
1835+
},
1836+
expectedReqs: 1,
1837+
expected: map[types.NamespacedName]ngfAPI.SnippetsFilterStatus{
1838+
{Namespace: "test", Name: "valid-snippet"}: {
1839+
Conditions: []metav1.Condition{
1840+
{
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",
1847+
},
1848+
},
1849+
},
1850+
},
1851+
},
1852+
{
1853+
name: "invalid snippetsFilter",
1854+
snippetsFilters: map[types.NamespacedName]*graph.SnippetsFilter{
1855+
{Namespace: "test", Name: "invalid-snippet"}: invalidSnippetsFilter,
1856+
},
1857+
expectedReqs: 1,
1858+
expected: map[types.NamespacedName]ngfAPI.SnippetsFilterStatus{
1859+
{Namespace: "test", Name: "invalid-snippet"}: {
1860+
Conditions: []metav1.Condition{
1861+
{
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+
},
1869+
},
1870+
},
1871+
},
1872+
},
1873+
}
1874+
1875+
for _, test := range tests {
1876+
t.Run(test.name, func(t *testing.T) {
1877+
g := NewWithT(t)
1878+
1879+
k8sClient := createK8sClientFor(&ngfAPI.SnippetsFilter{})
1880+
1881+
for _, snippets := range test.snippetsFilters {
1882+
err := k8sClient.Create(context.Background(), snippets.Source)
1883+
g.Expect(err).ToNot(HaveOccurred())
1884+
}
1885+
1886+
updater := statusFramework.NewUpdater(k8sClient, zap.New())
1887+
1888+
reqs := PrepareSnippetsFilterRequests(test.snippetsFilters, transitionTime)
1889+
1890+
g.Expect(reqs).To(HaveLen(test.expectedReqs))
1891+
1892+
updater.Update(context.Background(), reqs...)
1893+
1894+
for nsname, expected := range test.expected {
1895+
var snippetsFilter ngfAPI.SnippetsFilter
1896+
1897+
err := k8sClient.Get(context.Background(), nsname, &snippetsFilter)
1898+
g.Expect(err).ToNot(HaveOccurred())
1899+
g.Expect(helpers.Diff(expected, snippetsFilter.Status)).To(BeEmpty())
1900+
}
1901+
})
1902+
}
1903+
}

internal/mode/static/status/status_setters.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,16 @@ func ancestorStatusEqual(p1, p2 v1alpha2.PolicyAncestorStatus) bool {
333333

334334
return frameworkStatus.ConditionsEqual(p1.Conditions, p2.Conditions)
335335
}
336+
337+
func newSnippetsFilterStatusSetter(status ngfAPI.SnippetsFilterStatus) frameworkStatus.Setter {
338+
return func(obj client.Object) (wasSet bool) {
339+
sf := helpers.MustCastObject[*ngfAPI.SnippetsFilter](obj)
340+
341+
if frameworkStatus.ConditionsEqual(sf.Status.Conditions, status.Conditions) {
342+
return false
343+
}
344+
345+
sf.Status = status
346+
return true
347+
}
348+
}

internal/mode/static/status/status_setters_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,3 +1587,62 @@ func TestPolicyStatusEqual(t *testing.T) {
15871587
})
15881588
}
15891589
}
1590+
1591+
func TestNewSnippetsFilterStatusSetter(t *testing.T) {
1592+
tests := []struct {
1593+
name string
1594+
status, expStatus, newStatus ngfAPI.SnippetsFilterStatus
1595+
expStatusSet bool
1596+
}{
1597+
{
1598+
name: "SnippetsFilter has no status",
1599+
newStatus: ngfAPI.SnippetsFilterStatus{
1600+
Conditions: []metav1.Condition{{Message: "new condition"}},
1601+
},
1602+
expStatusSet: true,
1603+
expStatus: ngfAPI.SnippetsFilterStatus{
1604+
Conditions: []metav1.Condition{{Message: "new condition"}},
1605+
},
1606+
},
1607+
{
1608+
name: "SnippetsFilter has old status",
1609+
status: ngfAPI.SnippetsFilterStatus{
1610+
Conditions: []metav1.Condition{{Message: "old condition"}},
1611+
},
1612+
newStatus: ngfAPI.SnippetsFilterStatus{
1613+
Conditions: []metav1.Condition{{Message: "new condition"}},
1614+
},
1615+
expStatusSet: true,
1616+
expStatus: ngfAPI.SnippetsFilterStatus{
1617+
Conditions: []metav1.Condition{{Message: "new condition"}},
1618+
},
1619+
},
1620+
{
1621+
name: "SnippetsFilter has same status",
1622+
status: ngfAPI.SnippetsFilterStatus{
1623+
Conditions: []metav1.Condition{{Message: "same condition"}},
1624+
},
1625+
newStatus: ngfAPI.SnippetsFilterStatus{
1626+
Conditions: []metav1.Condition{{Message: "same condition"}},
1627+
},
1628+
expStatusSet: false,
1629+
expStatus: ngfAPI.SnippetsFilterStatus{
1630+
Conditions: []metav1.Condition{{Message: "same condition"}},
1631+
},
1632+
},
1633+
}
1634+
1635+
for _, test := range tests {
1636+
t.Run(test.name, func(t *testing.T) {
1637+
g := NewWithT(t)
1638+
1639+
setter := newSnippetsFilterStatusSetter(test.newStatus)
1640+
sf := &ngfAPI.SnippetsFilter{Status: test.status}
1641+
1642+
statusSet := setter(sf)
1643+
1644+
g.Expect(statusSet).To(Equal(test.expStatusSet))
1645+
g.Expect(sf.Status).To(Equal(test.expStatus))
1646+
})
1647+
}
1648+
}

0 commit comments

Comments
 (0)