Skip to content

Commit

Permalink
use v4 API for projects commands
Browse files Browse the repository at this point in the history
  • Loading branch information
Westwooo committed Jan 30, 2024
1 parent 08253c2 commit 2517ee9
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 27 deletions.
27 changes: 23 additions & 4 deletions src/cli/databases_create.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::cli::cloud_json::JSONCloudCreateClusterRequestV3;
use crate::cli::util::find_org_id;
use crate::cli::util::find_project_id;
use crate::client::CapellaRequest;
use crate::state::State;
Expand Down Expand Up @@ -78,22 +79,40 @@ fn clusters_create(

debug!("Running databases create for {}", &definition);

let guard = state.lock().unwrap();
let guard = &mut state.lock().unwrap();
let control = if let Some(c) = capella {
guard.capella_org_for_cluster(c)
} else {
guard.active_capella_org()
}?;
let client = control.client();
let deadline = Instant::now().add(control.timeout());
let timeout = control.timeout();
let deadline = Instant::now().add(timeout);

let project_name = match control.active_project() {
Some(p) => p,
None => {
return Err(no_active_project_error(span));
}
};
let project_id = find_project_id(ctrl_c.clone(), project_name, &client, deadline, span)?;

let org_id = match control.id() {
Some(id) => id,
None => {
let id = find_org_id(ctrl_c.clone(), &client, deadline, span)?;
guard.set_active_capella_org_id(id.clone())?;
id
}
};

let project_id = find_project_id(
ctrl_c.clone(),
project_name,
&client,
deadline,
span,
org_id,
)?;

let mut json: JSONCloudCreateClusterRequestV3 = serde_json::from_str(definition.as_str())
.map_err(|e| serialize_error(e.to_string(), span))?;
Expand All @@ -105,7 +124,7 @@ fn clusters_create(
payload: serde_json::to_string(&json)
.map_err(|e| serialize_error(e.to_string(), span))?,
},
Instant::now().add(control.timeout()),
Instant::now().add(timeout),
ctrl_c,
)
.map_err(|e| client_error_to_shell_error(e, span))?;
Expand Down
20 changes: 14 additions & 6 deletions src/cli/projects.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::cli::cloud_json::JSONCloudsProjectsResponse;
use crate::cli::util::find_org_id;
use crate::cli::util::NuValueMap;
use crate::client::CapellaRequest;
use crate::state::State;
Expand Down Expand Up @@ -61,15 +62,22 @@ fn projects(

debug!("Running projects");

let guard = state.lock().unwrap();
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 = match control.id() {
Some(id) => id,
None => {
let id = find_org_id(ctrl_c.clone(), &client, deadline, span)?;
guard.set_active_capella_org_id(id.clone())?;
id
}
};

let response = client
.capella_request(
CapellaRequest::GetProjects {},
Instant::now().add(control.timeout()),
ctrl_c,
)
.capella_request(CapellaRequest::GetProjects { org_id }, deadline, ctrl_c)
.map_err(|e| client_error_to_shell_error(e, span))?;
if response.status() != 200 {
return Err(unexpected_status_code_error(
Expand Down
17 changes: 15 additions & 2 deletions src/cli/projects_create.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::cli::cloud_json::JSONCloudCreateProjectRequest;
use crate::cli::util::find_org_id;
use crate::client::CapellaRequest;
use crate::state::State;
use log::debug;
Expand Down Expand Up @@ -64,17 +65,29 @@ fn projects_create(

debug!("Running projects create for {}", &name);

let guard = state.lock().unwrap();
let guard = &mut state.lock().unwrap();
let control = guard.active_capella_org()?;
let client = control.client();
let project = JSONCloudCreateProjectRequest::new(name);
let timeout = control.timeout();

let org_id = match control.id() {
Some(id) => id,
None => {
let id = find_org_id(ctrl_c.clone(), &client, Instant::now().add(timeout), span)?;
guard.set_active_capella_org_id(id.clone())?;
id
}
};

let response = client
.capella_request(
CapellaRequest::CreateProject {
org_id,
payload: serde_json::to_string(&project)
.map_err(|e| serialize_error(e.to_string(), span))?,
},
Instant::now().add(control.timeout()),
Instant::now().add(timeout),
ctrl_c,
)
.map_err(|e| client_error_to_shell_error(e, span))?;
Expand Down
24 changes: 21 additions & 3 deletions src/cli/projects_drop.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::cli::util::find_org_id;
use crate::cli::util::find_project_id;
use crate::client::CapellaRequest;
use crate::state::State;
Expand Down Expand Up @@ -63,15 +64,32 @@ fn projects_drop(

debug!("Running projects drop for {}", &name);

let guard = state.lock().unwrap();
let guard = &mut state.lock().unwrap();
let control = guard.active_capella_org()?;
let client = control.client();
let deadline = Instant::now().add(control.timeout());
let project_id = find_project_id(ctrl_c.clone(), name, &client, deadline, span)?;

let org_id = match control.id() {
Some(id) => id,
None => {
let id = find_org_id(ctrl_c.clone(), &client, deadline, span)?;
guard.set_active_capella_org_id(id.clone())?;
id
}
};

let project_id = find_project_id(
ctrl_c.clone(),
name,
&client,
deadline,
span,
org_id.clone(),
)?;

let response = client
.capella_request(
CapellaRequest::DeleteProject { project_id },
CapellaRequest::DeleteProject { org_id, project_id },
deadline,
ctrl_c,
)
Expand Down
29 changes: 28 additions & 1 deletion src/cli/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use std::sync::{Arc, Mutex, MutexGuard};
use std::time::Duration;
use tokio::time::Instant;

use super::cloud_json::JSONCloudsOrganizationsResponse;

pub fn is_http_status(response: &HttpResponse, status: u16, span: Span) -> Result<(), ShellError> {
if response.status() != status {
return Err(unexpected_status_code_error(
Expand Down Expand Up @@ -284,9 +286,10 @@ pub(crate) fn find_project_id(
client: &Arc<CapellaClient>,
deadline: Instant,
span: Span,
org_id: String,
) -> Result<String, ShellError> {
let response = client
.capella_request(CapellaRequest::GetProjects {}, deadline, ctrl_c)
.capella_request(CapellaRequest::GetProjects { org_id }, deadline, ctrl_c)
.map_err(|e| client_error_to_shell_error(e, span))?;
if response.status() != 200 {
return Err(UnexpectedResponseStatus {
Expand All @@ -308,6 +311,30 @@ pub(crate) fn find_project_id(
Err(ShellError::from(ProjectNotFound { name, span }))
}

pub(crate) fn find_org_id(
ctrl_c: Arc<AtomicBool>,
client: &Arc<CapellaClient>,
deadline: Instant,
span: Span,
) -> Result<String, ShellError> {
let response = client
.capella_request(CapellaRequest::GetOrganizations {}, deadline, ctrl_c)
.map_err(|e| client_error_to_shell_error(e, span))?;
if response.status() != 200 {
return Err(UnexpectedResponseStatus {
status_code: response.status(),
message: response.content().to_string(),
span,
}
.into());
}
let content: JSONCloudsOrganizationsResponse = serde_json::from_str(response.content())
.map_err(|e| deserialize_error(e.to_string(), span))?;

let org = content.items().first().unwrap().id();
Ok(org.to_string())
}

// 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 {
Expand Down
20 changes: 14 additions & 6 deletions src/client/cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ pub enum CapellaRequest {
payload: String,
},
CreateProject {
org_id: String,
payload: String,
},
CreateUser {
Expand All @@ -271,6 +272,7 @@ pub enum CapellaRequest {
cluster_id: String,
},
DeleteProject {
org_id: String,
project_id: String,
},
DeleteUser {
Expand Down Expand Up @@ -309,7 +311,9 @@ pub enum CapellaRequest {
// project_id: String,
// },
GetOrganizations,
GetProjects,
GetProjects {
org_id: String,
},
GetUsers {
cluster_id: String,
},
Expand Down Expand Up @@ -340,7 +344,9 @@ impl CapellaRequest {
}
Self::CreateCluster { .. } => "/v2/clusters".into(),
Self::CreateClusterV3 { .. } => "/v3/clusters".into(),
Self::CreateProject { .. } => "/v2/projects".into(),
Self::CreateProject { org_id, .. } => {
format!("/v4/organizations/{}/projects", org_id).into()
}
Self::CreateUser { cluster_id, .. } => {
format!("/v2/clusters/{}/users", cluster_id)
}
Expand All @@ -353,8 +359,8 @@ impl CapellaRequest {
Self::DeleteClusterV3 { cluster_id, .. } => {
format!("/v3/clusters/{}", cluster_id)
}
Self::DeleteProject { project_id } => {
format!("/v2/projects/{}", project_id)
Self::DeleteProject { org_id, project_id } => {
format!("/v4/organizations/{}/projects/{}", org_id, project_id).into()
}
Self::DeleteUser {
cluster_id,
Expand Down Expand Up @@ -395,7 +401,9 @@ impl CapellaRequest {
// format!("/v2/projects/{}", project_id)
// }
Self::GetOrganizations => "/v4/organizations".into(),
Self::GetProjects => "/v2/projects".into(),
Self::GetProjects { org_id } => {
format!("/v4/organizations/{}/projects?perPage=100", org_id)
}
Self::GetUsers { cluster_id } => {
format!("/v2/clusters/{}/users", cluster_id)
}
Expand Down Expand Up @@ -443,7 +451,7 @@ impl CapellaRequest {
// Self::GetOrgUsers => HttpVerb::Get,
// Self::GetProject { .. } => HttpVerb::Get,
Self::GetOrganizations => HttpVerb::Get,
Self::GetProjects => HttpVerb::Get,
Self::GetProjects { .. } => HttpVerb::Get,
Self::GetUsers { .. } => HttpVerb::Get,
// Self::UpdateAllowList { .. } => HttpVerb::Put,
Self::UpdateBucket { .. } => HttpVerb::Put,
Expand Down
36 changes: 31 additions & 5 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::tutorial::Tutorial;
use crate::RemoteCluster;
use nu_plugin::LabeledError;
use nu_protocol::ShellError;
use std::ops::Deref;
use std::path::PathBuf;
use std::sync::Arc;
use std::sync::Mutex;
Expand Down Expand Up @@ -142,9 +141,7 @@ impl State {
}

pub fn active_capella_org(&self) -> Result<&RemoteCapellaOrganization, ShellError> {
let guard = self.active_capella_org.lock().unwrap();

let active = match guard.deref() {
let active = match self.active_capella_org_name() {
Some(a) => a,
None => {
return Err(ShellError::GenericError(
Expand All @@ -157,7 +154,7 @@ impl State {
}
};

self.capella_orgs.get(active).ok_or_else(|| {
self.capella_orgs.get(&active).ok_or_else(|| {
ShellError::GenericError(
"Active Capella organization not known".to_string(),
"".to_string(),
Expand Down Expand Up @@ -191,6 +188,25 @@ impl State {
Ok(())
}

pub fn set_active_capella_org_id(&mut self, id: String) -> Result<(), ShellError> {
let active = self.active_capella_org_name().unwrap();
let orgs = &mut self.capella_orgs;
let org = match orgs.get_mut(&active) {
Some(org) => org,
None => {
return Err(ShellError::GenericError(
"Capella organization not known".to_string(),
format!("Capella organization {} has not been registered", active),
None,
None,
Vec::new(),
))
}
};
org.set_id(id);
Ok(())
}

pub fn capella_org_for_cluster(
&self,
identifier: String,
Expand Down Expand Up @@ -234,6 +250,7 @@ impl State {
}

pub struct RemoteCapellaOrganization {
id: Option<String>,
secret_key: String,
access_key: String,
client: Mutex<Option<Arc<CapellaClient>>>,
Expand All @@ -249,6 +266,7 @@ impl RemoteCapellaOrganization {
active_project: Option<String>,
) -> Self {
Self {
id: None,
secret_key,
access_key,
client: Mutex::new(None),
Expand Down Expand Up @@ -288,4 +306,12 @@ impl RemoteCapellaOrganization {
let mut active = self.active_project.lock().unwrap();
*active = Some(name);
}

pub fn id(&self) -> Option<String> {
self.id.clone()
}

pub fn set_id(&mut self, id: String) {
self.id = Some(id);
}
}

0 comments on commit 2517ee9

Please sign in to comment.