diff --git a/api/resource/definitions/runtime/runtime.proto b/api/resource/definitions/runtime/runtime.proto index d79d0d25f5..c200247c8a 100755 --- a/api/resource/definitions/runtime/runtime.proto +++ b/api/resource/definitions/runtime/runtime.proto @@ -13,6 +13,12 @@ message DevicesStatusSpec { bool ready = 1; } +// DiagnosticSpec is the spec for devices status. +message DiagnosticSpec { + string message = 1; + repeated string details = 2; +} + // EventSinkConfigSpec describes configuration of Talos event log streaming. message EventSinkConfigSpec { string endpoint = 1; diff --git a/hack/release.toml b/hack/release.toml index 3957e86fce..443653df57 100644 --- a/hack/release.toml +++ b/hack/release.toml @@ -58,6 +58,13 @@ Please note that on running cluster you will have to kill CoreDNS pods for this A list of PCI devices can now be obtained via `PCIDevices` resource, e.g. `talosctl get pcidevices`. """ + [notes.diagnostics] + title = "Diagnostics" + description = """\ +Talos Linux now shows diagnostics information for common problems related to misconfiguration via `talosctl health` and Talos dashboard. +""" + + [make_deps] [make_deps.tools] diff --git a/internal/app/machined/pkg/controllers/runtime/diagnostics.go b/internal/app/machined/pkg/controllers/runtime/diagnostics.go new file mode 100644 index 0000000000..c1043734a2 --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/diagnostics.go @@ -0,0 +1,135 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package runtime + +import ( + "context" + "time" + + "github.com/cosi-project/runtime/pkg/controller" + "github.com/cosi-project/runtime/pkg/safe" + "go.uber.org/zap" + + "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime/internal/diagnostics" + "github.com/siderolabs/talos/pkg/machinery/resources/config" + "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" +) + +// DiagnosticsController analyzes state of Talos Linux system and provides warnings on common problems. +type DiagnosticsController struct{} + +// Name implements controller.Controller interface. +func (ctrl *DiagnosticsController) Name() string { + return "runtime.DiagnosticsController" +} + +// Inputs implements controller.Controller interface. +func (ctrl *DiagnosticsController) Inputs() []controller.Input { + return []controller.Input{ + { + Namespace: network.NamespaceName, + Type: network.NodeAddressType, + Kind: controller.InputWeak, + }, + { + Namespace: config.NamespaceName, + Type: config.MachineConfigType, + Kind: controller.InputWeak, + }, + { + Namespace: v1alpha1.NamespaceName, + Type: v1alpha1.ServiceType, + Kind: controller.InputWeak, + }, + { + Namespace: k8s.NamespaceName, + Type: k8s.NodenameType, + Kind: controller.InputWeak, + }, + } +} + +// Outputs implements controller.Controller interface. +func (ctrl *DiagnosticsController) Outputs() []controller.Output { + return []controller.Output{ + { + Type: runtime.DiagnosticType, + Kind: controller.OutputExclusive, + }, + } +} + +const ( + diagnosticsCheckTimeout = time.Minute + diagnostricsCheckInterval = time.Minute +) + +// Run implements controller.Controller interface. +// +//nolint:gocyclo +func (ctrl *DiagnosticsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { + // firstDiscovery is used to track when a warning was first discovered. + firstDiscovered := map[string]time.Time{} + + ticker := time.NewTicker(diagnostricsCheckInterval) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return nil + case <-r.EventCh(): + case <-ticker.C: + } + + r.StartTrackingOutputs() + + for _, checkDescription := range diagnostics.Checks() { + if err := func() error { + checkCtx, checkCtxCancel := context.WithTimeout(ctx, diagnosticsCheckTimeout) + defer checkCtxCancel() + + warning, err := checkDescription.Check(checkCtx, r, logger) + if err != nil { + logger.Debug("diagnostic check failed", zap.String("check", checkDescription.ID), zap.Error(err)) + + return nil + } + + if warning == nil { + delete(firstDiscovered, checkDescription.ID) + + return nil + } + + firstDiscoveredTime, ok := firstDiscovered[checkDescription.ID] + if !ok { + firstDiscoveredTime = time.Now() + firstDiscovered[checkDescription.ID] = firstDiscoveredTime + } + + if time.Since(firstDiscoveredTime) < checkDescription.Hysteresis { + // don't publish it yet + return nil + } + + return safe.WriterModify(ctx, r, runtime.NewDiagnstic(runtime.NamespaceName, checkDescription.ID), func(res *runtime.Diagnostic) error { + *res.TypedSpec() = *warning + + return nil + }) + }(); err != nil { + return err + } + } + + if err := safe.CleanupOutputs[*runtime.Diagnostic](ctx, r); err != nil { + return err + } + } +} diff --git a/internal/app/machined/pkg/controllers/runtime/diagnostics_logger.go b/internal/app/machined/pkg/controllers/runtime/diagnostics_logger.go new file mode 100644 index 0000000000..5f69568864 --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/diagnostics_logger.go @@ -0,0 +1,114 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package runtime + +import ( + "context" + "fmt" + "time" + + "github.com/cosi-project/runtime/pkg/controller" + "github.com/cosi-project/runtime/pkg/safe" + "go.uber.org/zap" + + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +// DiagnosticsLoggerController logs warnings generated by DiagnosticsController. +type DiagnosticsLoggerController struct{} + +// Name implements controller.Controller interface. +func (ctrl *DiagnosticsLoggerController) Name() string { + return "runtime.DiagnosticsLoggerController" +} + +// Inputs implements controller.Controller interface. +func (ctrl *DiagnosticsLoggerController) Inputs() []controller.Input { + return []controller.Input{ + { + Namespace: runtime.NamespaceName, + Type: runtime.DiagnosticType, + Kind: controller.InputWeak, + }, + } +} + +// Outputs implements controller.Controller interface. +func (ctrl *DiagnosticsLoggerController) Outputs() []controller.Output { + return nil +} + +const diagnosticsReportInterval = 5 * time.Minute + +// Run implements controller.Controller interface. +// +//nolint:gocyclo +func (ctrl *DiagnosticsLoggerController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { + reportedWarnings := map[string]struct{}{} + + ticker := time.NewTicker(diagnosticsReportInterval) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return nil + case <-r.EventCh(): + warnings, err := safe.ReaderListAll[*runtime.Diagnostic](ctx, r) + if err != nil { + return fmt.Errorf("error listing diagnostics: %w", err) + } + + seenWarnings := map[string]struct{}{} + + for iter := warnings.Iterator(); iter.Next(); { + warning := iter.Value() + + seenWarnings[warning.Metadata().ID()] = struct{}{} + + if _, reported := reportedWarnings[warning.Metadata().ID()]; !reported { + logger.Warn("new diagnostic", + zap.String("id", warning.Metadata().ID()), + zap.String("message", warning.TypedSpec().Message), + zap.Strings("details", warning.TypedSpec().Details), + zap.String("url", warning.TypedSpec().DocumentationURL(warning.Metadata().ID())), + ) + + reportedWarnings[warning.Metadata().ID()] = struct{}{} + } + } + + for id := range reportedWarnings { + if _, seen := seenWarnings[id]; !seen { + logger.Info("diagnostic resolved", zap.String("id", id)) + + delete(reportedWarnings, id) + } + } + case <-ticker.C: + if len(reportedWarnings) == 0 { + continue + } + + warnings, err := safe.ReaderListAll[*runtime.Diagnostic](ctx, r) + if err != nil { + return fmt.Errorf("error listing diagnostics: %w", err) + } + + for iter := warnings.Iterator(); iter.Next(); { + warning := iter.Value() + + logger.Warn("diagnostic still active", + zap.String("id", warning.Metadata().ID()), + zap.String("message", warning.TypedSpec().Message), + zap.Strings("details", warning.TypedSpec().Details), + zap.String("url", warning.TypedSpec().DocumentationURL(warning.Metadata().ID())), + ) + } + } + + r.ResetRestartBackoff() + } +} diff --git a/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/address_overlap.go b/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/address_overlap.go new file mode 100644 index 0000000000..6170f77ba3 --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/address_overlap.go @@ -0,0 +1,70 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package diagnostics + +import ( + "context" + "fmt" + "net/netip" + + "github.com/cosi-project/runtime/pkg/controller" + "github.com/cosi-project/runtime/pkg/safe" + "github.com/cosi-project/runtime/pkg/state" + "github.com/siderolabs/gen/xslices" + "go.uber.org/zap" + + "github.com/siderolabs/talos/pkg/machinery/resources/config" + "github.com/siderolabs/talos/pkg/machinery/resources/k8s" + "github.com/siderolabs/talos/pkg/machinery/resources/network" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +// AddressOverlapCheck checks for overlapping host and Kubernetes pod/service CIDR addresses. +func AddressOverlapCheck(ctx context.Context, r controller.Reader, logger *zap.Logger) (*runtime.DiagnosticSpec, error) { + hostAddresses, err := safe.ReaderGetByID[*network.NodeAddress](ctx, r, network.NodeAddressRoutedID) + if err != nil { + if state.IsNotFoundError(err) { + return nil, nil + } + + return nil, fmt.Errorf("error reading host addresses: %w", err) + } + + hostMinusK8s, err := safe.ReaderGetByID[*network.NodeAddress](ctx, r, network.FilteredNodeAddressID(network.NodeAddressRoutedID, k8s.NodeAddressFilterNoK8s)) + if err != nil { + if state.IsNotFoundError(err) { + return nil, nil + } + + return nil, fmt.Errorf("error reading host minus k8s addresses: %w", err) + } + + cfg, err := safe.ReaderGetByID[*config.MachineConfig](ctx, r, config.V1Alpha1ID) + if err != nil { + if state.IsNotFoundError(err) { + return nil, nil + } + + return nil, fmt.Errorf("error reading machine configuration: %w", err) + } + + if len(hostAddresses.TypedSpec().Addresses) > 0 && len(hostMinusK8s.TypedSpec().Addresses) == 0 { + details := []string{ + fmt.Sprintf("host routed addresses: %q", xslices.Map(hostAddresses.TypedSpec().Addresses, netip.Prefix.String)), + } + + if cfg.Config().Cluster() != nil { + details = append(details, fmt.Sprintf("Kubernetes pod CIDRs: %q", cfg.Config().Cluster().Network().PodCIDRs())) + details = append(details, fmt.Sprintf("Kubernetes service CIDRs: %q", cfg.Config().Cluster().Network().ServiceCIDRs())) + } + + return &runtime.DiagnosticSpec{ + Message: "host and Kubernetes pod/service CIDR addresses overlap", + Details: details, + }, nil + } + + return nil, nil +} diff --git a/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/address_overlap_test.go b/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/address_overlap_test.go new file mode 100644 index 0000000000..9515e20efc --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/address_overlap_test.go @@ -0,0 +1,109 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package diagnostics_test + +import ( + "context" + "net/netip" + "testing" + "time" + + "github.com/cosi-project/runtime/pkg/state" + "github.com/cosi-project/runtime/pkg/state/impl/inmem" + "github.com/cosi-project/runtime/pkg/state/impl/namespaced" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zaptest" + + "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime/internal/diagnostics" + "github.com/siderolabs/talos/pkg/machinery/config/generate" + "github.com/siderolabs/talos/pkg/machinery/config/machine" + "github.com/siderolabs/talos/pkg/machinery/constants" + "github.com/siderolabs/talos/pkg/machinery/resources/config" + "github.com/siderolabs/talos/pkg/machinery/resources/k8s" + "github.com/siderolabs/talos/pkg/machinery/resources/network" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +func TestAddressOverlapCheck(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + t.Cleanup(cancel) + + for _, test := range []struct { + name string + + setup func(t *testing.T, ctx context.Context, st state.State) + + expectedWarning *runtime.DiagnosticSpec + }{ + { + name: "no addresses", + + setup: func(t *testing.T, ctx context.Context, st state.State) {}, + }, + { + name: "no overlap", + + setup: func(t *testing.T, ctx context.Context, st state.State) { + hostAddresses := network.NewNodeAddress(network.NamespaceName, network.NodeAddressRoutedID) + hostAddresses.TypedSpec().Addresses = []netip.Prefix{netip.MustParsePrefix("10.0.0.1/8"), netip.MustParsePrefix("10.244.1.3/32")} + require.NoError(t, st.Create(ctx, hostAddresses)) + + hostMinusK8s := network.NewNodeAddress(network.NamespaceName, network.FilteredNodeAddressID(network.NodeAddressRoutedID, k8s.NodeAddressFilterNoK8s)) + hostMinusK8s.TypedSpec().Addresses = []netip.Prefix{netip.MustParsePrefix("10.0.0.1/8")} + require.NoError(t, st.Create(ctx, hostMinusK8s)) + }, + }, + { + name: "with overlap", + + setup: func(t *testing.T, ctx context.Context, st state.State) { + hostAddresses := network.NewNodeAddress(network.NamespaceName, network.NodeAddressRoutedID) + hostAddresses.TypedSpec().Addresses = []netip.Prefix{netip.MustParsePrefix("10.244.3.4/24"), netip.MustParsePrefix("10.244.1.3/32")} + require.NoError(t, st.Create(ctx, hostAddresses)) + + hostMinusK8s := network.NewNodeAddress(network.NamespaceName, network.FilteredNodeAddressID(network.NodeAddressRoutedID, k8s.NodeAddressFilterNoK8s)) + hostMinusK8s.TypedSpec().Addresses = []netip.Prefix{} + require.NoError(t, st.Create(ctx, hostMinusK8s)) + }, + + expectedWarning: &runtime.DiagnosticSpec{ + Message: "host and Kubernetes pod/service CIDR addresses overlap", + Details: []string{ + "host routed addresses: [\"10.244.3.4/24\" \"10.244.1.3/32\"]", + "Kubernetes pod CIDRs: [\"10.244.0.0/16\"]", "Kubernetes service CIDRs: [\"10.96.0.0/12\"]", + }, + }, + }, + } { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + logger := zaptest.NewLogger(t) + st := state.WrapCore(namespaced.NewState(inmem.Build)) + + in, err := generate.NewInput("test-cluster", "https://localhost", constants.DefaultKubernetesVersion) + require.NoError(t, err) + + cfg, err := in.Config(machine.TypeWorker) + require.NoError(t, err) + + cfgResource := config.NewMachineConfig(cfg) + require.NoError(t, st.Create(ctx, cfgResource)) + + test.setup(t, ctx, st) + + spec, err := diagnostics.AddressOverlapCheck(ctx, st, logger) + require.NoError(t, err) + + if test.expectedWarning == nil { + require.Nil(t, spec) + } else { + require.Equal(t, test.expectedWarning, spec) + } + }) + } +} diff --git a/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/diagnostic.go b/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/diagnostic.go new file mode 100644 index 0000000000..08de1e3b1c --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/diagnostic.go @@ -0,0 +1,50 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Package diagnostics provides Talos diagnostics specific checks. +package diagnostics + +import ( + "context" + "time" + + "github.com/cosi-project/runtime/pkg/controller" + "go.uber.org/zap" + + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +// Check defines a function that checks for a specific issue. +// +// If the check produces a warning, it should return a non-nil warning and nil error. +// If the check produces an error, the error will be logged, and other checks will proceed running. +type Check func(ctx context.Context, r controller.Reader, logger *zap.Logger) (*runtime.DiagnosticSpec, error) + +// CheckDescription combines a check with a semantic ID. +type CheckDescription struct { + // Semantic ID is used to identify the check and help message. + ID string + + // Hysteresis time to wait before announcing the warning after the first appearance. + Hysteresis time.Duration + + // Check function to run. + Check Check +} + +// Checks returns a list of checks to be run by the diagnostics engine. +func Checks() []CheckDescription { + return []CheckDescription{ + { + ID: "address-overlap", + Hysteresis: 30 * time.Second, + Check: AddressOverlapCheck, + }, + { + ID: "kubelet-csr", + Hysteresis: 30 * time.Second, + Check: KubeletCSRNotApprovedCheck, + }, + } +} diff --git a/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/kubelet_csr_not_approved.go b/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/kubelet_csr_not_approved.go new file mode 100644 index 0000000000..4db3de407a --- /dev/null +++ b/internal/app/machined/pkg/controllers/runtime/internal/diagnostics/kubelet_csr_not_approved.go @@ -0,0 +1,131 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package diagnostics + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "net" + "strings" + "time" + + "github.com/cosi-project/runtime/pkg/controller" + "github.com/cosi-project/runtime/pkg/safe" + "github.com/cosi-project/runtime/pkg/state" + "github.com/siderolabs/gen/xslices" + "go.uber.org/zap" + v1 "k8s.io/api/certificates/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + + "github.com/siderolabs/talos/pkg/kubernetes" + "github.com/siderolabs/talos/pkg/machinery/resources/k8s" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" + "github.com/siderolabs/talos/pkg/machinery/resources/v1alpha1" +) + +// KubeletCSRNotApprovedCheck checks for kubelet server certificate rotation and no CSR approvers. +// +//nolint:gocyclo +func KubeletCSRNotApprovedCheck(ctx context.Context, r controller.Reader, logger *zap.Logger) (*runtime.DiagnosticSpec, error) { + // check kubelet status to make sure it's running & health before proceeding any further + kubeletService, err := safe.ReaderGetByID[*v1alpha1.Service](ctx, r, "kubelet") + if err != nil { + if state.IsNotFoundError(err) { + return nil, nil + } + + return nil, fmt.Errorf("error reading kubelet service: %w", err) + } + + if !kubeletService.TypedSpec().Running || !kubeletService.TypedSpec().Healthy { + return nil, nil + } + + // fetch nodename + nodeName, err := safe.ReaderGetByID[*k8s.Nodename](ctx, r, k8s.NodenameID) + if err != nil { + if state.IsNotFoundError(err) { + return nil, nil + } + + return nil, fmt.Errorf("error reading nodename: %w", err) + } + + // try to access kubelet API to see if we get 'tls: internal error' + c, err := tls.DialWithDialer( + &net.Dialer{Timeout: 5 * time.Second}, + "tcp", "127.0.0.1:10250", + &tls.Config{ + InsecureSkipVerify: true, + }, + ) + if err == nil { + return nil, c.Close() + } + + var netError *net.OpError + + if !errors.As(err, &netError) { + // not our error + return nil, nil + } + + if !(netError.Op == "remote error" && netError.Err.Error() == tls.AlertError(80).Error()) { // remote error: tls: internal error + return nil, nil + } + + k8sClient, err := kubernetes.NewClientFromKubeletKubeconfig() + if err != nil { + return nil, fmt.Errorf("error creating k8s client: %w", err) + } + + defer k8sClient.Close() //nolint:errcheck + + csrs, err := k8sClient.Clientset.CertificatesV1().CertificateSigningRequests().List(ctx, + metav1.ListOptions{ + FieldSelector: fields.OneTermEqualSelector("spec.signerName", "kubernetes.io/kubelet-serving").String(), + }, + ) + if err != nil { + // error getting CSRs + return nil, fmt.Errorf("error listing CSRs: %w", err) + } + + expectedUsername := fmt.Sprintf("system:node:%s", nodeName.TypedSpec().Nodename) + + csrs.Items = xslices.Filter(csrs.Items, func(csr v1.CertificateSigningRequest) bool { + if csr.Spec.Username != expectedUsername { + return false + } + + for _, condition := range csr.Status.Conditions { + if condition.Type == v1.CertificateApproved { + return false + } + } + + return true + }) + + if len(csrs.Items) == 0 { + return nil, nil + } + + return &runtime.DiagnosticSpec{ + Message: "kubelet server certificate rotation is enabled, but CSR is not approved", + Details: []string{ + fmt.Sprintf("kubelet API error: %s", netError), + fmt.Sprintf("pending CSRs: %s", + strings.Join( + xslices.Map(csrs.Items, func(csr v1.CertificateSigningRequest) string { return csr.Name }), + ", ", + ), + ), + }, + }, nil +} diff --git a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go index 9f72257376..50cf52303e 100644 --- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go +++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go @@ -263,6 +263,8 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error &runtimecontrollers.DevicesStatusController{ V1Alpha1Mode: ctrl.v1alpha1Runtime.State().Platform().Mode(), }, + &runtimecontrollers.DiagnosticsController{}, + &runtimecontrollers.DiagnosticsLoggerController{}, &runtimecontrollers.DropUpgradeFallbackController{ MetaProvider: ctrl.v1alpha1Runtime.State().Machine(), }, diff --git a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go index a4df8d4793..1c33808d52 100644 --- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go +++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go @@ -177,6 +177,7 @@ func NewState() (*State, error) { &perf.CPU{}, &perf.Memory{}, &runtime.DevicesStatus{}, + &runtime.Diagnostic{}, &runtime.EventSinkConfig{}, &runtime.ExtensionServiceConfig{}, &runtime.ExtensionServiceConfigStatus{}, diff --git a/internal/pkg/dashboard/components/diagnostics.go b/internal/pkg/dashboard/components/diagnostics.go new file mode 100644 index 0000000000..3b10ea2ffb --- /dev/null +++ b/internal/pkg/dashboard/components/diagnostics.go @@ -0,0 +1,107 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package components + +import ( + "fmt" + "slices" + + "github.com/rivo/tview" + + "github.com/siderolabs/talos/internal/pkg/dashboard/resourcedata" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +// Diagnostics represents the diagnostics widget. +type Diagnostics struct { + tview.Grid + + hline *HorizontalLine + info *tview.TextView + + selectedNode string + perNodeWarnings map[string][]*runtime.Diagnostic +} + +// NewDiagnostics initializes Diagnostics. +func NewDiagnostics() *Diagnostics { + widget := &Diagnostics{ + Grid: *tview.NewGrid(), + info: tview.NewTextView(), + hline: NewHorizontalLine("Diagnostics"), + perNodeWarnings: make(map[string][]*runtime.Diagnostic), + } + + widget.info. + SetDynamicColors(true). + SetBorderPadding(0, 0, 1, 1) + + widget.SetRows(1, 0).SetColumns(0) + + widget.AddItem(widget.hline, 0, 0, 1, 1, 0, 0, false) + widget.AddItem(widget.info, 1, 0, 1, 1, 0, 0, false) + + return widget +} + +// GetCurrentHeight returns the height of the widget. +func (widget *Diagnostics) GetCurrentHeight() int { + numWarnings := len(widget.perNodeWarnings[widget.selectedNode]) + if numWarnings == 0 { + return 0 + } + + return 1 + numWarnings +} + +// OnNodeSelect implements the NodeSelectListener interface. +func (widget *Diagnostics) OnNodeSelect(node string) { + if node != widget.selectedNode { + widget.selectedNode = node + + widget.redraw() + } +} + +// OnResourceDataChange implements the ResourceDataListener interface. +func (widget *Diagnostics) OnResourceDataChange(data resourcedata.Data) { + r, ok := data.Resource.(*runtime.Diagnostic) + if !ok { + return + } + + idx := slices.IndexFunc(widget.perNodeWarnings[data.Node], func(warning *runtime.Diagnostic) bool { + return warning.Metadata().ID() == r.Metadata().ID() + }) + + if data.Deleted { + if idx != -1 { + widget.perNodeWarnings[data.Node] = slices.Delete(widget.perNodeWarnings[data.Node], idx, idx+1) + } + } else { + if idx == -1 { + widget.perNodeWarnings[data.Node] = append(widget.perNodeWarnings[data.Node], r) + } else { + widget.perNodeWarnings[data.Node][idx] = r + } + } + + if data.Node == widget.selectedNode { + widget.redraw() + } +} + +// WriteLog writes the log line to the widget. +func (widget *Diagnostics) redraw() { + widget.info.SetWrap(true) + widget.info.Clear() + + for _, warning := range widget.perNodeWarnings[widget.selectedNode] { + widget.info.Write([]byte(fmt.Sprintf("■ (%s) [red]%s[-]\n", //nolint:errcheck + tview.Escape(warning.TypedSpec().DocumentationURL(warning.Metadata().ID())), + tview.Escape(warning.TypedSpec().Message))), + ) + } +} diff --git a/internal/pkg/dashboard/components/horizontalline.go b/internal/pkg/dashboard/components/horizontalline.go index 1a898828e5..531cfc8c31 100644 --- a/internal/pkg/dashboard/components/horizontalline.go +++ b/internal/pkg/dashboard/components/horizontalline.go @@ -12,19 +12,30 @@ import ( // HorizontalLine is a widget that draws a horizontal line. type HorizontalLine struct { tview.TextView + + label []rune } // NewHorizontalLine initializes HorizontalLine. -func NewHorizontalLine() *HorizontalLine { +func NewHorizontalLine(label string) *HorizontalLine { widget := &HorizontalLine{ TextView: *tview.NewTextView(), + label: []rune(" " + label + " "), } + const leftGap = 2 + // set the background to be a horizontal line widget.SetDrawFunc(func(screen tcell.Screen, x, y, width, height int) (int, int, int, int) { + labelLength := len(widget.label) + for i := x; i < x+width; i++ { for j := y; j < y+height; j++ { - screen.SetContent(i, j, tview.BoxDrawingsLightHorizontal, nil, tcell.StyleDefault.Foreground(tcell.ColorWhite)) + if j == y && i >= leftGap && i-leftGap < labelLength { + screen.SetContent(i, j, widget.label[i-leftGap], nil, tcell.StyleDefault.Foreground(tcell.ColorYellow)) + } else { + screen.SetContent(i, j, tview.BoxDrawingsLightHorizontal, nil, tcell.StyleDefault.Foreground(tcell.ColorWhite)) + } } } diff --git a/internal/pkg/dashboard/components/logviewer.go b/internal/pkg/dashboard/components/logviewer.go index 44a918cb42..67a22e4fa8 100644 --- a/internal/pkg/dashboard/components/logviewer.go +++ b/internal/pkg/dashboard/components/logviewer.go @@ -48,7 +48,7 @@ func NewLogViewer() *LogViewer { widget.SetRows(1, 0).SetColumns(0) - widget.AddItem(NewHorizontalLine(), 0, 0, 1, 1, 0, 0, false) + widget.AddItem(NewHorizontalLine("Logs"), 0, 0, 1, 1, 0, 0, false) widget.AddItem(&widget.logs, 1, 0, 1, 1, 0, 0, true) return widget diff --git a/internal/pkg/dashboard/resourcedata/resourcedata.go b/internal/pkg/dashboard/resourcedata/resourcedata.go index 9786790533..e23a0855d9 100644 --- a/internal/pkg/dashboard/resourcedata/resourcedata.go +++ b/internal/pkg/dashboard/resourcedata/resourcedata.go @@ -16,8 +16,10 @@ import ( "github.com/cosi-project/runtime/pkg/state" "github.com/siderolabs/gen/channel" "golang.org/x/sync/errgroup" + "google.golang.org/grpc/codes" "github.com/siderolabs/talos/internal/pkg/dashboard/util" + "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" @@ -176,6 +178,13 @@ func (source *Source) runResourceWatch(ctx context.Context, node string) error { return err } + if err := source.COSI.WatchKind(ctx, runtime.NewDiagnstic(runtime.NamespaceName, "").Metadata(), eventCh, state.WithBootstrapContents(true)); err != nil { + if client.StatusCode(err) != codes.PermissionDenied { + // ignore permission denied, means resource is not supported yet + return err + } + } + for { select { case <-ctx.Done(): diff --git a/internal/pkg/dashboard/summary.go b/internal/pkg/dashboard/summary.go index b8482ea4b2..87a43a4142 100644 --- a/internal/pkg/dashboard/summary.go +++ b/internal/pkg/dashboard/summary.go @@ -25,8 +25,13 @@ type SummaryGrid struct { active bool node string logViewers map[string]*components.LogViewer + + diagnostics *components.Diagnostics + diagnosticsVisible bool } +const summaryTopFixedRows = 8 + // NewSummaryGrid initializes SummaryGrid. func NewSummaryGrid(app *tview.Application) *SummaryGrid { widget := &SummaryGrid{ @@ -35,7 +40,7 @@ func NewSummaryGrid(app *tview.Application) *SummaryGrid { logViewers: make(map[string]*components.LogViewer), } - widget.SetRows(8, 0).SetColumns(-3, -2, -3) + widget.SetRows(summaryTopFixedRows, 0).SetColumns(-3, -2, -3) talosInfo := components.NewTalosInfo() widget.AddItem(talosInfo, 0, 0, 1, 1, 0, 0, false) @@ -46,6 +51,8 @@ func NewSummaryGrid(app *tview.Application) *SummaryGrid { networkInfo := components.NewNetworkInfo() widget.AddItem(networkInfo, 0, 2, 1, 1, 0, 0, false) + widget.diagnostics = components.NewDiagnostics() + widget.apiDataListeners = []APIDataListener{ kubernetesInfo, } @@ -54,12 +61,14 @@ func NewSummaryGrid(app *tview.Application) *SummaryGrid { talosInfo, kubernetesInfo, networkInfo, + widget.diagnostics, } widget.nodeSelectListeners = []NodeSelectListener{ talosInfo, kubernetesInfo, networkInfo, + widget.diagnostics, } return widget @@ -74,6 +83,8 @@ func (widget *SummaryGrid) OnNodeSelect(node string) { for _, nodeSelectListener := range widget.nodeSelectListeners { nodeSelectListener.OnNodeSelect(node) } + + widget.updateDiagnostics() } // OnAPIDataChange implements the APIDataListener interface. @@ -88,6 +99,8 @@ func (widget *SummaryGrid) OnResourceDataChange(nodeResource resourcedata.Data) for _, resourceListener := range widget.resourceListeners { resourceListener.OnResourceDataChange(nodeResource) } + + widget.updateDiagnostics() } // OnLogDataChange implements the LogDataListener interface. @@ -95,6 +108,23 @@ func (widget *SummaryGrid) OnLogDataChange(node, logLine, logError string) { widget.logViewer(node).WriteLog(logLine, logError) } +func (widget *SummaryGrid) updateDiagnostics() { + height := widget.diagnostics.GetCurrentHeight() + + switch { + case height == 0 && widget.diagnosticsVisible: + widget.RemoveItem(widget.diagnostics) + widget.SetRows(summaryTopFixedRows, 0) + widget.diagnosticsVisible = false + case height > 0 && !widget.diagnosticsVisible: + widget.SetRows(summaryTopFixedRows, 0, height) + widget.AddItem(widget.diagnostics, 2, 0, 1, 3, 0, 0, false) + widget.diagnosticsVisible = true + case height > 0: + widget.SetRows(summaryTopFixedRows, 0, height) + } +} + func (widget *SummaryGrid) updateLogViewer() { if !widget.active { return diff --git a/pkg/cluster/check/default.go b/pkg/cluster/check/default.go index 5f6478410b..6612f837f6 100644 --- a/pkg/cluster/check/default.go +++ b/pkg/cluster/check/default.go @@ -136,6 +136,13 @@ func PreBootSequenceChecks() []ClusterCheck { }, 5*time.Minute, 5*time.Second) }, + // check diagnostics + func(cluster ClusterInfo) conditions.Condition { + return conditions.PollingCondition("no diagnostics", func(ctx context.Context) error { + return NoDiagnostics(ctx, cluster) + }, time.Minute, 5*time.Second) + }, + // wait for kubelet to be healthy on all func(cluster ClusterInfo) conditions.Condition { return conditions.PollingCondition("kubelet to be healthy", func(ctx context.Context) error { diff --git a/pkg/cluster/check/diagnostics.go b/pkg/cluster/check/diagnostics.go new file mode 100644 index 0000000000..ed28362eb6 --- /dev/null +++ b/pkg/cluster/check/diagnostics.go @@ -0,0 +1,63 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package check + +import ( + "context" + "fmt" + "slices" + "strings" + + "github.com/cosi-project/runtime/pkg/safe" + "github.com/siderolabs/gen/maps" + "github.com/siderolabs/gen/xslices" + "google.golang.org/grpc/codes" + + "github.com/siderolabs/talos/pkg/conditions" + "github.com/siderolabs/talos/pkg/machinery/client" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +// NoDiagnostics checks whether there are no diagnostic warnings. +func NoDiagnostics(ctx context.Context, cluster ClusterInfo) error { + cli, err := cluster.Client() + if err != nil { + return err + } + + nodes := cluster.Nodes() + nodeInternalIPs := mapIPsToStrings(mapNodeInfosToInternalIPs(nodes)) + + warningsByNode := map[string][]*runtime.Diagnostic{} + + for _, nodeIP := range nodeInternalIPs { + warnings, err := safe.StateListAll[*runtime.Diagnostic](client.WithNode(ctx, nodeIP), cli.COSI) + if err != nil { + if client.StatusCode(err) == codes.PermissionDenied { + // not supported, skip + return conditions.ErrSkipAssertion + } + + return err + } + + for iter := warnings.Iterator(); iter.Next(); { + warningsByNode[nodeIP] = append(warningsByNode[nodeIP], iter.Value()) + } + } + + if len(warningsByNode) == 0 { + return nil + } + + nodesWithWarnings := maps.Keys(warningsByNode) + slices.Sort(nodesWithWarnings) + + return fmt.Errorf("active diagnostics: %s", strings.Join(xslices.Map(nodesWithWarnings, func(node string) string { + return node + ": " + strings.Join(xslices.Map(warningsByNode[node], func(warning *runtime.Diagnostic) string { + return warning.TypedSpec().Message + }), ", ") + }), "; ")) +} diff --git a/pkg/machinery/api/resource/definitions/runtime/runtime.pb.go b/pkg/machinery/api/resource/definitions/runtime/runtime.pb.go index 0c46a76db7..01eb6c31c5 100644 --- a/pkg/machinery/api/resource/definitions/runtime/runtime.pb.go +++ b/pkg/machinery/api/resource/definitions/runtime/runtime.pb.go @@ -73,6 +73,62 @@ func (x *DevicesStatusSpec) GetReady() bool { return false } +// DiagnosticSpec is the spec for devices status. +type DiagnosticSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Details []string `protobuf:"bytes,2,rep,name=details,proto3" json:"details,omitempty"` +} + +func (x *DiagnosticSpec) Reset() { + *x = DiagnosticSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DiagnosticSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiagnosticSpec) ProtoMessage() {} + +func (x *DiagnosticSpec) ProtoReflect() protoreflect.Message { + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DiagnosticSpec.ProtoReflect.Descriptor instead. +func (*DiagnosticSpec) Descriptor() ([]byte, []int) { + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{1} +} + +func (x *DiagnosticSpec) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *DiagnosticSpec) GetDetails() []string { + if x != nil { + return x.Details + } + return nil +} + // EventSinkConfigSpec describes configuration of Talos event log streaming. type EventSinkConfigSpec struct { state protoimpl.MessageState @@ -85,7 +141,7 @@ type EventSinkConfigSpec struct { func (x *EventSinkConfigSpec) Reset() { *x = EventSinkConfigSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[1] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -98,7 +154,7 @@ func (x *EventSinkConfigSpec) String() string { func (*EventSinkConfigSpec) ProtoMessage() {} func (x *EventSinkConfigSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[1] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -111,7 +167,7 @@ func (x *EventSinkConfigSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use EventSinkConfigSpec.ProtoReflect.Descriptor instead. func (*EventSinkConfigSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{1} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{2} } func (x *EventSinkConfigSpec) GetEndpoint() string { @@ -134,7 +190,7 @@ type ExtensionServiceConfigFile struct { func (x *ExtensionServiceConfigFile) Reset() { *x = ExtensionServiceConfigFile{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[2] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -147,7 +203,7 @@ func (x *ExtensionServiceConfigFile) String() string { func (*ExtensionServiceConfigFile) ProtoMessage() {} func (x *ExtensionServiceConfigFile) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[2] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -160,7 +216,7 @@ func (x *ExtensionServiceConfigFile) ProtoReflect() protoreflect.Message { // Deprecated: Use ExtensionServiceConfigFile.ProtoReflect.Descriptor instead. func (*ExtensionServiceConfigFile) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{2} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{3} } func (x *ExtensionServiceConfigFile) GetContent() string { @@ -190,7 +246,7 @@ type ExtensionServiceConfigSpec struct { func (x *ExtensionServiceConfigSpec) Reset() { *x = ExtensionServiceConfigSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[3] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -203,7 +259,7 @@ func (x *ExtensionServiceConfigSpec) String() string { func (*ExtensionServiceConfigSpec) ProtoMessage() {} func (x *ExtensionServiceConfigSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[3] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -216,7 +272,7 @@ func (x *ExtensionServiceConfigSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use ExtensionServiceConfigSpec.ProtoReflect.Descriptor instead. func (*ExtensionServiceConfigSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{3} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{4} } func (x *ExtensionServiceConfigSpec) GetFiles() []*ExtensionServiceConfigFile { @@ -245,7 +301,7 @@ type ExtensionServiceConfigStatusSpec struct { func (x *ExtensionServiceConfigStatusSpec) Reset() { *x = ExtensionServiceConfigStatusSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[4] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -258,7 +314,7 @@ func (x *ExtensionServiceConfigStatusSpec) String() string { func (*ExtensionServiceConfigStatusSpec) ProtoMessage() {} func (x *ExtensionServiceConfigStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[4] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -271,7 +327,7 @@ func (x *ExtensionServiceConfigStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use ExtensionServiceConfigStatusSpec.ProtoReflect.Descriptor instead. func (*ExtensionServiceConfigStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{4} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{5} } func (x *ExtensionServiceConfigStatusSpec) GetSpecVersion() string { @@ -294,7 +350,7 @@ type KernelModuleSpecSpec struct { func (x *KernelModuleSpecSpec) Reset() { *x = KernelModuleSpecSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[5] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -307,7 +363,7 @@ func (x *KernelModuleSpecSpec) String() string { func (*KernelModuleSpecSpec) ProtoMessage() {} func (x *KernelModuleSpecSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[5] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -320,7 +376,7 @@ func (x *KernelModuleSpecSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use KernelModuleSpecSpec.ProtoReflect.Descriptor instead. func (*KernelModuleSpecSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{5} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{6} } func (x *KernelModuleSpecSpec) GetName() string { @@ -350,7 +406,7 @@ type KernelParamSpecSpec struct { func (x *KernelParamSpecSpec) Reset() { *x = KernelParamSpecSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[6] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -363,7 +419,7 @@ func (x *KernelParamSpecSpec) String() string { func (*KernelParamSpecSpec) ProtoMessage() {} func (x *KernelParamSpecSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[6] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -376,7 +432,7 @@ func (x *KernelParamSpecSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use KernelParamSpecSpec.ProtoReflect.Descriptor instead. func (*KernelParamSpecSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{6} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{7} } func (x *KernelParamSpecSpec) GetValue() string { @@ -407,7 +463,7 @@ type KernelParamStatusSpec struct { func (x *KernelParamStatusSpec) Reset() { *x = KernelParamStatusSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[7] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -420,7 +476,7 @@ func (x *KernelParamStatusSpec) String() string { func (*KernelParamStatusSpec) ProtoMessage() {} func (x *KernelParamStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[7] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -433,7 +489,7 @@ func (x *KernelParamStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use KernelParamStatusSpec.ProtoReflect.Descriptor instead. func (*KernelParamStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{7} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{8} } func (x *KernelParamStatusSpec) GetCurrent() string { @@ -469,7 +525,7 @@ type KmsgLogConfigSpec struct { func (x *KmsgLogConfigSpec) Reset() { *x = KmsgLogConfigSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -482,7 +538,7 @@ func (x *KmsgLogConfigSpec) String() string { func (*KmsgLogConfigSpec) ProtoMessage() {} func (x *KmsgLogConfigSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -495,7 +551,7 @@ func (x *KmsgLogConfigSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use KmsgLogConfigSpec.ProtoReflect.Descriptor instead. func (*KmsgLogConfigSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{8} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{9} } func (x *KmsgLogConfigSpec) GetDestinations() []*common.URL { @@ -518,7 +574,7 @@ type MachineStatusSpec struct { func (x *MachineStatusSpec) Reset() { *x = MachineStatusSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -531,7 +587,7 @@ func (x *MachineStatusSpec) String() string { func (*MachineStatusSpec) ProtoMessage() {} func (x *MachineStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -544,7 +600,7 @@ func (x *MachineStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MachineStatusSpec.ProtoReflect.Descriptor instead. func (*MachineStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{9} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{10} } func (x *MachineStatusSpec) GetStage() enums.RuntimeMachineStage { @@ -574,7 +630,7 @@ type MachineStatusStatus struct { func (x *MachineStatusStatus) Reset() { *x = MachineStatusStatus{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -587,7 +643,7 @@ func (x *MachineStatusStatus) String() string { func (*MachineStatusStatus) ProtoMessage() {} func (x *MachineStatusStatus) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -600,7 +656,7 @@ func (x *MachineStatusStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use MachineStatusStatus.ProtoReflect.Descriptor instead. func (*MachineStatusStatus) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{10} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{11} } func (x *MachineStatusStatus) GetReady() bool { @@ -630,7 +686,7 @@ type MaintenanceServiceConfigSpec struct { func (x *MaintenanceServiceConfigSpec) Reset() { *x = MaintenanceServiceConfigSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -643,7 +699,7 @@ func (x *MaintenanceServiceConfigSpec) String() string { func (*MaintenanceServiceConfigSpec) ProtoMessage() {} func (x *MaintenanceServiceConfigSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -656,7 +712,7 @@ func (x *MaintenanceServiceConfigSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MaintenanceServiceConfigSpec.ProtoReflect.Descriptor instead. func (*MaintenanceServiceConfigSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{11} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{12} } func (x *MaintenanceServiceConfigSpec) GetListenAddress() string { @@ -685,7 +741,7 @@ type MetaKeySpec struct { func (x *MetaKeySpec) Reset() { *x = MetaKeySpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -698,7 +754,7 @@ func (x *MetaKeySpec) String() string { func (*MetaKeySpec) ProtoMessage() {} func (x *MetaKeySpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -711,7 +767,7 @@ func (x *MetaKeySpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MetaKeySpec.ProtoReflect.Descriptor instead. func (*MetaKeySpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{12} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{13} } func (x *MetaKeySpec) GetValue() string { @@ -733,7 +789,7 @@ type MetaLoadedSpec struct { func (x *MetaLoadedSpec) Reset() { *x = MetaLoadedSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[13] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -746,7 +802,7 @@ func (x *MetaLoadedSpec) String() string { func (*MetaLoadedSpec) ProtoMessage() {} func (x *MetaLoadedSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[13] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -759,7 +815,7 @@ func (x *MetaLoadedSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MetaLoadedSpec.ProtoReflect.Descriptor instead. func (*MetaLoadedSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{13} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{14} } func (x *MetaLoadedSpec) GetDone() bool { @@ -786,7 +842,7 @@ type MountStatusSpec struct { func (x *MountStatusSpec) Reset() { *x = MountStatusSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[14] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -799,7 +855,7 @@ func (x *MountStatusSpec) String() string { func (*MountStatusSpec) ProtoMessage() {} func (x *MountStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[14] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -812,7 +868,7 @@ func (x *MountStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MountStatusSpec.ProtoReflect.Descriptor instead. func (*MountStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{14} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{15} } func (x *MountStatusSpec) GetSource() string { @@ -878,7 +934,7 @@ type PlatformMetadataSpec struct { func (x *PlatformMetadataSpec) Reset() { *x = PlatformMetadataSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[15] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -891,7 +947,7 @@ func (x *PlatformMetadataSpec) String() string { func (*PlatformMetadataSpec) ProtoMessage() {} func (x *PlatformMetadataSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[15] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -904,7 +960,7 @@ func (x *PlatformMetadataSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use PlatformMetadataSpec.ProtoReflect.Descriptor instead. func (*PlatformMetadataSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{15} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{16} } func (x *PlatformMetadataSpec) GetPlatform() string { @@ -991,7 +1047,7 @@ type SecurityStateSpec struct { func (x *SecurityStateSpec) Reset() { *x = SecurityStateSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[16] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1004,7 +1060,7 @@ func (x *SecurityStateSpec) String() string { func (*SecurityStateSpec) ProtoMessage() {} func (x *SecurityStateSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[16] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1017,7 +1073,7 @@ func (x *SecurityStateSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use SecurityStateSpec.ProtoReflect.Descriptor instead. func (*SecurityStateSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{16} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{17} } func (x *SecurityStateSpec) GetSecureBoot() bool { @@ -1053,7 +1109,7 @@ type UniqueMachineTokenSpec struct { func (x *UniqueMachineTokenSpec) Reset() { *x = UniqueMachineTokenSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[17] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1066,7 +1122,7 @@ func (x *UniqueMachineTokenSpec) String() string { func (*UniqueMachineTokenSpec) ProtoMessage() {} func (x *UniqueMachineTokenSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[17] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1079,7 +1135,7 @@ func (x *UniqueMachineTokenSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use UniqueMachineTokenSpec.ProtoReflect.Descriptor instead. func (*UniqueMachineTokenSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{17} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{18} } func (x *UniqueMachineTokenSpec) GetToken() string { @@ -1102,7 +1158,7 @@ type UnmetCondition struct { func (x *UnmetCondition) Reset() { *x = UnmetCondition{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[18] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1115,7 +1171,7 @@ func (x *UnmetCondition) String() string { func (*UnmetCondition) ProtoMessage() {} func (x *UnmetCondition) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[18] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1128,7 +1184,7 @@ func (x *UnmetCondition) ProtoReflect() protoreflect.Message { // Deprecated: Use UnmetCondition.ProtoReflect.Descriptor instead. func (*UnmetCondition) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{18} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{19} } func (x *UnmetCondition) GetName() string { @@ -1158,7 +1214,7 @@ type WatchdogTimerConfigSpec struct { func (x *WatchdogTimerConfigSpec) Reset() { *x = WatchdogTimerConfigSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[19] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1171,7 +1227,7 @@ func (x *WatchdogTimerConfigSpec) String() string { func (*WatchdogTimerConfigSpec) ProtoMessage() {} func (x *WatchdogTimerConfigSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[19] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1184,7 +1240,7 @@ func (x *WatchdogTimerConfigSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchdogTimerConfigSpec.ProtoReflect.Descriptor instead. func (*WatchdogTimerConfigSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{19} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{20} } func (x *WatchdogTimerConfigSpec) GetDevice() string { @@ -1215,7 +1271,7 @@ type WatchdogTimerStatusSpec struct { func (x *WatchdogTimerStatusSpec) Reset() { *x = WatchdogTimerStatusSpec{} if protoimpl.UnsafeEnabled { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[20] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1228,7 +1284,7 @@ func (x *WatchdogTimerStatusSpec) String() string { func (*WatchdogTimerStatusSpec) ProtoMessage() {} func (x *WatchdogTimerStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[20] + mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1241,7 +1297,7 @@ func (x *WatchdogTimerStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchdogTimerStatusSpec.ProtoReflect.Descriptor instead. func (*WatchdogTimerStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{20} + return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{21} } func (x *WatchdogTimerStatusSpec) GetDevice() string { @@ -1281,158 +1337,162 @@ var file_resource_definitions_runtime_runtime_proto_rawDesc = []byte{ 0x73, 0x2f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x29, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x22, 0x31, 0x0a, 0x13, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x53, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, - 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x55, 0x0a, 0x1a, 0x45, - 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, - 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, - 0x74, 0x68, 0x22, 0x94, 0x01, 0x0a, 0x1a, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, - 0x63, 0x12, 0x54, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x3e, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, - 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, - 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x6e, - 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x45, 0x0a, 0x20, 0x45, 0x78, 0x74, + 0x08, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x22, 0x44, 0x0a, 0x0e, 0x44, 0x69, 0x61, 0x67, + 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x31, + 0x0a, 0x13, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x22, 0x55, 0x0a, 0x1a, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x22, 0x94, 0x01, 0x0a, 0x1a, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, - 0x0c, 0x73, 0x70, 0x65, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0x4a, 0x0a, 0x14, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x50, 0x0a, 0x13, - 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x70, 0x65, 0x63, 0x53, - 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x67, 0x6e, - 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x6d, - 0x0a, 0x15, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x75, - 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0b, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x22, 0x44, 0x0a, - 0x11, 0x4b, 0x6d, 0x73, 0x67, 0x4c, 0x6f, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x2f, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x55, 0x52, 0x4c, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4b, 0x0a, 0x05, 0x73, 0x74, 0x61, - 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x52, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x4f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, + 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x54, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x61, 0x63, 0x68, - 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x13, 0x4d, 0x61, 0x63, 0x68, - 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x14, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, - 0x72, 0x65, 0x61, 0x64, 0x79, 0x12, 0x5d, 0x0a, 0x10, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x5f, 0x63, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x55, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x85, 0x01, 0x0a, 0x1c, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3e, 0x0a, 0x13, - 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x12, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, - 0x62, 0x6c, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x23, 0x0a, 0x0b, - 0x4d, 0x65, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x22, 0x24, 0x0a, 0x0e, 0x4d, 0x65, 0x74, 0x61, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x53, - 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x22, 0xd5, 0x01, 0x0a, 0x0f, 0x4d, 0x6f, 0x75, 0x6e, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, - 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x14, - 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x65, 0x6e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, - 0xbb, 0x02, 0x0a, 0x14, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x7a, 0x6f, 0x6e, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6e, 0x73, 0x22, 0xb2, 0x01, - 0x0a, 0x11, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x62, 0x6f, - 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, - 0x42, 0x6f, 0x6f, 0x74, 0x12, 0x3d, 0x0a, 0x1b, 0x75, 0x6b, 0x69, 0x5f, 0x73, 0x69, 0x67, 0x6e, - 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x75, 0x6b, 0x69, 0x53, 0x69, - 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x1b, 0x70, 0x63, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, - 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x70, 0x63, 0x72, 0x53, 0x69, 0x67, - 0x6e, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x22, 0x2e, 0x0a, 0x16, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4d, 0x61, 0x63, 0x68, - 0x69, 0x6e, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x22, 0x3c, 0x0a, 0x0e, 0x55, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, - 0x22, 0x66, 0x0a, 0x17, 0x57, 0x61, 0x74, 0x63, 0x68, 0x64, 0x6f, 0x67, 0x54, 0x69, 0x6d, 0x65, - 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xa6, 0x01, 0x0a, 0x17, 0x57, 0x61, 0x74, - 0x63, 0x68, 0x64, 0x6f, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x07, - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x66, 0x65, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, - 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, - 0x6c, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, - 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x73, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x20, 0x0a, + 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x22, + 0x45, 0x0a, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, + 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x70, 0x65, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x70, 0x65, 0x63, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x4a, 0x0a, 0x14, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x22, 0x50, 0x0a, 0x13, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x73, 0x22, 0x6d, 0x0a, 0x15, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x22, 0x44, 0x0a, 0x11, 0x4b, 0x6d, 0x73, 0x67, 0x4c, 0x6f, 0x67, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2f, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x55, 0x52, 0x4c, 0x52, 0x0c, 0x64, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x4d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x4b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, + 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, + 0x73, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x4f, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x8a, 0x01, + 0x0a, 0x13, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x12, 0x5d, 0x0a, 0x10, 0x75, + 0x6e, 0x6d, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x55, 0x6e, 0x6d, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x75, 0x6e, 0x6d, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x85, 0x01, 0x0a, 0x1c, 0x4d, + 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0e, 0x6c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x3e, 0x0a, 0x13, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x12, + 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x22, 0x23, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, + 0x63, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x24, 0x0a, 0x0e, 0x4d, 0x65, 0x74, 0x61, 0x4c, + 0x6f, 0x61, 0x64, 0x65, 0x64, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x6f, 0x6e, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x22, 0xd5, 0x01, + 0x0a, 0x0f, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, + 0x63, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, + 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x65, 0x64, 0x12, 0x31, 0x0a, 0x14, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x13, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0xbb, 0x02, 0x0a, 0x14, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, + 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, + 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, + 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x6f, + 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x12, 0x21, 0x0a, + 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6e, 0x73, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6e, 0x73, + 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6e, 0x73, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x44, 0x6e, 0x73, 0x22, 0xb2, 0x01, 0x0a, 0x11, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x63, + 0x75, 0x72, 0x65, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x6f, 0x6f, 0x74, 0x12, 0x3d, 0x0a, 0x1b, 0x75, 0x6b, + 0x69, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, + 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x18, 0x75, 0x6b, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x46, 0x69, + 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x1b, 0x70, 0x63, 0x72, + 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, + 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, + 0x70, 0x63, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, + 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x22, 0x2e, 0x0a, 0x16, 0x55, 0x6e, 0x69, 0x71, + 0x75, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x70, + 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3c, 0x0a, 0x0e, 0x55, 0x6e, 0x6d, 0x65, + 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x66, 0x0a, 0x17, 0x57, 0x61, 0x74, 0x63, 0x68, 0x64, + 0x6f, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, + 0x63, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xa6, + 0x01, 0x0a, 0x17, 0x57, 0x61, 0x74, 0x63, 0x68, 0x64, 0x6f, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x66, 0x65, 0x65, 0x64, 0x5f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x64, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73, + 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1447,44 +1507,45 @@ func file_resource_definitions_runtime_runtime_proto_rawDescGZIP() []byte { return file_resource_definitions_runtime_runtime_proto_rawDescData } -var file_resource_definitions_runtime_runtime_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_resource_definitions_runtime_runtime_proto_msgTypes = make([]protoimpl.MessageInfo, 22) var file_resource_definitions_runtime_runtime_proto_goTypes = []interface{}{ (*DevicesStatusSpec)(nil), // 0: talos.resource.definitions.runtime.DevicesStatusSpec - (*EventSinkConfigSpec)(nil), // 1: talos.resource.definitions.runtime.EventSinkConfigSpec - (*ExtensionServiceConfigFile)(nil), // 2: talos.resource.definitions.runtime.ExtensionServiceConfigFile - (*ExtensionServiceConfigSpec)(nil), // 3: talos.resource.definitions.runtime.ExtensionServiceConfigSpec - (*ExtensionServiceConfigStatusSpec)(nil), // 4: talos.resource.definitions.runtime.ExtensionServiceConfigStatusSpec - (*KernelModuleSpecSpec)(nil), // 5: talos.resource.definitions.runtime.KernelModuleSpecSpec - (*KernelParamSpecSpec)(nil), // 6: talos.resource.definitions.runtime.KernelParamSpecSpec - (*KernelParamStatusSpec)(nil), // 7: talos.resource.definitions.runtime.KernelParamStatusSpec - (*KmsgLogConfigSpec)(nil), // 8: talos.resource.definitions.runtime.KmsgLogConfigSpec - (*MachineStatusSpec)(nil), // 9: talos.resource.definitions.runtime.MachineStatusSpec - (*MachineStatusStatus)(nil), // 10: talos.resource.definitions.runtime.MachineStatusStatus - (*MaintenanceServiceConfigSpec)(nil), // 11: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec - (*MetaKeySpec)(nil), // 12: talos.resource.definitions.runtime.MetaKeySpec - (*MetaLoadedSpec)(nil), // 13: talos.resource.definitions.runtime.MetaLoadedSpec - (*MountStatusSpec)(nil), // 14: talos.resource.definitions.runtime.MountStatusSpec - (*PlatformMetadataSpec)(nil), // 15: talos.resource.definitions.runtime.PlatformMetadataSpec - (*SecurityStateSpec)(nil), // 16: talos.resource.definitions.runtime.SecurityStateSpec - (*UniqueMachineTokenSpec)(nil), // 17: talos.resource.definitions.runtime.UniqueMachineTokenSpec - (*UnmetCondition)(nil), // 18: talos.resource.definitions.runtime.UnmetCondition - (*WatchdogTimerConfigSpec)(nil), // 19: talos.resource.definitions.runtime.WatchdogTimerConfigSpec - (*WatchdogTimerStatusSpec)(nil), // 20: talos.resource.definitions.runtime.WatchdogTimerStatusSpec - (*common.URL)(nil), // 21: common.URL - (enums.RuntimeMachineStage)(0), // 22: talos.resource.definitions.enums.RuntimeMachineStage - (*common.NetIP)(nil), // 23: common.NetIP - (*durationpb.Duration)(nil), // 24: google.protobuf.Duration + (*DiagnosticSpec)(nil), // 1: talos.resource.definitions.runtime.DiagnosticSpec + (*EventSinkConfigSpec)(nil), // 2: talos.resource.definitions.runtime.EventSinkConfigSpec + (*ExtensionServiceConfigFile)(nil), // 3: talos.resource.definitions.runtime.ExtensionServiceConfigFile + (*ExtensionServiceConfigSpec)(nil), // 4: talos.resource.definitions.runtime.ExtensionServiceConfigSpec + (*ExtensionServiceConfigStatusSpec)(nil), // 5: talos.resource.definitions.runtime.ExtensionServiceConfigStatusSpec + (*KernelModuleSpecSpec)(nil), // 6: talos.resource.definitions.runtime.KernelModuleSpecSpec + (*KernelParamSpecSpec)(nil), // 7: talos.resource.definitions.runtime.KernelParamSpecSpec + (*KernelParamStatusSpec)(nil), // 8: talos.resource.definitions.runtime.KernelParamStatusSpec + (*KmsgLogConfigSpec)(nil), // 9: talos.resource.definitions.runtime.KmsgLogConfigSpec + (*MachineStatusSpec)(nil), // 10: talos.resource.definitions.runtime.MachineStatusSpec + (*MachineStatusStatus)(nil), // 11: talos.resource.definitions.runtime.MachineStatusStatus + (*MaintenanceServiceConfigSpec)(nil), // 12: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec + (*MetaKeySpec)(nil), // 13: talos.resource.definitions.runtime.MetaKeySpec + (*MetaLoadedSpec)(nil), // 14: talos.resource.definitions.runtime.MetaLoadedSpec + (*MountStatusSpec)(nil), // 15: talos.resource.definitions.runtime.MountStatusSpec + (*PlatformMetadataSpec)(nil), // 16: talos.resource.definitions.runtime.PlatformMetadataSpec + (*SecurityStateSpec)(nil), // 17: talos.resource.definitions.runtime.SecurityStateSpec + (*UniqueMachineTokenSpec)(nil), // 18: talos.resource.definitions.runtime.UniqueMachineTokenSpec + (*UnmetCondition)(nil), // 19: talos.resource.definitions.runtime.UnmetCondition + (*WatchdogTimerConfigSpec)(nil), // 20: talos.resource.definitions.runtime.WatchdogTimerConfigSpec + (*WatchdogTimerStatusSpec)(nil), // 21: talos.resource.definitions.runtime.WatchdogTimerStatusSpec + (*common.URL)(nil), // 22: common.URL + (enums.RuntimeMachineStage)(0), // 23: talos.resource.definitions.enums.RuntimeMachineStage + (*common.NetIP)(nil), // 24: common.NetIP + (*durationpb.Duration)(nil), // 25: google.protobuf.Duration } var file_resource_definitions_runtime_runtime_proto_depIdxs = []int32{ - 2, // 0: talos.resource.definitions.runtime.ExtensionServiceConfigSpec.files:type_name -> talos.resource.definitions.runtime.ExtensionServiceConfigFile - 21, // 1: talos.resource.definitions.runtime.KmsgLogConfigSpec.destinations:type_name -> common.URL - 22, // 2: talos.resource.definitions.runtime.MachineStatusSpec.stage:type_name -> talos.resource.definitions.enums.RuntimeMachineStage - 10, // 3: talos.resource.definitions.runtime.MachineStatusSpec.status:type_name -> talos.resource.definitions.runtime.MachineStatusStatus - 18, // 4: talos.resource.definitions.runtime.MachineStatusStatus.unmet_conditions:type_name -> talos.resource.definitions.runtime.UnmetCondition - 23, // 5: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec.reachable_addresses:type_name -> common.NetIP - 24, // 6: talos.resource.definitions.runtime.WatchdogTimerConfigSpec.timeout:type_name -> google.protobuf.Duration - 24, // 7: talos.resource.definitions.runtime.WatchdogTimerStatusSpec.timeout:type_name -> google.protobuf.Duration - 24, // 8: talos.resource.definitions.runtime.WatchdogTimerStatusSpec.feed_interval:type_name -> google.protobuf.Duration + 3, // 0: talos.resource.definitions.runtime.ExtensionServiceConfigSpec.files:type_name -> talos.resource.definitions.runtime.ExtensionServiceConfigFile + 22, // 1: talos.resource.definitions.runtime.KmsgLogConfigSpec.destinations:type_name -> common.URL + 23, // 2: talos.resource.definitions.runtime.MachineStatusSpec.stage:type_name -> talos.resource.definitions.enums.RuntimeMachineStage + 11, // 3: talos.resource.definitions.runtime.MachineStatusSpec.status:type_name -> talos.resource.definitions.runtime.MachineStatusStatus + 19, // 4: talos.resource.definitions.runtime.MachineStatusStatus.unmet_conditions:type_name -> talos.resource.definitions.runtime.UnmetCondition + 24, // 5: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec.reachable_addresses:type_name -> common.NetIP + 25, // 6: talos.resource.definitions.runtime.WatchdogTimerConfigSpec.timeout:type_name -> google.protobuf.Duration + 25, // 7: talos.resource.definitions.runtime.WatchdogTimerStatusSpec.timeout:type_name -> google.protobuf.Duration + 25, // 8: talos.resource.definitions.runtime.WatchdogTimerStatusSpec.feed_interval:type_name -> google.protobuf.Duration 9, // [9:9] is the sub-list for method output_type 9, // [9:9] is the sub-list for method input_type 9, // [9:9] is the sub-list for extension type_name @@ -1511,7 +1572,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EventSinkConfigSpec); i { + switch v := v.(*DiagnosticSpec); i { case 0: return &v.state case 1: @@ -1523,7 +1584,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExtensionServiceConfigFile); i { + switch v := v.(*EventSinkConfigSpec); i { case 0: return &v.state case 1: @@ -1535,7 +1596,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExtensionServiceConfigSpec); i { + switch v := v.(*ExtensionServiceConfigFile); i { case 0: return &v.state case 1: @@ -1547,7 +1608,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExtensionServiceConfigStatusSpec); i { + switch v := v.(*ExtensionServiceConfigSpec); i { case 0: return &v.state case 1: @@ -1559,7 +1620,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KernelModuleSpecSpec); i { + switch v := v.(*ExtensionServiceConfigStatusSpec); i { case 0: return &v.state case 1: @@ -1571,7 +1632,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KernelParamSpecSpec); i { + switch v := v.(*KernelModuleSpecSpec); i { case 0: return &v.state case 1: @@ -1583,7 +1644,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KernelParamStatusSpec); i { + switch v := v.(*KernelParamSpecSpec); i { case 0: return &v.state case 1: @@ -1595,7 +1656,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KmsgLogConfigSpec); i { + switch v := v.(*KernelParamStatusSpec); i { case 0: return &v.state case 1: @@ -1607,7 +1668,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MachineStatusSpec); i { + switch v := v.(*KmsgLogConfigSpec); i { case 0: return &v.state case 1: @@ -1619,7 +1680,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MachineStatusStatus); i { + switch v := v.(*MachineStatusSpec); i { case 0: return &v.state case 1: @@ -1631,7 +1692,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MaintenanceServiceConfigSpec); i { + switch v := v.(*MachineStatusStatus); i { case 0: return &v.state case 1: @@ -1643,7 +1704,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MetaKeySpec); i { + switch v := v.(*MaintenanceServiceConfigSpec); i { case 0: return &v.state case 1: @@ -1655,7 +1716,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MetaLoadedSpec); i { + switch v := v.(*MetaKeySpec); i { case 0: return &v.state case 1: @@ -1667,7 +1728,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MountStatusSpec); i { + switch v := v.(*MetaLoadedSpec); i { case 0: return &v.state case 1: @@ -1679,7 +1740,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlatformMetadataSpec); i { + switch v := v.(*MountStatusSpec); i { case 0: return &v.state case 1: @@ -1691,7 +1752,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecurityStateSpec); i { + switch v := v.(*PlatformMetadataSpec); i { case 0: return &v.state case 1: @@ -1703,7 +1764,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UniqueMachineTokenSpec); i { + switch v := v.(*SecurityStateSpec); i { case 0: return &v.state case 1: @@ -1715,7 +1776,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnmetCondition); i { + switch v := v.(*UniqueMachineTokenSpec); i { case 0: return &v.state case 1: @@ -1727,7 +1788,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WatchdogTimerConfigSpec); i { + switch v := v.(*UnmetCondition); i { case 0: return &v.state case 1: @@ -1739,6 +1800,18 @@ func file_resource_definitions_runtime_runtime_proto_init() { } } file_resource_definitions_runtime_runtime_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WatchdogTimerConfigSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_definitions_runtime_runtime_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WatchdogTimerStatusSpec); i { case 0: return &v.state @@ -1757,7 +1830,7 @@ func file_resource_definitions_runtime_runtime_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_resource_definitions_runtime_runtime_proto_rawDesc, NumEnums: 0, - NumMessages: 21, + NumMessages: 22, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/machinery/api/resource/definitions/runtime/runtime_vtproto.pb.go b/pkg/machinery/api/resource/definitions/runtime/runtime_vtproto.pb.go index 485d4355af..90275ca731 100644 --- a/pkg/machinery/api/resource/definitions/runtime/runtime_vtproto.pb.go +++ b/pkg/machinery/api/resource/definitions/runtime/runtime_vtproto.pb.go @@ -68,6 +68,55 @@ func (m *DevicesStatusSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *DiagnosticSpec) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DiagnosticSpec) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *DiagnosticSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Details) > 0 { + for iNdEx := len(m.Details) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Details[iNdEx]) + copy(dAtA[i:], m.Details[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Details[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Message) > 0 { + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *EventSinkConfigSpec) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -1167,6 +1216,26 @@ func (m *DevicesStatusSpec) SizeVT() (n int) { return n } +func (m *DiagnosticSpec) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Message) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Details) > 0 { + for _, s := range m.Details { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + func (m *EventSinkConfigSpec) SizeVT() (n int) { if m == nil { return 0 @@ -1654,6 +1723,121 @@ func (m *DevicesStatusSpec) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *DiagnosticSpec) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DiagnosticSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DiagnosticSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Details = append(m.Details, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *EventSinkConfigSpec) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/machinery/resources/runtime/deep_copy.generated.go b/pkg/machinery/resources/runtime/deep_copy.generated.go index 8a837f29a2..d7341f328b 100644 --- a/pkg/machinery/resources/runtime/deep_copy.generated.go +++ b/pkg/machinery/resources/runtime/deep_copy.generated.go @@ -2,7 +2,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -// Code generated by "deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type ExtensionServiceConfigSpec -type ExtensionServiceConfigStatusSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineResetSignalSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -type SecurityStateSpec -type MetaLoadedSpec -type UniqueMachineTokenSpec -type WatchdogTimerConfigSpec -type WatchdogTimerStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT. +// Code generated by "deep-copy -type DevicesStatusSpec -type DiagnosticSpec -type EventSinkConfigSpec -type ExtensionServiceConfigSpec -type ExtensionServiceConfigStatusSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineResetSignalSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -type SecurityStateSpec -type MetaLoadedSpec -type UniqueMachineTokenSpec -type WatchdogTimerConfigSpec -type WatchdogTimerStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT. package runtime @@ -17,6 +17,16 @@ func (o DevicesStatusSpec) DeepCopy() DevicesStatusSpec { return cp } +// DeepCopy generates a deep copy of DiagnosticSpec. +func (o DiagnosticSpec) DeepCopy() DiagnosticSpec { + var cp DiagnosticSpec = o + if o.Details != nil { + cp.Details = make([]string, len(o.Details)) + copy(cp.Details, o.Details) + } + return cp +} + // DeepCopy generates a deep copy of EventSinkConfigSpec. func (o EventSinkConfigSpec) DeepCopy() EventSinkConfigSpec { var cp EventSinkConfigSpec = o diff --git a/pkg/machinery/resources/runtime/diagnostic.go b/pkg/machinery/resources/runtime/diagnostic.go new file mode 100644 index 0000000000..62be781e27 --- /dev/null +++ b/pkg/machinery/resources/runtime/diagnostic.go @@ -0,0 +1,70 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package runtime + +import ( + "github.com/cosi-project/runtime/pkg/resource" + "github.com/cosi-project/runtime/pkg/resource/meta" + "github.com/cosi-project/runtime/pkg/resource/protobuf" + "github.com/cosi-project/runtime/pkg/resource/typed" + + "github.com/siderolabs/talos/pkg/machinery/proto" +) + +// DiagnosticType is type of Diagnostic resource. +const DiagnosticType = resource.Type("Diagnostics.runtime.talos.dev") + +// Diagnostic resource contains warnings produced by Talos Diagnostics. +type Diagnostic = typed.Resource[DiagnosticSpec, DiagnosticExtension] + +// DiagnosticSpec is the spec for devices status. +// +//gotagsrewrite:gen +type DiagnosticSpec struct { + // Short message describing the problem. + Message string `yaml:"message" protobuf:"1"` + // Details about the problem. + Details []string `yaml:"details" protobuf:"2"` +} + +// DocumentationURL returns the URL to the documentation for the warning. +func (spec *DiagnosticSpec) DocumentationURL(id string) string { + return "https://talos.dev/diagnostic/" + id +} + +// NewDiagnstic initializes a Diagnostic resource. +func NewDiagnstic(namespace resource.Namespace, id resource.ID) *Diagnostic { + return typed.NewResource[DiagnosticSpec, DiagnosticExtension]( + resource.NewMetadata(namespace, DiagnosticType, id, resource.VersionUndefined), + DiagnosticSpec{}, + ) +} + +// DiagnosticExtension is auxiliary resource data for Diagnostic. +type DiagnosticExtension struct{} + +// ResourceDefinition implements meta.ResourceDefinitionProvider interface. +func (DiagnosticExtension) ResourceDefinition() meta.ResourceDefinitionSpec { + return meta.ResourceDefinitionSpec{ + Type: DiagnosticType, + Aliases: []resource.Type{}, + DefaultNamespace: NamespaceName, + PrintColumns: []meta.PrintColumn{ + { + Name: "Message", + JSONPath: `{.message}`, + }, + }, + } +} + +func init() { + proto.RegisterDefaultTypes() + + err := protobuf.RegisterDynamic[DiagnosticSpec](DiagnosticType, &Diagnostic{}) + if err != nil { + panic(err) + } +} diff --git a/pkg/machinery/resources/runtime/runtime.go b/pkg/machinery/resources/runtime/runtime.go index 8916e210e6..3a2cd25517 100644 --- a/pkg/machinery/resources/runtime/runtime.go +++ b/pkg/machinery/resources/runtime/runtime.go @@ -10,7 +10,7 @@ import ( "github.com/siderolabs/talos/pkg/machinery/resources/v1alpha1" ) -//go:generate deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type ExtensionServiceConfigSpec -type ExtensionServiceConfigStatusSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineResetSignalSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -type SecurityStateSpec -type MetaLoadedSpec -type UniqueMachineTokenSpec -type WatchdogTimerConfigSpec -type WatchdogTimerStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go . +//go:generate deep-copy -type DevicesStatusSpec -type DiagnosticSpec -type EventSinkConfigSpec -type ExtensionServiceConfigSpec -type ExtensionServiceConfigStatusSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineResetSignalSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -type SecurityStateSpec -type MetaLoadedSpec -type UniqueMachineTokenSpec -type WatchdogTimerConfigSpec -type WatchdogTimerStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go . // NamespaceName contains configuration resources. const NamespaceName resource.Namespace = v1alpha1.NamespaceName diff --git a/pkg/machinery/resources/runtime/runtime_test.go b/pkg/machinery/resources/runtime/runtime_test.go index 1d246a43a4..505b98e7ea 100644 --- a/pkg/machinery/resources/runtime/runtime_test.go +++ b/pkg/machinery/resources/runtime/runtime_test.go @@ -26,6 +26,7 @@ func TestRegisterResource(t *testing.T) { for _, resource := range []meta.ResourceWithRD{ &runtime.DevicesStatus{}, + &runtime.Diagnostic{}, &runtime.EventSinkConfig{}, &runtime.ExtensionStatus{}, &runtime.KernelModuleSpec{}, diff --git a/website/content/v1.8/reference/api.md b/website/content/v1.8/reference/api.md index d2e6e7faa2..1047fecd4e 100644 --- a/website/content/v1.8/reference/api.md +++ b/website/content/v1.8/reference/api.md @@ -215,6 +215,7 @@ description: Talos gRPC API reference. - [resource/definitions/runtime/runtime.proto](#resource/definitions/runtime/runtime.proto) - [DevicesStatusSpec](#talos.resource.definitions.runtime.DevicesStatusSpec) + - [DiagnosticSpec](#talos.resource.definitions.runtime.DiagnosticSpec) - [EventSinkConfigSpec](#talos.resource.definitions.runtime.EventSinkConfigSpec) - [ExtensionServiceConfigFile](#talos.resource.definitions.runtime.ExtensionServiceConfigFile) - [ExtensionServiceConfigSpec](#talos.resource.definitions.runtime.ExtensionServiceConfigSpec) @@ -3957,6 +3958,22 @@ DevicesStatusSpec is the spec for devices status. + + +### DiagnosticSpec +DiagnosticSpec is the spec for devices status. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| message | [string](#string) | | | +| details | [string](#string) | repeated | | + + + + + + ### EventSinkConfigSpec diff --git a/website/layouts/index.netlify_redirect b/website/layouts/index.netlify_redirect index ad1c59a276..6fece3ecc7 100644 --- a/website/layouts/index.netlify_redirect +++ b/website/layouts/index.netlify_redirect @@ -10,3 +10,8 @@ {{ printf "%s %s %d" (cond (hasPrefix . "/") . (path.Join $p.RelPermalink ".." .)) (path.Clean $p.RelPermalink) ($p.Params.HTTPCode | default 301) }} {{- end }} {{- end }} + +# Diagnostic redirects + +/diagnostic/kubelet-csr /docs/{{ .Site.Params.url_latest_version }}/introduction/troubleshooting/#talos-complains-about-certificate-errors-on-kubelet-api 302 +/diagnostic/address-overlap /docs/{{ .Site.Params.url_latest_version }}/introduction/troubleshooting/#conflict-on-kubernetes-and-host-subnets 302