Skip to content

Commit 161c454

Browse files
author
marc
committed
UI: show encryption stats on stores report.
requires #26802 for new `StoresResponse` fields. This adds basic file stats to the stores report page. Also improves the styling: - show decoded key info protobuf fields rather than raw proto (eg: creation date rather than unix timestamp) - table styling moved to core style file - full-width cells to head different sections Release note (admin ui change): add encryption statistics on stores report page
1 parent 620689c commit 161c454

File tree

4 files changed

+103
-17
lines changed

4 files changed

+103
-17
lines changed
Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
11
import React from "react";
22

33
import * as protos from "src/js/protos";
4+
import _ from "lodash";
5+
import Long from "long";
6+
import moment from "moment";
47
import { EncryptionStatusProps } from "oss/src/views/reports/containers/stores/encryption";
8+
import { Bytes } from "src/util/format";
9+
10+
const dateFormat = "Y-MM-DD HH:mm:ss Z";
511

612
export default class EncryptionStatus extends React.Component<EncryptionStatusProps, {}> {
713

14+
renderHeaderRow(header: string) {
15+
return (
16+
<tr className="stores-table__row">
17+
<td colspan=2 className="stores-table__cell stores-table__cell--header--row">{header}</td>
18+
</tr>
19+
);
20+
}
21+
822
renderSimpleRow(header: string, value: string) {
923
return (
1024
<tr className="stores-table__row">
@@ -14,16 +28,77 @@ export default class EncryptionStatus extends React.Component<EncryptionStatusPr
1428
);
1529
}
1630

17-
render(): React.ReactElement<any> {
31+
renderKey(isStoreKey: boolean, key: protos.cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo$Properties) {
32+
// Get the enum name from its value (eg: "AES128_CTR" for 1).
33+
const encryptionType = protos.cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionType[key.encryption_type];
34+
const createdAt = moment.unix(key.creation_time.toNumber()).utc().format(dateFormat);
35+
36+
if (isStoreKey) {
37+
return [
38+
this.renderHeaderRow("Active Store Key: user specified"),
39+
this.renderSimpleRow("Algorithm", encryptionType),
40+
this.renderSimpleRow("Key ID", key.key_id),
41+
this.renderSimpleRow("Created", createdAt),
42+
this.renderSimpleRow("Source", key.source),
43+
];
44+
} else {
45+
return [
46+
this.renderHeaderRow("Active Data Key: automatically generated"),
47+
this.renderSimpleRow("Algorithm", encryptionType),
48+
this.renderSimpleRow("Key ID", key.key_id),
49+
this.renderSimpleRow("Created", createdAt),
50+
this.renderSimpleRow("Parent Key ID", key.parent_key_id),
51+
];
52+
}
53+
}
54+
55+
renderFileStats(stats: protos.cockroach.server.serverpb.StoreDetails$Properties) {
56+
if (stats.total_files.eq(0) && stats.total_bytes.eq(0)) {
57+
return null;
58+
}
59+
60+
let percentFiles = 100;
61+
if (stats.active_key_files !== stats.total_files) {
62+
percentFiles = Long.fromInt(100).mul(stats.active_key_files).toNumber() / stats.total_files.toNumber();
63+
}
64+
let fileDetails = percentFiles.toFixed(2) + "%";
65+
fileDetails += " (" + stats.active_key_files + "/" + stats.total_files + ")";
66+
67+
let percentBytes = 100;
68+
if (stats.active_key_bytes !== stats.total_bytes) {
69+
percentBytes = Long.fromInt(100).mul(stats.active_key_bytes).toNumber() / stats.total_bytes.toNumber();
70+
}
71+
let byteDetails = percentBytes.toFixed(2) + "%";
72+
byteDetails += " (" + Bytes(stats.active_key_bytes.toNumber()) + "/" + Bytes(stats.total_bytes.toNumber()) + ")";
73+
74+
return [
75+
this.renderHeaderRow("Encryption Progress: fraction encrypted using the active data key"),
76+
this.renderSimpleRow("Files", fileDetails),
77+
this.renderSimpleRow("Bytes", byteDetails),
78+
];
79+
}
80+
81+
render() {
1882
const { store } = this.props;
1983
const rawStatus = store.encryption_status;
84+
if (_.isEmpty(rawStatus)) {
85+
return null;
86+
}
87+
88+
let decodedStatus;
2089

90+
// Attempt to decode protobuf.
2191
try {
22-
const decodedStatus = protos.cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus.decode(rawStatus);
23-
return this.renderSimpleRow("Encryption Status", JSON.stringify(decodedStatus.toJSON(), null, 2));
92+
decodedStatus = protos.cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus.decode(rawStatus);
2493
} catch (e) {
2594
console.log("Error decoding protobuf: ", e);
2695
return null;
2796
}
97+
98+
return [
99+
this.renderKey(true, decodedStatus.active_store_key),
100+
this.renderKey(false, decodedStatus.active_data_key),
101+
this.renderFileStats(store),
102+
];
28103
}
29104
}

pkg/ui/src/views/reports/containers/stores/index.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import { AdminUIState } from "src/redux/state";
1010
import { nodeIDAttr } from "src/util/constants";
1111
import EncryptionStatus from "src/views/reports/containers/stores/encryption";
1212

13-
import "./stores.styl";
14-
1513
interface StoresOwnProps {
1614
stores: protos.cockroach.server.serverpb.StoresResponse;
1715
lastError: Error;
@@ -58,9 +56,9 @@ class Stores extends React.Component<StoresProps, {}> {
5856
);
5957
}
6058

61-
renderStore(store: protos.cockroach.server.serverpb.StoreDetails$Properties, key: number) {
59+
renderStore(store: protos.cockroach.server.serverpb.StoreDetails$Properties) {
6260
return (
63-
<table key={key} className="stores-table">
61+
<table key={store.store_id} className="stores-table">
6462
<tbody>
6563
{ this.renderSimpleRow("Store ID", store.store_id.toString()) }
6664
<EncryptionStatus store={store} />
@@ -122,8 +120,8 @@ class Stores extends React.Component<StoresProps, {}> {
122120
<h1>Stores</h1>
123121
<h2>{header} stores</h2>
124122
{
125-
_.map(stores.stores, (store, key) => (
126-
this.renderStore(store, key)
123+
_.map(_.sortBy(stores.stores, (store) => store.store_id), (store) => (
124+
this.renderStore(store)
127125
))
128126
}
129127
</div>

pkg/ui/src/views/reports/containers/stores/stores.styl

Lines changed: 0 additions & 8 deletions
This file was deleted.

pkg/ui/styl/pages/reports.styl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,27 @@ $reports-table
139139
margin 0
140140
padding 0
141141

142+
.stores-table
143+
@extend $reports-table
144+
145+
&__cell
146+
background-color white
147+
padding 6px 12px
148+
max-width none
149+
width 100%
150+
151+
&--header
152+
background-color $link-color
153+
text-align right
154+
width 150px
155+
min-width 150px
156+
157+
&--row
158+
background-color $link-color
159+
text-align center
160+
color white
161+
font-weight 900
162+
142163
.connections-table
143164
@extend $reports-table
144165
font-size 12px

0 commit comments

Comments
 (0)