Skip to content

Commit 3d2dad4

Browse files
committed
chore: show securtiystate on dashboard
Show Talos SecurityState and MountStatus on dashboard. Fixes: #7675 Signed-off-by: Noel Georgi <git@frezbo.dev>
1 parent b485108 commit 3d2dad4

File tree

11 files changed

+239
-63
lines changed

11 files changed

+239
-63
lines changed

api/resource/definitions/runtime/runtime.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ message MountStatusSpec {
7171
string filesystem_type = 3;
7272
repeated string options = 4;
7373
bool encrypted = 5;
74+
repeated string encryption_providers = 6;
7475
}
7576

7677
// PlatformMetadataSpec describes platform metadata properties.

internal/pkg/dashboard/components/talosinfo.go

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,30 @@
55
package components
66

77
import (
8+
"fmt"
89
"strconv"
10+
"strings"
911

1012
"github.com/rivo/tview"
1113

1214
"github.com/siderolabs/talos/internal/pkg/dashboard/resourcedata"
15+
"github.com/siderolabs/talos/pkg/machinery/constants"
1316
"github.com/siderolabs/talos/pkg/machinery/resources/cluster"
1417
"github.com/siderolabs/talos/pkg/machinery/resources/config"
1518
"github.com/siderolabs/talos/pkg/machinery/resources/hardware"
1619
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
1720
)
1821

1922
type talosInfoData struct {
20-
uuid string
21-
clusterName string
22-
stage string
23-
ready string
24-
typ string
25-
numMachinesText string
23+
uuid string
24+
clusterName string
25+
stage string
26+
ready string
27+
typ string
28+
numMachinesText string
29+
secureBootState string
30+
statePartitionMountStatus string
31+
ephemeralPartitionMountStatus string
2632

2733
machineIDSet map[string]struct{}
2834
}
@@ -93,6 +99,28 @@ func (widget *TalosInfo) updateNodeData(data resourcedata.Data) {
9399
nodeData.stage = formatStatus(res.TypedSpec().Stage.String())
94100
nodeData.ready = formatStatus(res.TypedSpec().Status.Ready)
95101
}
102+
case *runtime.SecurityState:
103+
if data.Deleted {
104+
nodeData.secureBootState = notAvailable
105+
} else {
106+
nodeData.secureBootState = formatStatus(res.TypedSpec().SecureBoot)
107+
}
108+
case *runtime.MountStatus:
109+
switch res.Metadata().ID() {
110+
case constants.StatePartitionLabel:
111+
if data.Deleted {
112+
nodeData.statePartitionMountStatus = notAvailable
113+
} else {
114+
nodeData.statePartitionMountStatus = mountStatus(res.TypedSpec().Encrypted, res.TypedSpec().EncryptionProviders)
115+
}
116+
case constants.EphemeralPartitionLabel:
117+
if data.Deleted {
118+
nodeData.ephemeralPartitionMountStatus = notAvailable
119+
} else {
120+
nodeData.ephemeralPartitionMountStatus = mountStatus(res.TypedSpec().Encrypted, res.TypedSpec().EncryptionProviders)
121+
}
122+
}
123+
96124
case *config.MachineType:
97125
if data.Deleted {
98126
nodeData.typ = notAvailable
@@ -114,13 +142,16 @@ func (widget *TalosInfo) getOrCreateNodeData(node string) *talosInfoData {
114142
nodeData, ok := widget.nodeMap[node]
115143
if !ok {
116144
nodeData = &talosInfoData{
117-
uuid: notAvailable,
118-
clusterName: notAvailable,
119-
stage: notAvailable,
120-
ready: notAvailable,
121-
typ: notAvailable,
122-
numMachinesText: notAvailable,
123-
machineIDSet: make(map[string]struct{}),
145+
uuid: notAvailable,
146+
clusterName: notAvailable,
147+
stage: notAvailable,
148+
ready: notAvailable,
149+
typ: notAvailable,
150+
numMachinesText: notAvailable,
151+
secureBootState: notAvailable,
152+
statePartitionMountStatus: notAvailable,
153+
ephemeralPartitionMountStatus: notAvailable,
154+
machineIDSet: make(map[string]struct{}),
124155
}
125156

126157
widget.nodeMap[node] = nodeData
@@ -158,8 +189,28 @@ func (widget *TalosInfo) redraw() {
158189
Name: "MACHINES",
159190
Value: data.numMachinesText,
160191
},
192+
{
193+
Name: "SECUREBOOT",
194+
Value: data.secureBootState,
195+
},
196+
{
197+
Name: "STATE",
198+
Value: data.statePartitionMountStatus,
199+
},
200+
{
201+
Name: "EPHEMERAL",
202+
Value: data.ephemeralPartitionMountStatus,
203+
},
161204
},
162205
}
163206

164207
widget.SetText(fields.String())
165208
}
209+
210+
func mountStatus(encrypted bool, providers []string) string {
211+
if !encrypted {
212+
return "[green]OK[-]"
213+
}
214+
215+
return fmt.Sprintf("[green]OK - encrypted[-] (%s)", strings.Join(providers, ","))
216+
}

