Skip to content

Commit 330478e

Browse files
authored
Merge pull request #43 from kubewarden/issue13
fix: validate when envvar value is missing.
2 parents 078226c + 296530a commit 330478e

6 files changed

+167
-30
lines changed

e2e.bats

+29
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,52 @@
77
[ $(expr "$output" : '.*"allowed":true.*') -ne 0 ]
88
}
99

10+
@test "Test anyIn with name only" {
11+
run kwctl run --request-path test_data/deployment_anyin.json --settings-path test_data/settings_anyin_names_only.json annotated-policy.wasm
12+
[ "$status" -eq 0 ]
13+
echo "$output"
14+
[ $(expr "$output" : '.*"allowed":true.*') -ne 0 ]
15+
}
16+
1017
@test "Test anyNotIn" {
1118
run kwctl run --request-path test_data/deployment_anynotin.json --settings-path test_data/settings_anynotin.json annotated-policy.wasm
1219
[ "$status" -eq 0 ]
1320
echo "$output"
1421
[ $(expr "$output" : '.*"allowed":true.*') -ne 0 ]
1522
}
1623

24+
@test "Test anyNotIn with names only" {
25+
run kwctl run --request-path test_data/deployment_anynotin.json --settings-path test_data/settings_anynotin_names_only.json annotated-policy.wasm
26+
[ "$status" -eq 0 ]
27+
echo "$output"
28+
[ $(expr "$output" : '.*"allowed":true.*') -ne 0 ]
29+
}
30+
1731
@test "Test allAreUsed" {
1832
run kwctl run --request-path test_data/deployment_allareused.json --settings-path test_data/settings_allareused.json annotated-policy.wasm
1933
[ "$status" -eq 0 ]
2034
echo "$output"
2135
[ $(expr "$output" : '.*"allowed":false.*') -ne 0 ]
2236
}
2337

38+
@test "Test allAreUsed with names only" {
39+
run kwctl run --request-path test_data/deployment_allareused.json --settings-path test_data/settings_allareused_names_only.json annotated-policy.wasm
40+
[ "$status" -eq 0 ]
41+
echo "$output"
42+
[ $(expr "$output" : '.*"allowed":false.*') -ne 0 ]
43+
}
44+
2445
@test "Test notAllAreUsed" {
2546
run kwctl run --request-path test_data/deployment_notallareused.json --settings-path test_data/settings_notallareused.json annotated-policy.wasm
2647
[ "$status" -eq 0 ]
2748
echo "$output"
2849
[ $(expr "$output" : '.*"allowed":false.*') -ne 0 ]
2950
}
51+
52+
@test "Test notAllAreUsed with names only" {
53+
run kwctl run --request-path test_data/deployment_notallareused.json --settings-path test_data/settings_notallareused_names_only.json annotated-policy.wasm
54+
[ "$status" -eq 0 ]
55+
echo "$output"
56+
[ $(expr "$output" : '.*"allowed":false.*') -ne 0 ]
57+
}
58+

src/lib.rs

+92-30
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ use crate::settings::Rule;
1313
const ALL_ARE_USED_ERROR_MSG: &str =
1414
"Resource cannot have all the environment variables from the rule defined.";
1515
const NOT_ALL_ARE_USED_ERROR_MSG: &str =
16-
"Resource should have all the environment variables from the rule defined.";
16+
"Resource should have all the environment variables from the rule defined. Invalid environment variables found:";
1717
const ANY_IN_ERROR_MSG: &str =
18-
"Resource cannot define any of the environment variables from the rule.";
18+
"Resource cannot define any of the environment variables from the rule. Invalid environment variables found:";
1919
const ANY_NOT_IN_ERROR_MSG: &str =
20-
"Resource should define at least one of the environment variables from the rule.";
20+
"Resource should define at least one of the environment variables from the rule. Invalid environment variables found:";
2121

