Skip to content

Commit

Permalink
feat(rust): revamp the generation of the OpenAPI spec
Browse files Browse the repository at this point in the history
  • Loading branch information
imobachgs committed Aug 30, 2024
1 parent 4db0996 commit 0b88720
Show file tree
Hide file tree
Showing 17 changed files with 383 additions and 155 deletions.
1 change: 1 addition & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/agama-lib/src/network/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub struct WirelessSettings {
pub mode: String,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct BondSettings {
pub mode: String,
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down
2 changes: 1 addition & 1 deletion rust/agama-lib/src/network/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ impl TryFrom<&str> for Status {
}

/// Bond mode
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy, utoipa::ToSchema)]
pub enum BondMode {
#[serde(rename = "balance-rr")]
RoundRobin = 0,
Expand Down
2 changes: 1 addition & 1 deletion rust/agama-lib/src/software/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct Pattern {
}

/// Represents the reason why a pattern is selected.
#[derive(Clone, Copy, Debug, PartialEq, Serialize_repr)]
#[derive(Clone, Copy, Debug, PartialEq, Serialize_repr, utoipa::ToSchema)]
#[repr(u8)]
pub enum SelectedBy {
/// The pattern was selected by the user.
Expand Down
2 changes: 1 addition & 1 deletion rust/agama-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ tracing-journald = "0.3.0"
tracing = "0.1.40"
clap = { version = "4.5.0", features = ["derive", "wrap_help"] }
tower = "0.4.13"
utoipa = { version = "4.2.0", features = ["axum_extras"] }
utoipa = { version = "4.2.0", features = ["axum_extras", "uuid"] }
config = "0.14.0"
rand = "0.8.5"
jsonwebtoken = "9.2.0"
Expand Down
1 change: 0 additions & 1 deletion rust/agama-server/src/agama-web-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use openssl::ssl::{Ssl, SslAcceptor, SslMethod};
use tokio::sync::broadcast::channel;
use tokio_openssl::SslStream;
use tower::Service;
use utoipa::OpenApi;

const DEFAULT_WEB_UI_DIR: &str = "/usr/share/agama/web_ui";
const TOKEN_FILE: &str = "/run/agama/token";
Expand Down
24 changes: 12 additions & 12 deletions rust/agama-server/src/network/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ pub struct MatchConfig {
#[error("Unknown IP configuration method name: {0}")]
pub struct UnknownIpMethod(String);

#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize)]
#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub enum Ipv4Method {
#[default]
Expand Down Expand Up @@ -818,7 +818,7 @@ impl FromStr for Ipv4Method {
}
}

#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize)]
#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub enum Ipv6Method {
#[default]
Expand Down Expand Up @@ -866,7 +866,7 @@ impl From<UnknownIpMethod> for zbus::fdo::Error {
}
}

#[derive(Debug, PartialEq, Clone, Serialize)]
#[derive(Debug, PartialEq, Clone, Serialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct IpRoute {
pub destination: IpInet,
Expand Down Expand Up @@ -997,7 +997,7 @@ impl TryFrom<WirelessConfig> for WirelessSettings {
}
}

#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, utoipa::ToSchema)]
pub enum WirelessMode {
Unknown = 0,
AdHoc = 1,
Expand Down Expand Up @@ -1081,7 +1081,7 @@ impl TryFrom<&str> for SecurityProtocol {
}
}