internal/pkg/dashboard/resourcedata/resourcedata.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ import (
1919
"google.golang.org/grpc/metadata"
2020

2121
"github.com/siderolabs/talos/pkg/machinery/client"
22+
"github.com/siderolabs/talos/pkg/machinery/constants"
2223
"github.com/siderolabs/talos/pkg/machinery/resources/cluster"
2324
"github.com/siderolabs/talos/pkg/machinery/resources/config"
2425
"github.com/siderolabs/talos/pkg/machinery/resources/hardware"
2526
"github.com/siderolabs/talos/pkg/machinery/resources/k8s"
2627
"github.com/siderolabs/talos/pkg/machinery/resources/network"
2728
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
29+
"github.com/siderolabs/talos/pkg/machinery/resources/v1alpha1"
2830
)
2931

3032
// Data contains a resource, whether it is deleted and the node it came from.
@@ -114,6 +116,18 @@ func (source *Source) runResourceWatch(ctx context.Context, node string) error {
114116
return err
115117
}
116118

119+
if err := source.COSI.Watch(ctx, runtime.NewSecurityStateSpec(v1alpha1.NamespaceName).Metadata(), eventCh); err != nil {
120+
return err
121+
}
122+
123+
if err := source.COSI.Watch(ctx, runtime.NewMountStatus(v1alpha1.NamespaceName, constants.StatePartitionLabel).Metadata(), eventCh); err != nil {
124+
return err
125+
}
126+
127+
if err := source.COSI.Watch(ctx, runtime.NewMountStatus(v1alpha1.NamespaceName, constants.EphemeralPartitionLabel).Metadata(), eventCh); err != nil {
128+
return err
129+
}
130+
117131
if err := source.COSI.Watch(ctx, config.NewMachineType().Metadata(), eventCh); err != nil {
118132
return err
119133
}

internal/pkg/mount/system.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"sync"
1414

1515
"github.com/cosi-project/runtime/pkg/state"
16+
"github.com/siderolabs/gen/maps"
1617
"github.com/siderolabs/go-blockdevice/blockdevice"
1718
"github.com/siderolabs/go-blockdevice/blockdevice/filesystem"
1819
"golang.org/x/sys/unix"
@@ -235,6 +236,25 @@ func SystemPartitionMount(ctx context.Context, r runtime.Runtime, logger *log.Lo
235236
mountStatus.TypedSpec().FilesystemType = mountpoint.Fstype()
236237
mountStatus.TypedSpec().Encrypted = encrypted
237238

239+
if encrypted {
240+
encryptionProviders := make(map[string]struct{})
241+
242+
for _, cfg := range o.Encryption.Keys() {
243+
switch {
244+
case cfg.Static() != nil:
245+
encryptionProviders[cfg.Static().String()] = struct{}{}
246+
case cfg.NodeID() != nil:
247+
encryptionProviders[cfg.NodeID().String()] = struct{}{}
248+
case cfg.KMS() != nil:
249+
encryptionProviders[cfg.KMS().String()] = struct{}{}
250+
case cfg.TPM() != nil:
251+
encryptionProviders[cfg.TPM().String()] = struct{}{}
252+
}
253+
}
254+
255+
mountStatus.TypedSpec().EncryptionProviders = maps.Keys(encryptionProviders)
256+
}
257+
238258
// ignore the error if the MountStatus already exists, as many mounts are silently skipped with the flag SkipIfMounted
239259
if err = r.State().V1Alpha2().Resources().Create(context.Background(), mountStatus); err != nil && !state.IsConflictError(err) {
240260
return fmt.Errorf("error creating mount status resource: %w", err)

pkg/machinery/api/resource/definitions/runtime/runtime.pb.go

Lines changed: 54 additions & 43 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/machinery/api/resource/definitions/runtime/runtime_vtproto.pb.go

Lines changed: 47 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)