Skip to content

Commit 09ed9d3

Browse files
committed
feat: migrate events api
1 parent c1ee150 commit 09ed9d3

42 files changed

Lines changed: 2952 additions & 514 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

internal/cache/registries.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,19 @@ func (c *RegistryRuleSetCache) HashRules(specRules []rules.OCIRegistry) string {
241241
for i := range exact {
242242
exact[i] = strings.TrimSpace(exact[i])
243243
}
244+
244245
sort.Strings(exact)
245246

246247
policies := make([]string, 0, len(r.Policy))
247248
for _, p := range r.Policy {
248249
policies = append(policies, strings.TrimSpace(string(p)))
249250
}
251+
250252
sort.Strings(policies)
251253

252254
b.WriteString("exact")
253255
b.WriteString(sepField)
256+
254257
for i, v := range exact {
255258
if i > 0 {
256259
b.WriteString(sepList)
@@ -267,6 +270,7 @@ func (c *RegistryRuleSetCache) HashRules(specRules []rules.OCIRegistry) string {
267270
b.WriteString(sepField)
268271
b.WriteString("negate")
269272
b.WriteString(sepField)
273+
270274
if match.Negate {
271275
b.WriteString("1")
272276
} else {
@@ -276,6 +280,7 @@ func (c *RegistryRuleSetCache) HashRules(specRules []rules.OCIRegistry) string {
276280
b.WriteString(sepField)
277281
b.WriteString("policy")
278282
b.WriteString(sepField)
283+
279284
for i, p := range policies {
280285
if i > 0 {
281286
b.WriteString(sepList)

internal/cache/registries_test.go

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func TestRegistryRuleSetCacheGetOrBuild(t *testing.T) {
9494
{
9595
name: "registry with negated expression builds ruleset",
9696
rules: []rules.OCIRegistry{
97-
registryWithExpression(api.RegExpression{
97+
registryWithExpression(api.ExpressionRegex{
9898
Expression: "trusted/.*",
9999
Negate: true,
100100
}),
@@ -242,7 +242,7 @@ func TestRegistryRuleSetCacheBuildRuleSet(t *testing.T) {
242242
specRules := []rules.OCIRegistry{
243243
registry("harbor/.*"),
244244
registryWithPolicy("ghcr.io/.*", corev1.PullAlways, corev1.PullIfNotPresent),
245-
registryWithExpression(api.RegExpression{
245+
registryWithExpression(api.ExpressionRegex{
246246
Expression: "trusted/.*",
247247
Negate: true,
248248
}),
@@ -267,16 +267,16 @@ func TestRegistryRuleSetCacheBuildRuleSet(t *testing.T) {
267267
t.Fatalf("expected %d compiled rules, got %d", len(specRules), len(rs.Compiled))
268268
}
269269

270-
if rs.Compiled[0].Expression.Expression != "harbor/.*" {
271-
t.Fatalf("expected first expression harbor/.*, got %q", rs.Compiled[0].Expression.Expression)
270+
if rs.Compiled[0].Match.Expression != "harbor/.*" {
271+
t.Fatalf("expected first expression harbor/.*, got %q", rs.Compiled[0].Match.Expression)
272272
}
273273

274274
if len(rs.Compiled[0].AllowedPolicy) != 0 {
275275
t.Fatal("expected first rule to allow any pull policy")
276276
}
277277

278-
if rs.Compiled[1].Expression.Expression != "ghcr.io/.*" {
279-
t.Fatalf("expected second expression ghcr.io/.*, got %q", rs.Compiled[1].Expression.Expression)
278+
if rs.Compiled[1].Match.Expression != "ghcr.io/.*" {
279+
t.Fatalf("expected second expression ghcr.io/.*, got %q", rs.Compiled[1].Match.Expression)
280280
}
281281

282282
if len(rs.Compiled[1].AllowedPolicy) != 2 {
@@ -291,7 +291,7 @@ func TestRegistryRuleSetCacheBuildRuleSet(t *testing.T) {
291291
t.Fatal("expected PullIfNotPresent to be allowed")
292292
}
293293

294-
if !rs.Compiled[2].Expression.Negate {
294+
if !rs.Compiled[2].Match.Negate {
295295
t.Fatal("expected third expression to be negated")
296296
}
297297
}
@@ -363,7 +363,7 @@ func TestRegistryRuleSetCacheMatchReference(t *testing.T) {
363363
{
364364
name: "negated expression matches non-matching reference",
365365
rules: []rules.OCIRegistry{
366-
registryWithExpression(api.RegExpression{
366+
registryWithExpression(api.ExpressionRegex{
367367
Expression: "trusted/.*",
368368
Negate: true,
369369
}),
@@ -377,7 +377,7 @@ func TestRegistryRuleSetCacheMatchReference(t *testing.T) {
377377
{
378378
name: "negated expression does not match matching reference",
379379
rules: []rules.OCIRegistry{
380-
registryWithExpression(api.RegExpression{
380+
registryWithExpression(api.ExpressionRegex{
381381
Expression: "trusted/.*",
382382
Negate: true,
383383
}),
@@ -406,7 +406,7 @@ func TestRegistryRuleSetCacheMatchReference(t *testing.T) {
406406
{
407407
name: "nested regex expression wins over legacy url",
408408
rules: []rules.OCIRegistry{
409-
registryWithExpression(api.RegExpression{
409+
registryWithExpression(api.ExpressionRegex{
410410
Expression: "nested/.*",
411411
}),
412412
},
@@ -417,7 +417,7 @@ func TestRegistryRuleSetCacheMatchReference(t *testing.T) {
417417
{
418418
name: "legacy url is ignored when nested regex expression is set",
419419
rules: []rules.OCIRegistry{
420-
registryWithExpression(api.RegExpression{
420+
registryWithExpression(api.ExpressionRegex{
421421
Expression: "nested/.*",
422422
}),
423423
},
@@ -449,8 +449,8 @@ func TestRegistryRuleSetCacheMatchReference(t *testing.T) {
449449
t.Fatal("expected match, got nil")
450450
}
451451

452-
if got.Expression.Expression != tt.wantExpr {
453-
t.Fatalf("expected expression %q, got %q", tt.wantExpr, got.Expression.Expression)
452+
if got.Match.Expression != tt.wantExpr {
453+
t.Fatalf("expected expression %q, got %q", tt.wantExpr, got.Match.Expression)
454454
}
455455

456456
return
@@ -526,7 +526,7 @@ func TestRegistryRuleSetCacheMatchRuleSetWithPullPolicy(t *testing.T) {
526526
{
527527
name: "negated expression respects pull policy",
528528
rules: []rules.OCIRegistry{
529-
registryWithExpressionAndPolicy(api.RegExpression{
529+
registryWithExpressionAndPolicy(api.ExpressionRegex{
530530
Expression: "trusted/.*",
531531
Negate: true,
532532
}, corev1.PullIfNotPresent),
@@ -541,7 +541,7 @@ func TestRegistryRuleSetCacheMatchRuleSetWithPullPolicy(t *testing.T) {
541541
{
542542
name: "negated expression still rejects forbidden pull policy",
543543
rules: []rules.OCIRegistry{
544-
registryWithExpressionAndPolicy(api.RegExpression{
544+
registryWithExpressionAndPolicy(api.ExpressionRegex{
545545
Expression: "trusted/.*",
546546
Negate: true,
547547
}, corev1.PullNever),
@@ -577,8 +577,8 @@ func TestRegistryRuleSetCacheMatchRuleSetWithPullPolicy(t *testing.T) {
577577
t.Fatal("expected match, got nil")
578578
}
579579

580-
if got.Expression.Expression != tt.wantExpr {
581-
t.Fatalf("expected expression %q, got %q", tt.wantExpr, got.Expression.Expression)
580+
if got.Match.Expression != tt.wantExpr {
581+
t.Fatalf("expected expression %q, got %q", tt.wantExpr, got.Match.Expression)
582582
}
583583

584584
return
@@ -611,8 +611,8 @@ func TestRegistryRuleSetCacheMatch(t *testing.T) {
611611
t.Fatal("expected match, got nil")
612612
}
613613

614-
if got.Expression.Expression != "harbor/.*" {
615-
t.Fatalf("expected harbor/.*, got %q", got.Expression.Expression)
614+
if got.Match.Expression != "harbor/.*" {
615+
t.Fatalf("expected harbor/.*, got %q", got.Match.Expression)
616616
}
617617
}
618618

@@ -714,14 +714,14 @@ func TestRegistryRuleSetCacheHashRules(t *testing.T) {
714714
c := NewRegistryRuleSetCache(nil)
715715

716716
hashA := c.HashRules([]rules.OCIRegistry{
717-
registryWithExpression(api.RegExpression{
717+
registryWithExpression(api.ExpressionRegex{
718718
Expression: "trusted/.*",
719719
Negate: false,
720720
}),
721721
})
722722

723723
hashB := c.HashRules([]rules.OCIRegistry{
724-
registryWithExpression(api.RegExpression{
724+
registryWithExpression(api.ExpressionRegex{
725725
Expression: "trusted/.*",
726726
Negate: true,
727727
}),
@@ -924,35 +924,43 @@ func TestRegistryRuleSetCacheInsertForTest(t *testing.T) {
924924

925925
func registry(expression string) rules.OCIRegistry {
926926
return rules.OCIRegistry{
927-
RegExpression: api.RegExpression{
928-
Expression: expression,
929-
Negate: false,
927+
ExpressionMatch: api.ExpressionMatch{
928+
ExpressionRegex: api.ExpressionRegex{
929+
Expression: expression,
930+
Negate: false,
931+
},
930932
},
931933
}
932934
}
933935

934936
func registryWithPolicy(expression string, policies ...corev1.PullPolicy) rules.OCIRegistry {
935937
return rules.OCIRegistry{
936-
RegExpression: api.RegExpression{
937-
Expression: expression,
938-
Negate: false,
938+
ExpressionMatch: api.ExpressionMatch{
939+
ExpressionRegex: api.ExpressionRegex{
940+
Expression: expression,
941+
Negate: false,
942+
},
939943
},
940944
Policy: policies,
941945
}
942946
}
943947

944-
func registryWithExpression(expression api.RegExpression) rules.OCIRegistry {
948+
func registryWithExpression(expression api.ExpressionRegex) rules.OCIRegistry {
945949
return rules.OCIRegistry{
946-
RegExpression: expression,
950+
ExpressionMatch: api.ExpressionMatch{
951+
ExpressionRegex: expression,
952+
},
947953
}
948954
}
949955

950956
func registryWithExpressionAndPolicy(
951-
expression api.RegExpression,
957+
expression api.ExpressionRegex,
952958
policies ...corev1.PullPolicy,
953959
) rules.OCIRegistry {
954960
return rules.OCIRegistry{
955-
RegExpression: expression,
956-
Policy: policies,
961+
ExpressionMatch: api.ExpressionMatch{
962+
ExpressionRegex: expression,
963+
},
964+
Policy: policies,
957965
}
958966
}

internal/webhook/dra/validate.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package dra
55

66
import (
77
"context"
8+
"fmt"
89
"net/http"
910

1011
corev1 "k8s.io/api/core/v1"
@@ -119,7 +120,17 @@ func (h *deviceClass) validateResourceRequest(
119120
case allowed.Match(dc.Name) || selector:
120121
return nil
121122
default:
122-
recorder.Eventf(obj, tnt, corev1.EventTypeWarning, events.ReasonForbiddenDeviceClass, events.ActionValidationDenied, "%s %s/%s DeviceClass %s is forbidden for the current Tenant", req.Kind.Kind, req.Namespace, req.Name, &dc)
123+
recorder.LabeledEvent(
124+
obj,
125+
corev1.EventTypeWarning,
126+
events.ReasonForbiddenDeviceClass,
127+
events.ActionValidationDenied,
128+
fmt.Sprintf("%s %s/%s DeviceClass %s is forbidden for the current tenant", req.Kind.Kind, req.Namespace, req.Name, dc),
129+
).
130+
WithRelated(tnt).
131+
WithTenantLabel(tnt).
132+
WithRequestAnnotations(req).
133+
Emit(ctx)
123134

124135
return ad.Deny(caperrors.NewDeviceClassForbidden(dc.Name, *allowed).Error())
125136
}

internal/webhook/gateway/validate_class.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package gateway
55

66
import (
77
"context"
8+
"fmt"
89
"net/http"
910

1011
corev1 "k8s.io/api/core/v1"
@@ -100,7 +101,17 @@ func (r *class) validate(
100101
}
101102

102103
if gatewayClass == nil {
103-
recorder.Eventf(gatewayObj, tnt, corev1.EventTypeWarning, events.ReasonMissingGatewayClass, events.ActionValidationDenied, "Gateway %s/%s is missing GatewayClass", req.Namespace, req.Name)
104+
recorder.LabeledEvent(
105+
gatewayObj,
106+
corev1.EventTypeWarning,
107+
events.ReasonMissingGatewayClass,
108+
events.ActionValidationDenied,
109+
fmt.Sprintf("Gateway %s/%s is missing GatewayClass", req.Namespace, req.Name),
110+
).
111+
WithRelated(tnt).
112+
WithTenantLabel(tnt).
113+
WithRequestAnnotations(req).
114+
Emit(ctx)
104115

105116
return ad.Deny(caperrors.NewGatewayClassUndefined(*allowed).Error())
106117
}
@@ -127,7 +138,17 @@ func (r *class) validate(
127138
case allowed.Match(gatewayClass.Name) || selector:
128139
return nil
129140
default:
130-
recorder.Eventf(gatewayObj, tnt, corev1.EventTypeWarning, events.ReasonForbiddenGatewayClass, events.ActionValidationDenied, "Gateway %s/%s GatewayClass %s is forbidden for the current Tenant", req.Namespace, req.Name, &gatewayClass)
141+
recorder.LabeledEvent(
142+
gatewayObj,
143+
corev1.EventTypeWarning,
144+
events.ReasonForbiddenGatewayClass,
145+
events.ActionValidationDenied,
146+
fmt.Sprintf("Gateway %s/%s GatewayClass %s is forbidden for the current Tenant", req.Namespace, req.Name, gatewayClass.GetName()),
147+
).
148+
WithRelated(tnt).
149+
WithTenantLabel(tnt).
150+
WithRequestAnnotations(req).
151+
Emit(ctx)
131152

132153
return ad.Deny(caperrors.NewGatewayClassForbidden(gatewayObj.Name, *allowed).Error())
133154
}

internal/webhook/generic/custom_resource_quota.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,17 @@ func (r *resourceCounterHandler) OnCreate(
8080
})
8181
if err != nil {
8282
if errors.As(err, &caperrors.CustomResourceQuotaError{}) {
83-
recorder.Eventf(tnt, nil, corev1.EventTypeWarning, events.ReasonOverprovision, events.ActionValidationDenied, "Resource %s/%s in API group %s cannot be created, limit usage of %d has been reached", req.Namespace, req.Name, kgv, limit)
83+
recorder.LabeledEvent(
84+
tnt,
85+
corev1.EventTypeWarning,
86+
events.ReasonOverprovision,
87+
events.ActionValidationDenied,
88+
fmt.Sprintf("Resource %s/%s in API group %s cannot be created, limit usage of %d has been reached", req.Namespace, req.Name, kgv, limit),
89+
).
90+
WithRelated(tnt).
91+
WithTenantLabel(tnt).
92+
WithRequestAnnotations(req).
93+
Emit(ctx)
8494
}
8595

8696
return ad.ErroredResponse(err)

internal/webhook/ingress/validate_class.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package ingress
55

66
import (
77
"context"
8+
"fmt"
89
"net/http"
910

1011
corev1 "k8s.io/api/core/v1"
@@ -100,7 +101,17 @@ func (r *class) validate(
100101
ingressClass := ingress.IngressClass()
101102

102103
if ingressClass == nil {
103-
recorder.Eventf(ingress.GetClientObject(), tnt, corev1.EventTypeWarning, events.ReasonMissingIngressClass, events.ActionValidationDenied, "Ingress %s/%s is missing IngressClass", req.Namespace, req.Name)
104+
recorder.LabeledEvent(
105+
ingress.GetClientObject(),
106+
corev1.EventTypeWarning,
107+
events.ReasonMissingIngressClass,
108+
events.ActionValidationDenied,
109+
"ingress is missing ingressclass",
110+
).
111+
WithRelated(tnt).
112+
WithTenantLabel(tnt).
113+
WithRequestAnnotations(req).
114+
Emit(ctx)
104115

105116
return ad.Deny(caperrors.NewIngressClassUndefined(*allowed).Error())
106117
}
@@ -128,7 +139,17 @@ func (r *class) validate(
128139
case allowed.Match(*ingressClass) || selector:
129140
return nil
130141
default:
131-
recorder.Eventf(ingress.GetClientObject(), tnt, corev1.EventTypeWarning, events.ReasonForbiddenIngressClass, events.ActionValidationDenied, "Ingress %s/%s IngressClass %s is forbidden for the current Tenant", req.Namespace, req.Name, &ingressClass)
142+
recorder.LabeledEvent(
143+
ingress.GetClientObject(),
144+
corev1.EventTypeWarning,
145+
events.ReasonForbiddenIngressClass,
146+
events.ActionValidationDenied,
147+
fmt.Sprintf("ingressclass %s is forbidden for the elected tenant", *ingressClass),
148+
).
149+
WithRelated(tnt).
150+
WithTenantLabel(tnt).
151+
WithRequestAnnotations(req).
152+
Emit(ctx)
132153

133154
return ad.Deny(caperrors.NewIngressClassForbidden(*ingressClass, *allowed).Error())
134155
}

internal/webhook/ingress/validate_collision.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,17 @@ func (r *collision) validate(
9696

9797
var collisionErr *caperrors.IngressHostnameCollisionError
9898
if errors.As(err, &collisionErr) {
99-
recorder.Eventf(ing.GetClientObject(), tnt, corev1.EventTypeWarning, events.ReasonIngressHostnameCollision, events.ActionValidationDenied, "Ingress %s/%s hostname is colliding", ing.Namespace(), ing.Name())
99+
recorder.LabeledEvent(
100+
ing.GetClientObject(),
101+
corev1.EventTypeWarning,
102+
events.ReasonIngressHostnameCollision,
103+
events.ActionValidationDenied,
104+
"ingress hostname is colliding",
105+
).
106+
WithRelated(tnt).
107+
WithTenantLabel(tnt).
108+
WithRequestAnnotations(req).
109+
Emit(ctx)
100110
}
101111

102112
return ad.Deny(err.Error())

0 commit comments

Comments
 (0)