#[derive(Debug, Default, PartialEq, Clone, Serialize)]
#[derive(Debug, Default, PartialEq, Clone, Serialize, utoipa::ToSchema)]
pub struct WEPSecurity {
pub auth_alg: WEPAuthAlg,
pub wep_key_type: WEPKeyType,
Expand All @@ -1090,7 +1090,7 @@ pub struct WEPSecurity {
pub wep_key_index: u32,
}

#[derive(Debug, Default, PartialEq, Clone, Serialize)]
#[derive(Debug, Default, PartialEq, Clone, Serialize, utoipa::ToSchema)]
pub enum WEPKeyType {
#[default]
Unknown = 0,
Expand All @@ -1111,7 +1111,7 @@ impl TryFrom<u32> for WEPKeyType {
}
}

#[derive(Debug, Default, PartialEq, Clone, Serialize)]
#[derive(Debug, Default, PartialEq, Clone, Serialize, utoipa::ToSchema)]
pub enum WEPAuthAlg {
#[default]
Unset,
Expand Down Expand Up @@ -1146,7 +1146,7 @@ impl fmt::Display for WEPAuthAlg {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
#[derive(Debug, Clone, Copy, PartialEq, Serialize, utoipa::ToSchema)]
pub enum WirelessBand {
A, // 5GHz
BG, // 2.4GHz
Expand Down Expand Up @@ -1174,7 +1174,7 @@ impl TryFrom<&str> for WirelessBand {
}
}

#[derive(Debug, Default, Clone, PartialEq, Serialize)]
#[derive(Debug, Default, Clone, PartialEq, Serialize, utoipa::ToSchema)]
pub struct BondOptions(pub HashMap<String, String>);

impl TryFrom<&str> for BondOptions {
Expand Down Expand Up @@ -1266,7 +1266,7 @@ pub struct BridgeConfig {
pub ageing_time: Option<u32>,
}

#[derive(Debug, Default, PartialEq, Clone, Serialize)]
#[derive(Debug, Default, PartialEq, Clone, Serialize, utoipa::ToSchema)]
pub struct BridgePortConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option<u32>,
Expand All @@ -1281,7 +1281,7 @@ pub struct InfinibandConfig {
pub transport_mode: InfinibandTransportMode,
}

#[derive(Default, Debug, PartialEq, Clone, Serialize)]
#[derive(Default, Debug, PartialEq, Clone, Serialize, utoipa::ToSchema)]
pub enum InfinibandTransportMode {
#[default]
Datagram,
Expand Down Expand Up @@ -1314,7 +1314,7 @@ impl fmt::Display for InfinibandTransportMode {
}
}

#[derive(Default, Debug, PartialEq, Clone, Serialize)]
#[derive(Default, Debug, PartialEq, Clone, Serialize, utoipa::ToSchema)]
pub enum TunMode {
#[default]
Tun = 1,
Expand Down
3 changes: 2 additions & 1 deletion rust/agama-server/src/software/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,8 @@ async fn proposal(State(state): State<SoftwareState<'_>>) -> Result<Json<Softwar
(status = 200, description = "Read repositories data"),
(status = 400, description = "The D-Bus service could not perform the action
")
)
),
operation_id = "software_probe"
)]
async fn probe(State(state): State<SoftwareState<'_>>) -> Result<Json<()>, Error> {
state.software.probe().await?;
Expand Down
3 changes: 2 additions & 1 deletion rust/agama-server/src/storage/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ pub async fn storage_service(dbus: zbus::Connection) -> Result<Router, ServiceEr
responses(
(status = 200, description = "Devices were probed and an initial proposal were performed"),
(status = 400, description = "The D-Bus service could not perform the action")
)
),
operation_id = "storage_probe"
)]
async fn probe(State(state): State<StorageState<'_>>) -> Result<Json<()>, Error> {
Ok(Json(state.client.probe().await?))
Expand Down
193 changes: 57 additions & 136 deletions rust/agama-server/src/web/docs.rs
Original file line number Diff line number Diff line change
@@ -1,137 +1,58 @@
use utoipa::OpenApi;
#[derive(OpenApi)]
#[openapi(
info(description = "Agama web API description"),
paths(
crate::l10n::web::get_config,
crate::l10n::web::keymaps,
crate::l10n::web::locales,
crate::l10n::web::set_config,
crate::l10n::web::timezones,
crate::manager::web::finish_action,
crate::manager::web::install_action,
crate::manager::web::installer_status,
crate::manager::web::probe_action,
crate::network::web::add_connection,
crate::network::web::apply,
crate::network::web::connect,
crate::network::web::connections,
crate::network::web::delete_connection,
crate::network::web::devices,
crate::network::web::disconnect,
crate::network::web::update_connection,
crate::questions::web::answer,
crate::questions::web::list_questions,
crate::software::web::get_config,
crate::software::web::patterns,
crate::software::web::probe,
crate::software::web::products,
crate::software::web::proposal,
crate::software::web::set_config,
crate::storage::web::actions,
crate::storage::web::devices_dirty,
crate::storage::web::get_proposal_settings,
crate::storage::web::probe,
crate::storage::web::product_params,
crate::storage::web::set_proposal_settings,
crate::storage::web::staging_devices,
crate::storage::web::system_devices,
crate::storage::web::usable_devices,
crate::storage::web::volume_for,
crate::storage::web::iscsi::delete_node,
crate::storage::web::iscsi::discover,
crate::storage::web::iscsi::initiator,
crate::storage::web::iscsi::login_node,
crate::storage::web::iscsi::logout_node,
crate::storage::web::iscsi::nodes,
crate::storage::web::iscsi::update_initiator,
crate::storage::web::iscsi::update_node,
crate::users::web::get_root_config,
crate::users::web::get_user_config,
crate::users::web::patch_root,
crate::users::web::remove_first_user,
crate::users::web::set_first_user,
super::http::ping
),
components(
schemas(agama_locale_data::KeymapId),
schemas(agama_locale_data::LocaleId),
schemas(agama_lib::manager::InstallationPhase),
schemas(agama_lib::network::settings::NetworkConnection),
schemas(agama_lib::network::settings::NetworkSettings),
schemas(agama_lib::network::settings::WirelessSettings),
schemas(agama_lib::network::types::DeviceState),
schemas(agama_lib::network::types::DeviceType),
schemas(agama_lib::network::types::Status),
schemas(agama_lib::product::Product),
schemas(agama_lib::software::Pattern),
schemas(agama_lib::storage::model::Action),
schemas(agama_lib::storage::model::BlockDevice),
schemas(agama_lib::storage::model::Component),
schemas(agama_lib::storage::model::Device),
schemas(agama_lib::storage::model::DeviceInfo),
schemas(agama_lib::storage::model::DeviceSid),
schemas(agama_lib::storage::model::Drive),
schemas(agama_lib::storage::model::DriveInfo),
schemas(agama_lib::storage::model::DeviceSize),
schemas(agama_lib::storage::model::Filesystem),
schemas(agama_lib::storage::model::LvmLv),
schemas(agama_lib::storage::model::LvmVg),
schemas(agama_lib::storage::model::Md),
schemas(agama_lib::storage::model::Multipath),
schemas(agama_lib::storage::model::Partition),
schemas(agama_lib::storage::model::PartitionTable),
schemas(agama_lib::storage::model::ProposalSettings),
schemas(agama_lib::storage::model::ProposalSettingsPatch),
schemas(agama_lib::storage::model::ProposalTarget),
schemas(agama_lib::storage::model::Raid),
schemas(agama_lib::storage::model::SpaceAction),
schemas(agama_lib::storage::model::SpaceActionSettings),
schemas(agama_lib::storage::model::UnusedSlot),
schemas(agama_lib::storage::model::Volume),
schemas(agama_lib::storage::model::VolumeOutline),
schemas(agama_lib::storage::model::VolumeTarget),
schemas(agama_lib::storage::client::iscsi::ISCSIAuth),
schemas(agama_lib::storage::client::iscsi::ISCSIInitiator),
schemas(agama_lib::storage::client::iscsi::ISCSINode),
schemas(agama_lib::storage::client::iscsi::LoginResult),
schemas(agama_lib::users::FirstUser),
schemas(crate::l10n::Keymap),
schemas(crate::l10n::LocaleEntry),
schemas(crate::l10n::TimezoneEntry),
schemas(crate::l10n::web::LocaleConfig),
schemas(crate::manager::web::InstallerStatus),
schemas(crate::network::model::BondConfig),
schemas(crate::network::model::BridgeConfig),
schemas(crate::network::model::Connection),
schemas(crate::network::model::ConnectionConfig),
schemas(crate::network::model::Device),
schemas(crate::network::model::InfinibandConfig),
schemas(crate::network::model::IpConfig),
schemas(crate::network::model::MacAddress),
schemas(crate::network::model::MatchConfig),
schemas(crate::network::model::PortConfig),
schemas(crate::network::model::SecurityProtocol),
schemas(crate::network::model::TunConfig),
schemas(crate::network::model::VlanConfig),
schemas(crate::network::model::VlanProtocol),
schemas(crate::network::model::WirelessConfig),
schemas(crate::questions::web::Answer),
schemas(crate::questions::web::GenericAnswer),
schemas(crate::questions::web::GenericQuestion),
schemas(crate::questions::web::PasswordAnswer),
schemas(crate::questions::web::Question),
schemas(crate::questions::web::QuestionWithPassword),
schemas(crate::software::web::SoftwareConfig),
schemas(crate::software::web::SoftwareProposal),
schemas(crate::storage::web::ProductParams),
schemas(crate::storage::web::iscsi::DiscoverParams),
schemas(crate::storage::web::iscsi::InitiatorParams),
schemas(crate::storage::web::iscsi::LoginParams),
schemas(crate::storage::web::iscsi::NodeParams),
schemas(crate::users::web::RootConfig),
schemas(crate::users::web::RootPatchSettings),
schemas(super::http::PingResponse)
)
)]
use utoipa::openapi::{ComponentsBuilder, InfoBuilder, PathsBuilder};

