Skip to content

Commit

Permalink
chore: show securtiystate on dashboard
Browse files Browse the repository at this point in the history
Show Talos SecurityState and MountStatus on dashboard.

Fixes: #7675

Signed-off-by: Noel Georgi <git@frezbo.dev>
  • Loading branch information
frezbo committed Sep 6, 2023
1 parent b485108 commit 3d2dad4
Show file tree
Hide file tree
Showing 11 changed files with 239 additions and 63 deletions.
1 change: 1 addition & 0 deletions api/resource/definitions/runtime/runtime.proto
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ message MountStatusSpec {
string filesystem_type = 3;
repeated string options = 4;
bool encrypted = 5;
repeated string encryption_providers = 6;
}

// PlatformMetadataSpec describes platform metadata properties.
Expand Down
77 changes: 64 additions & 13 deletions internal/pkg/dashboard/components/talosinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,30 @@
package components

import (
"fmt"
"strconv"
"strings"

"github.com/rivo/tview"

"github.com/siderolabs/talos/internal/pkg/dashboard/resourcedata"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/cluster"
"github.com/siderolabs/talos/pkg/machinery/resources/config"
"github.com/siderolabs/talos/pkg/machinery/resources/hardware"
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
)

type talosInfoData struct {
uuid string
clusterName string
stage string
ready string
typ string
numMachinesText string
uuid string
clusterName string
stage string
ready string
typ string
numMachinesText string
secureBootState string
statePartitionMountStatus string
ephemeralPartitionMountStatus string

machineIDSet map[string]struct{}
}
Expand Down Expand Up @@ -93,6 +99,28 @@ func (widget *TalosInfo) updateNodeData(data resourcedata.Data) {
nodeData.stage = formatStatus(res.TypedSpec().Stage.String())
nodeData.ready = formatStatus(res.TypedSpec().Status.Ready)
}
case *runtime.SecurityState:
if data.Deleted {
nodeData.secureBootState = notAvailable
} else {
nodeData.secureBootState = formatStatus(res.TypedSpec().SecureBoot)
}
case *runtime.MountStatus:
switch res.Metadata().ID() {
case constants.StatePartitionLabel:
if data.Deleted {
nodeData.statePartitionMountStatus = notAvailable
} else {
nodeData.statePartitionMountStatus = mountStatus(res.TypedSpec().Encrypted, res.TypedSpec().EncryptionProviders)
}
case constants.EphemeralPartitionLabel:
if data.Deleted {
nodeData.ephemeralPartitionMountStatus = notAvailable
} else {
nodeData.ephemeralPartitionMountStatus = mountStatus(res.TypedSpec().Encrypted, res.TypedSpec().EncryptionProviders)
}
}

case *config.MachineType:
if data.Deleted {
nodeData.typ = notAvailable
Expand All @@ -114,13 +142,16 @@ func (widget *TalosInfo) getOrCreateNodeData(node string) *talosInfoData {
nodeData, ok := widget.nodeMap[node]
if !ok {
nodeData = &talosInfoData{
uuid: notAvailable,
clusterName: notAvailable,
stage: notAvailable,
ready: notAvailable,
typ: notAvailable,
numMachinesText: notAvailable,
machineIDSet: make(map[string]struct{}),
uuid: notAvailable,
clusterName: notAvailable,
stage: notAvailable,
ready: notAvailable,
typ: notAvailable,
numMachinesText: notAvailable,
secureBootState: notAvailable,
statePartitionMountStatus: notAvailable,
ephemeralPartitionMountStatus: notAvailable,
machineIDSet: make(map[string]struct{}),
}

widget.nodeMap[node] = nodeData
Expand Down Expand Up @@ -158,8 +189,28 @@ func (widget *TalosInfo) redraw() {
Name: "MACHINES",
Value: data.numMachinesText,
},
{
Name: "SECUREBOOT",
Value: data.secureBootState,
},
{
Name: "STATE",
Value: data.statePartitionMountStatus,
},
{
Name: "EPHEMERAL",
Value: data.ephemeralPartitionMountStatus,
},
},
}

widget.SetText(fields.String())
}

func mountStatus(encrypted bool, providers []string) string {
if !encrypted {
return "[green]OK[-]"
}

return fmt.Sprintf("[green]OK - encrypted[-] (%s)", strings.Join(providers, ","))
}
14 changes: 14 additions & 0 deletions internal/pkg/dashboard/resourcedata/resourcedata.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ import (
"google.golang.org/grpc/metadata"

"github.com/siderolabs/talos/pkg/machinery/client"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/cluster"
"github.com/siderolabs/talos/pkg/machinery/resources/config"
"github.com/siderolabs/talos/pkg/machinery/resources/hardware"
"github.com/siderolabs/talos/pkg/machinery/resources/k8s"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
"github.com/siderolabs/talos/pkg/machinery/resources/v1alpha1"
)

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

if err := source.COSI.Watch(ctx, runtime.NewSecurityStateSpec(v1alpha1.NamespaceName).Metadata(), eventCh); err != nil {
return err
}

if err := source.COSI.Watch(ctx, runtime.NewMountStatus(v1alpha1.NamespaceName, constants.StatePartitionLabel).Metadata(), eventCh); err != nil {
return err
}

if err := source.COSI.Watch(ctx, runtime.NewMountStatus(v1alpha1.NamespaceName, constants.EphemeralPartitionLabel).Metadata(), eventCh); err != nil {
return err
}

if err := source.COSI.Watch(ctx, config.NewMachineType().Metadata(), eventCh); err != nil {
return err
}
Expand Down
20 changes: 20 additions & 0 deletions internal/pkg/mount/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"sync"

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

if encrypted {
encryptionProviders := make(map[string]struct{})

for _, cfg := range o.Encryption.Keys() {
switch {
case cfg.Static() != nil:
encryptionProviders[cfg.Static().String()] = struct{}{}
case cfg.NodeID() != nil:
encryptionProviders[cfg.NodeID().String()] = struct{}{}
case cfg.KMS() != nil:
encryptionProviders[cfg.KMS().String()] = struct{}{}
case cfg.TPM() != nil:
encryptionProviders[cfg.TPM().String()] = struct{}{}
}
}

mountStatus.TypedSpec().EncryptionProviders = maps.Keys(encryptionProviders)
}

// ignore the error if the MountStatus already exists, as many mounts are silently skipped with the flag SkipIfMounted
if err = r.State().V1Alpha2().Resources().Create(context.Background(), mountStatus); err != nil && !state.IsConflictError(err) {
return fmt.Errorf("error creating mount status resource: %w", err)
Expand Down
97 changes: 54 additions & 43 deletions pkg/machinery/api/resource/definitions/runtime/runtime.pb.go

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

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

Loading

0 comments on commit 3d2dad4

Please sign in to comment.