Skip to content

Commit ad497e3

Browse files
authored
Merge pull request #813 from kitsudaiki/feat/more-information-in-the-dashboard
related issue: #810
2 parents 633f2d4 + 8cf0104 commit ad497e3

15 files changed

Lines changed: 111 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## [Unreleased]
44

5+
### BREAKING-CHANGES
6+
7+
#### Database-Breaking
8+
9+
- in the meta-cluster table of hanami the name of the cluster is now also stored
10+
511
### Added
612

713
- Vagrantfile with ansible playbook to deploy multiple virtual machines with a kubernestes with fully deployed ainari-setup and sdk-api-test
@@ -14,6 +20,8 @@
1420
- added cluster-list without actions to overview-page
1521
- automatic logout in case the token is expired
1622
- quota-management was added to the admin-section of the dashboard
23+
- dataset list in the dashboard now prints the number of rows and columns
24+
- cluster list in the dashboard now prints the cluster adress
1725

1826
### Changed
1927

@@ -26,6 +34,7 @@
2634
- hide admin-section in case that the user is not an admin
2735
- user-logo in the right upper corner now is always white with the starting letter of the user-id
2836
- gauge-charts of the overview-page now has animation
37+
- disabled the hexagon background pattern in the left upper corner again
2938

3039
### Fixed
3140

