Implement base operator #1

Merged
pierre merged 21 commits from operator into master 2023-05-08 16:20:17 +00:00
4 changed files with 116 additions and 0 deletions
Showing only changes of commit 1ae2cf7282 - Show all commits

View File

@ -23,6 +23,8 @@ enum MinioError {
SetQuotaFailed,
#[error("Failed to set bucket retention!")]
SetRetentionFailed,
#[error("Failed to set policy!")]
ApplyPolicyFailed,
}
#[derive(Debug, Clone)]
@ -91,6 +93,23 @@ struct MinioRetentionResult {
pub validity: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
struct MinioPolicy {
pub policy: String,
}
#[allow(non_snake_case)]
#[derive(Debug, Clone, Deserialize)]
struct MinioPolicyInfo {
pub policyInfo: PolicyInfo,
}
#[allow(non_snake_case)]
#[derive(Debug, Clone, Deserialize)]
struct PolicyInfo {
Policy: serde_json::Value,
}
impl BasicMinioResult {
pub fn success(&self) -> bool {
self.status == "success"
@ -412,6 +431,49 @@ impl MinioService {
}
Ok(None)
}
/// Apply a bucket policy
pub async fn policy_apply(&self, name: &str, content: &str) -> anyhow::Result<()> {
let tmp_file = mktemp::Temp::new_file()?;
std::fs::write(&tmp_file, content)?;
let res = self
.exec_mc_cmd::<BasicMinioResult>(&[
"admin",
"policy",
"create",
MC_ALIAS_NAME,
name,
tmp_file.to_str().unwrap(),
])
.await?;
if res.get(0).map(|r| r.success()) != Some(true) {
return Err(MinioError::ApplyPolicyFailed.into());
}
Ok(())
}
/// Get the list of existing policies
pub async fn policy_list(&self) -> anyhow::Result<Vec<String>> {
Ok(self
.exec_mc_cmd::<MinioPolicy>(&["admin", "policy", "list", MC_ALIAS_NAME])
.await?
.iter()
.map(|p| p.policy.to_string())
.collect())
}
/// Get the content of a given policy
pub async fn policy_content(&self, name: &str) -> anyhow::Result<String> {
let policy = self
.exec_mc_cmd::<MinioPolicyInfo>(&["admin", "policy", "info", MC_ALIAS_NAME, name])
.await?
.remove(0);
Ok(serde_json::to_string(&policy.policyInfo.Policy)?)
}
}
#[cfg(test)]
@ -420,6 +482,7 @@ mod test {
use crate::minio_test_server::MinioTestServer;
const TEST_BUCKET_NAME: &str = "mybucket";
const TEST_POLICY_NAME: &str = "mypolicy";
#[tokio::test]
async fn list_buckets_empty_instance() {
@ -863,4 +926,31 @@ mod test {
None
);
}
fn unify_policy(p: &str) -> String {
serde_json::to_string(&serde_json::from_str::<serde_json::Value>(p).unwrap()).unwrap()
}
#[tokio::test]
async fn policy_apply() {
let _ = env_logger::builder().is_test(true).try_init();
let srv = MinioTestServer::start().await.unwrap();
let service = srv.as_service();
let policy_1 = unify_policy(include_str!("../test/test-policy1.json"));
let policy_2 = unify_policy(include_str!("../test/test-policy2.json"));
assert_ne!(policy_1, policy_2);
assert!(!service.policy_list().await.unwrap().contains(&TEST_POLICY_NAME.to_string()));
service.policy_apply(TEST_POLICY_NAME, &policy_1).await.unwrap();
assert!(service.policy_list().await.unwrap().contains(&TEST_POLICY_NAME.to_string()));
assert_eq!(unify_policy(&service.policy_content(TEST_POLICY_NAME).await.unwrap()), policy_1);
service.policy_apply(TEST_POLICY_NAME, &policy_2).await.unwrap();
assert!(service.policy_list().await.unwrap().contains(&TEST_POLICY_NAME.to_string()));
assert_eq!(unify_policy(&service.policy_content(TEST_POLICY_NAME).await.unwrap()), policy_2);
}
}

15
test/test-policy1.json Normal file
View File

@ -0,0 +1,15 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::bucket"
]
}
]
}

11
test/test-policy2.json Normal file
View File

@ -0,0 +1,11 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::bucketdos"]
}
]
}