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

Add command to get organizations using v4 endpoint #265

Merged
merged 1 commit into from
Jan 30, 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
26 changes: 26 additions & 0 deletions src/cli/cloud_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,32 @@ impl JSONCloudClustersSummariesV3 {
}
}

#[derive(Debug, Deserialize)]
pub(crate) struct JSONCloudsOrganizationsResponse {
data: Vec<JSONCloudsOrganizationsResponseItem>,
}

impl JSONCloudsOrganizationsResponse {
pub fn items(&self) -> &Vec<JSONCloudsOrganizationsResponseItem> {
self.data.as_ref()
}
}

#[derive(Debug, Deserialize)]
pub(crate) struct JSONCloudsOrganizationsResponseItem {
id: String,
name: String,
}

impl JSONCloudsOrganizationsResponseItem {
pub fn id(&self) -> &str {
&self.id
}
pub fn name(&self) -> &str {
&self.name
}
}

#[derive(Debug, Deserialize)]
pub(crate) struct JSONCloudsProjectsResponseItem {
id: String,
Expand Down
2 changes: 2 additions & 0 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
mod health;
mod help;
mod nodes;
mod organizations;
mod ping;
// mod plugin_from_bson;
mod cbenv_bucket;
Expand Down Expand Up @@ -111,6 +112,7 @@
pub use health::HealthCheck;
pub use help::Help;
pub use nodes::Nodes;
pub use organizations::Organizations;
pub use ping::Ping;
// pub use plugin_from_bson::PluginFromBson;
pub use cbenv_bucket::UseBucket;
Expand Down Expand Up @@ -138,7 +140,7 @@
pub use tutorial_next::TutorialNext;
pub use tutorial_page::TutorialPage;
pub use tutorial_prev::TutorialPrev;
pub use user_builder::User;

Check warning on line 143 in src/cli/mod.rs

View workflow job for this annotation

GitHub Actions / test (7.1.1, ubuntu-20.04)

unused import: `user_builder::User`

Check warning on line 143 in src/cli/mod.rs

View workflow job for this annotation

GitHub Actions / test (7.0.3, ubuntu-20.04)

unused import: `user_builder::User`
pub use users::Users;
pub use users_drop::UsersDrop;
pub use users_get::UsersGet;
Expand Down
99 changes: 99 additions & 0 deletions src/cli/organizations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use crate::cli::cloud_json::JSONCloudsOrganizationsResponse;
use crate::cli::util::NuValueMap;
use crate::client::CapellaRequest;
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, deserialize_error, unexpected_status_code_error,
};
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{Category, IntoPipelineData, PipelineData, ShellError, Signature, Value};

#[derive(Clone)]
pub struct Organizations {
state: Arc<Mutex<State>>,
}

impl Organizations {
pub fn new(state: Arc<Mutex<State>>) -> Self {
Self { state }
}
}

impl Command for Organizations {
fn name(&self) -> &str {
"organizations"
}

fn signature(&self) -> Signature {
Signature::build("organizations").category(Category::Custom("couchbase".to_string()))
}

fn usage(&self) -> &str {
"Lists all organizations the user has access too"
}

fn run(
&self,
engine_state: &EngineState,
stack: &mut Stack,
call: &Call,
input: PipelineData,
) -> Result<PipelineData, ShellError> {
organizations(self.state.clone(), engine_state, stack, call, input)
}
}

fn organizations(
state: Arc<Mutex<State>>,
engine_state: &EngineState,
_stack: &mut Stack,
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
let span = call.head;
let ctrl_c = engine_state.ctrlc.as_ref().unwrap().clone();

debug!("Running organizations");

let guard = state.lock().unwrap();
let control = guard.active_capella_org()?;
let client = control.client();
let response = client
.capella_request(
CapellaRequest::GetOrganizations {},
Instant::now().add(control.timeout()),
ctrl_c,
)
.map_err(|e| client_error_to_shell_error(e, span))?;
if response.status() != 200 {
return Err(unexpected_status_code_error(
response.status(),
response.content(),
span,
));
}

let content: JSONCloudsOrganizationsResponse = serde_json::from_str(response.content())
.map_err(|e| deserialize_error(e.to_string(), span))?;

let mut results = vec![];
for project in content.items() {
let mut collected = NuValueMap::default();
collected.add_string("name", project.name(), span);
collected.add_string("id", project.id(), span);
results.push(collected.into_value(span))
}

Ok(Value::List {
vals: results,
span: span,
}
.into_pipeline_data())
}
17 changes: 12 additions & 5 deletions src/client/cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,15 @@ impl CapellaClient {
mac.update(bearer_payload.as_bytes());
let mac_result = mac.finalize();

let bearer = format!(
"Bearer {}:{}",
self.access_key.clone(),
general_purpose::STANDARD.encode(mac_result.into_bytes()),
);
let bearer = if path.contains("/v4/") {
format!("Bearer {}", &self.secret_key)
} else {
format!(
"Bearer {}:{}",
self.access_key.clone(),
general_purpose::STANDARD.encode(mac_result.into_bytes())
)
};

res_builder = res_builder
.timeout(timeout)
Expand Down Expand Up @@ -304,6 +308,7 @@ pub enum CapellaRequest {
// GetProject {
// project_id: String,
// },
GetOrganizations,
GetProjects,
GetUsers {
cluster_id: String,
Expand Down Expand Up @@ -389,6 +394,7 @@ impl CapellaRequest {
// Self::GetProject { project_id } => {
// format!("/v2/projects/{}", project_id)
// }
Self::GetOrganizations => "/v4/organizations".into(),
Self::GetProjects => "/v2/projects".into(),
Self::GetUsers { cluster_id } => {
format!("/v2/clusters/{}/users", cluster_id)
Expand Down Expand Up @@ -436,6 +442,7 @@ impl CapellaRequest {
// Self::GetClusterStatus { .. } => HttpVerb::Get,
// Self::GetOrgUsers => HttpVerb::Get,
// Self::GetProject { .. } => HttpVerb::Get,
Self::GetOrganizations => HttpVerb::Get,
Self::GetProjects => HttpVerb::Get,
Self::GetUsers { .. } => HttpVerb::Get,
// Self::UpdateAllowList { .. } => HttpVerb::Put,
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,7 @@ fn merge_couchbase_delta(context: &mut EngineState, state: Arc<Mutex<State>>) {
working_set.add_decl(Box::new(Help));
working_set.add_decl(Box::new(FakeData::new(state.clone())));
working_set.add_decl(Box::new(Nodes::new(state.clone())));
working_set.add_decl(Box::new(Organizations::new(state.clone())));
working_set.add_decl(Box::new(Ping::new(state.clone())));
working_set.add_decl(Box::new(Projects::new(state.clone())));
working_set.add_decl(Box::new(ProjectsCreate::new(state.clone())));
Expand Down
Loading