github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/cmdconfig/validate.go (about)

     1  package cmdconfig
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"github.com/spf13/viper"
     7  	filehelpers "github.com/turbot/go-kit/files"
     8  	"github.com/turbot/steampipe/pkg/cloud"
     9  	"github.com/turbot/steampipe/pkg/constants"
    10  	"github.com/turbot/steampipe/pkg/error_helpers"
    11  	"github.com/turbot/steampipe/pkg/steampipeconfig"
    12  	"strings"
    13  )
    14  
    15  func ValidateSnapshotArgs(ctx context.Context) error {
    16  	// only 1 of 'share' and 'snapshot' may be set
    17  	share := viper.GetBool(constants.ArgShare)
    18  	snapshot := viper.GetBool(constants.ArgSnapshot)
    19  	if share && snapshot {
    20  		return fmt.Errorf("only 1 of 'share' and 'snapshot' may be set")
    21  	}
    22  
    23  	// if neither share or snapshot are set, nothing more to do
    24  	if !share && !snapshot {
    25  		return nil
    26  	}
    27  
    28  	token := viper.GetString(constants.ArgPipesToken)
    29  
    30  	// determine whether snapshot location is a cloud workspace or a file location
    31  	// if a file location, check it exists
    32  	if err := validateSnapshotLocation(ctx, token); err != nil {
    33  		return err
    34  	}
    35  
    36  	// if workspace-database or snapshot-location are a cloud workspace handle, cloud token must be set
    37  	requireCloudToken := steampipeconfig.IsCloudWorkspaceIdentifier(viper.GetString(constants.ArgWorkspaceDatabase)) ||
    38  		steampipeconfig.IsCloudWorkspaceIdentifier(viper.GetString(constants.ArgSnapshotLocation))
    39  
    40  	// verify cloud token and workspace has been set
    41  	if requireCloudToken && token == "" {
    42  		return error_helpers.MissingCloudTokenError
    43  	}
    44  
    45  	// should never happen as there is a default set
    46  	if viper.GetString(constants.ArgPipesHost) == "" {
    47  		return fmt.Errorf("to share snapshots, cloud host must be set")
    48  	}
    49  
    50  	return validateSnapshotTags()
    51  }
    52  
    53  func validateSnapshotLocation(ctx context.Context, cloudToken string) error {
    54  	snapshotLocation := viper.GetString(constants.ArgSnapshotLocation)
    55  
    56  	// if snapshot location is not set, set to the users default
    57  	if snapshotLocation == "" {
    58  		if cloudToken == "" {
    59  			return error_helpers.MissingCloudTokenError
    60  		}
    61  		return setSnapshotLocationFromDefaultWorkspace(ctx, cloudToken)
    62  	}
    63  
    64  	// if it is NOT a workspace handle, assume it is a local file location:
    65  	// tildefy it and ensure it exists
    66  	if !steampipeconfig.IsCloudWorkspaceIdentifier(snapshotLocation) {
    67  		var err error
    68  		snapshotLocation, err = filehelpers.Tildefy(snapshotLocation)
    69  		if err != nil {
    70  			return err
    71  		}
    72  
    73  		// write back to viper
    74  		viper.Set(constants.ArgSnapshotLocation, snapshotLocation)
    75  
    76  		if !filehelpers.DirectoryExists(snapshotLocation) {
    77  			return fmt.Errorf("snapshot location %s does not exist", snapshotLocation)
    78  		}
    79  	}
    80  	return nil
    81  }
    82  
    83  func setSnapshotLocationFromDefaultWorkspace(ctx context.Context, cloudToken string) error {
    84  	workspaceHandle, err := cloud.GetUserWorkspaceHandle(ctx, cloudToken)
    85  	if err != nil {
    86  		return err
    87  	}
    88  
    89  	viper.Set(constants.ArgSnapshotLocation, workspaceHandle)
    90  	return nil
    91  }
    92  
    93  func validateSnapshotTags() error {
    94  	tags := viper.GetStringSlice(constants.ArgSnapshotTag)
    95  	for _, tagStr := range tags {
    96  		if len(strings.Split(tagStr, "=")) != 2 {
    97  			return fmt.Errorf("snapshot tags must be specified '--%s key=value'", constants.ArgSnapshotTag)
    98  		}
    99  	}
   100  	return nil
   101  }