parent
18343cc829
commit
37ae67bd1c
21 changed files with 240 additions and 188 deletions
@ -1,17 +1,18 @@ |
||||
set -ex |
||||
DIR=. |
||||
V3_CFG=v3.ext |
||||
V3_CFG=$DIR/v3.ext |
||||
|
||||
cat > $DIR/$V3_CFG << EOF |
||||
cat > $V3_CFG << EOF |
||||
authorityKeyIdentifier=keyid,issuer |
||||
basicConstraints=CA:FALSE |
||||
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign |
||||
EOF |
||||
|
||||
|
||||
openssl req -x509 -newkey rsa:4096 -keyout $DIR/ca.key -out $DIR/ca.crt -nodes -days 365 -subj "/CN=root" |
||||
openssl req -newkey rsa:4096 -keyout $DIR/alice.key -out $DIR/alice.csr -nodes -days 365 -subj "/CN=alice" |
||||
openssl req -newkey rsa:4096 -keyout $DIR/server.key -out $DIR/server.csr -nodes -days 365 -subj "/CN=u_server" |
||||
openssl x509 -req -in $DIR/alice.csr -CA $DIR/ca.crt -CAkey $DIR/ca.key -out $DIR/alice.crt -set_serial 01 -days 365 -extfile $DIR/$V3_CFG |
||||
openssl x509 -req -in $DIR/server.csr -CA $DIR/ca.crt -CAkey $DIR/ca.key -out $DIR/server.crt -set_serial 01 -days 365 -extfile $DIR/$V3_CFG |
||||
openssl pkcs12 -export -out $DIR/alice.p12 -inkey $DIR/alice.key -in $DIR/alice.crt -passin pass: -passout pass: |
||||
openssl x509 -req -in $DIR/alice.csr -CA $DIR/ca.crt -CAkey $DIR/ca.key -out $DIR/alice.crt -set_serial 01 -days 365 -extfile $V3_CFG |
||||
openssl x509 -req -in $DIR/server.csr -CA $DIR/ca.crt -CAkey $DIR/ca.key -out $DIR/server.crt -set_serial 01 -days 365 -extfile $V3_CFG |
||||
openssl pkcs12 -export -out $DIR/alice.p12 -inkey $DIR/alice.key -in $DIR/alice.crt -passin pass: -passout pass: |
||||
|
||||
rm $V3_CFG |
@ -1 +1,46 @@ |
||||
use crate::fixtures::agent::*; |
||||
use crate::helpers::Panel; |
||||
|
||||
use rstest::rstest; |
||||
use std::error::Error; |
||||
use std::thread::sleep; |
||||
use std::time::Duration; |
||||
use u_lib::models::*; |
||||
use uuid::Uuid; |
||||
|
||||
type TestResult<R = ()> = Result<R, Box<dyn Error>>; |
||||
|
||||
#[rstest] |
||||
#[tokio::test] |
||||
async fn test_registration(#[future] register_agent: RegisteredAgent) -> TestResult { |
||||
let agent = register_agent.await; |
||||
let agents: Vec<Agent> = Panel::check_output("agents list"); |
||||
let found = agents.iter().find(|v| v.id == agent.uid); |
||||
assert!(found.is_some()); |
||||
//teardown
|
||||
Panel::check_status::<i32>(&format!("agents delete {}", agent.uid)); |
||||
Ok(()) //TODO: ______^^^^^ REMOV
|
||||
} |
||||
|
||||
#[tokio::test] |
||||
async fn test_setup_tasks() -> TestResult { |
||||
//some independent agents should present
|
||||
let agents: Vec<Agent> = Panel::check_output("agents list"); |
||||
let agent_uid = agents[0].id; |
||||
let job_alias = "passwd_contents"; |
||||
let cmd = format!("jobs add --alias {} 'cat /etc/passwd'", job_alias); |
||||
Panel::check_status::<Empty>(&cmd); |
||||
let cmd = format!("jobmap add {} {}", agent_uid, job_alias); |
||||
let assigned_uids: Vec<Uuid> = Panel::check_output(cmd); |
||||
for _ in 0..3 { |
||||
let result: Vec<AssignedJob> = |
||||
Panel::check_output(format!("jobmap list {}", assigned_uids[0])); |
||||
if result[0].state == JobState::Finished { |
||||
return Ok(()); |
||||
} else { |
||||
sleep(Duration::from_secs(5)); |
||||
eprintln!("waiting for task"); |
||||
} |
||||
} |
||||
panic!("Job didn't appear in the job map"); |
||||
} |
||||
|
@ -0,0 +1,36 @@ |
||||
use u_lib::{api::ClientHandler, models::*}; |
||||
use uuid::Uuid; |
||||
|
||||
pub struct RegisteredAgent { |
||||
pub uid: Uuid, |
||||
} |
||||
|
||||
impl RegisteredAgent { |
||||
pub async fn unregister(self) { |
||||
let cli = ClientHandler::new(None); |
||||
cli.del(Some(self.uid)).await.unwrap(); |
||||
} |
||||
} |
||||
|
||||
#[fixture] |
||||
pub async fn register_agent() -> RegisteredAgent { |
||||
let cli = ClientHandler::new(None); |
||||
let agent_uid = Uuid::new_v4(); |
||||
let resp = cli |
||||
.get_personal_jobs(Some(agent_uid)) |
||||
.await |
||||
.unwrap() |
||||
.pop() |
||||
.unwrap(); |
||||
let job_id = resp.job_id; |
||||
let resp = cli.get_jobs(Some(job_id)).await.unwrap().pop().unwrap(); |
||||
assert_eq!(resp.alias, Some("agent_hello".to_string())); |
||||
let agent_data = Agent { |
||||
id: agent_uid, |
||||
..Default::default() |
||||
}; |
||||
cli.report(&vec![ExecResult::Agent(agent_data)]) |
||||
.await |
||||
.unwrap(); |
||||
RegisteredAgent { uid: agent_uid } |
||||
} |
@ -0,0 +1 @@ |
||||
pub mod agent; |
@ -1,48 +0,0 @@ |
||||
use reqwest::{Client, RequestBuilder, Url}; |
||||
use serde::Serialize; |
||||
use serde_json::{from_str, json, Value}; |
||||
|
||||
const SERVER: &str = "u_server"; |
||||
const PORT: &str = "63714"; |
||||
|
||||
pub struct AgentClient { |
||||
client: Client, |
||||
base_url: Url, |
||||
} |
||||
|
||||
impl AgentClient { |
||||
pub fn new() -> Self { |
||||
Self { |
||||
client: Client::new(), |
||||
base_url: Url::parse(&format!("http://{}:{}", SERVER, PORT)).unwrap(), |
||||
} |
||||
} |
||||
|
||||
async fn process_request(&self, req: RequestBuilder, resp_needed: bool) -> Value { |
||||
let resp = req.send().await.unwrap(); |
||||
if let Err(e) = resp.error_for_status_ref() { |
||||
panic!( |
||||
"Server responded with code {}\nError: {}", |
||||
e.status() |
||||
.map(|s| s.to_string()) |
||||
.unwrap_or(String::from("<none>")), |
||||
e.to_string() |
||||
); |
||||
} |
||||
if !resp_needed { |
||||
return json!([]); |
||||
} |
||||
let resp: Value = from_str(&resp.text().await.unwrap()).unwrap(); |
||||
resp.get("inner").unwrap().get(0).unwrap().clone() |
||||
} |
||||
|
||||
pub async fn get<S: AsRef<str>>(&self, url: S) -> Value { |
||||
let req = self.client.get(self.base_url.join(url.as_ref()).unwrap()); |
||||
self.process_request(req, true).await |
||||
} |
||||
|
||||
pub async fn post<S: AsRef<str>, B: Serialize>(&self, url: S, body: &B) -> Value { |
||||
let req = self.client.post(self.base_url.join(url.as_ref()).unwrap()); |
||||
self.process_request(req.json(body), false).await |
||||
} |
||||
} |
@ -1,67 +1,6 @@ |
||||
mod behaviour; |
||||
mod fixtures; |
||||
mod helpers; |
||||
|
||||
use helpers::Panel; |
||||
|
||||
use std::error::Error; |
||||
use std::thread::sleep; |
||||
use std::time::Duration; |
||||
use u_lib::{api::ClientHandler, models::*}; |
||||
use uuid::Uuid; |
||||
|
||||
type TestResult<R = ()> = Result<R, Box<dyn Error>>; |
||||
|
||||
async fn register_agent() -> Uuid { |
||||
let cli = ClientHandler::new(None); |
||||
let agent_uid = Uuid::new_v4(); |
||||
let resp = cli |
||||
.get_personal_jobs(Some(agent_uid)) |
||||
.await |
||||
.unwrap() |
||||
.pop() |
||||
.unwrap(); |
||||
let job_id = resp.job_id; |
||||
let resp = cli.get_jobs(Some(job_id)).await.unwrap().pop().unwrap(); |
||||
assert_eq!(resp.alias, Some("agent_hello".to_string())); |
||||
let agent_data = Agent { |
||||
id: agent_uid, |
||||
..Default::default() |
||||
}; |
||||
cli.report(&vec![ExecResult::Agent(agent_data)]) |
||||
.await |
||||
.unwrap(); |
||||
agent_uid |
||||
} |
||||
|
||||
#[tokio::test] |
||||
async fn test_registration() -> TestResult { |
||||
let agent_uid = register_agent().await; |
||||
let agents: Vec<Agent> = Panel::check_output("agents list"); |
||||
let found = agents.iter().find(|v| v.id == agent_uid); |
||||
assert!(found.is_some()); |
||||
//teardown
|
||||
Panel::check_status::<i32>(&format!("agents delete {}", agent_uid)); |
||||
Ok(()) |
||||
} |
||||
|
||||
#[tokio::test] |
||||
async fn test_setup_tasks() -> TestResult { |
||||
//some independent agents should present
|
||||
let agents: Vec<Agent> = Panel::check_output("agents list"); |
||||
let agent_uid = agents[0].id; |
||||
let job_alias = "passwd_contents"; |
||||
let cmd = format!("jobs add --alias {} 'cat /etc/passwd'", job_alias); |
||||
Panel::check_status::<Empty>(&cmd); |
||||
let cmd = format!("jobmap add {} {}", agent_uid, job_alias); |
||||
let assigned_uids: Vec<Uuid> = Panel::check_output(cmd); |
||||
for _ in 0..3 { |
||||
let result: Vec<AssignedJob> = |
||||
Panel::check_output(format!("jobmap list {}", assigned_uids[0])); |
||||
if result[0].state == JobState::Finished { |
||||
return Ok(()); |
||||
} else { |
||||
sleep(Duration::from_secs(5)); |
||||
eprintln!("waiting for task"); |
||||
} |
||||
} |
||||
panic!() |
||||
} |
||||
#[macro_use] |
||||
extern crate rstest; |
||||
|
@ -0,0 +1,8 @@ |
||||
use serde::{Deserialize, Serialize}; |
||||
use uuid::Uuid; |
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Default)] |
||||
pub struct DownloadInfo { |
||||
hashsum: String, |
||||
dl_fid: Uuid, |
||||
} |
@ -0,0 +1,29 @@ |
||||
mod base; |
||||
mod files; |
||||
|
||||
use crate::models::*; |
||||
pub use base::{AsMsg, BaseMessage}; |
||||
pub use files::*; |
||||
use serde::{Deserialize, Serialize}; |
||||
use std::fmt; |
||||
use uuid::Uuid; |
||||
|
||||
impl AsMsg for Agent {} |
||||
impl AsMsg for AssignedJob {} |
||||
impl AsMsg for DownloadInfo {} |
||||
impl AsMsg for ExecResult {} |
||||
impl AsMsg for JobMeta {} |
||||
impl AsMsg for String {} |
||||
impl AsMsg for Uuid {} |
||||
impl AsMsg for Empty {} |
||||
impl AsMsg for i32 {} |
||||
impl AsMsg for u8 {} |
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Default, Debug)] |
||||
pub struct Empty; |
||||
|
||||
impl fmt::Display for Empty { |
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
||||
write!(f, "<empty>") |
||||
} |
||||
} |
@ -1,29 +1,13 @@ |
||||
mod agent; |
||||
pub mod jobs; |
||||
mod result; |
||||
pub mod schema; |
||||
|
||||
use crate::messaging::AsMsg; |
||||
pub use crate::models::result::ExecResult; |
||||
pub use crate::models::{agent::*, jobs::*}; |
||||
use serde::{Deserialize, Serialize}; |
||||
use std::fmt; |
||||
use uuid::Uuid; |
||||
|
||||
impl AsMsg for Agent {} |
||||
impl AsMsg for AssignedJob {} |
||||
impl AsMsg for ExecResult {} |
||||
impl AsMsg for JobMeta {} |
||||
impl AsMsg for String {} |
||||
impl AsMsg for Uuid {} |
||||
impl AsMsg for Empty {} |
||||
impl AsMsg for i32 {} |
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Default, Debug)] |
||||
pub struct Empty; |
||||
|
||||
impl fmt::Display for Empty { |
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
||||
write!(f, "<empty>") |
||||
} |
||||
#[derive(Serialize, Deserialize, Clone, PartialEq)] |
||||
pub enum ExecResult { |
||||
Assigned(AssignedJob), |
||||
Agent(Agent), |
||||
Dummy, |
||||
} |
||||
|
@ -1,9 +0,0 @@ |
||||
use crate::models::{Agent, AssignedJob}; |
||||
use serde::{Deserialize, Serialize}; |
||||
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq)] |
||||
pub enum ExecResult { |
||||
Assigned(AssignedJob), |
||||
Agent(Agent), |
||||
Dummy, |
||||
} |
@ -0,0 +1,12 @@ |
||||
use std::fmt; |
||||
|
||||
pub struct Hexlify<'b>(pub &'b [u8]); |
||||
|
||||
impl<'a> fmt::LowerHex for Hexlify<'a> { |
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
||||
for byte in self.0.iter() { |
||||
write!(f, "{:02x}", byte)?; |
||||
} |
||||
Ok(()) |
||||
} |
||||
} |
@ -1,11 +1,15 @@ |
||||
pub mod combined_result; |
||||
pub mod conv; |
||||
pub mod misc; |
||||
pub mod tempfile; |
||||
pub mod vec_display; |
||||
mod combined_result; |
||||
mod conv; |
||||
mod hexlify; |
||||
mod misc; |
||||
mod storage; |
||||
mod tempfile; |
||||
mod vec_display; |
||||
|
||||
pub use combined_result::*; |
||||
pub use conv::*; |
||||
pub use hexlify::*; |
||||
pub use misc::*; |
||||
pub use storage::*; |
||||
pub use tempfile::*; |
||||
pub use vec_display::*; |
||||
|
@ -0,0 +1,39 @@ |
||||
use once_cell::sync::Lazy; |
||||
use std::cmp::Eq; |
||||
use std::collections::HashMap; |
||||
use std::hash::Hash; |
||||
use std::ops::Deref; |
||||
use std::sync::Arc; |
||||
use std::sync::{Mutex, MutexGuard}; |
||||
|
||||
//improve this later, replace job cacher with it
|
||||
//possibly add different backends (memory, disk)
|
||||
pub struct SharedStorage<Key, Val>(Arc<Mutex<HashMap<Key, Val>>>); |
||||
|
||||
impl<Key: Eq + Hash, Val> SharedStorage<Key, Val> { |
||||
pub fn new() -> Lazy<SharedStorage<Key, Val>> { |
||||
Lazy::new(|| SharedStorage(Arc::new(Mutex::new(HashMap::new())))) |
||||
} |
||||
|
||||
pub fn lock(&self) -> MutexGuard<'_, HashMap<Key, Val>> { |
||||
self.0.lock().unwrap() |
||||
} |
||||
|
||||
pub fn get<'get, 'slf: 'get>(&'slf self, key: &'get Key) -> Option<RefHolder<'get, Key, Val>> { |
||||
if !self.lock().contains_key(key) { |
||||
return None; |
||||
} |
||||
let lock = self.lock(); |
||||
Some(RefHolder(lock, key)) |
||||
} |
||||
} |
||||
|
||||
pub struct RefHolder<'h, Key, Val>(pub MutexGuard<'h, HashMap<Key, Val>>, pub &'h Key); |
||||
|
||||
impl<'h, Key: Eq + Hash, Val> Deref for RefHolder<'h, Key, Val> { |
||||
type Target = Val; |
||||
|
||||
fn deref(&self) -> &Self::Target { |
||||
self.0.get(self.1).unwrap() |
||||
} |
||||
} |
Loading…
Reference in new issue