Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add connection support #506

Merged
merged 16 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/01-powerpipe-pre-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
with:
repository: turbot/pipe-fittings
path: pipe-fittings
ref: v1.6.x

# this is required, check golangci-lint-action docs
- uses: actions/setup-go@v5
Expand Down Expand Up @@ -108,6 +109,7 @@ jobs:
- "params_and_args"
- "snapshot"
- "dashboard_parsing_validation"
- "database_precedence"
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout
Expand Down Expand Up @@ -555,6 +557,7 @@ jobs:
with:
repository: turbot/pipe-fittings
path: pipe-fittings
ref: v1.6.x

- name: Tag Release
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/02-powerpipe-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ jobs:
- "params_and_args"
- "snapshot"
- "dashboard_parsing_validation"
- "database_precedence"
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/10-test-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.54.1
version: v1.61.0
args: --timeout=10m
working-directory: powerpipe
1 change: 1 addition & 0 deletions .github/workflows/11-test-acceptance.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ jobs:
- "params_and_args"
- "snapshot"
- "dashboard_parsing_validation"
- "database_precedence"
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ require (
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.19.0
github.com/stevenle/topsort v0.2.0
github.com/stevenle/topsort v0.2.0 // indirect
github.com/turbot/go-kit v0.10.0-rc.0
github.com/turbot/pipe-fittings v1.5.4
github.com/turbot/steampipe-plugin-sdk/v5 v5.10.4
github.com/turbot/terraform-components v0.0.0-20231213122222-1f3526cab7a7 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/zclconf/go-cty v1.14.4
github.com/zclconf/go-cty v1.14.4 // indirect
github.com/zclconf/go-cty-yaml v1.0.3 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225
sigs.k8s.io/yaml v1.4.0 // indirect
Expand All @@ -38,6 +38,7 @@ require github.com/sethvargo/go-retry v0.3.0 // indirect
require (
github.com/Masterminds/sprig/v3 v3.2.3
github.com/didip/tollbooth/v7 v7.0.2
github.com/fsnotify/fsnotify v1.7.0
github.com/gin-contrib/gzip v1.0.1
github.com/gin-contrib/size v1.0.1
github.com/go-sql-driver/mysql v1.8.1
Expand Down Expand Up @@ -108,7 +109,6 @@ require (
github.com/eko/gocache/store/ristretto/v4 v4.2.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gertd/go-pluralize v0.2.1 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
Expand Down
5 changes: 2 additions & 3 deletions internal/cmd/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/spf13/viper"
"github.com/thediveo/enumflag/v2"
"github.com/turbot/go-kit/helpers"
"github.com/turbot/pipe-fittings/app_specific"
"github.com/turbot/pipe-fittings/cmdconfig"
"github.com/turbot/pipe-fittings/constants"
"github.com/turbot/pipe-fittings/contexthelpers"
Expand Down Expand Up @@ -58,7 +57,7 @@ func checkCmd[T controlinit.CheckTarget]() *cobra.Command {
builder.
AddCloudFlags().
AddModLocationFlag().
AddStringFlag(constants.ArgDatabase, app_specific.DefaultDatabase, "Turbot Pipes workspace database").
AddStringFlag(constants.ArgDatabase, "", "Turbot Pipes workspace database", cmdconfig.FlagOptions.Deprecated("use a variable or param")).
AddBoolFlag(constants.ArgHeader, true, "Include column headers for csv and table output").
AddBoolFlag(constants.ArgHelp, false, "Help for run command", cmdconfig.FlagOptions.WithShortHand("h")).
AddBoolFlag(constants.ArgInput, true, "Enable interactive prompts").
Expand Down Expand Up @@ -365,7 +364,7 @@ func validateCheckArgs(ctx context.Context) error {
return fmt.Errorf("only 1 of '--%s' and '--%s' may be set", constants.ArgWhere, constants.ArgTag)
}

return nil
return localcmdconfig.ValidateDatabaseArg()
}

func shouldPrintCheckTiming() bool {
Expand Down
5 changes: 2 additions & 3 deletions internal/cmd/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/spf13/viper"
"github.com/thediveo/enumflag/v2"
"github.com/turbot/go-kit/helpers"
"github.com/turbot/pipe-fittings/app_specific"
"github.com/turbot/pipe-fittings/cloud"
"github.com/turbot/pipe-fittings/cmdconfig"
"github.com/turbot/pipe-fittings/constants"
Expand Down Expand Up @@ -55,7 +54,7 @@ The current mod is the working directory, or the directory specified by the --mo
AddModLocationFlag().
AddStringArrayFlag(constants.ArgArg, nil, "Specify the value of a dashboard argument").
AddStringSliceFlag(constants.ArgExport, nil, "Export output to file, supported format: pps (snapshot)").
AddStringFlag(constants.ArgDatabase, app_specific.DefaultDatabase, "Turbot Pipes workspace database").
AddStringFlag(constants.ArgDatabase, "", "Turbot Pipes workspace database", cmdconfig.FlagOptions.Deprecated("use a variable or param")).
AddIntFlag(constants.ArgDatabaseQueryTimeout, localconstants.DatabaseDefaultQueryTimeout, "The query timeout").
AddBoolFlag(constants.ArgHelp, false, "Help for dashboard", cmdconfig.FlagOptions.WithShortHand("h")).
AddBoolFlag(constants.ArgInput, true, "Enable interactive prompts").
Expand Down Expand Up @@ -185,7 +184,7 @@ func validateDashboardArgs(ctx context.Context) error {
return fmt.Errorf("only one of --share or --snapshot may be set")
}

return nil
return localcmdconfig.ValidateDatabaseArg()
}

func displaySnapshot(snapshot *steampipeconfig.SteampipeSnapshot) {
Expand Down
17 changes: 15 additions & 2 deletions internal/cmd/mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/turbot/pipe-fittings/parse"
"github.com/turbot/pipe-fittings/plugin"
"github.com/turbot/pipe-fittings/utils"
localcmdconfig "github.com/turbot/powerpipe/internal/cmdconfig"
localconstants "github.com/turbot/powerpipe/internal/constants"
"github.com/turbot/powerpipe/internal/db_client"
"github.com/turbot/powerpipe/internal/display"
Expand Down Expand Up @@ -101,7 +102,7 @@ Examples:

cmdconfig.OnCmd(cmd).
AddBoolFlag(constants.ArgDryRun, false, "Show which mods would be installed/updated/uninstalled without modifying them").
AddStringFlag(constants.ArgDatabase, app_specific.DefaultDatabase, "Turbot Pipes workspace database").
AddStringFlag(constants.ArgDatabase, "", "Turbot Pipes workspace database", cmdconfig.FlagOptions.Deprecated("use a variable or param")).
AddBoolFlag(constants.ArgForce, false, "Install mods even if plugin/cli version requirements are not met (cannot be used with --dry-run)").
AddBoolFlag(constants.ArgHelp, false, "Help for install", cmdconfig.FlagOptions.WithShortHand("h")).
AddBoolFlag(constants.ArgPrune, true, "Remove unused dependencies after installation is complete").
Expand All @@ -124,6 +125,8 @@ func runModInstallCmd(cmd *cobra.Command, args []string) {
}
}()

error_helpers.FailOnError(validateModArgs())

// try to load the workspace mod definition
// - if it does not exist, this will return a nil mod and a nil error
workspacePath := viper.GetString(constants.ArgModLocation)
Expand Down Expand Up @@ -155,8 +158,18 @@ func runModInstallCmd(cmd *cobra.Command, args []string) {
fmt.Println(summary) //nolint:forbidigo // intended output
}

func validateModArgs() error {
return localcmdconfig.ValidateDatabaseArg()
}

func getPluginVersions(ctx context.Context) *plugin.PluginVersionMap {
defaultDatabase, _ := db_client.GetDefaultDatabaseConfig()
defaultDatabase, _, err := db_client.GetDefaultDatabaseConfig()
if err != nil {
if !viper.GetBool(constants.ArgForce) {
error_helpers.ShowWarning("Could not connect to database - plugin validation will not be performed")
}
return nil
}

client, err := db_client.NewDbClient(ctx, defaultDatabase)
if err != nil {
Expand Down
5 changes: 2 additions & 3 deletions internal/cmd/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"github.com/spf13/viper"
"github.com/thediveo/enumflag/v2"
"github.com/turbot/go-kit/helpers"
"github.com/turbot/pipe-fittings/app_specific"
"github.com/turbot/pipe-fittings/cmdconfig"
"github.com/turbot/pipe-fittings/constants"
"github.com/turbot/pipe-fittings/error_helpers"
Expand Down Expand Up @@ -52,7 +51,7 @@ The current mod is the working directory, or the directory specified by the --mo
// NOTE: use StringArrayFlag for ArgQueryInput, not StringSliceFlag
// Cobra will interpret values passed to a StringSliceFlag as CSV, where args passed to StringArrayFlag are not parsed and used raw
AddStringArrayFlag(constants.ArgArg, nil, "Specify the value of a query argument").
AddStringFlag(constants.ArgDatabase, app_specific.DefaultDatabase, "Turbot Pipes workspace database").
AddStringFlag(constants.ArgDatabase, "", "Turbot Pipes workspace database", cmdconfig.FlagOptions.Deprecated("use a variable or param")).
AddIntFlag(constants.ArgDatabaseQueryTimeout, localconstants.DatabaseDefaultQueryTimeout, "The query timeout").
AddStringSliceFlag(constants.ArgExport, nil, "Export output to file, supported formats: csv, html, json, md, nunit3, pps (snapshot), asff").
AddBoolFlag(constants.ArgHeader, true, "Include column headers for csv and table output").
Expand Down Expand Up @@ -197,7 +196,7 @@ func validateQueryArgs(ctx context.Context) error {
return fmt.Errorf("only one of --share or --snapshot may be set")
}

return nil
return localcmdconfig.ValidateDatabaseArg()
}

func queryExporters() []export.Exporter {
Expand Down
10 changes: 7 additions & 3 deletions internal/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/turbot/pipe-fittings/app_specific"
"github.com/turbot/pipe-fittings/cmdconfig"
"github.com/turbot/pipe-fittings/constants"
"github.com/turbot/pipe-fittings/error_helpers"
Expand Down Expand Up @@ -42,9 +41,9 @@ Powerpipe server runs in the foreground; Press Ctrl-C to exit.`,
AddIntFlag(constants.ArgPort, dashboardserver.DashboardServerDefaultPort, "Web server port").
AddBoolFlag(constants.ArgWatch, true, "Watch mod files for changes when running powerpipe server").
AddStringFlag(constants.ArgListen, string(dashboardserver.ListenTypeLocal), "Accept connections from local (localhost only) or network (all interfaces / IP addresses)").
AddStringSliceFlag(constants.ArgVariable, []string{}, "Specify the value of a variable. Multiple --var arguments may be passed.").
AddStringArrayFlag(constants.ArgVariable, []string{}, "Specify the value of a variable. Multiple --var arguments may be passed.").
AddStringFlag(constants.ArgVarFile, "", "Specify a .ppvar file containing variable values.").
AddStringFlag(constants.ArgDatabase, app_specific.DefaultDatabase, "Turbot Pipes workspace database").
AddStringFlag(constants.ArgDatabase, "", "Turbot Pipes workspace database", cmdconfig.FlagOptions.Deprecated("use a variable or param")).
AddIntFlag(constants.ArgDashboardTimeout, 0, "Set a the dashboard execution timeout")

return cmd
Expand All @@ -61,6 +60,7 @@ func runServerCmd(cmd *cobra.Command, _ []string) {
return
}

error_helpers.FailOnError(validateServerArgs())
// retrieve server params
serverPort := dashboardserver.ListenPort(viper.GetInt(constants.ArgPort))
error_helpers.FailOnError(serverPort.IsValid())
Expand Down Expand Up @@ -107,3 +107,7 @@ func runServerCmd(cmd *cobra.Command, _ []string) {

<-ctx.Done()
}

func validateServerArgs() error {
return localcmdconfig.ValidateDatabaseArg()
}
23 changes: 21 additions & 2 deletions internal/cmdconfig/app_specific.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ import (
"strings"

"github.com/Masterminds/semver/v3"
"github.com/hashicorp/hcl/v2"
"github.com/spf13/viper"
"github.com/turbot/go-kit/files"
"github.com/turbot/pipe-fittings/app_specific"
"github.com/turbot/pipe-fittings/app_specific_connection"
"github.com/turbot/pipe-fittings/cmdconfig"
"github.com/turbot/pipe-fittings/connection"
"github.com/turbot/pipe-fittings/constants"
"github.com/turbot/pipe-fittings/error_helpers"
"github.com/turbot/pipe-fittings/filepaths"
"github.com/turbot/pipe-fittings/utils"
)

// SetAppSpecificConstants sets app specific constants defined in pipe-fittings
Expand Down Expand Up @@ -46,8 +51,6 @@ func SetAppSpecificConstants() {

app_specific.DefaultVarsFileName = "powerpipe.ppvars"
app_specific.LegacyDefaultVarsFileName = "steampipe.spvars"
// default to local steampipe service
app_specific.DefaultDatabase = "postgres://[email protected]:9193/steampipe"

// extensions

Expand All @@ -70,4 +73,20 @@ func SetAppSpecificConstants() {
app_specific.VersionCheckHost = "hub.powerpipe.io"
app_specific.VersionCheckPath = "api/cli/version/latest"
app_specific.EnvProfile = "POWERPIPE_PROFILE"

// register supported connection types
registerConnections()
}

func registerConnections() {
app_specific_connection.RegisterConnections(
connection.NewSteampipePgConnection,
connection.NewPostgresConnection,
connection.NewSqliteConnection,
connection.NewDuckDbConnection,
)
// set default connections
var defaultSteampipeConnection = connection.NewSteampipePgConnection("default", hcl.Range{})
defaultSteampipeConnection.(*connection.SteampipePgConnection).ConnectionString = utils.ToStringPointer(constants.DefaultSteampipeConnectionString)
app_specific_connection.DefaultConnections["steampipe"] = defaultSteampipeConnection
}
22 changes: 20 additions & 2 deletions internal/cmdconfig/cmd_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/turbot/pipe-fittings/utils"
"github.com/turbot/pipe-fittings/workspace_profile"
"github.com/turbot/powerpipe/internal/logger"
"github.com/turbot/powerpipe/internal/powerpipeconfig"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
"github.com/turbot/steampipe-plugin-sdk/v5/sperr"
)
Expand Down Expand Up @@ -122,6 +123,13 @@ func initGlobalConfig() error_helpers.ErrorAndWarnings {

var cmd = viper.Get(constants.ConfigKeyActiveCommand).(*cobra.Command)

var config, ew = powerpipeconfig.LoadPowerpipeConfig(filepaths.EnsureConfigDir())
if ew.GetError() != nil {
return ew
}

powerpipeconfig.GlobalConfig = config

// set-up viper with defaults from the env and default workspace profile

cmdconfig.BootstrapViper(loader, cmd,
Expand All @@ -142,8 +150,9 @@ func initGlobalConfig() error_helpers.ErrorAndWarnings {
// if an explicit workspace profile was set, add to viper as highest precedence default
// NOTE: if install_dir/mod_location are set these will already have been passed to viper by BootstrapViper
// since the "ConfiguredProfile" is passed in through a cmdline flag, it will always take precedence
if loader.ConfiguredProfile != nil {
cmdconfig.SetDefaultsFromConfig(loader.ConfiguredProfile.ConfigMap(cmd))
wp := loader.ConfiguredProfile
if wp != nil {
cmdconfig.SetDefaultsFromConfig(wp.ConfigMap(cmd))
}

// now env vars have been processed, set filepaths.PipesInstallDir
Expand All @@ -157,6 +166,15 @@ func initGlobalConfig() error_helpers.ErrorAndWarnings {
return error_helpers.NewErrorsAndWarning(err)
}

// if the configured workspace is a cloud workspace, create cloud metadata and set the default connection
if wp != nil && wp.IsCloudWorkspace() {
defaultConnection, ew := wp.GetCloudMetadata()
if ew.GetError() != nil {
return ew
}
config.DefaultConnection = defaultConnection
}

// now validate all config values have appropriate values
return validateConfig()
}
Expand Down
30 changes: 30 additions & 0 deletions internal/cmdconfig/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmdconfig
import (
"context"
"fmt"
"github.com/turbot/pipe-fittings/connection"
"strings"

"github.com/spf13/viper"
Expand All @@ -11,8 +12,37 @@ import (
"github.com/turbot/pipe-fittings/constants"
"github.com/turbot/pipe-fittings/error_helpers"
"github.com/turbot/pipe-fittings/steampipeconfig"
"github.com/turbot/powerpipe/internal/powerpipeconfig"
)

// ValidateDatabaseArg validates the connection and database arg
// if both or neither are set, returns an error
// if connection is set, verify it is in the config and update the database arg with the connection string
func ValidateDatabaseArg() error {
databaseArg := viper.GetString(constants.ArgDatabase)
if databaseArg == "" {
return nil
}
if strings.HasPrefix(databaseArg, "connection.") {
conn, ok := powerpipeconfig.GlobalConfig.PipelingConnections[strings.TrimPrefix(databaseArg, "connection.")]
if !ok {
return fmt.Errorf("connection '%s' not found", databaseArg)
}

csp, ok := conn.(connection.ConnectionStringProvider)
if !ok {
// unexpected - all registered connections should implement this interface
return fmt.Errorf("connection '%s' does not implement connection.ConnectionStringProvider", databaseArg)
}
connectionString := csp.GetConnectionString()
powerpipeconfig.GlobalConfig.DefaultConnection = csp
// update viper Database arg with the connection string
viper.Set(constants.ArgDatabase, connectionString)
}

return nil
}

func ValidateSnapshotArgs(ctx context.Context) error {
// only 1 of 'share' and 'snapshot' may be set
share := viper.GetBool(constants.ArgShare)
Expand Down
1 change: 1 addition & 0 deletions internal/constants/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ package constants

const (
DatabaseDefaultQueryTimeout = 300
DefaultConnection = "connection.steampipe.default"
)
2 changes: 1 addition & 1 deletion internal/controlexecute/result_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ func (r *ResultGroup) addDimensionKeys(keys ...string) {
// onChildDone is a callback that gets called from the children of this result group when they are done
func (r *ResultGroup) onChildDone() {
newCount := atomic.AddUint32(&r.childrenComplete, 1)
totalCount := uint32(len(r.ControlRuns) + len(r.Groups))
totalCount := uint32(len(r.ControlRuns) + len(r.Groups)) //nolint:gosec // will not overflow
if newCount < totalCount {
// all children haven't finished execution yet
return
Expand Down
Loading
Loading