Skip to content

Commit 697c955

Browse files
committed
KafkaTopicACLs: filter by valid/invalid workloads
Fixes #71
1 parent 111885b commit 697c955

File tree

8 files changed

+289
-4
lines changed

8 files changed

+289
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: nais.io/v1alpha1
2+
kind: Application
3+
metadata:
4+
name: app1
5+
spec:
6+
image: navikt/app-name:latest
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
apiVersion: kafka.nais.io/v1
2+
kind: Topic
3+
metadata:
4+
labels:
5+
team: devteam
6+
name: dokument
7+
namespace: devteam
8+
resourceVersion: "467599169"
9+
uid: 09047c15-c504-42d0-a636-286cd4a7c0ea
10+
spec:
11+
acl:
12+
- access: read
13+
application: "*"
14+
team: devteam
15+
- access: readwrite
16+
application: all
17+
team: "*"
18+
- access: readwrite
19+
application: app1
20+
team: devteam
21+
- access: readwrite
22+
application: app2
23+
team: otherteam
24+
- access: readwrite
25+
application: missing
26+
team: devteam
27+
- access: readwrite
28+
application: missing
29+
team: otherteam
30+
config:
31+
cleanupPolicy: delete
32+
localRetentionBytes: -2
33+
localRetentionHours: -2
34+
maxMessageBytes: 1048588
35+
minimumInSyncReplicas: 1
36+
partitions: 1
37+
replication: 3
38+
retentionBytes: -1
39+
retentionHours: 720
40+
segmentHours: 168
41+
pool: dev
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: nais.io/v1alpha1
2+
kind: Application
3+
metadata:
4+
name: app2
5+
spec:
6+
image: navikt/app-name:latest

Diff for: integration_tests/kafka_acl_filter.lua

+206
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
Helper.readK8sResources("k8s_resources/kafka_acl_filter")
2+
3+
local team = Team.new("devteam", "purpose", "#slack-channel")
4+
local user = User.new()
5+
6+
Test.gql("topic without filter", function(t)
7+
t.addHeader("x-user-email", user:email())
8+
9+
t.query([[
10+
{
11+
team(slug: "devteam") {
12+
environment(name: "dev") {
13+
kafkaTopic(name: "dokument") {
14+
acl {
15+
nodes {
16+
workloadName
17+
teamName
18+
access
19+
}
20+
}
21+
}
22+
}
23+
}
24+
}
25+
]])
26+
27+
t.check {
28+
data = {
29+
team = {
30+
environment = {
31+
kafkaTopic = {
32+
acl = {
33+
nodes = {
34+
{ workloadName = "*", teamName = "devteam", access = "read" },
35+
{ workloadName = "all", teamName = "*", access = "readwrite" },
36+
{ workloadName = "app1", teamName = "devteam", access = "readwrite" },
37+
{ workloadName = "app2", teamName = "otherteam", access = "readwrite" },
38+
{ workloadName = "missing", teamName = "devteam", access = "readwrite" },
39+
{ workloadName = "missing", teamName = "otherteam", access = "readwrite" },
40+
},
41+
},
42+
},
43+
},
44+
},
45+
},
46+
}
47+
end)
48+
49+
Test.gql("topic filtering for workload", function(t)
50+
t.addHeader("x-user-email", user:email())
51+
52+
t.query([[
53+
{
54+
team(slug: "devteam") {
55+
environment(name: "dev") {
56+
kafkaTopic(name: "dokument") {
57+
acl(filter: { workload: "app1" }) {
58+
nodes {
59+
workloadName
60+
teamName
61+
access
62+
}
63+
}
64+
}
65+
}
66+
}
67+
}
68+
]])
69+
70+
t.check {
71+
data = {
72+
team = {
73+
environment = {
74+
kafkaTopic = {
75+
acl = {
76+
nodes = {
77+
{ workloadName = "*", teamName = "devteam", access = "read" },
78+
{ workloadName = "app1", teamName = "devteam", access = "readwrite" },
79+
},
80+
},
81+
},
82+
},
83+
},
84+
},
85+
}
86+
end)
87+
88+
Test.gql("topic filtering for team", function(t)
89+
t.addHeader("x-user-email", user:email())
90+
91+
t.query([[
92+
{
93+
team(slug: "devteam") {
94+
environment(name: "dev") {
95+
kafkaTopic(name: "dokument") {
96+
acl(filter: { team: "otherteam" }) {
97+
nodes {
98+
workloadName
99+
teamName
100+
access
101+
}
102+
}
103+
}
104+
}
105+
}
106+
}
107+
]])
108+
109+
t.check {
110+
data = {
111+
team = {
112+
environment = {
113+
kafkaTopic = {
114+
acl = {
115+
nodes = {
116+
{ workloadName = "all", teamName = "*", access = "readwrite" },
117+
{ workloadName = "app2", teamName = "otherteam", access = "readwrite" },
118+
{ workloadName = "missing", teamName = "otherteam", access = "readwrite" },
119+
},
120+
},
121+
},
122+
},
123+
},
124+
},
125+
}
126+
end)
127+
128+
Test.gql("topic filtering for valid workloads", function(t)
129+
t.addHeader("x-user-email", user:email())
130+
131+
t.query([[
132+
{
133+
team(slug: "devteam") {
134+
environment(name: "dev") {
135+
kafkaTopic(name: "dokument") {
136+
acl(filter: { validWorkloads: true }) {
137+
nodes {
138+
workloadName
139+
teamName
140+
access
141+
}
142+
}
143+
}
144+
}
145+
}
146+
}
147+
]])
148+
149+
t.check {
150+
data = {
151+
team = {
152+
environment = {
153+
kafkaTopic = {
154+
acl = {
155+
nodes = {
156+
{ workloadName = "*", teamName = "devteam", access = "read" },
157+
{ workloadName = "all", teamName = "*", access = "readwrite" },
158+
{ workloadName = "app1", teamName = "devteam", access = "readwrite" },
159+
{ workloadName = "app2", teamName = "otherteam", access = "readwrite" },
160+
},
161+
},
162+
},
163+
},
164+
},
165+
},
166+
}
167+
end)
168+
169+
Test.gql("topic filtering for invalid workloads", function(t)
170+
t.addHeader("x-user-email", user:email())
171+
172+
t.query([[
173+
{
174+
team(slug: "devteam") {
175+
environment(name: "dev") {
176+
kafkaTopic(name: "dokument") {
177+
acl(filter: { validWorkloads: false }) {
178+
nodes {
179+
workloadName
180+
teamName
181+
access
182+
}
183+
}
184+
}
185+
}
186+
}
187+
}
188+
]])
189+
190+
t.check {
191+
data = {
192+
team = {
193+
environment = {
194+
kafkaTopic = {
195+
acl = {
196+
nodes = {
197+
{ workloadName = "missing", teamName = "devteam", access = "readwrite" },
198+
{ workloadName = "missing", teamName = "otherteam", access = "readwrite" },
199+
},
200+
},
201+
},
202+
},
203+
},
204+
},
205+
}
206+
end)

