diff --git a/Cargo.lock b/Cargo.lock index 781f38e..d3aa969 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,6 +9,9 @@ dependencies = [ "pyo3", "reqwest", "serde", + "serde-pyobject", + "serde_json", + "tokio", ] [[package]] @@ -543,6 +546,15 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.28" @@ -648,6 +660,29 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link 0.2.1", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -782,6 +817,15 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + [[package]] name = "reqwest" version = "0.12.24" @@ -903,6 +947,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "security-framework" version = "2.11.1" @@ -936,6 +986,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-pyobject" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5614e792b7c36d3feeb45b8287ea2dc615f063896e59258d11ef5015c18bdf6a" +dependencies = [ + "log", + "pyo3", + "serde", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -987,6 +1048,15 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook-registry" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +dependencies = [ + "libc", +] + [[package]] name = "slab" version = "0.4.11" @@ -1111,11 +1181,25 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", + "signal-hook-registry", "socket2", + "tokio-macros", "windows-sys 0.61.2", ] +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tokio-native-tls" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index ac01ddc..aa9bbea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,21 @@ crate-type = ["cdylib"] [dependencies] pyo3 = { version = "0.27.0", features = ["extension-module", "generate-import-lib"] } -reqwest = "0.12.24" +reqwest = { version = "0.12.24", features = ["json", "native-tls"] } serde = "1.0.228" +serde-pyobject = "0.8.0" +serde_json = "1.0.145" +tokio = { version = "1.48.0", features = ["full"] } [package.metadata.maturin] generate-abi-stubs = true + +[profile.release] +opt-level = "z" +lto = "fat" +debug = false +codegen-units = 1 +panic = 'abort' +strip = true +debug-assertions = false +overflow-checks = false diff --git a/src/chunkinator.rs b/src/chunkinator.rs index e69de29..8b13789 100644 --- a/src/chunkinator.rs +++ b/src/chunkinator.rs @@ -0,0 +1 @@ + diff --git a/src/lib.rs b/src/lib.rs index 3344373..a2254e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,11 +4,10 @@ mod services; #[pymodule] fn airlock_libs(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(double, py)?)?; - m.add_function(wrap_pyfunction!(services::pull_policy_exec_histories, py)?)?; - m.add_function(wrap_pyfunction!(services::api, py)?)?; + m.add_function(wrap_pyfunction!(services::history_logging, py)?)?; Ok(()) } #[pyfunction] fn double(x: usize) -> usize { x * 2 -} \ No newline at end of file +} diff --git a/src/services.rs b/src/services.rs index 3de476a..5335ab0 100644 --- a/src/services.rs +++ b/src/services.rs @@ -1,12 +1,107 @@ -use pyo3::prelude::*; +use std::str::FromStr; -#[pyfunction] -pub fn pull_policy_exec_histories() { - println!("Hello World from Rust!"); +use pyo3::{ + prelude::*, + types::{PyDict, PyList, PyString}, +}; +use reqwest::{ + Client, + header::{HeaderMap, HeaderName, HeaderValue}, +}; +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use serde_pyobject::to_pyobject; + +#[derive(Debug, Deserialize, Serialize)] +struct ApiResponse { + error: String, + response: ExecHistories, } - +#[derive(Debug, Deserialize, Serialize)] +struct ExecHistories { + exechistories: Vec, +} +#[derive(Debug, Deserialize, Serialize)] +struct Group { + checkpoint: String, + #[serde(rename = "type")] + exectype: u8, + username: String, + hostname: String, + netdomain: String, + filename: String, + ppolicy: String, + policyname: String, + policyver: String, + commandline: String, + publisher: String, + pprocess: String, + gprocess: String, + sha256: String, + datetime: String, + md5: String, + sha128: String, + sha384: String, + sha512: String, + ip: String, + localip: String, +} +#[tokio::main] #[pyfunction] -pub fn api(py: Python<'_>, x: Py) { - let base_url: String = x.getattr(py, "base_url").unwrap().to_string(); - println!("{}", base_url); -} \ No newline at end of file +pub async fn history_logging( + py: Python<'_>, + py_self: Py, + exec_types: String, + checkpoint_number: String, + policy_names: String, +) -> Py { + let base_url = py_self.getattr(py, "base_url").unwrap().to_string(); + let headers = py_self.getattr(py, "headers").unwrap().to_string(); + let headers_replace = headers.replace('\'', "\""); + let parsed: Value = serde_json::from_str(&headers_replace.as_str()).unwrap(); + let mut header_map = HeaderMap::new(); + if let Some(obj) = parsed.as_object() { + for (key, value) in obj { + if let Some(v) = value.as_str() { + let val = HeaderValue::from_str(v).unwrap(); + header_map.insert(HeaderName::from_str("X-APIKey").unwrap(), val); + } + } + } + let payload = format!( + r#"{{ + "type": {}, + "checkpoint": "{}", + "policy": ["{}"] + }}"#, + exec_types, checkpoint_number, policy_names + ); + let client = Client::builder() + .danger_accept_invalid_certs(true) + .default_headers(header_map) + .timeout(std::time::Duration::from_secs(30)) + .build() + .unwrap(); + let res = client + .post(format!("{}/v1/logging/exechistories", base_url)) + .body(payload) + .send() + .await; + match res { + Ok(res) => { + let first_response: ApiResponse = serde_json::from_str(&res.text().await.unwrap()) + .expect("Failed to Parse JSON - Rust Lib"); + let py_any: Py = serde_pyobject::to_pyobject(py, &first_response.response.exechistories) + .unwrap().into(); + py_any.extract(py).unwrap() + } + Err(res) => { + let first_response = res.to_string(); + let py_any: Py = serde_pyobject::to_pyobject(py, &first_response) + .unwrap() + .into(); + let py_list: Py = py_any.extract(py).unwrap(); + return py_list; + } + } +}