Skip to content

Commit 2414485

Browse files
authored
feat: Switch to generated response structs (#1007)
Drop manually created resource structures in favor of autogenerated ones. With this we can also enable view configuration.
1 parent 84b871f commit 2414485

29 files changed

+463
-672
lines changed

doc/src/tui/config.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,4 @@ with different value.
2121
Every resource view can be configured in a separate section of the config.
2222
Resource key in a form <SERVICE>.<RESOURCE>[/<SUBRESOURCE>] as used by the
2323
codegenerator is a name of a view. `fields` is an array of field names to be
24-
populated.
25-
26-
NOTE: This a work in progress to pre-generate resource structures and column
27-
names.
24+
populated. All column names are forcibly converted to the UPPER CASE.

openstack_tui/.config/config.yaml

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -313,60 +313,86 @@ mode_aliases:
313313
views:
314314
# Block Storage
315315
block_storage.backup:
316-
fields: [Id, Name, AZ, Size, Status, Created]
316+
fields: [ID, NAME, AZ, SIZE, STATUS, CREATED_AT]
317+
wide: true
317318
block_storage.snapshots:
318-
fields: [Id, Name, Status, Created]
319+
fields: [ID, NAME, STATUS, CREATED_AT]
320+
wide: true
319321
block_storage.volume:
320-
fields: [Id, Name, AZ, Size, Status, Updated]
322+
fields: [ID, NAME, AZ, SIZE, STATUS, UPDATED_AT]
323+
wide: true
321324
# Compute
322325
compute.aggregate:
323-
fields: [Name, UUID, AZ, Updated]
326+
fields: [NAME, UUID, AZ, UPDATED_AT]
327+
wide: true
324328
compute.flavor:
325-
fields: [Id, Name, vCPU, ram, disk, disabled]
329+
fields: [ID, NAME, VCPUS, RAM, DISK]
330+
wide: true
326331
compute.hypervisor:
327-
fields: [IP, Hostname,Status, State]
332+
fields: [IP, HOSTNAME, STATUS, STATE]
333+
wide: true
328334
compute.server/instance_action/event:
329-
fields: [Event, Result, Started, Finished, Host]
335+
fields: [EVENT, RESULT, STARTED, FINISHED, HOST]
336+
wide: true
330337
compute.server/instance_action:
331-
fields: [Id, Action, Message, Started, User, "Server ID"]
338+
fields: [ID, ACTION, MESSAGE, STARTED, USER, "SERVER ID"]
339+
wide: true
332340
compute.server:
333-
fields: [Id, Name, Status, Created, Updated]
341+
fields: [ID, NAME, STATUS, CREATED, UPDATED]
342+
wide: true
334343
# DNS
335344
dns.recordset:
336-
fields: [Id, Name, Status, Created, Updated]
345+
fields: [ID, NAME, STATUS, CREATED, UPDATED]
346+
wide: true
337347
dns.zone:
338-
fields: [Id, Name, Status, Created, Updated]
348+
fields: [ID, NAME, STATUS, CREATED, UPDATED]
349+
wide: true
339350
# Identity
340351
identity.group:
341-
fields: [Id, Name, Domain, Description]
352+
fields: [ID, NAME, DOMAIN, DESCRIPTION]
353+
wide: true
342354
identity.project:
343-
fields: [Id, Name, "Parent ID", Enabled, "Domain ID"]
355+
fields: [ID, NAME, "PARENT ID", ENABLED, "DOMAIN ID"]
356+
wide: true
344357
identity.user/application_credential:
345-
fields: [Id, Name, "Expires at", "Unrestricted"]
358+
fields: [ID, NAME, "EXPIRES AT", "UNRESTRICTED"]
359+
wide: true
346360
identity.user:
347-
fields: [Name, Domain, Enabled, Email, "Pwd expiry"]
361+
fields: [NAME, DOMAIN, ENABLED, EMAIL, "PWD EXPIRY"]
362+
wide: true
348363
# Image
349364
image.image:
350-
fields: [Id, Name, Distro, Version, Arch, Visibility]
365+
fields: [ID, NAME, DISTRO, VERSION, ARCH, VISIBILITY]
366+
wide: true
351367
# Load Balancer
352368
load-balancer.healthmonitor:
353-
fields: [Id, Name, Status, Type]
369+
fields: [ID, NAME, STATUS, TYPE]
370+
wide: true
354371
load-balancer.listener:
355-
fields: [Id, Name, Status, Protocol, Port]
372+
fields: [ID, NAME, STATUS, PROTOCOL, PORT]
373+
wide: true
356374
load-balancer.loadbalancer:
357-
fields: [Id, Name, Status, Address]
375+
fields: [ID, NAME, STATUS, ADDRESS]
376+
wide: true
358377
load-balancer.pool/member:
359-
fields: [Id, Name, Status, Port]
378+
fields: [ID, NAME, STATUS, PORT]
379+
wide: true
360380
load-balancer.pool:
361-
fields: [Id, Name, Status, Protocol]
381+
fields: [ID, NAME, STATUS, PROTOCOL]
382+
wide: true
362383
# Network
363384
network.network:
364-
fields: [Id, Name, Status, Created, Updated]
385+
fields: [ID, NAME, STATUS, CREATED_AT, UPDATED_AT]
386+
wide: true
365387
network.router:
366-
fields: [Id, Name, Status, Created, Updated]
388+
fields: [ID, NAME, STATUS, CREATED_AT, UPDATED_AT]
389+
wide: true
367390
network.subnet:
368-
fields: [Id, Name, Cidr, Description, Created]
391+
fields: [ID, NAME, CIDR, DESCRIPTION, CREATED_AT]
392+
wide: true
369393
network.security_group_rule:
370-
fields: [Id, Ethertype, Direction, Protocol, "Range Min", "Range Max"]
394+
fields: [ID, ETHERTYPE, DIRECTION, PROTOCOL, "RANGE MIN", "RANGE MAX"]
395+
wide: true
371396
network.security_group:
372-
fields: [Id, Name, Created, Updated]
397+
fields: [ID, NAME, CREATED_AT, UPDATED_AT]
398+
wide: true

openstack_tui/src/components/block_storage/backups.rs

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,54 +15,33 @@
1515
use crossterm::event::KeyEvent;
1616
use eyre::Result;
1717
use ratatui::prelude::*;
18-
use serde::Deserialize;
19-
use structable_derive::StructTable;
2018
use tokio::sync::mpsc::UnboundedSender;
2119

2220
use crate::{
2321
action::Action,
2422
cloud_worker::block_storage::v3::{
25-
BlockStorageApiRequest, BlockStorageBackupApiRequest, BlockStorageBackupList,
23+
BlockStorageApiRequest, BlockStorageBackup, BlockStorageBackupApiRequest,
24+
BlockStorageBackupList,
2625
},
2726
cloud_worker::types::ApiRequest,
2827
components::{table_view::TableViewComponentBase, Component},
2928
config::Config,
3029
error::TuiError,
3130
mode::Mode,
32-
utils::{OutputConfig, ResourceKey, StructTable},
31+
utils::ResourceKey,
3332
};
3433

3534
const TITLE: &str = "Backups";
3635
const VIEW_CONFIG_KEY: &str = "block_storage.backup";
3736

38-
#[derive(Deserialize, StructTable)]
39-
pub struct BackupData {
40-
#[structable(title = "Id", wide)]
41-
id: String,
42-
#[structable(title = "Name", optional)]
43-
#[serde(default)]
44-
name: Option<String>,
45-
#[structable(title = "AZ", optional)]
46-
#[serde(default)]
47-
availability_zone: Option<String>,
48-
#[structable(title = "Size")]
49-
#[serde(default)]
50-
size: u32,
51-
#[structable(title = "Status")]
52-
#[serde(default)]
53-
status: String,
54-
#[structable(title = "Created")]
55-
#[serde(default)]
56-
created_at: String,
57-
}
58-
59-
impl ResourceKey for BackupData {
37+
impl ResourceKey for BlockStorageBackup {
6038
fn get_key() -> &'static str {
6139
VIEW_CONFIG_KEY
6240
}
6341
}
6442

65-
pub type BlockStorageBackups<'a> = TableViewComponentBase<'a, BackupData, BlockStorageBackupList>;
43+
pub type BlockStorageBackups<'a> =
44+
TableViewComponentBase<'a, BlockStorageBackup, BlockStorageBackupList>;
6645

6746
impl Component for BlockStorageBackups<'_> {
6847
fn register_config_handler(&mut self, config: Config) -> Result<(), TuiError> {

openstack_tui/src/components/block_storage/snapshots.rs

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,33 @@
1515
use crossterm::event::KeyEvent;
1616
use eyre::Result;
1717
use ratatui::prelude::*;
18-
use serde::Deserialize;
19-
use structable_derive::StructTable;
2018
use tokio::sync::mpsc::UnboundedSender;
2119

2220
use crate::{
2321
action::Action,
2422
cloud_worker::block_storage::v3::{
25-
BlockStorageApiRequest, BlockStorageSnapshotApiRequest, BlockStorageSnapshotList,
23+
BlockStorageApiRequest, BlockStorageSnapshot, BlockStorageSnapshotApiRequest,
24+
BlockStorageSnapshotList,
2625
},
2726
cloud_worker::types::ApiRequest,
2827
components::{table_view::TableViewComponentBase, Component},
2928
config::Config,
3029
error::TuiError,
3130
mode::Mode,
32-
utils::{OutputConfig, ResourceKey, StructTable},
31+
utils::ResourceKey,
3332
};
3433

3534
const TITLE: &str = "Snapshots";
3635
const VIEW_CONFIG_KEY: &str = "block_storage.snapshot";
3736

38-
#[derive(Deserialize, StructTable)]
39-
pub struct SnapshotData {
40-
#[structable(title = "Id", wide)]
41-
id: String,
42-
#[structable(title = "Name")]
43-
name: String,
44-
#[structable(title = "Status")]
45-
status: String,
46-
#[structable(title = "Created")]
47-
created_at: String,
48-
}
49-
50-
impl ResourceKey for SnapshotData {
37+
impl ResourceKey for BlockStorageSnapshot {
5138
fn get_key() -> &'static str {
5239
VIEW_CONFIG_KEY
5340
}
5441
}
5542

5643
pub type BlockStorageSnapshots<'a> =
57-
TableViewComponentBase<'a, SnapshotData, BlockStorageSnapshotList>;
44+
TableViewComponentBase<'a, BlockStorageSnapshot, BlockStorageSnapshotList>;
5845

5946
impl Component for BlockStorageSnapshots<'_> {
6047
fn register_config_handler(&mut self, config: Config) -> Result<(), TuiError> {

openstack_tui/src/components/block_storage/volumes.rs

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,51 +15,47 @@
1515
use crossterm::event::KeyEvent;
1616
use eyre::{Result, WrapErr};
1717
use ratatui::prelude::*;
18-
use serde::Deserialize;
19-
use structable_derive::StructTable;
2018
use tokio::sync::mpsc::UnboundedSender;
2119
use tracing::debug;
2220

2321
use crate::{
2422
action::Action,
2523
cloud_worker::block_storage::v3::{
26-
BlockStorageApiRequest, BlockStorageVolumeApiRequest, BlockStorageVolumeDeleteBuilder,
27-
BlockStorageVolumeList,
24+
BlockStorageApiRequest, BlockStorageVolume, BlockStorageVolumeApiRequest,
25+
BlockStorageVolumeDelete, BlockStorageVolumeDeleteBuilder,
26+
BlockStorageVolumeDeleteBuilderError, BlockStorageVolumeList,
2827
},
2928
cloud_worker::types::ApiRequest,
3029
components::{table_view::TableViewComponentBase, Component},
3130
config::Config,
3231
error::TuiError,
3332
mode::Mode,
34-
utils::{OutputConfig, ResourceKey, StructTable},
33+
utils::ResourceKey,
3534
};
3635

3736
const TITLE: &str = "Volumes";
3837
const VIEW_CONFIG_KEY: &str = "block_storage.volume";
3938

40-
#[derive(Deserialize, StructTable)]
41-
pub struct VolumeData {
42-
#[structable(title = "Id", wide)]
43-
id: String,
44-
#[structable(title = "Name")]
45-
name: String,
46-
#[structable(title = "AZ")]
47-
availability_zone: String,
48-
#[structable(title = "Size")]
49-
size: u32,
50-
#[structable(title = "Status")]
51-
status: String,
52-
#[structable(title = "Updated")]
53-
updated_at: String,
54-
}
55-
56-
impl ResourceKey for VolumeData {
39+
impl ResourceKey for BlockStorageVolume {
5740
fn get_key() -> &'static str {
5841
VIEW_CONFIG_KEY
5942
}
6043
}
6144

62-
pub type BlockStorageVolumes<'a> = TableViewComponentBase<'a, VolumeData, BlockStorageVolumeList>;
45+
pub type BlockStorageVolumes<'a> =
46+
TableViewComponentBase<'a, BlockStorageVolume, BlockStorageVolumeList>;
47+
48+
impl TryFrom<&BlockStorageVolume> for BlockStorageVolumeDelete {
49+
type Error = BlockStorageVolumeDeleteBuilderError;
50+
fn try_from(value: &BlockStorageVolume) -> Result<Self, Self::Error> {
51+
let mut builder = BlockStorageVolumeDeleteBuilder::default();
52+
builder.id(value.id.clone());
53+
if let Some(val) = &value.name {
54+
builder.name(val.clone());
55+
}
56+
builder.build()
57+
}
58+
}
6359

6460
impl Component for BlockStorageVolumes<'_> {
6561
fn register_config_handler(&mut self, config: Config) -> Result<(), TuiError> {
@@ -120,11 +116,8 @@ impl Component for BlockStorageVolumes<'_> {
120116
// send action to set SecurityGroupRulesList
121117
command_tx.send(Action::Confirm(ApiRequest::from(
122118
BlockStorageVolumeApiRequest::Delete(Box::new(
123-
BlockStorageVolumeDeleteBuilder::default()
124-
.id(selected_entry.id.clone())
125-
.name(selected_entry.name.clone())
126-
.build()
127-
.wrap_err("cannot prepare request")?,
119+
BlockStorageVolumeDelete::try_from(selected_entry)
120+
.wrap_err("error preparing OpenStack request")?,
128121
)),
129122
)))?;
130123
}

openstack_tui/src/components/compute/aggregates.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,45 +15,31 @@
1515
use crossterm::event::KeyEvent;
1616
use eyre::Result;
1717
use ratatui::prelude::*;
18-
use serde::Deserialize;
19-
use structable_derive::StructTable;
2018
use tokio::sync::mpsc::UnboundedSender;
2119

2220
use crate::{
2321
action::Action,
2422
cloud_worker::compute::v2::{
25-
ComputeAggregateApiRequest, ComputeAggregateList, ComputeApiRequest,
23+
ComputeAggregate, ComputeAggregateApiRequest, ComputeAggregateList, ComputeApiRequest,
2624
},
2725
cloud_worker::types::ApiRequest,
2826
components::{table_view::TableViewComponentBase, Component},
2927
config::Config,
3028
error::TuiError,
3129
mode::Mode,
32-
utils::{OutputConfig, ResourceKey, StructTable},
30+
utils::ResourceKey,
3331
};
3432

3533
const TITLE: &str = "Compute Aggregates";
3634
const VIEW_CONFIG_KEY: &str = "compute.aggregate";
3735

38-
#[derive(Deserialize, StructTable)]
39-
pub struct AggregateData {
40-
#[structable(title = "Name")]
41-
name: String,
42-
#[structable(title = "UUID")]
43-
uuid: String,
44-
#[structable(title = "AZ")]
45-
availability_zone: String,
46-
#[structable(title = "Updated")]
47-
updated_at: String,
48-
}
49-
50-
impl ResourceKey for AggregateData {
36+
impl ResourceKey for ComputeAggregate {
5137
fn get_key() -> &'static str {
5238
VIEW_CONFIG_KEY
5339
}
5440
}
5541

56-
pub type ComputeAggregates<'a> = TableViewComponentBase<'a, AggregateData, ComputeAggregateList>;
42+
pub type ComputeAggregates<'a> = TableViewComponentBase<'a, ComputeAggregate, ComputeAggregateList>;
5743

5844
impl Component for ComputeAggregates<'_> {
5945
fn register_config_handler(&mut self, config: Config) -> Result<(), TuiError> {

0 commit comments

Comments
 (0)