Skip to content

Commit

Permalink
Merge pull request #5026 from wasmerio/volumes-cli-fixes
Browse files Browse the repository at this point in the history
Various volumes CLI fixes
  • Loading branch information
theduke authored Aug 21, 2024
2 parents fe3d4b6 + 7c2b89b commit 20526d0
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 61 deletions.
16 changes: 14 additions & 2 deletions lib/backend-api/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type User implements Node & PackageOwner & Owner {

"""Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."""
username: String!
registerIntent: String
isEmailValidated: Boolean!
bio: String
location: String
Expand Down Expand Up @@ -950,6 +951,7 @@ type DeployApp implements Node & Owner {
secrets(offset: Int, before: String, after: String, first: Int, last: Int): SecretConnection!
usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]!
s3Url: URL
s3Credentials: S3Credentials
deleted: Boolean!
favicon: URL
screenshot(viewportSize: AppScreenshotViewportSize, appearance: AppScreenshotAppearance): URL
Expand Down Expand Up @@ -1090,6 +1092,12 @@ character sequences.
"""
scalar URL

type S3Credentials {
accessKey: String!
secretKey: String!
endpoint: String!
}

enum AppScreenshotViewportSize {
MOBILE
DESKTOP
Expand Down Expand Up @@ -1124,15 +1132,17 @@ enum LogStream {
}

type AppVersionVolume {
id: ID!
name: String!
s3Url: String!
mountPaths: [AppVersionVolumeMountPath]!
size: Int
usedSize: Int
usedSize: BigInt
}

type AppVersionVolumeMountPath {
path: String!
subpath: String!
subpath: String
}

type PackageDistribution {
Expand Down Expand Up @@ -3570,6 +3580,7 @@ input RegisterUserInput {
username: CaseInsensitiveString!
password: String!
acceptedTos: Boolean
intent: String
clientMutationId: String
}

Expand All @@ -3583,6 +3594,7 @@ input SocialAuthJWTInput {
provider: String!
accessToken: String!
register: Boolean = false
registerIntent: String
clientMutationId: String
}

Expand Down
58 changes: 12 additions & 46 deletions lib/backend-api/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,63 +209,29 @@ pub async fn get_app_volumes(
Ok(volumes)
}

/// S3 credentials for an app.
///
/// Retrieved with [`get_app_s3_credentials`].
#[derive(Clone)]
pub struct AppS3Credentials {
pub url: String,
pub access_key: String,
pub secret_key: String,
}

/// Load the S3 credentials.
///
/// S3 can be used to get access to an apps volumes.
pub async fn get_app_s3_credentials(
client: &WasmerClient,
app_id: impl Into<String>,
) -> Result<AppS3Credentials, anyhow::Error> {
const ACCESS_KEY_NAME: &str = "WASMER_APP_S3_ACCESS_KEY";
const SECRET_KEY_NAME: &str = "WASMER_APP_S3_SECRET_KEY";

) -> Result<types::S3Credentials, anyhow::Error> {
let app_id = app_id.into();

// Firt load the app to get the s3 url.
let app = get_app_by_id(client, app_id.clone()).await?;
let url = app.s3_url.context("app has no volumes")?;

// Load the secrets.
let secrets =
get_all_app_secrets_filtered(client, app_id, [ACCESS_KEY_NAME, SECRET_KEY_NAME]).await?;
let app1 = get_app_by_id(client, app_id.clone()).await?;

let access_key_id = secrets
.iter()
.find(|s| s.name == ACCESS_KEY_NAME)
.context("missing access key")?
.id
.clone();

let secret_key_id = secrets
.iter()
.find(|s| s.name == SECRET_KEY_NAME)
.context("missing secret key")?
.id
.clone();

let access_key = get_app_secret_value_by_id(client, access_key_id.into_inner())
.await?
.with_context(|| format!("No value found for secret with name '{}'", ACCESS_KEY_NAME))?;

let secret_key = get_app_secret_value_by_id(client, secret_key_id.into_inner())
let vars = types::GetDeployAppVars {
owner: app1.owner.global_name,
name: app1.name,
};
client
.run_graphql_strict(types::GetDeployAppS3Credentials::build(vars))
.await?
.with_context(|| format!("No value found for secret with name '{}'", SECRET_KEY_NAME))?;

Ok(AppS3Credentials {
url: url.0,
access_key,
secret_key,
})
.get_deploy_app
.context("app not found")?
.s3_credentials
.context("app does not have S3 credentials")
}

/// Load all available regions.
Expand Down
22 changes: 21 additions & 1 deletion lib/backend-api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,26 @@ mod queries {
pub get_deploy_app: Option<DeployApp>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "GetDeployAppVars")]
pub struct GetDeployAppS3Credentials {
#[arguments(owner: $owner, name: $name)]
pub get_deploy_app: Option<AppWithS3Credentials>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "DeployApp", variables = "GetDeployAppVars")]
pub struct AppWithS3Credentials {
pub s3_credentials: Option<S3Credentials>,
}

#[derive(cynic::QueryFragment, Debug)]
pub struct S3Credentials {
pub access_key: String,
pub secret_key: String,
pub endpoint: String,
}

#[derive(cynic::QueryVariables, Debug, Clone)]
pub struct PaginationVars {
pub offset: Option<i32>,
Expand Down Expand Up @@ -805,7 +825,7 @@ mod queries {
pub struct AppVersionVolume {
pub name: String,
pub size: Option<i32>,
pub used_size: Option<i32>,
pub used_size: Option<BigInt>,
}

#[derive(cynic::QueryFragment, Debug)]
Expand Down
2 changes: 0 additions & 2 deletions lib/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,6 @@ http.workspace = true
is-terminal = "0.4.7"
colored = "2.0"
anyhow = "1.0"

# For the inspect subcommand
bytesize = "1.0"
cfg-if = "1.0"
tempfile = "3.6.0"
Expand Down
4 changes: 2 additions & 2 deletions lib/cli/src/commands/app/volumes/s3_credentials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ endpoint = {endpoint}
app_name = app.name,
access_key = creds.access_key,
secret_key = creds.secret_key,
endpoint = creds.url,
endpoint = creds.endpoint,
);

println!("{}", rclone_config);
} else {
println!("S3 credentials for app {}:\n", app.name);
println!(" S3 URL: {}", creds.url);
println!(" S3 URL: {}", creds.endpoint);
println!(" Access key: {}", creds.access_key);
println!(" Secret key: {}", creds.secret_key);
println!();
Expand Down
23 changes: 15 additions & 8 deletions lib/cli/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ impl CliRender for wasmer_api::types::AppVersionVolume {
vec!["Name".to_string(), self.name.clone()],
vec![
"Used size".to_string(),
format_disk_size_opt(self.used_size),
format_disk_size_opt(self.used_size.clone()),
],
]);
table.to_string()
Expand All @@ -173,18 +173,25 @@ impl CliRender for wasmer_api::types::AppVersionVolume {
fn render_list_table(items: &[Self]) -> String {
let mut table = Table::new();
table.set_header(vec!["Name".to_string(), "Used size".to_string()]);
table.add_rows(
items
.iter()
.map(|vol| vec![vol.name.clone(), format_disk_size_opt(vol.used_size)]),
);
table.add_rows(items.iter().map(|vol| {
vec![
vol.name.clone(),
format_disk_size_opt(vol.used_size.clone()),
]
}));
table.to_string()
}
}

fn format_disk_size_opt(value: Option<i32>) -> String {
fn format_disk_size_opt(value: Option<wasmer_api::types::BigInt>) -> String {
let value = value.and_then(|x| {
let y: Option<u64> = x.0.try_into().ok();
y
});

if let Some(v) = value {
format!("{}Mb", v)
let s = bytesize::ByteSize(v);
s.to_string()
} else {
"n/a".to_string()
}
Expand Down

0 comments on commit 20526d0

Please sign in to comment.