2222
#[no_mangle]
2323
pub extern "C" fn wapc_init() {
@@ -26,54 +26,98 @@ pub extern "C" fn wapc_init() {
2626
register_function("protocol_version", protocol_version_guest);
2727
}
2828

29-
fn validate_envvar_with_rule(rule: &Rule, env_vars: &Vec<apicore::EnvVar>) -> Result<()> {
30-
let error_message: &str;
31-
let mut resource_env_var: HashSet<settings::EnvVar> = HashSet::new();
32-
for envvar in env_vars {
33-
resource_env_var.insert(settings::EnvVar {
29+
fn validate_envvar_with_rule(rule: &Rule, env_vars: &[apicore::EnvVar]) -> Result<()> {
30+
let error_message: String;
31+
let resource_env_var: HashSet<settings::EnvVar> = env_vars
32+
.iter()
33+
.map(|envvar| settings::EnvVar {
3434
name: envvar.name.clone(),
3535
value: envvar.value.clone(),
36-
});
37-
}
36+
})
37+
.collect();
38+
let resource_env_var_names: HashSet<settings::EnvVar> = env_vars
39+
.iter()
40+
.map(|envvar| settings::EnvVar {
41+
name: envvar.name.clone(),
42+
value: None,
43+
})
44+
.collect();
45+
let validation_envvar_with_values: HashSet<settings::EnvVar> = rule
46+
.environment_variables
47+
.clone()
48+
.into_iter()
49+
.filter(|envvar| envvar.value.is_some())
50+
.collect();
51+
let validation_envvar_name_only: HashSet<settings::EnvVar> = rule
52+
.environment_variables
53+
.clone()
54+
.into_iter()
55+
.filter(|envvar| envvar.value.is_none())
56+
.collect();
3857
match rule.reject {
3958
settings::Operator::AllAreUsed => {
40-
if !rule.environment_variables.is_subset(&resource_env_var) {
59+
if !validation_envvar_with_values.is_subset(&resource_env_var)
60+
|| !validation_envvar_name_only.is_subset(&resource_env_var_names)
61+
{
4162
return Ok(());
4263
} else {
43-
error_message = ALL_ARE_USED_ERROR_MSG
64+
error_message = ALL_ARE_USED_ERROR_MSG.to_owned()
4465
}
4566
}
4667
settings::Operator::NotAllAreUsed => {
47-
let difference: HashSet<_> = rule
48-
.environment_variables
68+
let difference: HashSet<_> = validation_envvar_with_values
4969
.difference(&resource_env_var)
5070
.collect();
51-
if difference.is_empty() {
71+
let difference_names_only: HashSet<_> = validation_envvar_name_only
72+
.difference(&resource_env_var_names)
73+
.collect();
74+
if difference.is_empty() && difference_names_only.is_empty() {
5275
return Ok(());
5376
} else {
54-
error_message = NOT_ALL_ARE_USED_ERROR_MSG
77+
let invalid_envvars = difference
78+
.union(&difference_names_only)
79+
.map(|envvar| envvar.name.clone())
80+
.collect::<Vec<String>>()
81+
.join(", ");
82+
error_message = format!("{NOT_ALL_ARE_USED_ERROR_MSG} {invalid_envvars}");
5583
}
5684
}
5785
settings::Operator::AnyIn => {
58-
let intersection: HashSet<_> = rule
59-
.environment_variables
86+
let name_value_intersection: HashSet<_> = validation_envvar_with_values
6087
.intersection(&resource_env_var)
6188
.collect();
62-
if intersection.is_empty() {
89+
let name_intersection: HashSet<_> = validation_envvar_name_only
90+
.intersection(&resource_env_var_names)
91+
.collect();
92+
if name_value_intersection.is_empty() && name_intersection.is_empty() {
6393
return Ok(());
6494
} else {
65-
error_message = ANY_IN_ERROR_MSG
95+
let invalid_envvars = name_value_intersection
96+
.union(&name_intersection)
97+
.map(|envvar| envvar.name.clone())
98+
.collect::<Vec<String>>()
99+
.join(", ");
100+
error_message = format!("{ANY_IN_ERROR_MSG} {invalid_envvars}");
66101
}
67102
}
68103
settings::Operator::AnyNotIn => {
69-
let intersection: HashSet<_> = rule
70-
.environment_variables
104+
let intersection: HashSet<_> = validation_envvar_with_values
71105
.difference(&resource_env_var)
72106
.collect();
73-
if intersection.is_empty() {
107+
let intersection_name: HashSet<_> = validation_envvar_name_only
108+
.difference(&resource_env_var_names)
109+
.collect();
110+
println!("{:?}", intersection);
111+
println!("{:?}", intersection_name);
112+
if intersection.is_empty() && intersection_name.is_empty() {
74113
return Ok(());
75114
} else {
76-
error_message = ANY_NOT_IN_ERROR_MSG
115+
let invalid_envvars = intersection
116+
.union(&intersection_name)
117+
.map(|envvar| envvar.name.clone())
118+
.collect::<Vec<String>>()
119+
.join(", ");
120+
error_message = format!("{ANY_NOT_IN_ERROR_MSG} {invalid_envvars}");
77121
}
78122
}
79123
}
@@ -236,7 +280,10 @@ mod tests {
236280
];
237281
let result = validate_envvar_with_rule(&rule, &envvar);
238282
assert!(result.is_err());
239-
assert_eq!(result.unwrap_err().to_string(), NOT_ALL_ARE_USED_ERROR_MSG);
283+
assert_eq!(
284+
result.unwrap_err().to_string(),
285+
format!("{NOT_ALL_ARE_USED_ERROR_MSG} name3")
286+
);
240287
Ok(())
241288
}
242289

@@ -333,7 +380,10 @@ mod tests {
333380
];
334381
let result = validate_envvar_with_rule(&rule, &envvar);
335382
assert!(result.is_err());
336-
assert_eq!(result.unwrap_err().to_string(), ANY_IN_ERROR_MSG);
383+
assert_eq!(
384+
result.unwrap_err().to_string(),
385+
format!("{ANY_IN_ERROR_MSG} name2")
386+
);
337387
Ok(())
338388
}
339389

@@ -398,7 +448,10 @@ mod tests {
398448
];
399449
let result = validate_envvar_with_rule(&rule, &envvar);
400450
assert!(result.is_err());
401-
assert_eq!(result.unwrap_err().to_string(), ANY_NOT_IN_ERROR_MSG);
451+
assert_eq!(
452+
result.unwrap_err().to_string(),
453+
format!("{ANY_NOT_IN_ERROR_MSG} name")
454+
);
402455
Ok(())
403456
}
404457

@@ -433,7 +486,10 @@ mod tests {
433486
};
434487
let result = validate_environment_variables(&podspec, &settings);
435488
assert!(result.is_err());
436-
assert_eq!(result.unwrap_err().to_string(), ANY_IN_ERROR_MSG);
489+
assert_eq!(
490+
result.unwrap_err().to_string(),
491+
format!("{ANY_IN_ERROR_MSG} name2")
492+
);
437493
Ok(())
438494
}
439495

@@ -468,7 +524,10 @@ mod tests {
468524
};
469525
let result = validate_environment_variables(&podspec, &settings);
470526
assert!(result.is_err());
471-
assert_eq!(result.unwrap_err().to_string(), ANY_IN_ERROR_MSG);
527+
assert_eq!(
528+
result.unwrap_err().to_string(),
529+
format!("{ANY_IN_ERROR_MSG} name")
530+
);
472531
Ok(())
473532
}
474533

@@ -503,7 +562,10 @@ mod tests {
503562
};
504563
let result = validate_environment_variables(&podspec, &settings);
505564
assert!(result.is_err());
506-
assert_eq!(result.unwrap_err().to_string(), ANY_IN_ERROR_MSG);
565+
assert_eq!(
566+
result.unwrap_err().to_string(),
567+
format!("{ANY_IN_ERROR_MSG} name")
568+
);
507569
Ok(())
508570
}
509571
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"rules": [
2+
{
3+
"reject": "allAreUsed",
4+
"environmentVariables": [
5+
{
6+
"name": "foo"
7+
},
8+
{
9+
"name": "foo2"
10+
}
11+
]
12+
}
13+
]
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"rules": [
2+
{
3+
"reject": "anyIn",
4+
"environmentVariables": [
5+
{
6+
"name": "envvar"
7+
}
8+
]
9+
}
10+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"rules": [
2+
{
3+
"reject": "anyNotIn",
4+
"environmentVariables": [
5+
{
6+
"name": "envvar"
7+
}
8+
]
9+
}
10+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"rules": [
2+
{
3+
"reject": "notAllAreUsed",
4+
"environmentVariables": [
5+
{
6+
"name": "foo"
7+
},
8+
{
9+
"name": "foo2"
10+
}
11+
]
12+
}
13+
]

0 commit comments

Comments
 (0)