Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use v4 API for projects commands #266

Merged
merged 1 commit into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 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 @@ -93,7 +94,20 @@ fn clusters_create(
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 => find_org_id(ctrl_c.clone(), &client, deadline, span)?,
};

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 +119,7 @@ fn clusters_create(
payload: serde_json::to_string(&json)
.map_err(|e| serialize_error(e.to_string(), span))?,
},
Instant::now().add(control.timeout()),
deadline,
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 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::CreateProject {
org_id,
payload: serde_json::to_string(&project)
.map_err(|e| serialize_error(e.to_string(), span))?,
},
Instant::now().add(control.timeout()),
deadline,
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
48 changes: 43 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,37 @@ impl State {
Ok(())
}

pub fn set_active_capella_org_id(&mut self, id: String) -> Result<(), ShellError> {
let active = match self.active_capella_org_name() {
Some(a) => a,
None => {
return Err(ShellError::GenericError(
"No active Capella organization set".to_string(),
"".to_string(),
None,
None,
Vec::new(),
))
}
};

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 +262,7 @@ impl State {
}

pub struct RemoteCapellaOrganization {
id: Option<String>,
secret_key: String,
access_key: String,
client: Mutex<Option<Arc<CapellaClient>>>,
Expand All @@ -249,6 +278,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 +318,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);
}
}
Loading