1use linkerd_policy_controller_k8s_api::{
2 self as api,
3 policy::{AuthorizationPolicy, AuthorizationPolicySpec, LocalTargetRef, NamespacedTargetRef},
4};
5use linkerd_policy_test::admission;
6
7#[tokio::test(flavor = "current_thread")]
8async fn accepts_valid() {
9 admission::accepts(|ns| AuthorizationPolicy {
10 metadata: api::ObjectMeta {
11 namespace: Some(ns),
12 name: Some("test".to_string()),
13 ..Default::default()
14 },
15 spec: AuthorizationPolicySpec {
16 target_ref: LocalTargetRef {
17 group: Some("policy.linkerd.io".to_string()),
18 kind: "Server".to_string(),
19 name: "api".to_string(),
20 },
21 required_authentication_refs: vec![
22 NamespacedTargetRef {
23 group: Some("policy.linkerd.io".to_string()),
24 kind: "MeshTLSAuthentication".to_string(),
25 name: "mtls-clients".to_string(),
26 namespace: None,
27 },
28 NamespacedTargetRef {
29 group: Some("policy.linkerd.io".to_string()),
30 kind: "NetworkAuthentication".to_string(),
31 name: "cluster-nets".to_string(),
32 namespace: Some("linkerd".to_string()),
33 },
34 ],
35 },
36 })
37 .await;
38}
39
40#[tokio::test(flavor = "current_thread")]
41async fn accepts_targets_namespace() {
42 admission::accepts(|ns| AuthorizationPolicy {
43 metadata: api::ObjectMeta {
44 namespace: Some(ns.clone()),
45 name: Some("test".to_string()),
46 ..Default::default()
47 },
48 spec: AuthorizationPolicySpec {
49 target_ref: LocalTargetRef {
50 group: None,
51 kind: "Namespace".to_string(),
52 name: ns,
53 },
54 required_authentication_refs: vec![
55 NamespacedTargetRef {
56 group: Some("policy.linkerd.io".to_string()),
57 kind: "MeshTLSAuthentication".to_string(),
58 name: "mtls-clients".to_string(),
59 namespace: None,
60 },
61 NamespacedTargetRef {
62 group: Some("policy.linkerd.io".to_string()),
63 kind: "NetworkAuthentication".to_string(),
64 name: "cluster-nets".to_string(),
65 namespace: Some("linkerd".to_string()),
66 },
67 ],
68 },
69 })
70 .await;
71}
72
73#[tokio::test(flavor = "current_thread")]
74async fn rejects_targets_other_namespace() {
75 admission::rejects(|ns| AuthorizationPolicy {
76 metadata: api::ObjectMeta {
77 namespace: Some(ns),
78 name: Some("test".to_string()),
79 ..Default::default()
80 },
81 spec: AuthorizationPolicySpec {
82 target_ref: LocalTargetRef {
83 group: None,
84 kind: "Namespace".to_string(),
85 name: "foobar".to_string(),
86 },
87 required_authentication_refs: vec![
88 NamespacedTargetRef {
89 group: Some("policy.linkerd.io".to_string()),
90 kind: "MeshTLSAuthentication".to_string(),
91 name: "mtls-clients".to_string(),
92 namespace: None,
93 },
94 NamespacedTargetRef {
95 group: Some("policy.linkerd.io".to_string()),
96 kind: "NetworkAuthentication".to_string(),
97 name: "cluster-nets".to_string(),
98 namespace: Some("linkerd".to_string()),
99 },
100 ],
101 },
102 })
103 .await;
104}
105
106#[tokio::test(flavor = "current_thread")]
107async fn accepts_targets_route() {
108 admission::accepts(|ns| AuthorizationPolicy {
109 metadata: api::ObjectMeta {
110 namespace: Some(ns),
111 name: Some("test".to_string()),
112 ..Default::default()
113 },
114 spec: AuthorizationPolicySpec {
115 target_ref: LocalTargetRef {
116 group: Some("policy.linkerd.io".to_string()),
117 kind: "HttpRoute".to_string(),
118 name: "route-foo".to_string(),
119 },
120 required_authentication_refs: vec![
121 NamespacedTargetRef {
122 group: Some("policy.linkerd.io".to_string()),
123 kind: "MeshTLSAuthentication".to_string(),
124 name: "mtls-clients".to_string(),
125 namespace: None,
126 },
127 NamespacedTargetRef {
128 group: Some("policy.linkerd.io".to_string()),
129 kind: "NetworkAuthentication".to_string(),
130 name: "cluster-nets".to_string(),
131 namespace: Some("linkerd".to_string()),
132 },
133 ],
134 },
135 })
136 .await;
137}
138
139#[tokio::test(flavor = "current_thread")]
140async fn accepts_valid_with_only_meshtls() {
141 admission::accepts(|ns| AuthorizationPolicy {
142 metadata: api::ObjectMeta {
143 namespace: Some(ns),
144 name: Some("test".to_string()),
145 ..Default::default()
146 },
147 spec: AuthorizationPolicySpec {
148 target_ref: LocalTargetRef {
149 group: Some("policy.linkerd.io".to_string()),
150 kind: "Server".to_string(),
151 name: "api".to_string(),
152 },
153 required_authentication_refs: vec![NamespacedTargetRef {
154 group: Some("policy.linkerd.io".to_string()),
155 kind: "MeshTLSAuthentication".to_string(),
156 name: "mtls-clients".to_string(),
157 namespace: None,
158 }],
159 },
160 })
161 .await;
162}
163
164#[tokio::test(flavor = "current_thread")]
165async fn accepts_valid_with_only_network() {
166 admission::accepts(|ns| AuthorizationPolicy {
167 metadata: api::ObjectMeta {
168 namespace: Some(ns),
169 name: Some("test".to_string()),
170 ..Default::default()
171 },
172 spec: AuthorizationPolicySpec {
173 target_ref: LocalTargetRef {
174 group: Some("policy.linkerd.io".to_string()),
175 kind: "Server".to_string(),
176 name: "api".to_string(),
177 },
178 required_authentication_refs: vec![NamespacedTargetRef {
179 group: Some("policy.linkerd.io".to_string()),
180 kind: "NetworkAuthentication".to_string(),
181 name: "cluster-nets".to_string(),
182 namespace: Some("linkerd".to_string()),
183 }],
184 },
185 })
186 .await;
187}
188
189#[tokio::test(flavor = "current_thread")]
190async fn accepts_empty_required_authentications() {
191 admission::accepts(|ns| AuthorizationPolicy {
192 metadata: api::ObjectMeta {
193 namespace: Some(ns),
194 name: Some("test".to_string()),
195 ..Default::default()
196 },
197 spec: AuthorizationPolicySpec {
198 target_ref: LocalTargetRef {
199 group: Some("policy.linkerd.io".to_string()),
200 kind: "Server".to_string(),
201 name: "deny".to_string(),
202 },
203 required_authentication_refs: vec![],
204 },
205 })
206 .await;
207}
208
209#[tokio::test(flavor = "current_thread")]
210async fn rejects_missing_required_authentications() {
211 #[derive(
212 Clone,
213 Debug,
214 kube::CustomResource,
215 serde::Deserialize,
216 serde::Serialize,
217 schemars::JsonSchema,
218 )]
219 #[kube(
220 group = "policy.linkerd.io",
221 version = "v1alpha1",
222 kind = "AuthorizationPolicy",
223 namespaced
224 )]
225 #[serde(rename_all = "camelCase")]
226 pub struct FakeAuthorizationPolicySpec {
227 pub target_ref: LocalTargetRef,
228 pub required_authentication_refs: Option<Vec<NamespacedTargetRef>>,
229 }
230
231 admission::rejects(|ns| AuthorizationPolicy {
232 metadata: api::ObjectMeta {
233 namespace: Some(ns),
234 name: Some("test".to_string()),
235 ..Default::default()
236 },
237 spec: FakeAuthorizationPolicySpec {
238 target_ref: LocalTargetRef {
239 group: Some("policy.linkerd.io".to_string()),
240 kind: "Server".to_string(),
241 name: "deny".to_string(),
242 },
243 required_authentication_refs: None,
244 },
245 })
246 .await;
247}
248
249#[tokio::test(flavor = "current_thread")]
250async fn rejects_target_ref_deployment() {
251 admission::rejects(|ns| AuthorizationPolicy {
252 metadata: api::ObjectMeta {
253 namespace: Some(ns),
254 name: Some("test".to_string()),
255 ..Default::default()
256 },
257 spec: AuthorizationPolicySpec {
258 target_ref: LocalTargetRef {
259 group: Some("apps".to_string()),
260 kind: "Deployment".to_string(),
261 name: "someapp".to_string(),
262 },
263 required_authentication_refs: vec![NamespacedTargetRef {
264 group: Some("policy.linkerd.io".to_string()),
265 kind: "NetworkAuthentication".to_string(),
266 namespace: Some("linkerd".to_string()),
267 name: "cluster-nets".to_string(),
268 }],
269 },
270 })
271 .await;
272}
273
274#[tokio::test(flavor = "current_thread")]
275async fn rejects_duplicate_mtls_authns() {
276 admission::rejects(|ns| AuthorizationPolicy {
277 metadata: api::ObjectMeta {
278 namespace: Some(ns),
279 name: Some("test".to_string()),
280 ..Default::default()
281 },
282 spec: AuthorizationPolicySpec {
283 target_ref: LocalTargetRef {
284 group: Some("policy.linkerd.io".to_string()),
285 kind: "Server".to_string(),
286 name: "some-srv".to_string(),
287 },
288 required_authentication_refs: vec![
289 NamespacedTargetRef {
290 group: Some("policy.linkerd.io".to_string()),
291 kind: "MeshTLSAuthentication".to_string(),
292 namespace: Some("some-ns".to_string()),
293 name: "some-ids".to_string(),
294 },
295 NamespacedTargetRef {
296 group: Some("policy.linkerd.io".to_string()),
297 kind: "MeshTLSAuthentication".to_string(),
298 namespace: Some("other-ns".to_string()),
299 name: "other-ids".to_string(),
300 },
301 ],
302 },
303 })
304 .await;
305}
306
307#[tokio::test(flavor = "current_thread")]
308async fn rejects_duplicate_network_authns() {
309 admission::rejects(|ns| AuthorizationPolicy {
310 metadata: api::ObjectMeta {
311 namespace: Some(ns),
312 name: Some("test".to_string()),
313 ..Default::default()
314 },
315 spec: AuthorizationPolicySpec {
316 target_ref: LocalTargetRef {
317 group: Some("policy.linkerd.io".to_string()),
318 kind: "Server".to_string(),
319 name: "some-srv".to_string(),
320 },
321 required_authentication_refs: vec![
322 NamespacedTargetRef {
323 group: Some("policy.linkerd.io".to_string()),
324 kind: "NetworkAuthentication".to_string(),
325 namespace: Some("some-ns".to_string()),
326 name: "some-nets".to_string(),
327 },
328 NamespacedTargetRef {
329 group: Some("policy.linkerd.io".to_string()),
330 kind: "NetworkAuthentication".to_string(),
331 namespace: Some("other-ns".to_string()),
332 name: "other-nets".to_string(),
333 },
334 ],
335 },
336 })
337 .await;
338}
View as plain text