diff --git a/Cargo.lock b/Cargo.lock index 880029d6..75797626 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -772,6 +772,16 @@ dependencies = [ "tonic-build", ] +[[package]] +name = "dummy_sha256_sdk" +version = "0.1.0" +dependencies = [ + "clap", + "hipcheck-sdk", + "sha2", + "tokio", +] + [[package]] name = "dyn-clone" version = "1.0.17" diff --git a/Cargo.toml b/Cargo.toml index f9d0dc2a..30e594a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ members = [ "plugins/dummy_rand_data_sdk", "plugins/dummy_rand_data", "plugins/dummy_sha256", + "plugins/dummy_sha256_sdk", "sdk/rust", ] diff --git a/hipcheck/src/main.rs b/hipcheck/src/main.rs index 2fdece46..6bae9dfa 100644 --- a/hipcheck/src/main.rs +++ b/hipcheck/src/main.rs @@ -548,15 +548,17 @@ fn cmd_plugin(args: PluginArgs) { let tgt_dir = "./target/debug"; - let entrypoint1 = match args.sdk { - true => { - pathbuf![tgt_dir, "dummy_rand_data_sdk"] - } - false => { - pathbuf![tgt_dir, "dummy_rand_data"] - } + let (entrypoint1, entrypoint2) = match args.sdk { + true => ( + pathbuf![tgt_dir, "dummy_rand_data_sdk"], + pathbuf![tgt_dir, "dummy_sha256_sdk"], + ), + false => ( + pathbuf![tgt_dir, "dummy_rand_data"], + pathbuf![tgt_dir, "dummy_sha256"], + ), }; - let entrypoint2 = pathbuf![tgt_dir, "dummy_sha256"]; + let plugin1 = Plugin { name: "dummy/rand_data".to_owned(), entrypoint: entrypoint1.display().to_string(), diff --git a/plugins/dummy_sha256_sdk/Cargo.toml b/plugins/dummy_sha256_sdk/Cargo.toml new file mode 100644 index 00000000..513a7030 --- /dev/null +++ b/plugins/dummy_sha256_sdk/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "dummy_sha256_sdk" +version = "0.1.0" +license = "Apache-2.0" +edition = "2021" +publish = false + +[dependencies] +clap = { version = "4.5.18", features = ["derive"] } +hipcheck-sdk = { path = "../../sdk/rust" } +sha2 = "0.10.8" +tokio = { version = "1.40.0", features = ["rt"] } diff --git a/plugins/dummy_sha256_sdk/schema/query_schema_sha256.json b/plugins/dummy_sha256_sdk/schema/query_schema_sha256.json new file mode 100644 index 00000000..8b50ea30 --- /dev/null +++ b/plugins/dummy_sha256_sdk/schema/query_schema_sha256.json @@ -0,0 +1,3 @@ +{ + "type": "integer" +} diff --git a/plugins/dummy_sha256_sdk/src/main.rs b/plugins/dummy_sha256_sdk/src/main.rs new file mode 100644 index 00000000..2a3f2359 --- /dev/null +++ b/plugins/dummy_sha256_sdk/src/main.rs @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use hipcheck_sdk::prelude::*; +use sha2::{Digest, Sha256}; + +static SHA256_KEY_SCHEMA: &str = include_str!("../schema/query_schema_sha256.json"); +static SHA256_OUTPUT_SCHEMA: &str = include_str!("../schema/query_schema_sha256.json"); + +/// calculate sha256 of provided content +fn sha256(content: &[u8]) -> Vec { + let mut hasher = Sha256::new(); + hasher.update(content); + hasher.finalize().to_vec() +} + +/// This plugin takes in a Value::Array(Vec) and calculates its sha256 +#[derive(Clone, Debug)] +struct Sha256Plugin; + +#[async_trait] +impl Query for Sha256Plugin { + fn input_schema(&self) -> JsonSchema { + from_str(SHA256_KEY_SCHEMA).unwrap() + } + + fn output_schema(&self) -> JsonSchema { + from_str(SHA256_OUTPUT_SCHEMA).unwrap() + } + + async fn run( + &self, + _engine: &mut PluginEngine, + input: Value, + ) -> hipcheck_sdk::error::Result { + let Value::Array(data) = &input else { + return Err(Error::UnexpectedPluginQueryInputFormat); + }; + + let data = data + .iter() + .map(|elem| elem.as_u64().map(|num| num as u8)) + .collect::>>() + .ok_or_else(|| Error::UnexpectedPluginQueryInputFormat)?; + + let hash = sha256(&data); + // convert to Value + let hash = hash.iter().map(|x| Value::Number((*x).into())).collect(); + Ok(hash) + } +} + +impl Plugin for Sha256Plugin { + const PUBLISHER: &'static str = "dummy"; + + const NAME: &'static str = "sha256"; + + fn set_config(&self, _config: Value) -> std::result::Result<(), ConfigError> { + Ok(()) + } + + fn default_policy_expr(&self) -> hipcheck_sdk::prelude::Result { + Ok("".to_owned()) + } + + fn explain_default_query(&self) -> hipcheck_sdk::prelude::Result> { + Ok(Some("calculate sha256 of provided array".to_owned())) + } + + fn queries(&self) -> impl Iterator { + vec![NamedQuery { + name: "sha256", + inner: Box::new(Sha256Plugin), + }] + .into_iter() + } +} + +#[derive(Parser, Debug)] +struct Args { + #[arg(long)] + port: u16, +} + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<()> { + let args = Args::try_parse().unwrap(); + PluginServer::register(Sha256Plugin).listen(args.port).await +}