Files
steampipe/pkg/cmdconfig/validate.go
2025-11-11 17:29:59 +08:00

107 lines
3.1 KiB
Go

package cmdconfig
import (
"context"
"fmt"
"strings"
"github.com/spf13/viper"
filehelpers "github.com/turbot/go-kit/files"
pconstants "github.com/turbot/pipe-fittings/v2/constants"
"github.com/turbot/pipe-fittings/v2/pipes"
"github.com/turbot/pipe-fittings/v2/steampipeconfig"
"github.com/turbot/steampipe/v2/pkg/error_helpers"
)
func ValidateSnapshotArgs(ctx context.Context) error {
// only 1 of 'share' and 'snapshot' may be set
share := viper.GetBool(pconstants.ArgShare)
snapshot := viper.GetBool(pconstants.ArgSnapshot)
if share && snapshot {
return fmt.Errorf("only 1 of 'share' and 'snapshot' may be set")
}
// if neither share or snapshot are set, nothing more to do
if !share && !snapshot {
return nil
}
token := viper.GetString(pconstants.ArgPipesToken)
// determine whether snapshot location is a cloud workspace or a file location
// if a file location, check it exists
if err := validateSnapshotLocation(ctx, token); err != nil {
return err
}
// if workspace-database or snapshot-location are a cloud workspace handle, cloud token must be set
requireCloudToken := steampipeconfig.IsPipesWorkspaceIdentifier(viper.GetString(pconstants.ArgWorkspaceDatabase)) ||
steampipeconfig.IsPipesWorkspaceIdentifier(viper.GetString(pconstants.ArgSnapshotLocation))
// verify cloud token and workspace has been set
if requireCloudToken && token == "" {
return error_helpers.MissingCloudTokenError
}
// should never happen as there is a default set
if viper.GetString(pconstants.ArgPipesHost) == "" {
return fmt.Errorf("to share snapshots, cloud host must be set")
}
return validateSnapshotTags()
}
func validateSnapshotLocation(ctx context.Context, cloudToken string) error {
snapshotLocation := viper.GetString(pconstants.ArgSnapshotLocation)
// if snapshot location is not set, set to the users default
if snapshotLocation == "" {
if cloudToken == "" {
return error_helpers.MissingCloudTokenError
}
return setSnapshotLocationFromDefaultWorkspace(ctx, cloudToken)
}
// if it is NOT a workspace handle, assume it is a local file location:
// tildefy it and ensure it exists
if !steampipeconfig.IsPipesWorkspaceIdentifier(snapshotLocation) {
var err error
snapshotLocation, err = filehelpers.Tildefy(snapshotLocation)
if err != nil {
return err
}
// write back to viper
viperMutex.Lock()
viper.Set(pconstants.ArgSnapshotLocation, snapshotLocation)
viperMutex.Unlock()
if !filehelpers.DirectoryExists(snapshotLocation) {
return fmt.Errorf("snapshot location %s does not exist", snapshotLocation)
}
}
return nil
}
func setSnapshotLocationFromDefaultWorkspace(ctx context.Context, cloudToken string) error {
workspaceHandle, err := pipes.GetUserWorkspaceHandle(ctx, cloudToken)
if err != nil {
return err
}
viperMutex.Lock()
viper.Set(pconstants.ArgSnapshotLocation, workspaceHandle)
viperMutex.Unlock()
return nil
}
func validateSnapshotTags() error {
tags := viper.GetStringSlice(pconstants.ArgSnapshotTag)
for _, tagStr := range tags {
if len(strings.Split(tagStr, "=")) != 2 {
return fmt.Errorf("snapshot tags must be specified '--%s key=value'", pconstants.ArgSnapshotTag)
}
}
return nil
}