make squid's allowed domains editable at runtime in the swarm ui
This commit is contained in:
parent
86e80250bb
commit
c9abc2a42b
2 changed files with 2307 additions and 35 deletions
56
swarm-controller-api/src/egress.rs
Normal file
56
swarm-controller-api/src/egress.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//! `/api/egress/allowed-domains` — the destinations the swarm lets agents
|
||||
//! reach through their hive's egress proxy.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// One allowed destination and who may reach it.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct AllowedDomain {
|
||||
/// A DNS name of at least two labels, such as `github.com`, stored
|
||||
/// lower-cased. One leading dot, as in `.githubusercontent.com`, also
|
||||
/// allows every subdomain. IP addresses, wildcards, ports, paths and the
|
||||
/// proxy's own always-allowed names are refused.
|
||||
#[cfg_attr(feature = "schema", schema(example = "github.com"))]
|
||||
pub domain: String,
|
||||
/// The agent this entry is for. Absent means every agent in the swarm.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[cfg_attr(feature = "schema", schema(example = "atlas"))]
|
||||
pub agent: Option<String>,
|
||||
}
|
||||
|
||||
/// The swarm's allow-list: every entry, swarm-wide and per agent, sorted.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
|
||||
pub struct AllowedDomains {
|
||||
pub entries: Vec<AllowedDomain>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn an_entry_leaves_out_an_unset_agent_and_refuses_unknown_fields() {
|
||||
let swarm_wide = AllowedDomain {
|
||||
domain: "github.com".to_owned(),
|
||||
agent: None,
|
||||
};
|
||||
let wire = r#"{"domain":"github.com"}"#;
|
||||
assert_eq!(serde_json::to_string(&swarm_wide).unwrap(), wire);
|
||||
assert_eq!(
|
||||
serde_json::from_str::<AllowedDomain>(wire).unwrap(),
|
||||
swarm_wide
|
||||
);
|
||||
let scoped = r#"{"domain":"crates.io","agent":"atlas"}"#;
|
||||
assert_eq!(
|
||||
serde_json::from_str::<AllowedDomain>(scoped)
|
||||
.unwrap()
|
||||
.agent
|
||||
.as_deref(),
|
||||
Some("atlas")
|
||||
);
|
||||
assert!(serde_json::from_str::<AllowedDomain>(r#"{"domain":"a.io","hive":"x"}"#).is_err());
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
pub mod agents;
|
||||
pub mod agents_md;
|
||||
pub mod egress;
|
||||
pub mod forge;
|
||||
pub mod inference;
|
||||
pub mod limits;
|
||||
|
|
|
|||
Loading…
Reference in a new issue