diff --git a/src/cli/allow_ip.rs b/src/cli/allow_ip.rs index dfe7fda8..d1be94f6 100644 --- a/src/cli/allow_ip.rs +++ b/src/cli/allow_ip.rs @@ -9,9 +9,7 @@ use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{Category, PipelineData, ShellError, Signature, SyntaxShape, Value}; -use std::ops::Add; use std::sync::{Arc, Mutex}; -use tokio::time::Instant; #[derive(Clone)] pub struct AllowIP { @@ -105,17 +103,14 @@ fn allow_ip( let cluster = get_active_cluster(identifier.clone(), &guard, span)?; let org = guard.named_or_active_org(cluster.capella_org())?; - let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; + let org_id = find_org_id(ctrl_c.clone(), &client, span)?; let project_id = find_project_id( ctrl_c.clone(), guard.named_or_active_project(cluster.project())?, &client, - deadline, span, org_id.clone(), )?; @@ -125,7 +120,6 @@ fn allow_ip( ctrl_c.clone(), cluster.hostnames().clone(), &client, - deadline, span, org_id.clone(), project_id.clone(), @@ -137,7 +131,6 @@ fn allow_ip( project_id, json_cluster.id(), ip_address.clone(), - deadline, ctrl_c.clone(), ) .map_err(|e| client_error_to_shell_error(e, span))?; diff --git a/src/cli/buckets.rs b/src/cli/buckets.rs index be4890af..8e559b05 100644 --- a/src/cli/buckets.rs +++ b/src/cli/buckets.rs @@ -1,8 +1,7 @@ use crate::cli::buckets_builder::{BucketSettings, JSONBucketSettings}; use crate::cli::buckets_get::bucket_to_nu_value; use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, }; use crate::client::ManagementRequest; use crate::state::{RemoteCapellaOrganization, State}; @@ -170,31 +169,18 @@ pub fn get_capella_buckets( span: Span, ) -> Result, ShellError> { let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - project, + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, span, - org_id.clone(), - project_id.clone(), + identifier.clone(), + project, + cluster, )?; let buckets = client - .list_buckets(org_id, project_id, json_cluster.id(), deadline, ctrl_c) + .list_buckets(org_id, project_id, cluster_id, ctrl_c) .map_err(|e| client_error_to_shell_error(e, span))?; let mut buckets_settings: Vec = vec![]; for bucket in buckets.items() { diff --git a/src/cli/buckets_create.rs b/src/cli/buckets_create.rs index a0f3f495..e9fe531a 100644 --- a/src/cli/buckets_create.rs +++ b/src/cli/buckets_create.rs @@ -224,25 +224,14 @@ pub fn create_capella_bucket( span: Span, ) -> Result<(), ShellError> { let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; + let org_id = find_org_id(ctrl_c.clone(), &client, span)?; + let project_id = find_project_id(ctrl_c.clone(), project, &client, span, org_id.clone())?; let json_cluster = cluster_from_conn_str( identifier.clone(), ctrl_c.clone(), cluster.hostnames().clone(), &client, - deadline, span, org_id.clone(), project_id.clone(), @@ -262,7 +251,6 @@ pub fn create_capella_bucket( project_id, json_cluster.id(), serde_json::to_string(&json).unwrap(), - deadline, ctrl_c, ) .map_err(|e| client_error_to_shell_error(e, span)) diff --git a/src/cli/buckets_drop.rs b/src/cli/buckets_drop.rs index 6340d7de..34e9b28f 100644 --- a/src/cli/buckets_drop.rs +++ b/src/cli/buckets_drop.rs @@ -1,13 +1,12 @@ //! The `buckets get` command fetches buckets from the server. use crate::cli::error::client_error_to_shell_error; use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, }; use crate::client::{ClientError, ManagementRequest}; use crate::remote_cluster::RemoteCluster; use crate::remote_cluster::RemoteClusterType::Provisioned; -use crate::state::{RemoteCapellaOrganization, State}; +use crate::state::State; use log::debug; use nu_engine::CallExt; use nu_protocol::ast::Call; @@ -78,22 +77,27 @@ fn buckets_drop( debug!("Running buckets drop for bucket {:?}", &name); for identifier in cluster_identifiers { - let cluster = get_active_cluster(identifier.clone(), &guard, span)?; + let active_cluster = get_active_cluster(identifier.clone(), &guard, span)?; - if cluster.cluster_type() == Provisioned { - let org = guard.named_or_active_org(cluster.capella_org())?; + if active_cluster.cluster_type() == Provisioned { + let client = guard + .named_or_active_org(active_cluster.capella_org())? + .client(); - drop_capella_bucket( - org, - guard.named_or_active_project(cluster.project())?, - cluster, - name.clone(), - identifier.clone(), + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( + &client, ctrl_c.clone(), span, - ) + identifier.clone(), + guard.named_or_active_project(active_cluster.project())?, + active_cluster, + )?; + + client + .delete_bucket(org_id, project_id, cluster_id, name.clone(), ctrl_c.clone()) + .map_err(|e| client_error_to_shell_error(e, span)) } else { - drop_server_bucket(cluster, name.clone(), ctrl_c.clone(), span) + drop_server_bucket(active_cluster, name.clone(), ctrl_c.clone(), span) }?; } @@ -125,48 +129,3 @@ fn drop_server_bucket( } Ok(()) } - -fn drop_capella_bucket( - org: &RemoteCapellaOrganization, - project: String, - cluster: &RemoteCluster, - bucket: String, - identifier: String, - ctrl_c: Arc, - span: Span, -) -> Result<(), ShellError> { - let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), - ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, - span, - org_id.clone(), - project_id.clone(), - )?; - - client - .delete_bucket( - org_id, - project_id, - json_cluster.id(), - bucket, - deadline, - ctrl_c.clone(), - ) - .map_err(|e| client_error_to_shell_error(e, span)) -} diff --git a/src/cli/buckets_get.rs b/src/cli/buckets_get.rs index 80f63c6c..0fbeae99 100644 --- a/src/cli/buckets_get.rs +++ b/src/cli/buckets_get.rs @@ -3,8 +3,7 @@ use crate::state::{RemoteCapellaOrganization, State}; use crate::cli::buckets_builder::{BucketSettings, JSONBucketSettings}; use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, NuValueMap, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, NuValueMap, }; use crate::client::{HttpResponse, ManagementRequest}; use log::debug; @@ -88,23 +87,23 @@ fn buckets_get( let mut results: Vec = vec![]; for identifier in cluster_identifiers { let guard = state.lock().unwrap(); - let cluster = get_active_cluster(identifier.clone(), &guard, span)?; + let active_cluster = get_active_cluster(identifier.clone(), &guard, span)?; - let content = if cluster.cluster_type() == Provisioned { - let org = guard.named_or_active_org(cluster.capella_org())?; + let content = if active_cluster.cluster_type() == Provisioned { + let org = guard.named_or_active_org(active_cluster.capella_org())?; get_capella_bucket( org, - guard.named_or_active_project(cluster.project())?, - cluster, + guard.named_or_active_project(active_cluster.project())?, + active_cluster, bucket.clone(), identifier.clone(), ctrl_c.clone(), span, - )? + ) } else { - get_server_bucket(cluster, bucket.clone(), ctrl_c.clone(), span)? - }; + get_server_bucket(active_cluster, bucket.clone(), ctrl_c.clone(), span) + }?; results.push(bucket_to_nu_value(content, identifier, false, span)); } @@ -158,38 +157,18 @@ pub fn get_capella_bucket( span: Span, ) -> Result { let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - project, + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, span, - org_id.clone(), - project_id.clone(), + identifier.clone(), + project, + cluster, )?; let bucket = client - .get_bucket( - org_id, - project_id, - json_cluster.id(), - bucket_name, - deadline, - ctrl_c, - ) + .get_bucket(org_id, project_id, cluster_id, bucket_name, ctrl_c) .map_err(|e| client_error_to_shell_error(e, span))?; BucketSettings::try_from(&bucket).map_err(|e| { diff --git a/src/cli/buckets_sample.rs b/src/cli/buckets_sample.rs index ea569233..e07c1dcb 100644 --- a/src/cli/buckets_sample.rs +++ b/src/cli/buckets_sample.rs @@ -1,12 +1,11 @@ use crate::cli::error::client_error_to_shell_error; use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, NuValueMap, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, NuValueMap, }; use crate::client::{ClientError, ManagementRequest}; use crate::remote_cluster::RemoteCluster; use crate::remote_cluster::RemoteClusterType::Provisioned; -use crate::state::{RemoteCapellaOrganization, State}; +use crate::state::State; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; @@ -81,22 +80,33 @@ fn load_sample_bucket( let mut results: Vec = vec![]; for identifier in cluster_identifiers { - let cluster = get_active_cluster(identifier.clone(), &guard, span)?; + let active_cluster = get_active_cluster(identifier.clone(), &guard, span)?; - let result = if cluster.cluster_type() == Provisioned { - let org = guard.named_or_active_org(cluster.capella_org())?; + let result = if active_cluster.cluster_type() == Provisioned { + let client = guard + .named_or_active_org(active_cluster.capella_org())? + .client(); - load_capella_sample( - org, - guard.named_or_active_project(cluster.project())?, - cluster, - identifier.clone(), - bucket_name.clone(), + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( + &client, ctrl_c.clone(), span, - ) + identifier.clone(), + guard.named_or_active_project(active_cluster.project())?, + active_cluster, + )?; + + client + .load_sample_bucket( + org_id, + project_id, + cluster_id, + bucket_name.clone(), + ctrl_c.clone(), + ) + .map_err(|e| client_error_to_shell_error(e, span)) } else { - load_sever_sample(cluster, bucket_name.clone(), ctrl_c.clone(), span) + load_sever_sample(active_cluster, bucket_name.clone(), ctrl_c.clone(), span) }; let mut collected = NuValueMap::default(); @@ -122,52 +132,6 @@ fn load_sample_bucket( .into_pipeline_data()) } -fn load_capella_sample( - org: &RemoteCapellaOrganization, - project: String, - cluster: &RemoteCluster, - identifier: String, - sample: String, - ctrl_c: Arc, - span: Span, -) -> Result<(), ShellError> { - let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), - ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, - span, - org_id.clone(), - project_id.clone(), - )?; - - client - .load_sample_bucket( - org_id, - project_id, - json_cluster.id(), - sample, - deadline, - ctrl_c.clone(), - ) - .map_err(|e| client_error_to_shell_error(e, span)) -} - fn load_sever_sample( cluster: &RemoteCluster, sample: String, diff --git a/src/cli/buckets_update.rs b/src/cli/buckets_update.rs index 7a9f8746..d560fe8b 100644 --- a/src/cli/buckets_update.rs +++ b/src/cli/buckets_update.rs @@ -3,13 +3,12 @@ use crate::cli::buckets_get::{get_capella_bucket, get_server_bucket}; use crate::cli::error::{client_error_to_shell_error, generic_error, serialize_error}; use crate::cli::unexpected_status_code_error; use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, }; use crate::client::ManagementRequest; use crate::remote_cluster::RemoteCluster; use crate::remote_cluster::RemoteClusterType::Provisioned; -use crate::state::{RemoteCapellaOrganization, State}; +use crate::state::State; use log::debug; use nu_engine::CallExt; use nu_protocol::ast::Call; @@ -146,17 +145,31 @@ fn buckets_update( )?; if active_cluster.cluster_type() == Provisioned { - let org = guard.named_or_active_org(active_cluster.capella_org())?; + let client = guard + .named_or_active_org(active_cluster.capella_org())? + .client(); - update_capella_bucket( - org, - guard.named_or_active_project(active_cluster.project())?, - active_cluster, - identifier.clone(), - settings, + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( + &client, ctrl_c.clone(), span, - ) + identifier.clone(), + guard.named_or_active_project(active_cluster.project())?, + active_cluster, + )?; + + let json = settings.as_json(); + + client + .update_bucket( + org_id, + project_id, + cluster_id, + settings.name().into(), + serde_json::to_string(&json).unwrap(), + ctrl_c.clone(), + ) + .map_err(|e| client_error_to_shell_error(e, span)) } else { update_server_bucket(settings, active_cluster, ctrl_c.clone(), span) }?; @@ -198,55 +211,6 @@ fn update_server_bucket( Ok(()) } -fn update_capella_bucket( - org: &RemoteCapellaOrganization, - project: String, - cluster: &RemoteCluster, - identifier: String, - settings: BucketSettings, - ctrl_c: Arc, - span: Span, -) -> Result<(), ShellError> { - let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), - ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, - span, - org_id.clone(), - project_id.clone(), - )?; - - let json = settings.as_json(); - - client - .update_bucket( - org_id, - project_id, - json_cluster.id(), - settings.name().into(), - serde_json::to_string(&json).unwrap(), - deadline, - ctrl_c, - ) - .map_err(|e| client_error_to_shell_error(e, span)) -} - fn update_bucket_settings( settings: &mut BucketSettings, ram: Option, diff --git a/src/cli/clusters.rs b/src/cli/clusters.rs index 3dc4844b..b93f07e6 100644 --- a/src/cli/clusters.rs +++ b/src/cli/clusters.rs @@ -7,9 +7,7 @@ use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{ Category, IntoPipelineData, PipelineData, ShellError, Signature, SyntaxShape, Value, }; -use std::ops::Add; use std::sync::{Arc, Mutex}; -use tokio::time::Instant; #[derive(Clone)] pub struct Clusters { @@ -77,20 +75,12 @@ fn clusters( guard.named_or_active_project(call.get_flag(engine_state, stack, "project")?)?; let client = control.client(); - let deadline = Instant::now().add(control.timeout()); - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; + let org_id = find_org_id(ctrl_c.clone(), &client, span)?; + let project_id = find_project_id(ctrl_c.clone(), project, &client, span, org_id.clone())?; let clusters = client - .list_clusters(org_id, project_id, deadline, ctrl_c) + .list_clusters(org_id, project_id, ctrl_c) .map_err(|e| client_error_to_shell_error(e, span))?; let mut results = vec![]; diff --git a/src/cli/clusters_create.rs b/src/cli/clusters_create.rs index 17885dcc..219b51ad 100644 --- a/src/cli/clusters_create.rs +++ b/src/cli/clusters_create.rs @@ -2,9 +2,7 @@ use crate::client::cloud_json::{ClusterCreateRequest, Provider}; use crate::state::State; use log::{debug, info}; use std::convert::TryFrom; -use std::ops::Add; use std::sync::{Arc, Mutex}; -use tokio::time::Instant; use crate::cli::error::{client_error_to_shell_error, serialize_error}; use crate::cli::generic_error; @@ -144,25 +142,17 @@ fn clusters_create( let guard = state.lock().unwrap(); let control = guard.named_or_active_org(capella)?; let client = control.client(); - let deadline = Instant::now().add(control.timeout()); let project = guard.named_or_active_project(call.get_flag(engine_state, stack, "project")?)?; - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; + let org_id = find_org_id(ctrl_c.clone(), &client, span)?; + let project_id = find_project_id(ctrl_c.clone(), project, &client, span, org_id.clone())?; let payload = serde_json::to_string(&definition).map_err(|e| serialize_error(e.to_string(), span))?; client - .create_cluster(org_id, project_id, payload, deadline, ctrl_c) + .create_cluster(org_id, project_id, payload, ctrl_c) .map_err(|e| client_error_to_shell_error(e, span))?; Ok(PipelineData::empty()) diff --git a/src/cli/clusters_drop.rs b/src/cli/clusters_drop.rs index f4425289..156060d1 100644 --- a/src/cli/clusters_drop.rs +++ b/src/cli/clusters_drop.rs @@ -1,8 +1,6 @@ use crate::state::State; use log::debug; -use std::ops::Add; use std::sync::{Arc, Mutex}; -use tokio::time::Instant; use crate::cli::error::client_error_to_shell_error; use crate::cli::util::{find_org_id, find_project_id}; @@ -82,30 +80,16 @@ fn clusters_drop( guard.named_or_active_project(call.get_flag(engine_state, stack, "project")?)?; let client = control.client(); - let deadline = Instant::now().add(control.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; + + let org_id = find_org_id(ctrl_c.clone(), &client, span)?; + let project_id = find_project_id(ctrl_c.clone(), project, &client, span, org_id.clone())?; let cluster = client - .get_cluster( - name, - org_id.clone(), - project_id.clone(), - deadline, - ctrl_c.clone(), - ) + .get_cluster(name, org_id.clone(), project_id.clone(), ctrl_c.clone()) .map_err(|e| client_error_to_shell_error(e, span))?; client - .delete_cluster(org_id, project_id, cluster.id(), deadline, ctrl_c) + .delete_cluster(org_id, project_id, cluster.id(), ctrl_c) .map_err(|e| client_error_to_shell_error(e, span))?; let identifier = { diff --git a/src/cli/clusters_get.rs b/src/cli/clusters_get.rs index 25f8eeec..5bba9f65 100644 --- a/src/cli/clusters_get.rs +++ b/src/cli/clusters_get.rs @@ -1,8 +1,6 @@ use crate::state::State; use log::debug; -use std::ops::Add; use std::sync::{Arc, Mutex}; -use tokio::time::Instant; use crate::cli::error::client_error_to_shell_error; use crate::cli::util::{convert_json_value_to_nu_value, find_org_id, find_project_id, NuValueMap}; @@ -82,26 +80,12 @@ fn clusters_get( guard.named_or_active_project(call.get_flag(engine_state, stack, "project")?)?; let client = control.client(); - let deadline = Instant::now().add(control.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; + + let org_id = find_org_id(ctrl_c.clone(), &client, span)?; + let project_id = find_project_id(ctrl_c.clone(), project, &client, span, org_id.clone())?; let cluster = client - .get_cluster( - name, - org_id.clone(), - project_id.clone(), - deadline, - ctrl_c.clone(), - ) + .get_cluster(name, org_id.clone(), project_id.clone(), ctrl_c.clone()) .map_err(|e| client_error_to_shell_error(e, span))?; let mut collected = NuValueMap::default(); diff --git a/src/cli/collections.rs b/src/cli/collections.rs index 959270ad..32251784 100644 --- a/src/cli/collections.rs +++ b/src/cli/collections.rs @@ -1,9 +1,8 @@ use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, NuValueMap, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, NuValueMap, }; use crate::client::ManagementRequest; -use crate::state::{RemoteCapellaOrganization, State}; +use crate::state::State; use log::debug; use serde_derive::Deserialize; use std::ops::Add; @@ -17,6 +16,7 @@ use crate::cli::error::{ unexpected_status_code_error, }; use crate::cli::no_active_scope_error; +use crate::client::cloud::CollectionNamespace; use crate::client::cloud_json::Collection; use crate::remote_cluster::RemoteClusterType::Provisioned; use crate::RemoteCluster; @@ -103,16 +103,26 @@ fn collections_get( ); let collections = if active_cluster.cluster_type() == Provisioned { - get_capella_collections( + let client = guard + .named_or_active_org(active_cluster.capella_org())? + .client(); + + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( + &client, + ctrl_c.clone(), + span, identifier.clone(), - guard.named_or_active_org(active_cluster.capella_org())?, guard.named_or_active_project(active_cluster.project())?, active_cluster, - bucket.clone(), - scope.clone(), - ctrl_c.clone(), - span, - ) + )?; + + let namespace = CollectionNamespace::new(org_id, project_id, cluster_id, bucket, scope); + + let collections = client + .list_collections(namespace, ctrl_c.clone()) + .map_err(|e| client_error_to_shell_error(e, span))?; + + collections.items() } else { get_server_collections( active_cluster, @@ -120,8 +130,8 @@ fn collections_get( scope.clone(), ctrl_c.clone(), span, - ) - }?; + )? + }; for collection in collections { let mut collected = NuValueMap::default(); @@ -205,55 +215,6 @@ impl Manifest { } } -fn get_capella_collections( - identifier: String, - org: &RemoteCapellaOrganization, - project: String, - cluster: &RemoteCluster, - bucket: String, - scope: String, - ctrl_c: Arc, - span: Span, -) -> Result, ShellError> { - let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), - ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, - span, - org_id.clone(), - project_id.clone(), - )?; - - let collections = client - .list_collections( - org_id, - project_id, - json_cluster.id(), - bucket, - scope, - deadline, - ctrl_c, - ) - .map_err(|e| client_error_to_shell_error(e, span))?; - - Ok(collections.items()) -} - fn get_server_collections( cluster: &RemoteCluster, bucket: String, diff --git a/src/cli/collections_create.rs b/src/cli/collections_create.rs index 01ccee72..6537c73f 100644 --- a/src/cli/collections_create.rs +++ b/src/cli/collections_create.rs @@ -1,11 +1,10 @@ //! The `collections get` command fetches all of the collection names from the server. use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, }; use crate::client::ManagementRequest::CreateCollection; -use crate::state::{RemoteCapellaOrganization, State}; +use crate::state::State; use log::debug; use std::ops::Add; use std::sync::atomic::AtomicBool; @@ -16,7 +15,7 @@ use crate::cli::collections::{get_bucket_or_active, get_scope_or_active}; use crate::cli::error::{ client_error_to_shell_error, serialize_error, unexpected_status_code_error, }; -use crate::client::cloud_json::Collection; +use crate::client::cloud::CollectionNamespace; use crate::remote_cluster::RemoteCluster; use crate::remote_cluster::RemoteClusterType::Provisioned; use nu_engine::CallExt; @@ -109,18 +108,24 @@ fn collections_create( ); if active_cluster.cluster_type() == Provisioned { - create_capella_collection( - guard.named_or_active_org(active_cluster.capella_org())?, - guard.named_or_active_project(active_cluster.project())?, - active_cluster, - bucket.clone(), - scope.clone(), - collection.clone(), - expiry, - identifier.clone(), + let client = guard + .named_or_active_org(active_cluster.capella_org())? + .client(); + + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( + &client, ctrl_c.clone(), span, - ) + identifier, + guard.named_or_active_project(active_cluster.project())?, + active_cluster, + )?; + + let namespace = CollectionNamespace::new(org_id, project_id, cluster_id, bucket, scope); + + client + .create_collection(collection.clone(), expiry, namespace, ctrl_c.clone()) + .map_err(|e| client_error_to_shell_error(e, span)) } else { create_server_collection( active_cluster, @@ -137,60 +142,6 @@ fn collections_create( Ok(PipelineData::empty()) } -#[allow(clippy::too_many_arguments)] -fn create_capella_collection( - org: &RemoteCapellaOrganization, - project: String, - cluster: &RemoteCluster, - bucket: String, - scope: String, - collection: String, - expiry: i64, - identifier: String, - ctrl_c: Arc, - span: Span, -) -> Result<(), ShellError> { - let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), - ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, - span, - org_id.clone(), - project_id.clone(), - )?; - - let payload = serde_json::to_string(&Collection::new(collection, expiry)).unwrap(); - - client - .create_collection( - org_id, - project_id, - json_cluster.id(), - bucket, - scope, - payload, - deadline, - ctrl_c, - ) - .map_err(|e| client_error_to_shell_error(e, span)) -} - fn create_server_collection( cluster: &RemoteCluster, scope: String, diff --git a/src/cli/collections_drop.rs b/src/cli/collections_drop.rs index c57555f5..ba325229 100644 --- a/src/cli/collections_drop.rs +++ b/src/cli/collections_drop.rs @@ -1,11 +1,10 @@ //! The `collections drop` commanddrop a collection from the server. use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, }; use crate::client::ManagementRequest::DropCollection; -use crate::state::{RemoteCapellaOrganization, State}; +use crate::state::State; use log::debug; use std::ops::Add; use std::sync::atomic::AtomicBool; @@ -14,6 +13,7 @@ use tokio::time::Instant; use crate::cli::collections::{get_bucket_or_active, get_scope_or_active}; use crate::cli::error::{client_error_to_shell_error, unexpected_status_code_error}; +use crate::client::cloud::CollectionNamespace; use crate::remote_cluster::RemoteCluster; use crate::remote_cluster::RemoteClusterType::Provisioned; use nu_engine::CallExt; @@ -97,17 +97,24 @@ fn collections_drop( ); if active_cluster.cluster_type() == Provisioned { - drop_capella_collection( - guard.named_or_active_org(active_cluster.capella_org())?, - guard.named_or_active_project(active_cluster.project())?, - active_cluster, - bucket.clone(), - scope.clone(), - collection.clone(), - identifier, + let client = guard + .named_or_active_org(active_cluster.capella_org())? + .client(); + + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( + &client, ctrl_c.clone(), span, - ) + identifier, + guard.named_or_active_project(active_cluster.project())?, + active_cluster, + )?; + + let namespace = CollectionNamespace::new(org_id, project_id, cluster_id, bucket, scope); + + client + .delete_collection(namespace, collection.clone(), ctrl_c.clone()) + .map_err(|e| client_error_to_shell_error(e, span)) } else { drop_server_collection( active_cluster, @@ -123,57 +130,6 @@ fn collections_drop( Ok(PipelineData::empty()) } -#[allow(clippy::too_many_arguments)] -fn drop_capella_collection( - org: &RemoteCapellaOrganization, - project: String, - cluster: &RemoteCluster, - bucket: String, - scope: String, - collection: String, - identifier: String, - ctrl_c: Arc, - span: Span, -) -> Result<(), ShellError> { - let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), - ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, - span, - org_id.clone(), - project_id.clone(), - )?; - - client - .delete_collection( - org_id, - project_id, - json_cluster.id(), - bucket, - scope, - collection, - deadline, - ctrl_c, - ) - .map_err(|e| client_error_to_shell_error(e, span)) -} - fn drop_server_collection( cluster: &RemoteCluster, bucket: String, diff --git a/src/cli/credentials_create.rs b/src/cli/credentials_create.rs index c23d2821..1e582264 100644 --- a/src/cli/credentials_create.rs +++ b/src/cli/credentials_create.rs @@ -9,9 +9,7 @@ use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{Category, PipelineData, ShellError, Signature, SyntaxShape}; -use std::ops::Add; use std::sync::{Arc, Mutex}; -use tokio::time::Instant; #[derive(Clone)] pub struct CredentialsCreate { @@ -106,15 +104,13 @@ fn credentials_create( let org = guard.named_or_active_org(cluster.capella_org())?; let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; + let org_id = find_org_id(ctrl_c.clone(), &client, span)?; let project_id = find_project_id( ctrl_c.clone(), guard.active_project().unwrap(), &client, - deadline, span, org_id.clone(), )?; @@ -124,7 +120,6 @@ fn credentials_create( ctrl_c.clone(), cluster.hostnames().clone(), &client, - deadline, span, org_id.clone(), project_id.clone(), @@ -157,7 +152,6 @@ fn credentials_create( project_id, json_cluster.id(), serde_json::to_string(&payload).unwrap(), - deadline, ctrl_c.clone(), ) .map_err(|e| client_error_to_shell_error(e, span))?; diff --git a/src/cli/organizations.rs b/src/cli/organizations.rs index 19c4106d..77745ef4 100644 --- a/src/cli/organizations.rs +++ b/src/cli/organizations.rs @@ -3,8 +3,6 @@ use crate::state::State; use std::sync::{Arc, Mutex}; use log::debug; -use std::ops::Add; -use tokio::time::Instant; use crate::cli::error::client_error_to_shell_error; use nu_protocol::ast::Call; @@ -66,9 +64,8 @@ fn organizations( let mut collected = NuValueMap::default(); collected.add_string("identifier", identifier, span); - let deadline = Instant::now().add(org.timeout()); let orgs = client - .list_organizations(deadline, ctrl_c.clone()) + .list_organizations(ctrl_c.clone()) .map_err(|e| client_error_to_shell_error(e, span))?; for org in orgs.items() { diff --git a/src/cli/projects.rs b/src/cli/projects.rs index 95bbc385..517f1079 100644 --- a/src/cli/projects.rs +++ b/src/cli/projects.rs @@ -3,9 +3,7 @@ use crate::cli::util::NuValueMap; use crate::state::State; use log::debug; use nu_engine::CallExt; -use std::ops::Add; use std::sync::{Arc, Mutex}; -use tokio::time::Instant; use crate::cli::error::client_error_to_shell_error; use nu_protocol::ast::Call; @@ -65,12 +63,11 @@ fn projects( let guard = &mut state.lock().unwrap(); let control = guard.active_capella_org()?; let client = control.client(); - let deadline = Instant::now().add(control.timeout()); - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; + let org_id = find_org_id(ctrl_c.clone(), &client, span)?; let projects = client - .list_projects(org_id, deadline, ctrl_c) + .list_projects(org_id, ctrl_c) .map_err(|e| client_error_to_shell_error(e, span))?; let mut results = vec![]; diff --git a/src/cli/projects_create.rs b/src/cli/projects_create.rs index 44162f49..03b87c67 100644 --- a/src/cli/projects_create.rs +++ b/src/cli/projects_create.rs @@ -1,9 +1,7 @@ use crate::cli::util::find_org_id; use crate::state::State; use log::debug; -use std::ops::Add; use std::sync::{Arc, Mutex}; -use tokio::time::Instant; use crate::cli::error::client_error_to_shell_error; use nu_engine::CallExt; @@ -64,11 +62,10 @@ fn projects_create( let guard = &mut state.lock().unwrap(); let control = guard.active_capella_org()?; let client = control.client(); - let deadline = Instant::now().add(control.timeout()); - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; + let org_id = find_org_id(ctrl_c.clone(), &client, span)?; client - .create_project(org_id, name, deadline, ctrl_c) + .create_project(org_id, name, ctrl_c) .map_err(|e| client_error_to_shell_error(e, span))?; Ok(PipelineData::empty()) diff --git a/src/cli/projects_drop.rs b/src/cli/projects_drop.rs index e07a573b..4d88167d 100644 --- a/src/cli/projects_drop.rs +++ b/src/cli/projects_drop.rs @@ -1,9 +1,7 @@ use crate::cli::util::{find_org_id, find_project_id}; use crate::state::State; use log::debug; -use std::ops::Add; use std::sync::{Arc, Mutex}; -use tokio::time::Instant; use crate::cli::error::client_error_to_shell_error; use nu_engine::CallExt; @@ -65,20 +63,12 @@ fn projects_drop( let guard = &mut state.lock().unwrap(); let control = guard.active_capella_org()?; let client = control.client(); - let deadline = Instant::now().add(control.timeout()); - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - name, - &client, - deadline, - span, - org_id.clone(), - )?; + let org_id = find_org_id(ctrl_c.clone(), &client, span)?; + let project_id = find_project_id(ctrl_c.clone(), name, &client, span, org_id.clone())?; client - .delete_project(org_id, project_id, deadline, ctrl_c) + .delete_project(org_id, project_id, ctrl_c) .map_err(|e| client_error_to_shell_error(e, span))?; Ok(PipelineData::empty()) diff --git a/src/cli/scopes.rs b/src/cli/scopes.rs index ffc06b5c..b8437502 100644 --- a/src/cli/scopes.rs +++ b/src/cli/scopes.rs @@ -3,13 +3,12 @@ use crate::cli::error::{ client_error_to_shell_error, deserialize_error, unexpected_status_code_error, }; use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, NuValueMap, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, NuValueMap, }; use crate::client::ManagementRequest; use crate::remote_cluster::RemoteCluster; use crate::remote_cluster::RemoteClusterType::Provisioned; -use crate::state::{RemoteCapellaOrganization, State}; +use crate::state::State; use log::debug; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; @@ -92,18 +91,33 @@ fn run( debug!("Running scopes get for bucket {:?}", &bucket); let scopes = if active_cluster.cluster_type() == Provisioned { - get_capella_scopes( - guard.named_or_active_org(active_cluster.capella_org())?, - guard.named_or_active_project(active_cluster.project())?, - active_cluster, - identifier.clone(), - bucket, + let client = guard + .named_or_active_org(active_cluster.capella_org())? + .client(); + + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( + &client, ctrl_c.clone(), span, - ) + identifier.clone(), + guard.named_or_active_project(active_cluster.project())?, + active_cluster, + )?; + + let scopes = client + .list_scopes( + org_id, + project_id, + cluster_id, + bucket.clone(), + ctrl_c.clone(), + ) + .map_err(|e| client_error_to_shell_error(e, span))?; + + scopes.scopes().iter().map(|s| s.name().clone()).collect() } else { - get_server_scopes(active_cluster, bucket, ctrl_c.clone(), span) - }?; + get_server_scopes(active_cluster, bucket, ctrl_c.clone(), span)? + }; for scope in scopes { let mut collected = NuValueMap::default(); @@ -120,53 +134,6 @@ fn run( .into_pipeline_data()) } -fn get_capella_scopes( - org: &RemoteCapellaOrganization, - project: String, - cluster: &RemoteCluster, - identifier: String, - bucket: String, - ctrl_c: Arc, - span: Span, -) -> Result, ShellError> { - let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), - ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, - span, - org_id.clone(), - project_id.clone(), - )?; - - let scopes = client - .list_scopes( - org_id, - project_id, - json_cluster.id(), - bucket, - deadline, - ctrl_c, - ) - .map_err(|e| client_error_to_shell_error(e, span))?; - - Ok(scopes.scopes().iter().map(|s| s.name().clone()).collect()) -} - fn get_server_scopes( cluster: &RemoteCluster, bucket: String, diff --git a/src/cli/scopes_create.rs b/src/cli/scopes_create.rs index a153452b..1b146f94 100644 --- a/src/cli/scopes_create.rs +++ b/src/cli/scopes_create.rs @@ -1,9 +1,8 @@ use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, }; use crate::client::ManagementRequest; -use crate::state::{RemoteCapellaOrganization, State}; +use crate::state::State; use log::debug; use std::ops::Add; use std::sync::atomic::AtomicBool; @@ -96,16 +95,29 @@ fn run( ); if active_cluster.cluster_type() == Provisioned { - create_capella_scope( - guard.named_or_active_org(active_cluster.capella_org())?, - guard.named_or_active_project(active_cluster.project())?, - active_cluster, - identifier.clone(), - bucket.clone(), - scope.clone(), + let client = guard + .named_or_active_org(active_cluster.capella_org())? + .client(); + + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( + &client, ctrl_c.clone(), span, - ) + identifier.clone(), + guard.named_or_active_project(active_cluster.project())?, + active_cluster, + )?; + + client + .create_scope( + org_id, + project_id, + cluster_id, + bucket, + scope.clone(), + ctrl_c.clone(), + ) + .map_err(|e| client_error_to_shell_error(e, span)) } else { create_server_scope( active_cluster, @@ -120,54 +132,6 @@ fn run( Ok(PipelineData::empty()) } -fn create_capella_scope( - org: &RemoteCapellaOrganization, - project: String, - cluster: &RemoteCluster, - identifier: String, - bucket: String, - name: String, - ctrl_c: Arc, - span: Span, -) -> Result<(), ShellError> { - let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), - ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, - span, - org_id.clone(), - project_id.clone(), - )?; - - client - .create_scope( - org_id, - project_id, - json_cluster.id(), - bucket, - name, - deadline, - ctrl_c, - ) - .map_err(|e| client_error_to_shell_error(e, span)) -} - fn create_server_scope( cluster: &RemoteCluster, bucket: String, diff --git a/src/cli/scopes_drop.rs b/src/cli/scopes_drop.rs index e03328e9..9c0e2972 100644 --- a/src/cli/scopes_drop.rs +++ b/src/cli/scopes_drop.rs @@ -1,9 +1,8 @@ use crate::cli::util::{ - cluster_from_conn_str, cluster_identifiers_from, find_org_id, find_project_id, - get_active_cluster, + cluster_identifiers_from, find_org_project_cluster_ids, get_active_cluster, }; use crate::client::ManagementRequest; -use crate::state::{RemoteCapellaOrganization, State}; +use crate::state::State; use log::debug; use std::ops::Add; use std::sync::atomic::AtomicBool; @@ -94,16 +93,29 @@ fn run( ); if active_cluster.cluster_type() == Provisioned { - drop_capella_scope( - guard.named_or_active_org(active_cluster.capella_org())?, - guard.named_or_active_project(active_cluster.project())?, - active_cluster, - identifier.clone(), - bucket.clone(), - scope.clone(), + let client = guard + .named_or_active_org(active_cluster.capella_org())? + .client(); + + let (org_id, project_id, cluster_id) = find_org_project_cluster_ids( + &client, ctrl_c.clone(), span, - ) + identifier.clone(), + guard.named_or_active_project(active_cluster.project())?, + active_cluster, + )?; + + client + .delete_scope( + org_id, + project_id, + cluster_id, + bucket, + scope.clone(), + ctrl_c.clone(), + ) + .map_err(|e| client_error_to_shell_error(e, span)) } else { drop_server_scope( active_cluster, @@ -149,50 +161,3 @@ fn drop_server_scope( } } } - -fn drop_capella_scope( - org: &RemoteCapellaOrganization, - project: String, - cluster: &RemoteCluster, - identifier: String, - bucket: String, - scope_name: String, - ctrl_c: Arc, - span: Span, -) -> Result<(), ShellError> { - let client = org.client(); - let deadline = Instant::now().add(org.timeout()); - - let org_id = find_org_id(ctrl_c.clone(), &client, deadline, span)?; - let project_id = find_project_id( - ctrl_c.clone(), - project, - &client, - deadline, - span, - org_id.clone(), - )?; - - let json_cluster = cluster_from_conn_str( - identifier.clone(), - ctrl_c.clone(), - cluster.hostnames().clone(), - &client, - deadline, - span, - org_id.clone(), - project_id.clone(), - )?; - - client - .delete_scope( - org_id, - project_id, - json_cluster.id(), - bucket, - scope_name, - deadline, - ctrl_c.clone(), - ) - .map_err(|e| client_error_to_shell_error(e, span)) -} diff --git a/src/cli/util.rs b/src/cli/util.rs index f41dc810..07c305ee 100644 --- a/src/cli/util.rs +++ b/src/cli/util.rs @@ -20,7 +20,6 @@ use regex::Regex; use std::sync::atomic::AtomicBool; use std::sync::{Arc, Mutex, MutexGuard}; use std::time::Duration; -use tokio::time::Instant; pub fn is_http_status(response: &HttpResponse, status: u16, span: Span) -> Result<(), ShellError> { if response.status() != status { @@ -312,13 +311,12 @@ pub(crate) fn cluster_from_conn_str( ctrl_c: Arc, hostnames: Vec, client: &Arc, - deadline: Instant, span: Span, org_id: String, project_id: String, ) -> Result { let response = client - .list_clusters(org_id, project_id, deadline, ctrl_c) + .list_clusters(org_id, project_id, ctrl_c) .map_err(|e| client_error_to_shell_error(e, span))?; for c in response.items() { @@ -332,16 +330,31 @@ pub(crate) fn cluster_from_conn_str( Err(ShellError::from(ClusterNotFound { identifier, span })) } +pub(crate) fn find_cluster_id( + identifier: String, + ctrl_c: Arc, + hostnames: Vec, + client: &Arc, + span: Span, + org_id: String, + project_id: String, +) -> Result { + let cluster = cluster_from_conn_str( + identifier, ctrl_c, hostnames, client, span, org_id, project_id, + )?; + + Ok(cluster.id()) +} + pub(crate) fn find_project_id( ctrl_c: Arc, name: String, client: &Arc, - deadline: Instant, span: Span, org_id: String, ) -> Result { let projects = client - .list_projects(org_id, deadline, ctrl_c) + .list_projects(org_id, ctrl_c) .map_err(|e| client_error_to_shell_error(e, span))?; for p in projects.items() { @@ -356,11 +369,10 @@ pub(crate) fn find_project_id( pub(crate) fn find_org_id( ctrl_c: Arc, client: &Arc, - deadline: Instant, span: Span, ) -> Result { let orgs = client - .list_organizations(deadline, ctrl_c.clone()) + .list_organizations(ctrl_c.clone()) .map_err(|e| client_error_to_shell_error(e, span))?; let org_id = match orgs.items().first() { @@ -371,6 +383,29 @@ pub(crate) fn find_org_id( Ok(org_id.to_string()) } +pub(crate) fn find_org_project_cluster_ids( + client: &Arc, + ctrl_c: Arc, + span: Span, + identifier: String, + project: String, + cluster: &RemoteCluster, +) -> Result<(String, String, String), ShellError> { + let org_id = find_org_id(ctrl_c.clone(), client, span)?; + let project_id = find_project_id(ctrl_c.clone(), project, client, span, org_id.clone())?; + let cluster_id = find_cluster_id( + identifier.clone(), + ctrl_c.clone(), + cluster.hostnames().clone(), + client, + span, + org_id.clone(), + project_id.clone(), + )?; + + Ok((org_id, project_id, cluster_id)) +} + // duration_to_golang_string creates a golang formatted string to use with timeouts. Unlike Golang // strings it does not deal with fractional seconds, we do not need that accuracy. pub fn duration_to_golang_string(duration: Duration) -> String { diff --git a/src/client/cloud.rs b/src/client/cloud.rs index ef4b7e99..c9db822f 100644 --- a/src/client/cloud.rs +++ b/src/client/cloud.rs @@ -1,7 +1,7 @@ use crate::cli::CtrlcFuture; use crate::client::cloud_json::{ - Bucket, BucketsResponse, Cluster, ClustersResponse, CollectionsResponse, OrganizationsResponse, - ProjectsResponse, ScopesResponse, + Bucket, BucketsResponse, Cluster, ClustersResponse, Collection, CollectionsResponse, + OrganizationsResponse, ProjectsResponse, ScopesResponse, }; use crate::client::error::ClientError; use crate::client::http_handler::{HttpResponse, HttpVerb}; @@ -12,10 +12,10 @@ use hmac::{Hmac, Mac}; use log::debug; use reqwest::Client; use sha2::Sha256; -use std::ops::Sub; +use std::ops::{Add, Sub}; use std::sync::atomic::AtomicBool; use std::sync::Arc; -use std::time::{SystemTime, UNIX_EPOCH}; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; use tokio::runtime::Runtime; use tokio::{select, time::Instant}; @@ -26,30 +26,40 @@ pub struct CapellaClient { secret_key: String, access_key: String, api_endpoint: String, + timeout: Duration, } impl CapellaClient { - pub fn new(secret_key: String, access_key: String, api_endpoint: String) -> Self { + pub fn new( + secret_key: String, + access_key: String, + api_endpoint: String, + timeout: Duration, + ) -> Self { Self { secret_key, access_key, api_endpoint, + timeout, } } + fn deadline(&self) -> Instant { + Instant::now().add(self.timeout) + } + fn http_do( &self, verb: HttpVerb, path: &str, payload: Option>, - deadline: Instant, ctrl_c: Arc, ) -> Result<(String, u16), ClientError> { let now = Instant::now(); - if now >= deadline { + if now >= self.deadline() { return Err(ClientError::Timeout { key: None }); } - let timeout = deadline.sub(now); + let timeout = self.deadline().sub(now); let ctrl_c_fut = CtrlcFuture::new(ctrl_c); let uri = format!("{}{}", self.api_endpoint, path); @@ -111,62 +121,49 @@ impl CapellaClient { }) } - fn http_get( - &self, - path: &str, - deadline: Instant, - ctrl_c: Arc, - ) -> Result<(String, u16), ClientError> { - self.http_do(HttpVerb::Get, path, None, deadline, ctrl_c) + fn http_get(&self, path: &str, ctrl_c: Arc) -> Result<(String, u16), ClientError> { + self.http_do(HttpVerb::Get, path, None, ctrl_c) } fn http_delete( &self, path: &str, payload: Option>, - deadline: Instant, ctrl_c: Arc, ) -> Result<(String, u16), ClientError> { - self.http_do(HttpVerb::Delete, path, payload, deadline, ctrl_c) + self.http_do(HttpVerb::Delete, path, payload, ctrl_c) } fn http_post( &self, path: &str, payload: Option>, - deadline: Instant, ctrl_c: Arc, ) -> Result<(String, u16), ClientError> { - self.http_do(HttpVerb::Post, path, payload, deadline, ctrl_c) + self.http_do(HttpVerb::Post, path, payload, ctrl_c) } fn http_put( &self, path: &str, payload: Option>, - deadline: Instant, ctrl_c: Arc, ) -> Result<(String, u16), ClientError> { - self.http_do(HttpVerb::Put, path, payload, deadline, ctrl_c) + self.http_do(HttpVerb::Put, path, payload, ctrl_c) } pub fn capella_request( &self, request: CapellaRequest, - deadline: Instant, ctrl_c: Arc, ) -> Result { let (content, status) = match request.verb() { - HttpVerb::Get => self.http_get(request.path().as_str(), deadline, ctrl_c)?, - HttpVerb::Post => { - self.http_post(request.path().as_str(), request.payload(), deadline, ctrl_c)? - } + HttpVerb::Get => self.http_get(request.path().as_str(), ctrl_c)?, + HttpVerb::Post => self.http_post(request.path().as_str(), request.payload(), ctrl_c)?, HttpVerb::Delete => { - self.http_delete(request.path().as_str(), request.payload(), deadline, ctrl_c)? - } - HttpVerb::Put => { - self.http_put(request.path().as_str(), request.payload(), deadline, ctrl_c)? + self.http_delete(request.path().as_str(), request.payload(), ctrl_c)? } + HttpVerb::Put => self.http_put(request.path().as_str(), request.payload(), ctrl_c)?, }; // This endpoint is pretty undenyably a hack, but doesn't really matter for now. Ok(HttpResponse::new( @@ -178,11 +175,10 @@ impl CapellaClient { pub fn list_organizations( &self, - deadline: Instant, ctrl_c: Arc, ) -> Result { let request = CapellaRequest::OrganizationList {}; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 200 { return Err(ClientError::RequestFailed { @@ -198,11 +194,10 @@ impl CapellaClient { pub fn list_projects( &self, org_id: String, - deadline: Instant, ctrl_c: Arc, ) -> Result { let request = CapellaRequest::ProjectList { org_id }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 200 { return Err(ClientError::RequestFailed { @@ -219,14 +214,13 @@ impl CapellaClient { &self, org_id: String, name: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::ProjectCreate { org_id, payload: format!("{{\"name\": \"{}\"}}", name), }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 201 { return Err(ClientError::RequestFailed { @@ -242,11 +236,10 @@ impl CapellaClient { &self, org_id: String, project_id: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::ProjectDelete { org_id, project_id }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 204 { return Err(ClientError::RequestFailed { @@ -263,11 +256,10 @@ impl CapellaClient { cluster_name: String, org_id: String, project_id: String, - deadline: Instant, ctrl_c: Arc, ) -> Result { let request = CapellaRequest::ClusterList { org_id, project_id }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 200 { return Err(ClientError::RequestFailed { @@ -291,11 +283,10 @@ impl CapellaClient { &self, org_id: String, project_id: String, - deadline: Instant, ctrl_c: Arc, ) -> Result { let request = CapellaRequest::ClusterList { org_id, project_id }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 200 { return Err(ClientError::RequestFailed { @@ -313,7 +304,6 @@ impl CapellaClient { org_id: String, project_id: String, payload: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::ClusterCreate { @@ -321,7 +311,7 @@ impl CapellaClient { project_id, payload, }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 202 { return Err(ClientError::RequestFailed { @@ -337,7 +327,6 @@ impl CapellaClient { org_id: String, project_id: String, cluster_id: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::ClusterDelete { @@ -345,7 +334,7 @@ impl CapellaClient { project_id, cluster_id, }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 202 { return Err(ClientError::RequestFailed { @@ -362,7 +351,6 @@ impl CapellaClient { project_id: String, cluster_id: String, payload: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::CredentialsCreate { @@ -371,7 +359,7 @@ impl CapellaClient { cluster_id, payload, }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 201 { return Err(ClientError::RequestFailed { @@ -388,7 +376,6 @@ impl CapellaClient { project_id: String, cluster_id: String, bucket: String, - deadline: Instant, ctrl_c: Arc, ) -> Result { let request = CapellaRequest::BucketGet { @@ -397,7 +384,7 @@ impl CapellaClient { cluster_id, bucket_id: BASE64_STANDARD.encode(bucket), }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 200 { return Err(ClientError::RequestFailed { @@ -415,7 +402,6 @@ impl CapellaClient { org_id: String, project_id: String, cluster_id: String, - deadline: Instant, ctrl_c: Arc, ) -> Result { let request = CapellaRequest::BucketList { @@ -423,7 +409,7 @@ impl CapellaClient { project_id, cluster_id, }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 200 { return Err(ClientError::RequestFailed { @@ -442,7 +428,6 @@ impl CapellaClient { project_id: String, cluster_id: String, payload: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::BucketCreate { @@ -451,7 +436,7 @@ impl CapellaClient { cluster_id, payload, }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 201 { return Err(ClientError::RequestFailed { @@ -468,7 +453,6 @@ impl CapellaClient { project_id: String, cluster_id: String, bucket: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::BucketDelete { @@ -477,7 +461,7 @@ impl CapellaClient { cluster_id, bucket_id: BASE64_STANDARD.encode(bucket), }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 204 { return Err(ClientError::RequestFailed { @@ -495,7 +479,6 @@ impl CapellaClient { cluster_id: String, bucket: String, payload: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::BucketUpdate { @@ -505,7 +488,7 @@ impl CapellaClient { bucket_id: BASE64_STANDARD.encode(bucket), payload, }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 204 { return Err(ClientError::RequestFailed { @@ -522,7 +505,6 @@ impl CapellaClient { project_id: String, cluster_id: String, sample: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::BucketLoadSample { @@ -531,7 +513,7 @@ impl CapellaClient { cluster_id, payload: format!("{{\"name\": \"{}\"}}", sample.clone()), }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; // TODO - need to add handling for sample already loaded once AV-82577 is complete match response.status() { @@ -550,7 +532,6 @@ impl CapellaClient { project_id: String, cluster_id: String, address: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::AllowIPAddress { @@ -559,7 +540,7 @@ impl CapellaClient { cluster_id, payload: format!("{{\"cidr\": \"{}\"}}", address.clone()), }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; match response.status() { 201 => Ok(()), @@ -576,7 +557,6 @@ impl CapellaClient { project_id: String, cluster_id: String, bucket: String, - deadline: Instant, ctrl_c: Arc, ) -> Result { let request = CapellaRequest::ScopeList { @@ -585,7 +565,7 @@ impl CapellaClient { cluster_id, bucket_id: BASE64_STANDARD.encode(bucket), }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 200 { return Err(ClientError::RequestFailed { @@ -601,24 +581,20 @@ impl CapellaClient { #[allow(clippy::too_many_arguments)] pub fn create_collection( &self, - org_id: String, - project_id: String, - cluster_id: String, - bucket: String, - scope: String, - payload: String, - deadline: Instant, + collection: String, + expiry: i64, + namespace: CollectionNamespace, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::CollectionCreate { - org_id, - project_id, - cluster_id, - bucket_id: BASE64_STANDARD.encode(bucket), - scope, - payload, + org_id: namespace.org_id, + project_id: namespace.project_id, + cluster_id: namespace.cluster_id, + bucket_id: namespace.bucket_id, + scope: namespace.scope, + payload: serde_json::to_string(&Collection::new(collection.clone(), expiry)).unwrap(), }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 201 { return Err(ClientError::RequestFailed { @@ -633,24 +609,19 @@ impl CapellaClient { #[allow(clippy::too_many_arguments)] pub fn delete_collection( &self, - org_id: String, - project_id: String, - cluster_id: String, - bucket: String, - scope: String, + namespace: CollectionNamespace, collection: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::CollectionDelete { - org_id, - project_id, - cluster_id, - bucket_id: BASE64_STANDARD.encode(bucket), - scope, + org_id: namespace.org_id, + project_id: namespace.project_id, + cluster_id: namespace.cluster_id, + bucket_id: namespace.bucket_id, + scope: namespace.scope, collection, }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 204 { return Err(ClientError::RequestFailed { @@ -664,22 +635,17 @@ impl CapellaClient { pub fn list_collections( &self, - org_id: String, - project_id: String, - cluster_id: String, - bucket: String, - scope: String, - deadline: Instant, + namespace: CollectionNamespace, ctrl_c: Arc, ) -> Result { let request = CapellaRequest::CollectionList { - org_id, - project_id, - cluster_id, - bucket_id: BASE64_STANDARD.encode(bucket), - scope, + org_id: namespace.org_id, + project_id: namespace.project_id, + cluster_id: namespace.cluster_id, + bucket_id: namespace.bucket_id, + scope: namespace.scope, }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 200 { return Err(ClientError::RequestFailed { @@ -699,7 +665,6 @@ impl CapellaClient { cluster_id: String, bucket: String, scope: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::ScopeCreate { @@ -709,7 +674,7 @@ impl CapellaClient { bucket_id: BASE64_STANDARD.encode(bucket), payload: format!("{{\"name\": \"{}\"}}", scope), }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 201 { return Err(ClientError::RequestFailed { @@ -728,7 +693,6 @@ impl CapellaClient { cluster_id: String, bucket: String, scope: String, - deadline: Instant, ctrl_c: Arc, ) -> Result<(), ClientError> { let request = CapellaRequest::ScopeDelete { @@ -738,7 +702,7 @@ impl CapellaClient { bucket_id: BASE64_STANDARD.encode(bucket), scope, }; - let response = self.capella_request(request, deadline, ctrl_c)?; + let response = self.capella_request(request, ctrl_c)?; if response.status() != 204 { return Err(ClientError::RequestFailed { @@ -1130,3 +1094,29 @@ impl CapellaRequest { } } } + +pub struct CollectionNamespace { + org_id: String, + project_id: String, + cluster_id: String, + bucket_id: String, + scope: String, +} + +impl CollectionNamespace { + pub fn new( + org_id: String, + project_id: String, + cluster_id: String, + bucket: String, + scope: String, + ) -> Self { + Self { + org_id, + project_id, + cluster_id, + bucket_id: BASE64_STANDARD.encode(bucket), + scope, + } + } +} diff --git a/src/client/mod.rs b/src/client/mod.rs index 2be15071..eca3cbb5 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -20,7 +20,7 @@ extern crate utilities; mod bedrock_client; mod capella_ca; -mod cloud; +pub(crate) mod cloud; pub mod cloud_json; mod codec; mod crc; diff --git a/src/state.rs b/src/state.rs index a2de90f0..01174ffc 100644 --- a/src/state.rs +++ b/src/state.rs @@ -371,6 +371,7 @@ impl RemoteCapellaOrganization { self.secret_key.clone(), self.access_key.clone(), self.api_endpoint.clone(), + self.timeout, ))); } c.as_ref().unwrap().clone()