use aleph_sdk::aggregate_models::corechannel::NodeHash;
use aleph_types::item_hash::ItemHash;
use clap::{Args, Parser, Subcommand, ValueEnum};
use std::path::PathBuf;
pub fn parse_size_to_mib(s: &str) -> Result<u64, String> {
let s = s.trim();
let unit_start = s
.find(|c: char| c.is_alphabetic())
.ok_or_else(|| format!("missing unit in size '{s}' (use e.g. 20GB, 1024MB, 1TiB)"))?;
let (num_str, unit) = s.split_at(unit_start);
let value: f64 = num_str
.trim()
.parse()
.map_err(|_| format!("invalid number in size '{s}'"))?;
if value < 0.0 {
return Err(format!("size cannot be negative: '{s}'"));
}
let mib = match unit.to_lowercase().as_str() {
"mib" => value,
"gib" => value * 1024.0,
"tib" => value * 1024.0 * 1024.0,
"mb" => value * 1_000_000.0 / 1_048_576.0,
"gb" => value * 1_000_000_000.0 / 1_048_576.0,
"tb" => value * 1_000_000_000_000.0 / 1_048_576.0,
_ => {
return Err(format!(
"unknown size unit '{unit}' (use MB, GB, TB, MiB, GiB, TiB)"
));
}
};
let mib_rounded = mib.round() as u64;
if mib_rounded == 0 {
return Err(format!("size too small: '{s}' rounds to 0 MiB"));
}
Ok(mib_rounded)
}
const IMAGE_PRESETS: &[(&str, &str)] = &[
(
"ubuntu22",
"4a0f62da42f4478544616519e6f5d58adb1096e069b392b151d47c3609492d0c",
),
(
"ubuntu24",
"5330dcefe1857bcd97b7b7f24d1420a7d46232d53f27be280c8a7071d88bd84e",
),
(
"debian12",
"b6ff5c3a8205d1ca4c7c3369300eeafff498b558f71b851aa2114afd0a532717",
),
];
pub fn parse_image(s: &str) -> Result<ItemHash, String> {
for (name, hash) in IMAGE_PRESETS {
if s.eq_ignore_ascii_case(name) {
return hash.parse().map_err(|e| format!("{e}"));
}
}
ItemHash::try_from(s).map_err(|_| {
let preset_names: Vec<&str> = IMAGE_PRESETS.iter().map(|(n, _)| *n).collect();
format!(
"'{s}' is not a valid image. Use a preset ({}) or an item hash.",
preset_names.join(", ")
)
})
}
#[derive(Parser)]
#[command(name = "aleph", version, about = "Aleph CLI")]
pub struct Cli {
#[arg(long, conflicts_with = "ccn")]
pub ccn_url: Option<String>,
#[arg(long, conflicts_with = "ccn_url")]
pub ccn: Option<String>,
#[arg(long, global = true)]
pub json: bool,
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
Account {
#[clap(subcommand)]
command: AccountCommand,
},
Aggregate {
#[clap(subcommand)]
command: AggregateCommand,
},
Authorization {
#[clap(subcommand)]
command: AuthorizationCommand,
},
Config {
#[clap(subcommand)]
command: ConfigCommand,
},
Crn {
#[clap(subcommand)]
command: CrnCommand,
},
File {
#[clap(subcommand)]
command: FileCommand,
},
Instance {
#[clap(subcommand)]
command: InstanceCommand,
},
Message {
#[clap(subcommand)]
command: MessageCommand,
},
Node {
#[clap(subcommand)]
command: NodeCommand,
},
Post {
#[clap(subcommand)]
command: PostCommand,
},
}
#[derive(Subcommand)]
pub enum MessageCommand {
Forget(ForgetArgs),
Get(GetMessageArgs),
List(Box<MessageFilterCli>),
Sync(Box<SyncArgs>),
}
#[derive(Args)]
pub struct SyncArgs {
#[arg(long)]
pub source: String,
#[arg(long)]
pub target: String,
#[arg(long, default_value = "200")]
pub count: u32,
#[arg(long)]
pub dry_run: bool,
#[command(flatten)]
pub filter: MessageFilterCli,
}
#[derive(Args)]
pub struct GetMessageArgs {
pub item_hash: ItemHash,
}
#[derive(Subcommand)]
pub enum PostCommand {
Amend(PostAmendArgs),
Create(PostCreateArgs),
List(Box<PostListArgs>),
}
#[derive(Args)]
pub struct PostListArgs {
#[arg(long, default_value = "1")]
pub api_version: u8,
#[command(flatten)]
pub filter: PostFilterCli,
}
use aleph_sdk::client::{MessageFilter, PostFilter, SortBy, SortOrder};
use aleph_types::message::{MessageStatus, MessageType};
use aleph_types::timestamp::Timestamp;
use chrono::{DateTime, FixedOffset};
use std::str::FromStr;
fn parse_timestamp(s: &str) -> Result<Timestamp, String> {
println!("Parsing datetime: {}", s);
if let Ok(timestamp) = s.parse::<f64>() {
return Ok(Timestamp::from(timestamp));
}
let timestamp = DateTime::<FixedOffset>::from_str(s)
.map_err(|e| e.to_string())?
.timestamp();
Ok(Timestamp::from(timestamp as f64))
}
#[derive(Copy, Clone, Debug, ValueEnum)]
pub enum MessageTypeCli {
Aggregate,
Forget,
Instance,
Program,
Post,
Store,
}
impl From<MessageTypeCli> for MessageType {
fn from(v: MessageTypeCli) -> Self {
match v {
MessageTypeCli::Aggregate => MessageType::Aggregate,
MessageTypeCli::Forget => MessageType::Forget,
MessageTypeCli::Instance => MessageType::Instance,
MessageTypeCli::Post => MessageType::Post,
MessageTypeCli::Program => MessageType::Program,
MessageTypeCli::Store => MessageType::Store,
}
}
}
#[derive(Copy, Clone, Debug, ValueEnum)]
pub enum MessageStatusCli {
Pending,
Processed,
Removing,
Removed,
Forgotten,
}
impl From<MessageStatusCli> for MessageStatus {
fn from(v: MessageStatusCli) -> Self {
match v {
MessageStatusCli::Pending => MessageStatus::Pending,
MessageStatusCli::Processed => MessageStatus::Processed,
MessageStatusCli::Removing => MessageStatus::Removing,
MessageStatusCli::Removed => MessageStatus::Removed,
MessageStatusCli::Forgotten => MessageStatus::Forgotten,
}
}
}
#[derive(Copy, Clone, Debug, ValueEnum)]
pub enum SortByCli {
Time,
TxTime,
}
impl From<SortByCli> for SortBy {
fn from(v: SortByCli) -> Self {
match v {
SortByCli::Time => SortBy::Time,
SortByCli::TxTime => SortBy::TxTime,
}
}
}
#[derive(Copy, Clone, Debug, ValueEnum)]
pub enum SortOrderCli {
Asc,
Desc,
}
impl From<SortOrderCli> for SortOrder {
fn from(v: SortOrderCli) -> Self {
match v {
SortOrderCli::Asc => SortOrder::Asc,
SortOrderCli::Desc => SortOrder::Desc,
}
}
}
#[derive(Copy, Clone, Debug, ValueEnum)]
pub enum ChainCli {
Arb,
Aurora,
Avax,
Base,
Blast,
Bob,
Bsc,
Cyber,
Eth,
Etherlink,
Frax,
Hype,
Ink,
Lens,
Linea,
Lisk,
Metis,
Mode,
Op,
Pol,
Stt,
Sonic,
Unichain,
Wld,
Zora,
Sol,
Es,
}
impl From<ChainCli> for aleph_types::chain::Chain {
fn from(v: ChainCli) -> Self {
use aleph_types::chain::Chain;
match v {
ChainCli::Arb => Chain::Arbitrum,
ChainCli::Aurora => Chain::Aurora,
ChainCli::Avax => Chain::Avax,
ChainCli::Base => Chain::Base,
ChainCli::Blast => Chain::Blast,
ChainCli::Bob => Chain::Bob,
ChainCli::Bsc => Chain::Bsc,
ChainCli::Cyber => Chain::Cyber,
ChainCli::Eth => Chain::Ethereum,
ChainCli::Etherlink => Chain::Etherlink,
ChainCli::Frax => Chain::Fraxtal,
ChainCli::Hype => Chain::Hype,
ChainCli::Ink => Chain::Ink,
ChainCli::Lens => Chain::Lens,
ChainCli::Linea => Chain::Linea,
ChainCli::Lisk => Chain::Lisk,
ChainCli::Metis => Chain::Metis,
ChainCli::Mode => Chain::Mode,
ChainCli::Op => Chain::Optimism,
ChainCli::Pol => Chain::Pol,
ChainCli::Stt => Chain::Somnia,
ChainCli::Sonic => Chain::Sonic,
ChainCli::Unichain => Chain::Unichain,
ChainCli::Wld => Chain::Worldchain,
ChainCli::Zora => Chain::Zora,
ChainCli::Sol => Chain::Sol,
ChainCli::Es => Chain::Eclipse,
}
}
}
#[derive(Debug, Clone, Args)]
pub struct SigningArgs {
#[arg(long)]
pub account: Option<String>,
#[arg(long)]
pub private_key: Option<String>,
#[arg(long, value_enum, default_value = "eth")]
pub chain: ChainCli,
#[arg(long)]
pub dry_run: bool,
}
#[derive(Debug, Clone, Args)]
pub struct MessageFilterCli {
#[arg(long, value_delimiter = ',', value_enum)]
pub message_type: Option<MessageTypeCli>,
#[arg(long, value_delimiter = ',', value_enum)]
pub message_types: Option<Vec<MessageTypeCli>>,
#[arg(long, value_delimiter = ',')]
pub content_types: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub content_keys: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub content_hashes: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub refs: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub addresses: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub tags: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub hashes: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub channels: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub chains: Option<Vec<String>>,
#[arg(long, value_parser = parse_timestamp)]
pub start_date: Option<Timestamp>,
#[arg(long, value_parser = parse_timestamp)]
pub end_date: Option<Timestamp>,
#[arg(long, value_enum)]
pub sort_by: Option<SortByCli>,
#[arg(long, value_enum)]
pub sort_order: Option<SortOrderCli>,
#[arg(long, value_delimiter = ',')]
pub message_statuses: Option<Vec<MessageStatusCli>>,
#[arg(long, default_value = "200")]
pub pagination: u32,
#[arg(long, default_value = "1")]
pub page: u32,
}
impl From<MessageFilterCli> for MessageFilter {
fn from(c: MessageFilterCli) -> Self {
MessageFilter {
message_type: c.message_type.map(Into::into),
message_types: c
.message_types
.map(|v| v.into_iter().map(Into::into).collect()),
content_types: c.content_types,
content_keys: c.content_keys,
content_hashes: c
.content_hashes
.map(|v| v.into_iter().map(|s| s.parse().unwrap()).collect()),
refs: c.refs,
addresses: c.addresses.map(|v| v.into_iter().map(Into::into).collect()),
owners: None,
tags: c.tags,
hashes: c
.hashes
.map(|v| v.into_iter().map(|s| s.parse().unwrap()).collect()),
channels: c.channels,
chains: c.chains,
start_date: c.start_date,
end_date: c.end_date,
sort_by: c.sort_by.map(Into::into),
sort_order: c.sort_order.map(Into::into),
message_statuses: c
.message_statuses
.map(|v| v.into_iter().map(Into::into).collect()),
}
}
}
#[derive(Debug, Clone, Args)]
pub struct PostFilterCli {
#[arg(long, value_delimiter = ',')]
pub addresses: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub hashes: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub refs: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub post_types: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub tags: Option<Vec<String>>,
#[arg(long, value_delimiter = ',')]
pub channels: Option<Vec<String>>,
#[arg(long, value_parser = parse_timestamp)]
pub start_date: Option<Timestamp>,
#[arg(long, value_parser = parse_timestamp)]
pub end_date: Option<Timestamp>,
#[arg(long, value_enum)]
pub sort_by: Option<SortByCli>,
#[arg(long, value_enum)]
pub sort_order: Option<SortOrderCli>,
#[arg(long, default_value = "200")]
pub pagination: u32,
#[arg(long, default_value = "1")]
pub page: u32,
}
impl From<PostFilterCli> for PostFilter {
fn from(c: PostFilterCli) -> Self {
PostFilter {
addresses: c.addresses.map(|v| v.into_iter().map(Into::into).collect()),
hashes: c
.hashes
.map(|v| v.into_iter().map(|s| s.parse().unwrap()).collect()),
refs: c.refs,
post_types: c.post_types,
tags: c.tags,
channels: c.channels,
start_date: c.start_date,
end_date: c.end_date,
sort_by: c.sort_by.map(Into::into),
sort_order: c.sort_order.map(Into::into),
}
}
}
#[derive(Args)]
pub struct PostCreateArgs {
#[arg(long = "type")]
pub post_type: String,
#[arg(long)]
pub content: Option<String>,
#[arg(long)]
pub channel: Option<String>,
#[arg(long)]
pub on_behalf_of: Option<String>,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct PostAmendArgs {
#[arg(long = "ref")]
pub reference: ItemHash,
#[arg(long)]
pub content: Option<String>,
#[arg(long)]
pub channel: Option<String>,
#[arg(long)]
pub on_behalf_of: Option<String>,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Subcommand)]
pub enum AggregateCommand {
Create(AggregateCreateArgs),
}
#[derive(Args)]
pub struct AggregateCreateArgs {
#[arg(long)]
pub key: String,
#[arg(long)]
pub content: Option<String>,
#[arg(long)]
pub channel: Option<String>,
#[arg(long)]
pub on_behalf_of: Option<String>,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct ForgetArgs {
pub hashes: Vec<ItemHash>,
#[arg(long, value_delimiter = ',')]
pub aggregates: Option<Vec<ItemHash>>,
#[arg(long)]
pub reason: Option<String>,
#[arg(long)]
pub channel: Option<String>,
#[arg(long)]
pub on_behalf_of: Option<String>,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Subcommand)]
#[allow(clippy::large_enum_variant)]
pub enum NodeCommand {
Amend(AmendNodeArgs),
CreateCcn(CreateCcnArgs),
CreateCrn(CreateCrnArgs),
Drop(DropNodeArgs),
Link(LinkCrnArgs),
List(NodeListArgs),
Stake(StakeArgs),
Unlink(UnlinkCrnArgs),
Unstake(UnstakeArgs),
}
#[derive(Debug, Clone, Args)]
#[command(group = clap::ArgGroup::new("scope").args(["address", "all"]))]
pub struct NodeListArgs {
#[arg(long)]
pub address: Option<String>,
#[arg(long)]
pub all: bool,
#[arg(long, value_enum, rename_all = "lowercase")]
pub r#type: Option<NodeTypeCli>,
#[arg(long)]
pub corechannel_address: Option<String>,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Copy, Clone, Debug, ValueEnum)]
pub enum NodeTypeCli {
Ccn,
Crn,
}
#[derive(Args)]
pub struct CreateCcnArgs {
#[arg(long)]
pub name: String,
#[arg(long)]
pub multiaddress: String,
#[arg(long, default_value = "mainnet")]
pub network: String,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct CreateCrnArgs {
#[arg(long)]
pub name: String,
#[arg(long)]
pub address: String,
#[arg(long, default_value = "mainnet")]
pub network: String,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct LinkCrnArgs {
#[arg(long)]
pub crn: NodeHash,
#[arg(long, default_value = "mainnet")]
pub network: String,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct UnlinkCrnArgs {
#[arg(long)]
pub crn: NodeHash,
#[arg(long, default_value = "mainnet")]
pub network: String,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct StakeArgs {
#[arg(long)]
pub node: NodeHash,
#[arg(long, default_value = "mainnet")]
pub network: String,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct UnstakeArgs {
#[arg(long)]
pub node: NodeHash,
#[arg(long, default_value = "mainnet")]
pub network: String,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct DropNodeArgs {
#[arg(long)]
pub node: NodeHash,
#[arg(long, default_value = "mainnet")]
pub network: String,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct AmendNodeArgs {
#[arg(long)]
pub node: NodeHash,
#[arg(long)]
pub name: Option<String>,
#[arg(long)]
pub multiaddress: Option<String>,
#[arg(long)]
pub address: Option<String>,
#[arg(long)]
pub picture: Option<String>,
#[arg(long)]
pub banner: Option<String>,
#[arg(long)]
pub description: Option<String>,
#[arg(long)]
pub reward: Option<String>,
#[arg(long)]
pub stream_reward: Option<String>,
#[arg(long)]
pub manager: Option<String>,
#[arg(long, value_delimiter = ',')]
pub authorized: Option<Vec<String>>,
#[arg(long)]
pub locked: Option<bool>,
#[arg(long)]
pub registration_url: Option<String>,
#[arg(long)]
pub terms_and_conditions: Option<String>,
#[arg(long, default_value = "mainnet")]
pub network: String,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Subcommand)]
pub enum AccountCommand {
Alias {
#[clap(subcommand)]
command: AliasCommand,
},
Balance(AccountBalanceArgs),
Create(AccountCreateArgs),
Delete(AccountDeleteArgs),
Export(AccountExportArgs),
Import(AccountImportArgs),
List,
Migrate(AccountMigrateArgs),
Show(AccountShowArgs),
Use(AccountUseArgs),
}
#[derive(Args)]
pub struct AccountCreateArgs {
#[arg(long)]
pub name: String,
#[arg(long, value_enum, default_value = "eth")]
pub chain: ChainCli,
}
#[derive(Args)]
pub struct AccountImportArgs {
#[arg(long)]
pub name: String,
#[arg(long, value_enum, default_value = "eth")]
pub chain: ChainCli,
#[arg(long, conflicts_with = "ledger")]
pub private_key: Option<String>,
#[arg(long, conflicts_with_all = ["private_key", "ledger"])]
pub from_file: Option<PathBuf>,
#[arg(long)]
pub ledger: bool,
#[arg(long, requires = "ledger")]
pub derivation_path: Option<String>,
#[arg(long, requires = "ledger", default_value = "5")]
pub ledger_count: usize,
}
#[derive(Args)]
pub struct AccountMigrateArgs {
#[arg(long)]
pub python_home: Option<PathBuf>,
#[arg(long)]
pub dry_run: bool,
}
#[derive(Args)]
pub struct AccountShowArgs {
pub name: Option<String>,
}
#[derive(Args)]
pub struct AccountBalanceArgs {
pub address: Option<String>,
}
#[derive(Args)]
pub struct AccountDeleteArgs {
pub name: String,
}
#[derive(Args)]
pub struct AccountUseArgs {
pub name: String,
}
#[derive(Args)]
pub struct AccountExportArgs {
pub name: String,
#[arg(long)]
pub yes: bool,
}
#[derive(Subcommand)]
pub enum AliasCommand {
Add(AliasAddArgs),
List,
Remove(AliasRemoveArgs),
}
#[derive(Args)]
pub struct AliasAddArgs {
pub name: String,
pub address: String,
}
#[derive(Args)]
pub struct AliasRemoveArgs {
pub name: String,
}
#[derive(Subcommand)]
pub enum FileCommand {
Download(FileDownloadArgs),
Upload(FileUploadArgs),
}
#[derive(Copy, Clone, Debug, ValueEnum)]
pub enum StorageEngineCli {
Storage,
Ipfs,
}
#[derive(Args)]
pub struct FileUploadArgs {
pub path: std::path::PathBuf,
#[arg(long, value_enum, default_value = "storage")]
pub storage_engine: StorageEngineCli,
#[arg(long)]
pub channel: Option<String>,
#[arg(long = "ref")]
pub reference: Option<String>,
#[arg(long)]
pub on_behalf_of: Option<String>,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct FileDownloadArgs {
#[arg(conflicts_with_all = ["message_hash", "reference"])]
pub hash: Option<ItemHash>,
#[arg(long, conflicts_with_all = ["hash", "reference"])]
pub message_hash: Option<ItemHash>,
#[arg(long = "ref", conflicts_with_all = ["hash", "message_hash"])]
pub reference: Option<String>,
#[arg(long, requires = "reference")]
pub owner: Option<String>,
#[arg(short, long)]
pub output: Option<std::path::PathBuf>,
#[arg(long)]
pub stdout: bool,
}
#[derive(Subcommand)]
#[allow(clippy::large_enum_variant)]
pub enum InstanceCommand {
Create(InstanceCreateArgs),
#[command(long_about = "\
Show pricing for an instance configuration.
There are three ways to specify the instance:
1. By size slug: --size 1vcpu-2gb
2. By resources: --vcpus 4 --memory 8GB --disk-size 100GB
3. By GPU model: --gpu h100
GPU instances have a minimum size determined by the model. Use --size \
or --vcpus/--memory to request more resources (must be >= the GPU minimum). \
GPU and confidential instances use separate pricing tiers and cannot \
be combined.
Examples:
aleph instance price --size 4vcpu-8gb
aleph instance price --vcpus 2 --memory 4GB --disk-size 50GB
aleph instance price --gpu h100
aleph instance price --gpu h100 --size 32vcpu-192gb
aleph instance price --gpu # list available GPU models
aleph instance price --size 1vcpu-2gb --confidential")]
Price(InstancePriceArgs),
}
#[derive(Args)]
pub struct InstancePriceArgs {
#[arg(long)]
pub size: Option<String>,
#[arg(long)]
pub vcpus: Option<u32>,
#[arg(long, value_parser = parse_size_to_mib)]
pub memory: Option<u64>,
#[arg(long, value_parser = parse_size_to_mib)]
pub disk_size: Option<u64>,
#[arg(long, num_args = 0..=1, default_missing_value = "")]
pub gpu: Option<String>,
#[arg(long)]
pub confidential: bool,
}
#[derive(Args)]
pub struct InstanceCreateArgs {
#[arg(long, value_parser = parse_image)]
pub image: ItemHash,
#[arg(long, value_parser = parse_size_to_mib)]
pub disk_size: Option<u64>,
#[arg(long)]
pub size: Option<String>,
#[arg(long)]
pub vcpus: Option<u32>,
#[arg(long, value_parser = parse_size_to_mib)]
pub memory: Option<u64>,
#[arg(long, required = true)]
pub ssh_pubkey_file: Vec<PathBuf>,
#[arg(long)]
pub name: Option<String>,
#[arg(long)]
pub channel: Option<String>,
#[arg(long)]
pub persistent_volume: Option<Vec<String>>,
#[arg(long)]
pub ephemeral_volume: Option<Vec<String>>,
#[arg(long)]
pub immutable_volume: Option<Vec<String>>,
#[arg(long)]
pub confidential: bool,
#[arg(
long,
default_value = "ba5bb13f3abca960b101a759be162b229e2b7e93ecad9d1307e54de887f177ff"
)]
pub confidential_firmware: String,
#[arg(long)]
pub gpu: Option<Vec<String>>,
#[arg(long)]
pub crn_hash: Option<String>,
#[arg(long)]
pub on_behalf_of: Option<String>,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Subcommand)]
pub enum AuthorizationCommand {
Add(AuthorizationAddArgs),
List(AuthorizationListArgs),
Received(AuthorizationReceivedArgs),
Revoke(AuthorizationRevokeArgs),
}
#[derive(Debug, Clone, Args)]
pub struct AuthorizationListArgs {
#[arg(long)]
pub address: Option<String>,
#[arg(long)]
pub delegate: Option<String>,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Debug, Clone, Args)]
pub struct AuthorizationReceivedArgs {
#[arg(long)]
pub address: Option<String>,
#[arg(long)]
pub granter: Option<String>,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Debug, Clone, Args)]
pub struct AuthorizationAddArgs {
pub delegate_address: String,
#[arg(long = "delegate-chain", value_enum)]
pub delegate_chain: Option<ChainCli>,
#[arg(long, value_delimiter = ',')]
pub channels: Vec<String>,
#[arg(long, value_delimiter = ',', value_enum)]
pub message_types: Vec<MessageTypeCli>,
#[arg(long, value_delimiter = ',')]
pub post_types: Vec<String>,
#[arg(long, value_delimiter = ',')]
pub aggregate_keys: Vec<String>,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Debug, Clone, Args)]
#[command(group(clap::ArgGroup::new("target").required(true)))]
pub struct AuthorizationRevokeArgs {
#[arg(group = "target")]
pub delegate_address: Option<String>,
#[arg(long, group = "target")]
pub all: bool,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Subcommand)]
pub enum CrnCommand {
Erase(CrnArgs),
Logs(CrnArgs),
Reboot(CrnArgs),
Start(CrnStartArgs),
Stop(CrnArgs),
}
#[derive(Args)]
pub struct CrnArgs {
#[arg(long)]
pub crn_url: String,
pub vm_id: ItemHash,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Args)]
pub struct CrnStartArgs {
#[arg(long)]
pub crn_url: String,
pub vm_id: ItemHash,
#[command(flatten)]
pub signing: SigningArgs,
}
#[derive(Subcommand)]
pub enum ConfigCommand {
Ccn {
#[clap(subcommand)]
command: CcnCommand,
},
}
#[derive(Subcommand)]
pub enum CcnCommand {
Add(CcnAddArgs),
List,
Remove(CcnRemoveArgs),
Show(CcnShowArgs),
Use(CcnUseArgs),
}
#[derive(Args)]
pub struct CcnAddArgs {
pub name: String,
pub url: String,
}
#[derive(Args)]
pub struct CcnUseArgs {
pub name: String,
}
#[derive(Args)]
pub struct CcnShowArgs {
pub name: Option<String>,
}
#[derive(Args)]
pub struct CcnRemoveArgs {
pub name: String,
}