src/binaries/hanami/src/api/http_endpoints/cluster/create_cluster_v1_0.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ pub async fn create_cluster(
110110
let cluster_uuid = cluster_resp.uuid;
111111
meta_cluster_table::add_new_meta_cluster(
112112
&cluster_uuid,
113+
&body.name,
113114
&sakura_uuid,
114115
&proxy_resp.uuid,
115116
&context,

src/binaries/hanami/src/api/http_endpoints/cluster/list_cluster_v1_0.rs

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ use actix_web::web::Json;
1616
use apistos::api_operation;
1717

1818
use crate::config;
19-
use crate::database::host_table;
19+
use crate::database::meta_cluster_table;
2020

2121
use ainari_api::common_functions::*;
2222
use ainari_api::errors::ErrorResponse;
2323
use ainari_api_structs::cluster_structs::*;
2424
use ainari_api_structs::user_context::UserContext;
25-
use ainari_clients::cluster as cluster_clients;
25+
use ainari_clients::endpoints::*;
26+
use ainari_clients::proxy as proxy_clients;
2627

2728
#[api_operation(
2829
tag = "cluster",
@@ -32,26 +33,45 @@ use ainari_clients::cluster as cluster_clients;
3233
error_code = 500
3334
)]
3435
pub async fn list_cluster(context: UserContext) -> Result<Json<ClusterListResp>, ErrorResponse> {
35-
let mut complete_resp = ClusterListResp {
36+
// get clusters from db
37+
let clusters = meta_cluster_table::list_meta_clusters(&context)
38+
.map_err(|e| map_db_list_error("hosts", e))?;
39+
40+
// get endpoints from miko
41+
let miko_endpoint = &config::CONFIG.miko;
42+
let endpoints = get_endpoints(miko_endpoint, config::CONFIG.skip_tls_verification)
43+
.await
44+
.map_err(map_ainari_error_to_api_response)?;
45+
46+
// prepare response
47+
let mut resp = ClusterListResp {
3648
clusters: Vec::new(),
3749
};
3850

39-
let host_list = host_table::list_hosts(&context).map_err(|e| map_db_list_error("hosts", e))?;
51+
// fill reponse
52+
for cluster in clusters {
53+
let uuid = convert_uuid(&cluster.uuid)?;
4054

41-
for host in host_list {
42-
let cluster_list_resp = cluster_clients::list_cluster(
43-
&host.address,
55+
// get port of the cluster from torii
56+
let proxy_uuid = convert_uuid(&cluster.proxy_uuid)?;
57+
let proxy_resp = proxy_clients::get_proxy(
58+
&endpoints.torii,
4459
&context.token,
45-
&config::INTERNAL_API_KEY,
60+
&proxy_uuid,
4661
config::CONFIG.skip_tls_verification,
4762
)
4863
.await
4964
.map_err(map_ainari_error_to_api_response)?;
5065

51-
for cluster in cluster_list_resp.clusters {
52-
complete_resp.clusters.push(cluster);
53-
}
66+
// add single object to the reponse-list
67+
let obj = ClusterBasicResp {
68+
uuid,
69+
name: cluster.name.clone(),
70+
proxy_port: proxy_resp.port,
71+
};
72+
73+
resp.clusters.push(obj);
5474
}
5575

56-
Ok(Json(complete_resp))
76+
Ok(Json(resp))
5777
}

src/binaries/hanami/src/database/meta_cluster_table.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use ainari_common::enums;
2828
table! {
2929
meta_clusters (uuid) {
3030
uuid -> Varchar,
31+
name -> Varchar,
3132
sakura_host_uuid -> Varchar,
3233
proxy_uuid -> Varchar,
3334
owner_id -> Varchar,
@@ -46,6 +47,7 @@ table! {
4647
#[diesel(table_name = meta_clusters)]
4748
pub struct MetaClusterEntry {
4849
pub uuid: String,
50+
pub name: String,
4951
pub sakura_host_uuid: String,
5052
pub proxy_uuid: String,
5153
pub owner_id: String,
@@ -64,6 +66,7 @@ pub fn init_meta_cluster_table() -> Result<(), Box<dyn Error>> {
6466
conn.batch_execute(
6567
"CREATE TABLE IF NOT EXISTS meta_clusters (
6668
uuid VARCHAR(40) PRIMARY KEY,
69+
name VARCHAR(256),
6770
sakura_host_uuid VARCHAR(40),
6871
proxy_uuid VARCHAR(40),
6972
owner_id VARCHAR(256),
@@ -83,12 +86,14 @@ pub fn init_meta_cluster_table() -> Result<(), Box<dyn Error>> {
8386

8487
pub fn add_new_meta_cluster(
8588
meta_cluster_uuid: &Uuid,
89+
cluster_name: &str,
8690
sakura_host_uuid: &Uuid,
8791
proxy_uuid: &Uuid,
8892
context: &UserContext,
8993
) -> QueryResult<usize> {
9094
let meta_cluster = MetaClusterEntry {
9195
uuid: meta_cluster_uuid.to_string().clone(),
96+
name: cluster_name.to_string().clone(),
9297
sakura_host_uuid: sakura_host_uuid.to_string().clone(),
9398
proxy_uuid: proxy_uuid.to_string().clone(),
9499
owner_id: context.user_id.clone(),
@@ -259,6 +264,7 @@ mod tests {
259264
fn test_add_get_meta_cluster() {
260265
let _ = init_meta_cluster_table();
261266
let uuid1 = Uuid::new_v4();
267+
let name = "test-cluster".to_string();
262268
let sakura_host_uuid1 = Uuid::new_v4();
263269
let proxy_uuid1 = Uuid::new_v4();
264270

@@ -274,6 +280,7 @@ mod tests {
274280

275281
let meta_cluster = MetaClusterEntry {
276282
uuid: uuid1.to_string(),
283+
name: name.clone(),
277284
sakura_host_uuid: sakura_host_uuid1.to_string(),
278285
proxy_uuid: proxy_uuid1.to_string(),
279286
owner_id: owner_id.clone(),
@@ -320,6 +327,7 @@ mod tests {
320327
let _ = init_meta_cluster_table();
321328
let uuid1 = Uuid::new_v4();
322329
let uuid2 = Uuid::new_v4();
330+
let name = "test-cluster".to_string();
323331
let sakura_host_uuid1 = Uuid::new_v4();
324332
let proxy_uuid1 = Uuid::new_v4();
325333

@@ -335,6 +343,7 @@ mod tests {
335343

336344
let meta_cluster1 = MetaClusterEntry {
337345
uuid: uuid1.to_string(),
346+
name: name.clone(),
338347
sakura_host_uuid: sakura_host_uuid1.to_string(),
339348
proxy_uuid: proxy_uuid1.to_string(),
340349
owner_id: owner_id.clone(),
@@ -350,6 +359,7 @@ mod tests {
350359

351360
let meta_cluster2 = MetaClusterEntry {
352361
uuid: uuid2.to_string(),
362+
name: name.clone(),
353363
sakura_host_uuid: sakura_host_uuid1.to_string(),
354364
proxy_uuid: proxy_uuid1.to_string(),
355365
owner_id: owner_id.clone(),
@@ -379,6 +389,7 @@ mod tests {
379389
fn test_delete_meta_cluster() {
380390
let _ = init_meta_cluster_table();
381391
let uuid1 = Uuid::new_v4();
392+
let name = "test-cluster".to_string();
382393
let sakura_host_uuid1 = Uuid::new_v4();
383394
let proxy_uuid1 = Uuid::new_v4();
384395

@@ -394,6 +405,7 @@ mod tests {
394405

395406
let meta_cluster = MetaClusterEntry {
396407
uuid: uuid1.to_string(),
408+
name: name.clone(),
397409
sakura_host_uuid: sakura_host_uuid1.to_string(),
398410
proxy_uuid: proxy_uuid1.to_string(),
399411
owner_id: owner_id.clone(),
@@ -422,6 +434,7 @@ mod tests {
422434
let uuid1 = Uuid::new_v4();
423435
let uuid2 = Uuid::new_v4();
424436
let uuid3 = Uuid::new_v4();
437+
let name = "test-cluster".to_string();
425438
let sakura_host_uuid1 = Uuid::new_v4();
426439
let proxy_uuid1 = Uuid::new_v4();
427440

@@ -437,6 +450,7 @@ mod tests {
437450

438451
let meta_cluster1 = MetaClusterEntry {
439452
uuid: uuid1.to_string(),
453+
name: name.clone(),
440454
sakura_host_uuid: sakura_host_uuid1.to_string(),
441455
proxy_uuid: proxy_uuid1.to_string(),
442456
owner_id: owner_id.clone(),
@@ -452,6 +466,7 @@ mod tests {
452466

453467
let meta_cluster2 = MetaClusterEntry {
454468
uuid: uuid2.to_string(),
469+
name: name.clone(),
455470
sakura_host_uuid: sakura_host_uuid1.to_string(),
456471
proxy_uuid: proxy_uuid1.to_string(),
457472
owner_id: owner_id.clone(),
@@ -467,6 +482,7 @@ mod tests {
467482

468483
let meta_cluster3 = MetaClusterEntry {
469484
uuid: uuid3.to_string(),
485+
name: name.clone(),
470486
sakura_host_uuid: sakura_host_uuid1.to_string(),
471487
proxy_uuid: proxy_uuid1.to_string(),
472488
owner_id: owner_id.clone(),
@@ -503,11 +519,13 @@ mod tests {
503519
let uuid1 = Uuid::new_v4();
504520
let uuid2 = Uuid::new_v4();
505521
let uuid3 = Uuid::new_v4();
522+
let name = "test-cluster".to_string();
506523
let sakura_host_uuid1 = Uuid::new_v4();
507524
let proxy_uuid1 = Uuid::new_v4();
508525

509526
let meta_cluster1 = MetaClusterEntry {
510527
uuid: uuid1.to_string(),
528+
name: name.clone(),
511529
sakura_host_uuid: sakura_host_uuid1.to_string(),
512530
proxy_uuid: proxy_uuid1.to_string(),
513531
owner_id: "test-user-42".to_string(),
@@ -523,6 +541,7 @@ mod tests {
523541

524542
let meta_cluster2 = MetaClusterEntry {
525543
uuid: uuid2.to_string(),
544+
name: name.clone(),
526545
sakura_host_uuid: sakura_host_uuid1.to_string(),
527546
proxy_uuid: proxy_uuid1.to_string(),
528547
owner_id: "test-user-43".to_string(),
@@ -538,6 +557,7 @@ mod tests {
538557

539558
let meta_cluster3 = MetaClusterEntry {
540559
uuid: uuid3.to_string(),
560+
name: name.clone(),
541561
sakura_host_uuid: sakura_host_uuid1.to_string(),
542562
proxy_uuid: proxy_uuid1.to_string(),
543563
owner_id: "test-user-44".to_string(),

src/binaries/ryokan/src/api/http_endpoints/dataset/list_dataset_v1_0.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ pub async fn list_dataset(context: UserContext) -> Result<Json<DatasetListResp>,
4242
let obj = DatasetBasicResp {
4343
uuid,
4444
name: dataset.name.clone(),
45+
number_of_rows: dataset.number_of_rows as u64,
46+
number_of_columns: dataset.number_of_columns as u64,
4547
};
4648

4749
resp.datasets.push(obj);

src/binaries/sakura/src/api/http_endpoints/cluster/list_cluster_internal_v1_0.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub async fn list_cluster_internal(
4949
let obj = ClusterBasicResp {
5050
uuid,
5151
name: cluster.name,
52+
proxy_port: 0,
5253
};
5354

5455
resp.clusters.push(obj);

src/dashboard/app/src/App.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
<template>
1818
<div class="app">
1919
<div class="background">
20-
<img
20+
<!-- <img
2121
src="./assets/background_pattern.svg"
2222
class="logo-icon top-left"
23-
/>
23+
/> -->
2424
<img
2525
src="./assets/background_pattern2.svg"
2626
class="logo-icon bottom-right"

src/dashboard/app/src/auth_context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@ export async function createAuthContext(token: string) {
143143
// This is useful for constructing URLs without specifying a port
144144
if (authContext.torii_address) {
145145
const toriiParts = authContext.torii_address.split(":");
146-
if (toriiParts.length > 1) {
146+
if (toriiParts.length > 2) {
147147
// Remove the port and any path/query parameters
148-
authContext.torii_base_address = toriiParts[0];
148+
authContext.torii_base_address = toriiParts[0] + ":" + toriiParts[1];
149149
} else {
150150
// If there's no port, use the full address as the base
151151
authContext.torii_base_address = authContext.torii_address;

src/dashboard/app/src/components/overview.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
2626
<tr>
2727
<th>UUID</th>
2828
<th>Name</th>
29+
<th>Adress</th>
2930
<th></th>
3031
</tr>
3132
</thead>
3233
<tbody>
3334
<tr v-for="cluster in clusters" :key="cluster.uuid">
3435
<td>{{ cluster.uuid }}</td>
3536
<td>{{ cluster.name }}</td>
37+
<td>{{torii_base_address}}:{{ cluster.proxy_port }}</td>
3638
<td></td>
3739
</tr>
3840
</tbody>
@@ -89,6 +91,7 @@ import { handleAxiosError } from "@/handleAxiosError";
8991
9092
// Cluster management
9193
const clusters = ref<{ uuid: string; clusterName: string }[]>([]);
94+
const torii_base_address = ref<string>("");
9295
9396
// Error handling
9497
const errorPopupMsg = ref<string>("");
@@ -116,6 +119,8 @@ const quotaMetrics = reactive({
116119
// API client creation helper
117120
function createApiClient(baseURL: string | null) {
118121
const authContext = getAuthContext();
122+
torii_base_address.value = authContext.torii_base_address;
123+
119124
return axios.create({
120125
baseURL,
121126
headers: { Authorization: `Bearer ${authContext.token}` },
@@ -221,4 +226,9 @@ onMounted(() => {
221226
display: flex;
222227
flex-wrap: wrap;
223228
}
229+
/* Columns 2 through n-1 share remaining space equally */
230+
th:not(:first-child):not(:last-child),
231+
td:not(:first-child):not(:last-child) {
232+
width: 30%;
233+
}
224234
</style>

src/dashboard/app/src/components/storage/dataset/dataset_create_modal.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ const onFile2Change = (event: Event) => {
128128
};
129129
130130
async function handleAccept() {
131-
datasetNameError.value = form.datasetName.length < 8;
131+
datasetNameError.value = form.datasetName.length < 4;
132132
133133
if (datasetNameError.value) {
134134
return;
@@ -156,6 +156,8 @@ async function handleAccept() {
156156
},
157157
},
158158
);
159+
160+
emit("accept");
159161
} catch (err) {
160162
errorPopupMsg.value = handleAxiosError(
161163
err,

0 commit comments

Comments
 (0)