Artem Chernyshev 78544a8557
feat: restrict directories for included files in the cluster templates
By default only allow to include files from the same directory where the
template file lives.
This is to prevent malicious cluster templates that include something
like `/etc/passwd`.
Fixes: https://github.com/siderolabs/omni/issues/2590

Signed-off-by: Artem Chernyshev <artem.chernyshev@talos-systems.com>
2026-04-16 19:28:33 +03:00

66 lines
2.0 KiB
Go

// 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 models
import (
"fmt"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/hashicorp/go-multierror"
"github.com/siderolabs/omni/client/pkg/omni/resources/omni"
)
// KindControlPlane is ControlPlane model kind.
const KindControlPlane = "ControlPlane"
// ControlPlane describes Cluster controlplane nodes.
type ControlPlane struct {
MachineSet `yaml:",inline"`
}
// Validate the model.
func (controlplane *ControlPlane) Validate(opts ValidateOptions) error {
var multiErr error
if controlplane.Name != "" {
multiErr = multierror.Append(multiErr, fmt.Errorf("custom name is not allowed in the controlplane"))
}
if controlplane.BootstrapSpec != nil {
if controlplane.BootstrapSpec.ClusterUUID == "" {
multiErr = multierror.Append(multiErr, fmt.Errorf("clusterUUID is required in bootstrapSpec"))
}
if controlplane.BootstrapSpec.Snapshot == "" {
multiErr = multierror.Append(multiErr, fmt.Errorf("snapshot is required in bootstrapSpec"))
}
}
if controlplane.UpdateStrategy != nil {
multiErr = multierror.Append(multiErr, fmt.Errorf("updateStrategy is not allowed in the controlplane"))
}
if controlplane.DeleteStrategy != nil {
multiErr = multierror.Append(multiErr, fmt.Errorf("deleteStrategy is not allowed in the controlplane"))
}
multiErr = joinErrors(multiErr, controlplane.MachineSet.Validate(), controlplane.Machines.Validate(), controlplane.Patches.Validate(opts))
if multiErr != nil {
return fmt.Errorf("controlplane is invalid: %w", multiErr)
}
return nil
}
// Translate the model.
func (controlplane *ControlPlane) Translate(ctx TranslateContext) ([]resource.Resource, error) {
return controlplane.translate(ctx, omni.ControlPlanesIDSuffix, omni.LabelControlPlaneRole)
}
func init() {
register[ControlPlane](KindControlPlane)
}