greentic_interfaces/
validate.rs1use greentic_types::error::{ErrorCode, GResult, GreenticError};
4use semver::Version;
5
6use crate::bindings;
7
8fn invalid_input(message: impl Into<String>) -> GreenticError {
9 GreenticError::new(ErrorCode::InvalidInput, message)
10}
11
12pub fn validate_provider_meta(
14 meta: bindings::greentic::interfaces_provider::provider::ProviderMeta,
15) -> GResult<()> {
16 if meta.name.trim().is_empty() {
17 return Err(invalid_input("provider name must not be empty"));
18 }
19
20 Version::parse(&meta.version)
21 .map_err(|err| invalid_input(format!("invalid semantic version: {err}")))?;
22
23 for domain in &meta.allow_list.domains {
24 if domain.trim().is_empty() {
25 return Err(invalid_input(
26 "allow-list domains must not contain empty entries",
27 ));
28 }
29 }
30
31 for port in &meta.allow_list.ports {
32 if *port == 0 {
33 return Err(invalid_input("allow-list ports must be greater than zero"));
34 }
35 }
36
37 for protocol in &meta.allow_list.protocols {
38 if let bindings::greentic::interfaces_types::types::Protocol::Custom(value) = protocol
39 && value.trim().is_empty()
40 {
41 return Err(invalid_input(
42 "custom protocol identifiers must not be empty",
43 ));
44 }
45 }
46
47 if meta.network_policy.deny_on_miss {
48 let allow = &meta.network_policy.egress;
50 if allow.domains.is_empty() && allow.ports.is_empty() && allow.protocols.is_empty() {
51 return Err(invalid_input(
52 "network policy denying misses requires explicit allow rules",
53 ));
54 }
55 }
56
57 Ok(())
58}