1use linkerd_policy_controller_k8s_api::{
2 self as api,
3 policy::network_authentication::{Network, NetworkAuthentication, NetworkAuthenticationSpec},
4};
5use linkerd_policy_test::admission;
6
7#[tokio::test(flavor = "current_thread")]
8async fn accepts_valid() {
9 admission::accepts(|ns| NetworkAuthentication {
10 metadata: api::ObjectMeta {
11 namespace: Some(ns),
12 name: Some("test".to_string()),
13 ..Default::default()
14 },
15 spec: NetworkAuthenticationSpec {
16 networks: vec![
17 Network {
18 cidr: "10.1.0.0/24".parse().unwrap(),
19 except: None,
20 },
21 Network {
22 cidr: "10.1.1.0/24".parse().unwrap(),
23 except: Some(vec!["10.1.1.0/28".parse().unwrap()]),
24 },
25 ],
26 },
27 })
28 .await;
29}
30
31#[tokio::test(flavor = "current_thread")]
32async fn accepts_ip_except() {
33 admission::accepts(|ns| NetworkAuthentication {
34 metadata: api::ObjectMeta {
35 namespace: Some(ns),
36 name: Some("test".to_string()),
37 ..Default::default()
38 },
39 spec: NetworkAuthenticationSpec {
40 networks: vec![Network {
41 cidr: "10.1.0.0/16".parse().unwrap(),
42 except: Some(vec!["10.1.1.1".parse().unwrap()]),
43 }],
44 },
45 })
46 .await;
47}
48
49#[tokio::test(flavor = "current_thread")]
50async fn rejects_except_whole_cidr() {
51 admission::rejects(|ns| NetworkAuthentication {
52 metadata: api::ObjectMeta {
53 namespace: Some(ns),
54 name: Some("test".to_string()),
55 ..Default::default()
56 },
57 spec: NetworkAuthenticationSpec {
58 networks: vec![Network {
59 cidr: "10.1.1.0/24".parse().unwrap(),
60 except: Some(vec!["10.1.0.0/16".parse().unwrap()]),
61 }],
62 },
63 })
64 .await;
65}
66
67#[tokio::test(flavor = "current_thread")]
68async fn rejects_except_not_in_cidr() {
69 admission::rejects(|ns| NetworkAuthentication {
70 metadata: api::ObjectMeta {
71 namespace: Some(ns),
72 name: Some("test".to_string()),
73 ..Default::default()
74 },
75 spec: NetworkAuthenticationSpec {
76 networks: vec![Network {
77 cidr: "10.1.1.0/24".parse().unwrap(),
78 except: Some(vec!["10.1.2.0/24".parse().unwrap()]),
79 }],
80 },
81 })
82 .await;
83}
84
85#[tokio::test(flavor = "current_thread")]
86async fn rejects_invalid_cidr() {
87 // Duplicate the CRD with relaxed validation so we can send an invalid CIDR value.
88 #[derive(
89 Clone,
90 Debug,
91 Default,
92 kube::CustomResource,
93 serde::Deserialize,
94 serde::Serialize,
95 schemars::JsonSchema,
96 )]
97 #[kube(
98 group = "policy.linkerd.io",
99 version = "v1alpha1",
100 kind = "NetworkAuthentication",
101 namespaced
102 )]
103 #[serde(rename_all = "camelCase")]
104 pub struct NetworkAuthenticationSpec {
105 pub networks: Vec<Network>,
106 }
107
108 #[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
109 #[serde(rename_all = "camelCase")]
110 pub struct Network {
111 pub cidr: String,
112 pub except: Option<Vec<String>>,
113 }
114
115 admission::rejects(|ns| NetworkAuthentication {
116 metadata: api::ObjectMeta {
117 namespace: Some(ns),
118 name: Some("test".to_string()),
119 ..Default::default()
120 },
121 spec: NetworkAuthenticationSpec {
122 networks: vec![Network {
123 cidr: "10.1.0.0/16".to_string(),
124 except: Some(vec!["bogus".to_string()]),
125 }],
126 },
127 })
128 .await;
129}
130
131#[tokio::test(flavor = "current_thread")]
132async fn rejects_empty() {
133 admission::rejects(|ns| NetworkAuthentication {
134 metadata: api::ObjectMeta {
135 namespace: Some(ns),
136 name: Some("test".to_string()),
137 ..Default::default()
138 },
139 spec: NetworkAuthenticationSpec { networks: vec![] },
140 })
141 .await;
142}
View as plain text