Diff for: internal/graph/gengql/generated.go

+9-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: internal/graph/schema/kafka.graphqls

+1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ type KafkaTopicAclEdge {
119119
input KafkaTopicAclFilter {
120120
team: Slug
121121
workload: String
122+
validWorkloads: Boolean
122123
}
123124

124125
input KafkaTopicOrder {

Diff for: internal/persistence/kafkatopic/models.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ func (e KafkaTopicACLOrderField) MarshalGQL(w io.Writer) {
140140
}
141141

142142
type KafkaTopicACLFilter struct {
143-
Team *slug.Slug `json:"team,omitempty"`
144-
Workload *string `json:"workload,omitempty"`
143+
Team *slug.Slug `json:"team,omitempty"`
144+
Workload *string `json:"workload,omitempty"`
145+
ValidWorkloads *bool `json:"validWorkloads,omitempty"`
145146
}
146147

147148
func toKafkaTopicConfiguration(cfg *kafka_nais_io_v1.Config) *KafkaTopicConfiguration {

Diff for: internal/persistence/kafkatopic/sortfilter.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"strings"
66

77
"github.com/nais/api/internal/graph/sortfilter"
8+
"github.com/nais/api/internal/slug"
9+
"github.com/nais/api/internal/workload/application"
810
)
911

1012
var (
@@ -22,7 +24,7 @@ func init() {
2224

2325
SortFilterTopicACL.RegisterSort("TOPIC_NAME", func(ctx context.Context, a, b *KafkaTopicACL) int {
2426
return strings.Compare(a.TopicName, b.TopicName)
25-
})
27+
}, "CONSUMER", "TEAM_SLUG", "ACCESS")
2628
SortFilterTopicACL.RegisterSort("TEAM_SLUG", func(ctx context.Context, a, b *KafkaTopicACL) int {
2729
return strings.Compare(a.TeamName, b.TeamName)
2830
})
@@ -42,6 +44,20 @@ func init() {
4244
return false
4345
}
4446

47+
if filter.ValidWorkloads != nil {
48+
if v.WorkloadName == "*" || v.WorkloadName == "" {
49+
return *filter.ValidWorkloads
50+
}
51+
if v.TeamName == "*" || v.TeamName == "" {
52+
return *filter.ValidWorkloads
53+
}
54+
55+
if _, err := application.Get(ctx, slug.Slug(v.TeamName), v.EnvironmentName, v.WorkloadName); err != nil {
56+
return !*filter.ValidWorkloads
57+
}
58+
return *filter.ValidWorkloads
59+
}
60+
4561
return true
4662
})
4763
}

0 commit comments

Comments
 (0)