1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
//! OpenStackCLI - a.k.a. `osc` rewritten in Rust.
//!
//! This is a new OpenStackCLI written in Rust.
//!
//! Facts:
//! - not specifying `-o` will cause a Table output with a CLI
//! normalized and known attribute names only. Requesting
//! unsupported fields present in the API response is not going
//! to be supported (due to the name convention collision)
//!
//! - `-o wide` is still considered a human response and support
//! normalized/supported names only
//!
//! - `--plain` may be implemented to output a text form table
//! without borders and separators
//!
//! - `-o json` is treated as machine response and returns
//! server side names and does not support requesting certain
//! fields (they are not known in advance). This decision may be
//! re-evaluated
//!
//! More description to come
#![deny(missing_docs)]
// #![allow(unused_variables, dead_code, unused_imports)]
use std::io::{self, IsTerminal};
use clap::Parser;
use tracing::Level;
use openstack_sdk::AsyncOpenStack;
mod api;
mod auth;
mod block_storage;
mod catalog;
mod common;
mod compute;
mod identity;
mod image;
mod network;
mod object_store;
pub mod cli;
pub mod error;
pub mod output;
use crate::error::OpenStackCliError;
pub use cli::Cli;
use cli::TopLevelCommands;
pub(crate) use output::OutputConfig;
pub(crate) use output::StructTable;
/// Entry point for the CLI wrapper
pub async fn entry_point() -> Result<(), OpenStackCliError> {
let cli = Cli::parse();
tracing_subscriber::fmt()
.with_writer(io::stderr)
.with_max_level(match cli.global_opts.verbose {
0 => Level::ERROR,
1 => Level::INFO,
2 => Level::DEBUG,
_ => Level::TRACE,
})
.init();
let cfg = openstack_sdk::config::ConfigFile::new().unwrap();
let profile = cfg
.get_cloud_config(
cli.global_opts
.os_cloud
.clone()
.expect("--os-cloud or OS_CLOUD env must be given"),
)?
.ok_or(OpenStackCliError::ConnectionNotFound(
cli.global_opts.os_cloud.clone().unwrap(),
))?;
let mut renew_auth: bool = false;
// Login command need to be analyzed before authorization
if let TopLevelCommands::Auth(args) = &cli.command {
if let auth::AuthCommands::Login(login_args) = &args.command {
if login_args.renew {
renew_auth = true;
}
}
}
let mut session;
if std::io::stdin().is_terminal() {
session = AsyncOpenStack::new_interactive(&profile, renew_auth).await?;
} else {
session = AsyncOpenStack::new(&profile).await?;
}
// Invoke the command
cli.take_action(&mut session).await
}