From 5e82b9ed1f7f236d596500478588dd2f84231fef Mon Sep 17 00:00:00 2001 From: "Carpenter, Adam (CORP)" Date: Wed, 8 Dec 2021 15:29:59 -0500 Subject: feat: begin basic filter --- angelsharkd/src/routes/extensions/simple_deprov.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'angelsharkd/src/routes') diff --git a/angelsharkd/src/routes/extensions/simple_deprov.rs b/angelsharkd/src/routes/extensions/simple_deprov.rs index 2b5ad40..eeb27a0 100644 --- a/angelsharkd/src/routes/extensions/simple_deprov.rs +++ b/angelsharkd/src/routes/extensions/simple_deprov.rs @@ -1,5 +1,12 @@ -use warp::{Filter, Rejection, Reply}; +use warp::{ + body::{content_length_limit, json}, + post, Filter, Rejection, Reply, +}; pub fn filter() -> impl Filter + Clone { - warp::path("deprov").map(|| -> &str { todo!() }) // TODO: + warp::path("deprov") + .and(post()) + .and(content_length_limit(1024 * 16)) + .and(json()) + .map(|_: String| -> &str { todo!() }) // TODO: } -- cgit v1.2.3 From 8cf1549a87c984337eb013a67e8e211cfe18cd24 Mon Sep 17 00:00:00 2001 From: "Carpenter, Adam (CORP)" Date: Thu, 9 Dec 2021 11:56:49 -0500 Subject: chore: cleanup, remove commented code, naming --- angelsharkd/src/routes/extensions/mod.rs | 6 +++--- angelsharkd/src/routes/extensions/simple_search/mod.rs | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'angelsharkd/src/routes') diff --git a/angelsharkd/src/routes/extensions/mod.rs b/angelsharkd/src/routes/extensions/mod.rs index cada47f..54053af 100644 --- a/angelsharkd/src/routes/extensions/mod.rs +++ b/angelsharkd/src/routes/extensions/mod.rs @@ -8,7 +8,7 @@ mod simple_search; /// The extension filter; consists of all compiled optional Angelshark extension /// filters combined under `/extensions`. -pub fn filter(_config: &Config) -> impl Filter + Clone { +pub fn filter(config: &Config) -> impl Filter + Clone { // Note: this next line deals with the common edge case of having no // extensions loaded with feature flags. It ensures that the the type // checking is right when the return `.and()` is called below. @@ -17,14 +17,14 @@ pub fn filter(_config: &Config) -> impl Filter Result { - // Ok(haystack.search(Vec::new())?) - // if let Ok(matches = haystack.search(needle); match haystack.search(needles) { Ok(matches) => Ok(reply::with_status(reply::json(&matches), StatusCode::OK)), Err(e) => Ok(reply::with_status( -- cgit v1.2.3 From ab4a81cf5a794b9d84a854a4a5449a5ed622ebdd Mon Sep 17 00:00:00 2001 From: "Carpenter, Adam (CORP)" Date: Thu, 9 Dec 2021 11:58:01 -0500 Subject: feat: begin impl basic deprov filter --- angelsharkd/src/routes/extensions/simple_deprov.rs | 35 ++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'angelsharkd/src/routes') diff --git a/angelsharkd/src/routes/extensions/simple_deprov.rs b/angelsharkd/src/routes/extensions/simple_deprov.rs index eeb27a0..de45d9b 100644 --- a/angelsharkd/src/routes/extensions/simple_deprov.rs +++ b/angelsharkd/src/routes/extensions/simple_deprov.rs @@ -1,12 +1,43 @@ +use std::{convert::Infallible, fmt::Display}; + +use libangelshark::{AcmRunner, Message}; +use serde::Deserialize; use warp::{ body::{content_length_limit, json}, post, Filter, Rejection, Reply, }; -pub fn filter() -> impl Filter + Clone { +pub fn filter(runner: AcmRunner) -> impl Filter + Clone { warp::path("deprov") .and(post()) .and(content_length_limit(1024 * 16)) .and(json()) - .map(|_: String| -> &str { todo!() }) // TODO: + .and_then(move |entries: Entries| remove_entries(entries, runner.to_owned())) +} + +async fn remove_entries(entries: Entries, runner: AcmRunner) -> Result { + Ok("") +} + +type Entries = Vec; + +#[derive(Debug, Deserialize)] +enum Entry { + #[serde(rename(deserialize = "station-user"))] + StationUser { acm: String, ext: String }, + #[serde(rename(deserialize = "agent-loginid"))] + AgentLoginId { acm: String, ext: String }, +} + +impl From for Vec { + fn from(entry: Entry) -> Self { + match entry { + Entry::StationUser { acm, ext } => { + vec![Message::new(&format!("clear amw all {}", ext))] + } + Entry::AgentLoginId { acm, ext } => { + todo!() + } + } + } } -- cgit v1.2.3 From 8c1c700ec1d5a28a2d85c662ec48db0a8ff84707 Mon Sep 17 00:00:00 2001 From: "Carpenter, Adam (CORP)" Date: Fri, 10 Dec 2021 10:11:10 -0500 Subject: chore: remove completed todo --- angelsharkd/src/routes/extensions/simple_search/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'angelsharkd/src/routes') diff --git a/angelsharkd/src/routes/extensions/simple_search/mod.rs b/angelsharkd/src/routes/extensions/simple_search/mod.rs index 350edc8..159137a 100644 --- a/angelsharkd/src/routes/extensions/simple_search/mod.rs +++ b/angelsharkd/src/routes/extensions/simple_search/mod.rs @@ -54,7 +54,7 @@ async fn refresh(haystack: Haystack) -> Result { // Run refresh as a background task and immediately return. tokio::spawn(async move { if let Err(e) = haystack.refresh() { - error!("{}", e.to_string()); // TODO: use logger + error!("{}", e.to_string()); } else { info!("Search haystack refreshed."); } -- cgit v1.2.3 From a91ee6ff6467d131c76151fb18ca2c55345db188 Mon Sep 17 00:00:00 2001 From: "Carpenter, Adam (CORP)" Date: Fri, 10 Dec 2021 10:11:27 -0500 Subject: feat: impl deprov runner queueing from requests --- angelsharkd/src/routes/extensions/simple_deprov.rs | 30 ++++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'angelsharkd/src/routes') diff --git a/angelsharkd/src/routes/extensions/simple_deprov.rs b/angelsharkd/src/routes/extensions/simple_deprov.rs index de45d9b..eb6f04b 100644 --- a/angelsharkd/src/routes/extensions/simple_deprov.rs +++ b/angelsharkd/src/routes/extensions/simple_deprov.rs @@ -15,7 +15,22 @@ pub fn filter(runner: AcmRunner) -> impl Filter Result { +async fn remove_entries(entries: Entries, mut runner: AcmRunner) -> Result { + for entry in entries { + match entry { + Entry::StationUser { acm, ext } => { + runner.queue_input(&acm, &Message::new(&format!("clear amw all {}", ext))); + runner.queue_input(&acm, &Message::new(&format!("remove station {}", ext))); + } + Entry::AgentLoginId { acm, ext } => { + runner.queue_input( + &acm, + &Message::new(&format!("remove agent-loginID {}", ext)), + ); + } + } + } + dbg!(&runner); Ok("") } @@ -28,16 +43,3 @@ enum Entry { #[serde(rename(deserialize = "agent-loginid"))] AgentLoginId { acm: String, ext: String }, } - -impl From for Vec { - fn from(entry: Entry) -> Self { - match entry { - Entry::StationUser { acm, ext } => { - vec![Message::new(&format!("clear amw all {}", ext))] - } - Entry::AgentLoginId { acm, ext } => { - todo!() - } - } - } -} -- cgit v1.2.3 From 7b6b942b8d70f5bcf0c48ecf2c67c4af460d98ab Mon Sep 17 00:00:00 2001 From: "Carpenter, Adam (CORP)" Date: Fri, 10 Dec 2021 11:11:33 -0500 Subject: feat: complete impl simple deprov --- angelsharkd/src/routes/extensions/simple_deprov.rs | 35 +++++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'angelsharkd/src/routes') diff --git a/angelsharkd/src/routes/extensions/simple_deprov.rs b/angelsharkd/src/routes/extensions/simple_deprov.rs index eb6f04b..df818f0 100644 --- a/angelsharkd/src/routes/extensions/simple_deprov.rs +++ b/angelsharkd/src/routes/extensions/simple_deprov.rs @@ -1,21 +1,25 @@ -use std::{convert::Infallible, fmt::Display}; - -use libangelshark::{AcmRunner, Message}; +use libangelshark::{AcmRunner, Message, ParallelIterator}; use serde::Deserialize; +use std::convert::Infallible; use warp::{ body::{content_length_limit, json}, - post, Filter, Rejection, Reply, + post, reply, Filter, Rejection, Reply, }; +const SIXTEEN_K: u64 = 1024 * 16; + +/// Returns a warp filter to handle HTTP POSTs for deprovisioning stations, agents, etc. pub fn filter(runner: AcmRunner) -> impl Filter + Clone { warp::path("deprov") .and(post()) - .and(content_length_limit(1024 * 16)) + .and(content_length_limit(SIXTEEN_K)) .and(json()) - .and_then(move |entries: Entries| remove_entries(entries, runner.to_owned())) + .and_then(move |entries| remove_entries(entries, runner.to_owned())) } +/// Queues removal commands for [Entries] on an [AcmRunner]. Gathers any errors encountered and returns those. async fn remove_entries(entries: Entries, mut runner: AcmRunner) -> Result { + // Construct OSSI messages to carry out removals. for entry in entries { match entry { Entry::StationUser { acm, ext } => { @@ -30,12 +34,27 @@ async fn remove_entries(entries: Entries, mut runner: AcmRunner) -> Result = runner + .run_cached() + .map(|(acm, output)| match output { + Ok(messages) => messages + .into_iter() + .filter_map(|message| Some(format!("ACM {}: {}", acm.clone(), message.error?))) + .collect(), + Err(error) => vec![format!("ACM {}: {}", acm, error)], + }) + .flatten() + .collect(); + + Ok(reply::json(&errors)) } +/// Collection of [Entry]. type Entries = Vec; +/// Very basic [Deserialize] target for deprov inputs. Going from stringly typed to strongly typed. #[derive(Debug, Deserialize)] enum Entry { #[serde(rename(deserialize = "station-user"))] -- cgit v1.2.3 From 5e63f0a5ac067630c2ca0d4d0face7f68058906b Mon Sep 17 00:00:00 2001 From: "Carpenter, Adam (CORP)" Date: Fri, 10 Dec 2021 11:19:23 -0500 Subject: feat: log all encountered errors as well --- angelsharkd/src/routes/extensions/simple_deprov.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'angelsharkd/src/routes') diff --git a/angelsharkd/src/routes/extensions/simple_deprov.rs b/angelsharkd/src/routes/extensions/simple_deprov.rs index df818f0..6e7ca71 100644 --- a/angelsharkd/src/routes/extensions/simple_deprov.rs +++ b/angelsharkd/src/routes/extensions/simple_deprov.rs @@ -1,4 +1,5 @@ use libangelshark::{AcmRunner, Message, ParallelIterator}; +use log::error; use serde::Deserialize; use std::convert::Infallible; use warp::{ @@ -48,6 +49,11 @@ async fn remove_entries(entries: Entries, mut runner: AcmRunner) -> Result Date: Fri, 10 Dec 2021 11:20:23 -0500 Subject: fix: only log necessary info --- angelsharkd/src/routes/extensions/simple_deprov.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'angelsharkd/src/routes') diff --git a/angelsharkd/src/routes/extensions/simple_deprov.rs b/angelsharkd/src/routes/extensions/simple_deprov.rs index 6e7ca71..fc734f3 100644 --- a/angelsharkd/src/routes/extensions/simple_deprov.rs +++ b/angelsharkd/src/routes/extensions/simple_deprov.rs @@ -51,7 +51,7 @@ async fn remove_entries(entries: Entries, mut runner: AcmRunner) -> Result Date: Fri, 10 Dec 2021 11:27:55 -0500 Subject: chore: move deprov into subdir --- angelsharkd/src/routes/extensions/simple_deprov.rs | 70 ---------------------- .../src/routes/extensions/simple_deprov/mod.rs | 70 ++++++++++++++++++++++ 2 files changed, 70 insertions(+), 70 deletions(-) delete mode 100644 angelsharkd/src/routes/extensions/simple_deprov.rs create mode 100644 angelsharkd/src/routes/extensions/simple_deprov/mod.rs (limited to 'angelsharkd/src/routes') diff --git a/angelsharkd/src/routes/extensions/simple_deprov.rs b/angelsharkd/src/routes/extensions/simple_deprov.rs deleted file mode 100644 index fc734f3..0000000 --- a/angelsharkd/src/routes/extensions/simple_deprov.rs +++ /dev/null @@ -1,70 +0,0 @@ -use libangelshark::{AcmRunner, Message, ParallelIterator}; -use log::error; -use serde::Deserialize; -use std::convert::Infallible; -use warp::{ - body::{content_length_limit, json}, - post, reply, Filter, Rejection, Reply, -}; - -const SIXTEEN_K: u64 = 1024 * 16; - -/// Returns a warp filter to handle HTTP POSTs for deprovisioning stations, agents, etc. -pub fn filter(runner: AcmRunner) -> impl Filter + Clone { - warp::path("deprov") - .and(post()) - .and(content_length_limit(SIXTEEN_K)) - .and(json()) - .and_then(move |entries| remove_entries(entries, runner.to_owned())) -} - -/// Queues removal commands for [Entries] on an [AcmRunner]. Gathers any errors encountered and returns those. -async fn remove_entries(entries: Entries, mut runner: AcmRunner) -> Result { - // Construct OSSI messages to carry out removals. - for entry in entries { - match entry { - Entry::StationUser { acm, ext } => { - runner.queue_input(&acm, &Message::new(&format!("clear amw all {}", ext))); - runner.queue_input(&acm, &Message::new(&format!("remove station {}", ext))); - } - Entry::AgentLoginId { acm, ext } => { - runner.queue_input( - &acm, - &Message::new(&format!("remove agent-loginID {}", ext)), - ); - } - } - } - - // Gather any errors encountered and format them for the client response. - let errors: Vec = runner - .run_cached() - .map(|(acm, output)| match output { - Ok(messages) => messages - .into_iter() - .filter_map(|message| Some(format!("ACM {}: {}", acm.clone(), message.error?))) - .collect(), - Err(error) => vec![format!("ACM {}: {}", acm, error)], - }) - .flatten() - .collect(); - - // Log errors for tracking. - for error in &errors { - error!("{}", error); - } - - Ok(reply::json(&errors)) -} - -/// Collection of [Entry]. -type Entries = Vec; - -/// Very basic [Deserialize] target for deprov inputs. Going from stringly typed to strongly typed. -#[derive(Debug, Deserialize)] -enum Entry { - #[serde(rename(deserialize = "station-user"))] - StationUser { acm: String, ext: String }, - #[serde(rename(deserialize = "agent-loginid"))] - AgentLoginId { acm: String, ext: String }, -} diff --git a/angelsharkd/src/routes/extensions/simple_deprov/mod.rs b/angelsharkd/src/routes/extensions/simple_deprov/mod.rs new file mode 100644 index 0000000..fc734f3 --- /dev/null +++ b/angelsharkd/src/routes/extensions/simple_deprov/mod.rs @@ -0,0 +1,70 @@ +use libangelshark::{AcmRunner, Message, ParallelIterator}; +use log::error; +use serde::Deserialize; +use std::convert::Infallible; +use warp::{ + body::{content_length_limit, json}, + post, reply, Filter, Rejection, Reply, +}; + +const SIXTEEN_K: u64 = 1024 * 16; + +/// Returns a warp filter to handle HTTP POSTs for deprovisioning stations, agents, etc. +pub fn filter(runner: AcmRunner) -> impl Filter + Clone { + warp::path("deprov") + .and(post()) + .and(content_length_limit(SIXTEEN_K)) + .and(json()) + .and_then(move |entries| remove_entries(entries, runner.to_owned())) +} + +/// Queues removal commands for [Entries] on an [AcmRunner]. Gathers any errors encountered and returns those. +async fn remove_entries(entries: Entries, mut runner: AcmRunner) -> Result { + // Construct OSSI messages to carry out removals. + for entry in entries { + match entry { + Entry::StationUser { acm, ext } => { + runner.queue_input(&acm, &Message::new(&format!("clear amw all {}", ext))); + runner.queue_input(&acm, &Message::new(&format!("remove station {}", ext))); + } + Entry::AgentLoginId { acm, ext } => { + runner.queue_input( + &acm, + &Message::new(&format!("remove agent-loginID {}", ext)), + ); + } + } + } + + // Gather any errors encountered and format them for the client response. + let errors: Vec = runner + .run_cached() + .map(|(acm, output)| match output { + Ok(messages) => messages + .into_iter() + .filter_map(|message| Some(format!("ACM {}: {}", acm.clone(), message.error?))) + .collect(), + Err(error) => vec![format!("ACM {}: {}", acm, error)], + }) + .flatten() + .collect(); + + // Log errors for tracking. + for error in &errors { + error!("{}", error); + } + + Ok(reply::json(&errors)) +} + +/// Collection of [Entry]. +type Entries = Vec; + +/// Very basic [Deserialize] target for deprov inputs. Going from stringly typed to strongly typed. +#[derive(Debug, Deserialize)] +enum Entry { + #[serde(rename(deserialize = "station-user"))] + StationUser { acm: String, ext: String }, + #[serde(rename(deserialize = "agent-loginid"))] + AgentLoginId { acm: String, ext: String }, +} -- cgit v1.2.3 From f98a1fa3035fb4834441ead1cce6710739312e14 Mon Sep 17 00:00:00 2001 From: "Carpenter, Adam (CORP)" Date: Fri, 10 Dec 2021 11:35:06 -0500 Subject: docs: add readme for deprov --- .../src/routes/extensions/simple_deprov/README.md | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 angelsharkd/src/routes/extensions/simple_deprov/README.md (limited to 'angelsharkd/src/routes') diff --git a/angelsharkd/src/routes/extensions/simple_deprov/README.md b/angelsharkd/src/routes/extensions/simple_deprov/README.md new file mode 100644 index 0000000..4900075 --- /dev/null +++ b/angelsharkd/src/routes/extensions/simple_deprov/README.md @@ -0,0 +1,61 @@ +# Daemon Extension `simple_deprov` + +This extension implements excruciatingly simple extension de-provisioning. For +example, if an agent was provisioned with a `station-user` and an +`agent-loginid`, you can submit those extensions, their type, and the ACM they +were provision on. They relevant commands to remove those objects will be +executed in parallel, and any errors encountered will be returned. + +## Getting Started + +To enable this feature, compile `angelsharkd` with the `simple_deprov` flag: + +```sh +cargo build --bin angelsharkd --features simple_deprov ... +``` + +## `POST /extensions/deprov` Remove Objects + +The request type is TODO: + +```json +POST /extensions/deprov +[ + { + "station-user": { + "acm": "01", + "ext": "17571230000" + } + }, + { + "agent-loginid": { + "acm": "01", + "ext": "17571240000" + } + } +] +``` + +If all of the deprov commands were successful, the response is an empty array. + +```json +200 OK +[] +``` + +If there were errors running the relevant deprov commands (such as when an +extension does not exist), they are included in the resulting array. + +```json +200 OK +[ + "ACM lab: 1 00000000 309e Extension exists but assigned to a different object", + "ACM lab: 1 00000000 2ed5 Extension assigned as remote extension on the uniform-dialplan form", + "ACM lab: 1 00000000 2ed5 Extension assigned as remote extension on the uniform-dialplan form" +] +``` + +## Logging + +The `deprov` endpoint always returns successfully. Any errors encountered during +the command execution are logged as `ERROR`. -- cgit v1.2.3