mod network;
pub use network::NetworkApiDocBuilder;
mod storage;
pub use storage::StorageApiDocBuilder;
mod software;
pub use software::SoftwareApiDocBuilder;
mod l10n;
pub use l10n::L10nApiDocBuilder;
mod questions;
pub use questions::QuestionsApiDocBuilder;
mod manager;
pub use manager::ManagerApiDocBuilder;
mod users;
pub use users::UsersApiDocBuilder;

pub struct ApiDoc;

impl ApiDoc {
pub fn build() -> utoipa::openapi::OpenApi {
let info = InfoBuilder::new()
.title("Agama HTTP API")
.version("0.1.0")
.build();

let paths = PathsBuilder::new()
.path_from::<super::http::__path_ping>()
.build();

let components = ComponentsBuilder::new()
.schema_from::<super::http::PingResponse>()
.build();

let mut openapi = utoipa::openapi::OpenApiBuilder::new()
.info(info)
.paths(paths)
.components(Some(components))
.build();

let l10n = L10nApiDocBuilder::build();
let manager = ManagerApiDocBuilder::build();
let network = NetworkApiDocBuilder::build();
let questions = QuestionsApiDocBuilder::build();
let software = SoftwareApiDocBuilder::build();
let storage = StorageApiDocBuilder::build();
let users = UsersApiDocBuilder::build();

openapi.merge(l10n);
openapi.merge(manager);
openapi.merge(network);
openapi.merge(questions);
openapi.merge(software);
openapi.merge(storage);
openapi.merge(users);
openapi
}
}
Loading

0 comments on commit 0b88720

Please sign in to comment.