mirror of
https://github.com/turbot/steampipe.git
synced 2025-12-19 18:12:43 -05:00
move stuff to pipe-fittings
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
putils "github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -13,6 +14,8 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/turbot/go-kit/helpers"
|
||||
perror_helpers "github.com/turbot/pipe-fittings/error_helpers"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller/versionfile"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/sperr"
|
||||
"github.com/turbot/steampipe/pkg/cmdconfig"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
@@ -22,7 +25,6 @@ import (
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/installationstate"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller/versionfile"
|
||||
"github.com/turbot/steampipe/pkg/plugin"
|
||||
"github.com/turbot/steampipe/pkg/statushooks"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig"
|
||||
@@ -260,7 +262,7 @@ func runPluginInstallCmd(cmd *cobra.Command, args []string) {
|
||||
|
||||
// get the list of plugins to install
|
||||
for imageRef := range steampipeconfig.GlobalConfig.Plugins {
|
||||
ref := ociinstaller.NewSteampipeImageRef(imageRef)
|
||||
ref := putils.NewImageRef(imageRef)
|
||||
plugins = append(plugins, ref.GetFriendlyName())
|
||||
}
|
||||
}
|
||||
@@ -285,11 +287,11 @@ func runPluginInstallCmd(cmd *cobra.Command, args []string) {
|
||||
installWaitGroup.Add(1)
|
||||
bar := createProgressBar(pluginName, progressBars)
|
||||
|
||||
ref := ociinstaller.NewSteampipeImageRef(pluginName)
|
||||
org, name, constraint := ref.GetOrgNameAndConstraint()
|
||||
ref := putils.NewImageRef(pluginName)
|
||||
org, name, constraint := ref.GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
orgAndName := fmt.Sprintf("%s/%s", org, name)
|
||||
var resolved plugin.ResolvedPluginVersion
|
||||
if ref.IsFromSteampipeHub() {
|
||||
if ref.IsFromTurbotHub(constants.SteampipeHubOCIBase) {
|
||||
rpv, err := plugin.GetLatestPluginVersionByConstraint(ctx, state.InstallationID, org, name, constraint)
|
||||
if err != nil || rpv == nil {
|
||||
report := &display.PluginInstallReport{
|
||||
@@ -442,8 +444,8 @@ func runPluginUpdateCmd(cmd *cobra.Command, args []string) {
|
||||
|
||||
if cmdconfig.Viper().GetBool(constants.ArgAll) {
|
||||
for k, v := range pluginVersions {
|
||||
ref := ociinstaller.NewSteampipeImageRef(k)
|
||||
org, name, constraint := ref.GetOrgNameAndConstraint()
|
||||
ref := putils.NewImageRef(k)
|
||||
org, name, constraint := ref.GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
key := fmt.Sprintf("%s/%s@%s", org, name, constraint)
|
||||
|
||||
plugins = append(plugins, key)
|
||||
@@ -452,7 +454,7 @@ func runPluginUpdateCmd(cmd *cobra.Command, args []string) {
|
||||
} else {
|
||||
// get the args and retrieve the installed versions
|
||||
for _, p := range plugins {
|
||||
ref := ociinstaller.NewSteampipeImageRef(p)
|
||||
ref := putils.NewImageRef(p)
|
||||
isExists, _ := plugin.Exists(ctx, p)
|
||||
if isExists {
|
||||
if strings.HasPrefix(ref.DisplayImageRef(), constants.SteampipeHubOCIBase) {
|
||||
@@ -596,7 +598,7 @@ func installPlugin(ctx context.Context, resolvedPlugin plugin.ResolvedPluginVers
|
||||
if err != nil {
|
||||
msg := ""
|
||||
// used to build data for the plugin install report to be used for display purposes
|
||||
_, name, constraint := ociinstaller.NewSteampipeImageRef(resolvedPlugin.GetVersionTag()).GetOrgNameAndConstraint()
|
||||
_, name, constraint := putils.NewImageRef(resolvedPlugin.GetVersionTag()).GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
if isPluginNotFoundErr(err) {
|
||||
exitCode = constants.ExitCodePluginNotFound
|
||||
msg = constants.InstallMessagePluginNotFound
|
||||
@@ -612,13 +614,13 @@ func installPlugin(ctx context.Context, resolvedPlugin plugin.ResolvedPluginVers
|
||||
}
|
||||
|
||||
// used to build data for the plugin install report to be used for display purposes
|
||||
org, name, _ := image.ImageRef.GetOrgNameAndConstraint()
|
||||
org, name, _ := image.ImageRef.GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
versionString := ""
|
||||
if image.Config.Plugin.Version != "" {
|
||||
versionString = " v" + image.Config.Plugin.Version
|
||||
}
|
||||
docURL := fmt.Sprintf("https://hub.steampipe.io/plugins/%s/%s", org, name)
|
||||
if !image.ImageRef.IsFromSteampipeHub() {
|
||||
if !image.ImageRef.IsFromTurbotHub(constants.SteampipeHubOCIBase) {
|
||||
docURL = fmt.Sprintf("https://%s/%s", org, name)
|
||||
}
|
||||
return &display.PluginInstallReport{
|
||||
@@ -679,7 +681,7 @@ func runPluginListCmd(cmd *cobra.Command, _ []string) {
|
||||
|
||||
}
|
||||
|
||||
func showPluginListOutput(pluginList []plugin.PluginListItem, failedPluginMap, missingPluginMap map[string][]*modconfig.Connection, res error_helpers.ErrorAndWarnings, outputFormat string) error {
|
||||
func showPluginListOutput(pluginList []plugin.PluginListItem, failedPluginMap, missingPluginMap map[string][]*modconfig.Connection, res perror_helpers.ErrorAndWarnings, outputFormat string) error {
|
||||
switch outputFormat {
|
||||
case "table":
|
||||
return showPluginListAsTable(pluginList, failedPluginMap, missingPluginMap, res)
|
||||
@@ -690,7 +692,7 @@ func showPluginListOutput(pluginList []plugin.PluginListItem, failedPluginMap, m
|
||||
}
|
||||
}
|
||||
|
||||
func showPluginListAsTable(pluginList []plugin.PluginListItem, failedPluginMap, missingPluginMap map[string][]*modconfig.Connection, res error_helpers.ErrorAndWarnings) error {
|
||||
func showPluginListAsTable(pluginList []plugin.PluginListItem, failedPluginMap, missingPluginMap map[string][]*modconfig.Connection, res perror_helpers.ErrorAndWarnings) error {
|
||||
headers := []string{"Installed", "Version", "Connections"}
|
||||
var rows [][]string
|
||||
// List installed plugins in a table
|
||||
@@ -740,7 +742,7 @@ func showPluginListAsTable(pluginList []plugin.PluginListItem, failedPluginMap,
|
||||
return nil
|
||||
}
|
||||
|
||||
func showPluginListAsJSON(pluginList []plugin.PluginListItem, failedPluginMap, missingPluginMap map[string][]*modconfig.Connection, res error_helpers.ErrorAndWarnings) error {
|
||||
func showPluginListAsJSON(pluginList []plugin.PluginListItem, failedPluginMap, missingPluginMap map[string][]*modconfig.Connection, res perror_helpers.ErrorAndWarnings) error {
|
||||
output := pluginJsonOutput{}
|
||||
|
||||
for _, item := range pluginList {
|
||||
@@ -841,7 +843,7 @@ func runPluginUninstallCmd(cmd *cobra.Command, args []string) {
|
||||
reports.Print()
|
||||
}
|
||||
|
||||
func getPluginList(ctx context.Context) (pluginList []plugin.PluginListItem, failedPluginMap, missingPluginMap map[string][]*modconfig.Connection, res error_helpers.ErrorAndWarnings) {
|
||||
func getPluginList(ctx context.Context) (pluginList []plugin.PluginListItem, failedPluginMap, missingPluginMap map[string][]*modconfig.Connection, res perror_helpers.ErrorAndWarnings) {
|
||||
statushooks.Show(ctx)
|
||||
defer statushooks.Done(ctx)
|
||||
|
||||
@@ -872,13 +874,13 @@ func getPluginList(ctx context.Context) (pluginList []plugin.PluginListItem, fai
|
||||
return pluginList, failedPluginMap, missingPluginMap, res
|
||||
}
|
||||
|
||||
func getPluginConnectionMap(ctx context.Context) (pluginConnectionMap, failedPluginMap, missingPluginMap map[string][]*modconfig.Connection, res error_helpers.ErrorAndWarnings) {
|
||||
func getPluginConnectionMap(ctx context.Context) (pluginConnectionMap, failedPluginMap, missingPluginMap map[string][]*modconfig.Connection, res perror_helpers.ErrorAndWarnings) {
|
||||
utils.LogTime("cmd.getPluginConnectionMap start")
|
||||
defer utils.LogTime("cmd.getPluginConnectionMap end")
|
||||
|
||||
statushooks.SetStatus(ctx, "Fetching connection map")
|
||||
|
||||
res = error_helpers.ErrorAndWarnings{}
|
||||
res = perror_helpers.ErrorAndWarnings{}
|
||||
|
||||
connectionStateMap, stateRes := getConnectionState(ctx)
|
||||
res.Merge(stateRes)
|
||||
@@ -910,7 +912,7 @@ func getPluginConnectionMap(ctx context.Context) (pluginConnectionMap, failedPlu
|
||||
}
|
||||
|
||||
// load the connection state, waiting until all connections are loaded
|
||||
func getConnectionState(ctx context.Context) (steampipeconfig.ConnectionStateMap, error_helpers.ErrorAndWarnings) {
|
||||
func getConnectionState(ctx context.Context) (steampipeconfig.ConnectionStateMap, perror_helpers.ErrorAndWarnings) {
|
||||
utils.LogTime("cmd.getConnectionState start")
|
||||
defer utils.LogTime("cmd.getConnectionState end")
|
||||
|
||||
|
||||
1
go.mod
1
go.mod
@@ -3,6 +3,7 @@ module github.com/turbot/steampipe
|
||||
go 1.22.4
|
||||
|
||||
replace (
|
||||
github.com/turbot/pipe-fittings => ../pipe-fittings
|
||||
github.com/c-bata/go-prompt => github.com/turbot/go-prompt v0.2.6-steampipe.0.0.20221028122246-eb118ec58d50
|
||||
github.com/docker/distribution => github.com/distribution/distribution v2.7.1+incompatible
|
||||
github.com/docker/docker => github.com/moby/moby v20.10.17+incompatible
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
error_helpers2 "github.com/turbot/pipe-fittings/error_helpers"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller/versionfile"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
@@ -27,7 +29,6 @@ import (
|
||||
"github.com/turbot/steampipe/pkg/constants/runtime"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/filepaths"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller/versionfile"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig"
|
||||
"github.com/turbot/steampipe/pkg/task"
|
||||
"github.com/turbot/steampipe/pkg/utils"
|
||||
@@ -130,7 +131,7 @@ func setMemoryLimit() {
|
||||
// task run is complete
|
||||
//
|
||||
// runScheduledTasks skips running tasks if this instance is the plugin manager
|
||||
func runScheduledTasks(ctx context.Context, cmd *cobra.Command, args []string, ew error_helpers.ErrorAndWarnings) chan struct{} {
|
||||
func runScheduledTasks(ctx context.Context, cmd *cobra.Command, args []string, ew error_helpers2.ErrorAndWarnings) chan struct{} {
|
||||
// skip running the task runner if this is the plugin manager
|
||||
// since it's supposed to be a daemon
|
||||
if task.IsPluginManagerCmd(cmd) {
|
||||
@@ -189,7 +190,7 @@ func envLogLevelSet() bool {
|
||||
}
|
||||
|
||||
// initGlobalConfig reads in config file and ENV variables if set.
|
||||
func initGlobalConfig() error_helpers.ErrorAndWarnings {
|
||||
func initGlobalConfig() error_helpers2.ErrorAndWarnings {
|
||||
utils.LogTime("cmdconfig.initGlobalConfig start")
|
||||
defer utils.LogTime("cmdconfig.initGlobalConfig end")
|
||||
|
||||
@@ -199,7 +200,7 @@ func initGlobalConfig() error_helpers.ErrorAndWarnings {
|
||||
// load workspace profile from the configured install dir
|
||||
loader, err := getWorkspaceProfileLoader(ctx)
|
||||
if err != nil {
|
||||
return error_helpers.NewErrorsAndWarning(err)
|
||||
return error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
// set global workspace profile
|
||||
@@ -208,7 +209,7 @@ func initGlobalConfig() error_helpers.ErrorAndWarnings {
|
||||
// set-up viper with defaults from the env and default workspace profile
|
||||
err = bootstrapViper(loader, cmd)
|
||||
if err != nil {
|
||||
return error_helpers.NewErrorsAndWarning(err)
|
||||
return error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
// set global containing the configured install dir (create directory if needed)
|
||||
@@ -263,8 +264,8 @@ func initGlobalConfig() error_helpers.ErrorAndWarnings {
|
||||
return loadConfigErrorsAndWarnings
|
||||
}
|
||||
|
||||
func handleDeprecations() error_helpers.ErrorAndWarnings {
|
||||
var ew = error_helpers.ErrorAndWarnings{}
|
||||
func handleDeprecations() error_helpers2.ErrorAndWarnings {
|
||||
var ew = error_helpers2.ErrorAndWarnings{}
|
||||
// if deprecated cloud-token or cloud-host is set, show a warning and copy the value to the new arg
|
||||
if viper.IsSet(constants.ArgCloudToken) {
|
||||
if viper.IsSet(constants.ArgPipesToken) {
|
||||
@@ -370,8 +371,8 @@ func getWorkspaceProfileLoader(ctx context.Context) (*steampipeconfig.WorkspaceP
|
||||
|
||||
// now validate config values have appropriate values
|
||||
// (currently validates telemetry)
|
||||
func validateConfig() error_helpers.ErrorAndWarnings {
|
||||
var res = error_helpers.ErrorAndWarnings{}
|
||||
func validateConfig() error_helpers2.ErrorAndWarnings {
|
||||
var res = error_helpers2.ErrorAndWarnings{}
|
||||
telemetry := viper.GetString(constants.ArgTelemetry)
|
||||
if !helpers.StringSliceContains(constants.TelemetryLevels, telemetry) {
|
||||
res.Error = sperr.New(`invalid value of 'telemetry' (%s), must be one of: %s`, telemetry, strings.Join(constants.TelemetryLevels, ", "))
|
||||
@@ -459,7 +460,7 @@ func ensureInstallDir() {
|
||||
}
|
||||
|
||||
// displayDeprecationWarnings shows the deprecated warnings in a formatted way
|
||||
func displayDeprecationWarnings(errorsAndWarnings error_helpers.ErrorAndWarnings) {
|
||||
func displayDeprecationWarnings(errorsAndWarnings error_helpers2.ErrorAndWarnings) {
|
||||
if len(errorsAndWarnings.Warnings) > 0 {
|
||||
fmt.Println(color.YellowString(fmt.Sprintf("\nDeprecation %s:", utils.Pluralize("warning", len(errorsAndWarnings.Warnings)))))
|
||||
for _, warning := range errorsAndWarnings.Warnings {
|
||||
|
||||
@@ -3,8 +3,8 @@ package connection
|
||||
import (
|
||||
"context"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/pluginmanager_service/grpc/shared"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ package connection
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
error_helpers2 "github.com/turbot/pipe-fittings/error_helpers"
|
||||
"log"
|
||||
"os"
|
||||
"slices"
|
||||
@@ -225,7 +226,7 @@ func (s *refreshConnectionState) updateRateLimiterDefinitions(ctx context.Contex
|
||||
if len(updatedPluginLimiters) > 0 {
|
||||
err := s.pluginManager.HandlePluginLimiterChanges(updatedPluginLimiters)
|
||||
if err != nil {
|
||||
s.pluginManager.SendPostgresErrorsAndWarningsNotification(ctx, error_helpers.NewErrorsAndWarning(err))
|
||||
s.pluginManager.SendPostgresErrorsAndWarningsNotification(ctx, error_helpers2.NewErrorsAndWarning(err))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -1,26 +1,12 @@
|
||||
package constants
|
||||
|
||||
import "github.com/turbot/go-kit/helpers"
|
||||
|
||||
var ModDataExtensions = []string{".sp"}
|
||||
var VariablesExtensions = []string{".spvars"}
|
||||
var AutoVariablesExtensions = []string{".auto.spvars"}
|
||||
|
||||
const (
|
||||
PluginExtension = ".plugin"
|
||||
ConfigExtension = ".spc"
|
||||
SqlExtension = ".sql"
|
||||
JsonExtension = ".json"
|
||||
TextExtension = ".txt"
|
||||
SnapshotExtension = ".sps"
|
||||
TokenExtension = ".tptt"
|
||||
LegacyTokenExtension = ".sptt"
|
||||
)
|
||||
|
||||
var YamlExtensions = []string{".yml", ".yaml"}
|
||||
|
||||
var ConnectionConfigExtensions = append(YamlExtensions, ConfigExtension, JsonExtension)
|
||||
|
||||
func IsYamlExtension(ext string) bool {
|
||||
return helpers.StringSliceContains(YamlExtensions, ext)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package db_common
|
||||
|
||||
import (
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
)
|
||||
|
||||
type AcquireSessionResult struct {
|
||||
|
||||
@@ -2,10 +2,10 @@ package db_common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
)
|
||||
|
||||
func ValidateClientCacheSettings(c Client) error_helpers.ErrorAndWarnings {
|
||||
|
||||
@@ -3,6 +3,7 @@ package db_local
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
"log"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/db/db_client"
|
||||
"github.com/turbot/steampipe/pkg/db/db_common"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
pb "github.com/turbot/steampipe/pkg/pluginmanager_service/grpc/proto"
|
||||
"github.com/turbot/steampipe/pkg/utils"
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
error_helpers2 "github.com/turbot/pipe-fittings/error_helpers"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -27,7 +28,7 @@ import (
|
||||
|
||||
// StartResult is a pseudoEnum for outcomes of StartNewInstance
|
||||
type StartResult struct {
|
||||
error_helpers.ErrorAndWarnings
|
||||
error_helpers2.ErrorAndWarnings
|
||||
Status StartDbStatus
|
||||
DbState *RunningDBInstanceInfo
|
||||
PluginManagerState *pluginmanager.State
|
||||
|
||||
@@ -2,12 +2,11 @@ package display
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
utils2 "github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
"github.com/turbot/steampipe/pkg/utils"
|
||||
)
|
||||
|
||||
type PluginInstallReports []*PluginInstallReport
|
||||
@@ -27,8 +26,8 @@ type PluginInstallReport struct {
|
||||
}
|
||||
|
||||
func (i *PluginInstallReport) skipString() string {
|
||||
ref := ociinstaller.NewSteampipeImageRef(i.Plugin)
|
||||
_, name, constraint := ref.GetOrgNameAndConstraint()
|
||||
ref := ociinstaller.NewImageRef(i.Plugin)
|
||||
_, name, constraint := ref.GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
|
||||
return fmt.Sprintf("Plugin: %s\nReason: %s", fmt.Sprintf("%s@%s", name, constraint), i.SkipReason)
|
||||
}
|
||||
@@ -123,7 +122,7 @@ func PrintInstallReports(reports PluginInstallReports, isUpdateReport bool) {
|
||||
if (len(installSkipReports)) > 0 {
|
||||
fmt.Printf(
|
||||
"\nSkipped the following %s:\n\n%s\n",
|
||||
utils.Pluralize("plugin", skipCount),
|
||||
utils2.Pluralize("plugin", skipCount),
|
||||
strings.Join(installSkipReports, "\n\n"),
|
||||
)
|
||||
}
|
||||
@@ -136,8 +135,8 @@ func PrintInstallReports(reports PluginInstallReports, isUpdateReport bool) {
|
||||
fmt.Println()
|
||||
fmt.Printf(
|
||||
"To install %s which %s not installed, please run %s\n",
|
||||
utils.Pluralize("plugin", len(canBeInstalled)),
|
||||
utils.Pluralize("is", len(canBeInstalled)),
|
||||
utils2.Pluralize("plugin", len(canBeInstalled)),
|
||||
utils2.Pluralize("is", len(canBeInstalled)),
|
||||
constants.Bold(fmt.Sprintf(
|
||||
"steampipe plugin install %s",
|
||||
strings.Join(pluginList, " "),
|
||||
@@ -153,8 +152,8 @@ func PrintInstallReports(reports PluginInstallReports, isUpdateReport bool) {
|
||||
fmt.Println()
|
||||
fmt.Printf(
|
||||
"To update %s %s: %s\nTo update all plugins: %s",
|
||||
utils.Pluralize("this", len(pluginList)),
|
||||
utils.Pluralize("plugin", len(pluginList)),
|
||||
utils2.Pluralize("this", len(pluginList)),
|
||||
utils2.Pluralize("plugin", len(pluginList)),
|
||||
constants.Bold(fmt.Sprintf("steampipe plugin update %s", strings.Join(pluginList, " "))),
|
||||
constants.Bold(fmt.Sprintln("steampipe plugin update --all")),
|
||||
)
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
package error_helpers
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/sperr"
|
||||
)
|
||||
|
||||
type ErrorAndWarnings struct {
|
||||
Error error
|
||||
Warnings []string
|
||||
}
|
||||
|
||||
func DiagsToErrorsAndWarnings(errPrefix string, diags hcl.Diagnostics) ErrorAndWarnings {
|
||||
return NewErrorsAndWarning(
|
||||
plugin.DiagsToError(errPrefix, diags),
|
||||
plugin.DiagsToWarnings(diags)...,
|
||||
)
|
||||
}
|
||||
|
||||
func EmptyErrorsAndWarning() ErrorAndWarnings {
|
||||
return NewErrorsAndWarning(nil)
|
||||
}
|
||||
|
||||
func NewErrorsAndWarning(err error, warnings ...string) ErrorAndWarnings {
|
||||
return ErrorAndWarnings{
|
||||
Error: err, Warnings: warnings,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ErrorAndWarnings) WrapErrorWithMessage(msg string) ErrorAndWarnings {
|
||||
if r.Error != nil {
|
||||
r.Error = sperr.WrapWithMessage(r.Error, msg)
|
||||
}
|
||||
return *r
|
||||
}
|
||||
|
||||
func (r *ErrorAndWarnings) AddWarning(warnings ...string) {
|
||||
// avoid duplicates
|
||||
for _, w := range warnings {
|
||||
if !r.hasWarning(w) {
|
||||
r.Warnings = append(r.Warnings, w)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *ErrorAndWarnings) ShowWarnings() {
|
||||
for _, w := range r.Warnings {
|
||||
ShowWarning(w)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ErrorAndWarnings) GetError() error {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
return r.Error
|
||||
}
|
||||
|
||||
func (r *ErrorAndWarnings) Merge(other ErrorAndWarnings) ErrorAndWarnings {
|
||||
// TODO: Restructure ErrorsAndWarning
|
||||
// [issue](https://github.com/turbot/steampipe/issues/3845)
|
||||
if r.Error == nil {
|
||||
r.Error = other.Error
|
||||
}
|
||||
if len(other.Warnings) > 0 {
|
||||
r.AddWarning(other.Warnings...)
|
||||
}
|
||||
return *r
|
||||
}
|
||||
|
||||
func (r *ErrorAndWarnings) Empty() bool {
|
||||
return r.Error == nil && len(r.Warnings) == 0
|
||||
}
|
||||
|
||||
func (r *ErrorAndWarnings) hasWarning(w string) bool {
|
||||
for _, warning := range r.Warnings {
|
||||
if warning == w {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package filepaths
|
||||
|
||||
import "strings"
|
||||
|
||||
func PluginAliasToShortName(pluginName string) string {
|
||||
// remove prefix
|
||||
split := strings.Split(pluginName, "/")
|
||||
pluginName = split[len(split)-1]
|
||||
|
||||
if strings.HasPrefix(pluginName, "steampipe-plugin-") {
|
||||
return strings.TrimPrefix(pluginName, "steampipe-plugin-")
|
||||
}
|
||||
return pluginName
|
||||
}
|
||||
func PluginAliasToLongName(pluginName string) string {
|
||||
// remove prefix
|
||||
split := strings.Split(pluginName, "/")
|
||||
pluginName = split[len(split)-1]
|
||||
|
||||
if !strings.HasPrefix(pluginName, "steampipe-plugin-") {
|
||||
return "steampipe-plugin-" + pluginName
|
||||
}
|
||||
return pluginName
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package filepaths
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/sperr"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/utils"
|
||||
)
|
||||
|
||||
func GetPluginPath(pluginImageRef, pluginAlias string) (string, error) {
|
||||
// the fully qualified name of the plugin is the relative path of the folder containing the plugin
|
||||
// calculate absolute folder path
|
||||
pluginFolder := filepath.Join(EnsurePluginDir(), pluginImageRef)
|
||||
|
||||
// if the plugin folder is missing, it is possible the plugin path was truncated to create a schema name
|
||||
// - so search for a folder which when truncated would match the schema
|
||||
if _, err := os.Stat(pluginFolder); os.IsNotExist(err) {
|
||||
log.Printf("[TRACE] plugin path %s not found - searching for folder using hashed name\n", pluginFolder)
|
||||
if pluginFolder, err = FindPluginFolder(pluginImageRef); err != nil {
|
||||
return "", err
|
||||
} else if pluginFolder == "" {
|
||||
return "", fmt.Errorf("no plugin installed matching %s", pluginAlias)
|
||||
}
|
||||
}
|
||||
|
||||
// there should be just 1 file with extension pluginExtension (".plugin")
|
||||
entries, err := os.ReadDir(pluginFolder)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to load plugin %s: %v", pluginImageRef, err)
|
||||
}
|
||||
var matches []string
|
||||
for _, entry := range entries {
|
||||
if filepath.Ext(entry.Name()) == constants.PluginExtension {
|
||||
matches = append(matches, entry.Name())
|
||||
}
|
||||
}
|
||||
if len(matches) != 1 {
|
||||
return "", fmt.Errorf("plugin folder %s should contain a single plugin file. %d plugins were found ", pluginFolder, len(matches))
|
||||
}
|
||||
|
||||
return filepath.Join(pluginFolder, matches[0]), nil
|
||||
}
|
||||
|
||||
// FindPluginFolder searches for a folder which when hashed would match the schema
|
||||
func FindPluginFolder(remoteSchema string) (string, error) {
|
||||
pluginDir := EnsurePluginDir()
|
||||
|
||||
// first try searching by prefix - trim the schema name
|
||||
globPattern := filepath.Join(pluginDir, utils.TrimSchemaName(remoteSchema)) + "*"
|
||||
matches, err := filepath.Glob(globPattern)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// there was no match
|
||||
if len(matches) == 0 {
|
||||
return "", sperr.WrapWithMessage(os.ErrNotExist, "no plugin installed matching %s", remoteSchema)
|
||||
}
|
||||
|
||||
// we found a match
|
||||
if len(matches) == 1 {
|
||||
return matches[0], nil
|
||||
}
|
||||
|
||||
// when there are multiple matches,
|
||||
// find the first match which has the same hashed name as the schema
|
||||
for _, match := range matches {
|
||||
// get the relative path to this match from the plugin folder
|
||||
folderRelativePath, err := filepath.Rel(pluginDir, match)
|
||||
if err != nil {
|
||||
// do not fail on error here
|
||||
continue
|
||||
}
|
||||
hashedName := utils.PluginFQNToSchemaName(folderRelativePath)
|
||||
if hashedName == remoteSchema {
|
||||
return filepath.Join(pluginDir, folderRelativePath), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package filepaths
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
filepaths2 "github.com/turbot/pipe-fittings/filepaths"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@@ -76,7 +77,7 @@ func PluginInstallDir(pluginImageDisplayRef string) string {
|
||||
}
|
||||
|
||||
func PluginBinaryPath(pluginImageDisplayRef, pluginAlias string) string {
|
||||
return filepath.Join(PluginInstallDir(pluginImageDisplayRef), PluginAliasToLongName(pluginAlias)+".plugin")
|
||||
return filepath.Join(PluginInstallDir(pluginImageDisplayRef), filepaths2.PluginAliasToLongName(pluginAlias)+".plugin")
|
||||
}
|
||||
|
||||
// EnsureConfigDir returns the path to the config directory (creates if missing)
|
||||
|
||||
@@ -3,6 +3,7 @@ package initialisation
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
error_helpers2 "github.com/turbot/pipe-fittings/error_helpers"
|
||||
"log"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
@@ -189,11 +190,11 @@ func validateModRequirementsRecursively(mod *modconfig.Mod, pluginVersionMap map
|
||||
}
|
||||
|
||||
// GetDbClient either creates a DB client using the configured connection string (if present) or creates a LocalDbClient
|
||||
func GetDbClient(ctx context.Context, invoker constants.Invoker, onConnectionCallback db_client.DbConnectionCallback, opts ...db_client.ClientOption) (db_common.Client, error_helpers.ErrorAndWarnings) {
|
||||
func GetDbClient(ctx context.Context, invoker constants.Invoker, onConnectionCallback db_client.DbConnectionCallback, opts ...db_client.ClientOption) (db_common.Client, error_helpers2.ErrorAndWarnings) {
|
||||
if connectionString := viper.GetString(constants.ArgConnectionString); connectionString != "" {
|
||||
statushooks.SetStatus(ctx, "Connecting to remote Steampipe database")
|
||||
client, err := db_client.NewDbClient(ctx, connectionString, onConnectionCallback, opts...)
|
||||
return client, error_helpers.NewErrorsAndWarning(err)
|
||||
return client, error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
statushooks.SetStatus(ctx, "Starting local Steampipe database")
|
||||
|
||||
@@ -3,6 +3,7 @@ package ociinstaller
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"log"
|
||||
"path/filepath"
|
||||
|
||||
@@ -21,7 +22,7 @@ func InstallAssets(ctx context.Context, assetsLocation string) error {
|
||||
|
||||
// download the blobs
|
||||
imageDownloader := NewOciDownloader()
|
||||
image, err := imageDownloader.Download(ctx, NewSteampipeImageRef(constants.DashboardAssetsImageRef), ImageTypeAssets, tempDir.Path)
|
||||
image, err := imageDownloader.Download(ctx, ociinstaller.NewImageRef(constants.DashboardAssetsImageRef), ImageTypeAssets, tempDir.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package ociinstaller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"time"
|
||||
@@ -22,7 +23,7 @@ func InstallDB(ctx context.Context, dblocation string) (string, error) {
|
||||
imageDownloader := NewOciDownloader()
|
||||
|
||||
// Download the blobs
|
||||
image, err := imageDownloader.Download(ctx, NewSteampipeImageRef(constants.PostgresImageRef), ImageTypeDatabase, tempDir.Path)
|
||||
image, err := imageDownloader.Download(ctx, ociinstaller.NewImageRef(constants.PostgresImageRef), ImageTypeDatabase, tempDir.Path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -47,7 +48,7 @@ func updateVersionFileDB(image *SteampipeImage) error {
|
||||
v.EmbeddedDB.Version = image.Config.Database.Version
|
||||
v.EmbeddedDB.Name = "embeddedDB"
|
||||
v.EmbeddedDB.ImageDigest = string(image.OCIDescriptor.Digest)
|
||||
v.EmbeddedDB.InstalledFrom = image.ImageRef.requestedRef
|
||||
v.EmbeddedDB.InstalledFrom = image.ImageRef.RequestedRef
|
||||
v.EmbeddedDB.LastCheckedDate = timeNow
|
||||
v.EmbeddedDB.InstallDate = timeNow
|
||||
return v.Save()
|
||||
|
||||
@@ -3,6 +3,7 @@ package ociinstaller
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -25,7 +26,7 @@ func InstallFdw(ctx context.Context, dbLocation string) (string, error) {
|
||||
imageDownloader := NewOciDownloader()
|
||||
|
||||
// download the blobs.
|
||||
image, err := imageDownloader.Download(ctx, NewSteampipeImageRef(constants.FdwImageRef), ImageTypeFdw, tempDir.Path)
|
||||
image, err := imageDownloader.Download(ctx, ociinstaller.NewImageRef(constants.FdwImageRef), ImageTypeFdw, tempDir.Path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -51,7 +52,7 @@ func updateVersionFileFdw(image *SteampipeImage) error {
|
||||
v.FdwExtension.Version = image.Config.Fdw.Version
|
||||
v.FdwExtension.Name = "fdwExtension"
|
||||
v.FdwExtension.ImageDigest = string(image.OCIDescriptor.Digest)
|
||||
v.FdwExtension.InstalledFrom = image.ImageRef.requestedRef
|
||||
v.FdwExtension.InstalledFrom = image.ImageRef.RequestedRef
|
||||
v.FdwExtension.LastCheckedDate = timeNow
|
||||
v.FdwExtension.InstallDate = timeNow
|
||||
return v.Save()
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
package ociinstaller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultImageTag = "latest"
|
||||
DefaultImageRepoActualURL = "ghcr.io/turbot/steampipe"
|
||||
DefaultImageRepoDisplayURL = "hub.steampipe.io"
|
||||
|
||||
DefaultImageOrg = "turbot"
|
||||
DefaultImageType = "plugins"
|
||||
)
|
||||
|
||||
// SteampipeImageRef a struct encapsulating a ref to an OCI image
|
||||
type SteampipeImageRef struct {
|
||||
requestedRef string
|
||||
}
|
||||
|
||||
// NewSteampipeImageRef creates and returns a New SteampipeImageRef
|
||||
func NewSteampipeImageRef(ref string) *SteampipeImageRef {
|
||||
ref = sanitizeRefStream(ref)
|
||||
return &SteampipeImageRef{
|
||||
requestedRef: ref,
|
||||
}
|
||||
}
|
||||
|
||||
// ActualImageRef returns the actual, physical full image ref
|
||||
// (ghcr.io/turbot/steampipe/plugins/turbot/aws:1.0.0)
|
||||
func (r *SteampipeImageRef) ActualImageRef() string {
|
||||
ref := r.requestedRef
|
||||
|
||||
if !isDigestRef(ref) {
|
||||
ref = strings.ReplaceAll(ref, "@", ":")
|
||||
}
|
||||
|
||||
fullRef := getFullImageRef(ref)
|
||||
|
||||
if strings.HasPrefix(fullRef, DefaultImageRepoDisplayURL) {
|
||||
fullRef = strings.ReplaceAll(fullRef, DefaultImageRepoDisplayURL, DefaultImageRepoActualURL)
|
||||
}
|
||||
|
||||
return fullRef
|
||||
}
|
||||
|
||||
// DisplayImageRef returns the "friendly" user-facing full image ref
|
||||
// (hub.steampipe.io/plugins/turbot/aws@1.0.0)
|
||||
func (r *SteampipeImageRef) DisplayImageRef() string {
|
||||
fullRef := r.ActualImageRef()
|
||||
if isDigestRef(fullRef) {
|
||||
fullRef = strings.ReplaceAll(fullRef, ":", "-")
|
||||
}
|
||||
fullRef = strings.ReplaceAll(fullRef, ":", "@")
|
||||
|
||||
if strings.HasPrefix(fullRef, DefaultImageRepoActualURL) {
|
||||
fullRef = strings.ReplaceAll(fullRef, DefaultImageRepoActualURL, DefaultImageRepoDisplayURL)
|
||||
}
|
||||
|
||||
return fullRef
|
||||
}
|
||||
|
||||
// DisplayImageRefConstraintOverride returns a "friendly" user-facing version of the image ref
|
||||
// but with the version replaced by provided constraint
|
||||
// (hub.steampipe.io/plugins/turbot/aws@^1.0)
|
||||
func (r *SteampipeImageRef) DisplayImageRefConstraintOverride(constraint string) string {
|
||||
dir := r.DisplayImageRef()
|
||||
s := strings.Split(dir, "@")
|
||||
return fmt.Sprintf("%s@%s", s[0], constraint)
|
||||
}
|
||||
|
||||
func isDigestRef(ref string) bool {
|
||||
return strings.Contains(ref, "@sha256:")
|
||||
}
|
||||
|
||||
// sanitizes the ref to exclude any 'v' prefix
|
||||
// in the stream (if any)
|
||||
func sanitizeRefStream(ref string) string {
|
||||
if !isDigestRef(ref) {
|
||||
splitByAt := strings.Split(ref, "@")
|
||||
if len(splitByAt) == 1 {
|
||||
// no stream mentioned
|
||||
return ref
|
||||
}
|
||||
// trim out the 'v' prefix
|
||||
splitByAt[1] = strings.TrimPrefix(splitByAt[1], "v")
|
||||
|
||||
ref = strings.Join(splitByAt, "@")
|
||||
}
|
||||
return ref
|
||||
}
|
||||
|
||||
func (r *SteampipeImageRef) IsFromSteampipeHub() bool {
|
||||
return strings.HasPrefix(r.DisplayImageRef(), constants.SteampipeHubOCIBase)
|
||||
}
|
||||
|
||||
// GetOrgNameAndConstraint splits the full image reference into (org, name, constraint)
|
||||
// Constraint will be either a SemVer version (1.2.3) or a SemVer constraint (^0.4)
|
||||
func (r *SteampipeImageRef) GetOrgNameAndConstraint() (string, string, string) {
|
||||
// plugin.Name looks like `hub.steampipe.io/plugins/turbot/aws@latest`
|
||||
split := strings.Split(r.DisplayImageRef(), "/")
|
||||
pluginNameAndSuffix := strings.Split(split[len(split)-1], "@")
|
||||
if r.IsFromSteampipeHub() {
|
||||
return split[len(split)-2], pluginNameAndSuffix[0], pluginNameAndSuffix[1]
|
||||
}
|
||||
return strings.Join(split[0:len(split)-1], "/"), pluginNameAndSuffix[0], pluginNameAndSuffix[1]
|
||||
}
|
||||
|
||||
// GetFriendlyName returns the minimum friendly name so that the original name can be rebuilt using preset defaults:
|
||||
// hub.steampipe.io/plugins/turbot/aws@1.0.0 => aws@1.0.0
|
||||
// hub.steampipe.io/plugins/turbot/aws@latest => aws
|
||||
// hub.steampipe.io/plugins/otherOrg/aws@latest => otherOrg/aws
|
||||
// hub.steampipe.io/plugins/otherOrg/aws@1.0.0 => otherOrg/aws@1.0.0
|
||||
// differentRegistry.com/otherOrg/aws@latest => differentRegistry.com/otherOrg/aws@latest
|
||||
// differentRegistry.com/otherOrg/aws@1.0.0 => differentRegistry.com/otherOrg/aws@1.0.0
|
||||
func (r *SteampipeImageRef) GetFriendlyName() string {
|
||||
return getCondensedImageRef(r.DisplayImageRef())
|
||||
}
|
||||
|
||||
func getCondensedImageRef(imageRef string) string {
|
||||
// if this is not from the default steampipe registry - DO NOT CONDENSE - return as is
|
||||
// (we are not aware of any conventions in the registry)
|
||||
if !strings.HasPrefix(imageRef, DefaultImageRepoDisplayURL) {
|
||||
return imageRef
|
||||
}
|
||||
|
||||
// So this is an image reference from the Steampipe HUB registry
|
||||
// remove the registry URL
|
||||
ref := strings.TrimPrefix(imageRef, DefaultImageRepoDisplayURL)
|
||||
// remove the 'plugins' namespace where steampipe hub keeps the images
|
||||
ref = strings.TrimPrefix(ref, "/plugins/")
|
||||
// remove the default organization - "turbot"
|
||||
ref = strings.TrimPrefix(ref, DefaultImageOrg)
|
||||
// remove any leading '/'
|
||||
ref = strings.TrimPrefix(ref, "/")
|
||||
// remove the '@latest' tag (not others)
|
||||
ref = strings.TrimSuffix(ref, fmt.Sprintf("@%s", DefaultImageTag))
|
||||
|
||||
return ref
|
||||
}
|
||||
|
||||
// possible formats include
|
||||
// ghcr.io/turbot/steampipe/plugins/turbot/aws:1.0.0
|
||||
// ghcr.io/turbot/steampipe/plugins/turbot/aws@sha256:766389c9dd892132c7e7b9124f446b9599a80863d466cd1d333a167dedf2c2b1
|
||||
// turbot/aws:1.0.0
|
||||
// turbot/aws
|
||||
// dockerhub.org/myimage
|
||||
// dockerhub.org/myimage:mytag
|
||||
// aws:1.0.0
|
||||
// aws
|
||||
// ghcr.io/turbot/steampipe/plugins/turbot/aws@1.0.0
|
||||
// ghcr.io/turbot/steampipe/plugins/turbot/aws@sha256:766389c9dd892132c7e7b9124f446b9599a80863d466cd1d333a167dedf2c2b1
|
||||
// turbot/aws@1.0.0
|
||||
// dockerhub.org/myimage@mytag
|
||||
// aws@1.0.0
|
||||
// hub.steampipe.io/plugin/turbot/aws@1.0.0
|
||||
|
||||
func getFullImageRef(imagePath string) string {
|
||||
|
||||
tag := DefaultImageTag
|
||||
|
||||
// Get the tag, default to `latest`
|
||||
items := strings.Split(imagePath, ":")
|
||||
if len(items) > 1 {
|
||||
tag = items[1]
|
||||
}
|
||||
|
||||
// Image path
|
||||
parts := strings.Split(items[0], "/")
|
||||
switch len(parts) {
|
||||
case 1: //ex: aws
|
||||
return fmt.Sprintf("%s/%s/%s/%s:%s", DefaultImageRepoActualURL, DefaultImageType, DefaultImageOrg, parts[len(parts)-1], tag)
|
||||
case 2: //ex: turbot/aws OR dockerhub.com/my-image
|
||||
org := parts[len(parts)-2]
|
||||
if strings.Contains(org, ".") {
|
||||
return fmt.Sprintf("%s:%s", items[0], tag)
|
||||
}
|
||||
return fmt.Sprintf("%s/%s/%s/%s:%s", DefaultImageRepoActualURL, DefaultImageType, org, parts[len(parts)-1], tag)
|
||||
default: //ex: ghcr.io/turbot/steampipe/plugins/turbot/aws
|
||||
return fmt.Sprintf("%s:%s", items[0], tag)
|
||||
}
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
package ociinstaller
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFriendlyImageRef(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"hub.steampipe.io/plugins/turbot/aws@latest": "aws",
|
||||
"turbot/aws@latest": "aws",
|
||||
"aws@latest": "aws",
|
||||
"hub.steampipe.io/plugins/turbot/aws@1.0.0": "aws@1.0.0",
|
||||
"hub.steampipe.io/plugins/otherOrg/aws@latest": "otherOrg/aws",
|
||||
"otherOrg/aws@latest": "otherOrg/aws",
|
||||
"hub.steampipe.io/plugins/otherOrg/aws@1.0.0": "otherOrg/aws@1.0.0",
|
||||
"otherOrg/aws@1.0.0": "otherOrg/aws@1.0.0",
|
||||
"differentRegistry.com/otherOrg/aws@latest": "differentRegistry.com/otherOrg/aws@latest",
|
||||
"differentRegistry.com/otherOrg/aws@1.0.0": "differentRegistry.com/otherOrg/aws@1.0.0",
|
||||
}
|
||||
|
||||
for testCase, want := range cases {
|
||||
t.Run(testCase, func(t *testing.T) {
|
||||
r := NewSteampipeImageRef(testCase)
|
||||
|
||||
if got := r.GetFriendlyName(); got != want {
|
||||
t.Errorf("TestFriendlyImageRef failed for case '%s': expected %s, got %s", testCase, want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestActualImageRef(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"ghcr.io/turbot/steampipe/plugins/turbot/aws:1.0.0": "ghcr.io/turbot/steampipe/plugins/turbot/aws:1.0.0",
|
||||
"ghcr.io/turbot/steampipe/plugins/turbot/aws@sha256:766389c9dd892132c7e7b9124f446b9599a80863d466cd1d333a167dedf2c2b1": "ghcr.io/turbot/steampipe/plugins/turbot/aws@sha256:766389c9dd892132c7e7b9124f446b9599a80863d466cd1d333a167dedf2c2b1",
|
||||
"aws": "ghcr.io/turbot/steampipe/plugins/turbot/aws:latest",
|
||||
"aws:1": "ghcr.io/turbot/steampipe/plugins/turbot/aws:1",
|
||||
"turbot/aws:1": "ghcr.io/turbot/steampipe/plugins/turbot/aws:1",
|
||||
"turbot/aws:1.0": "ghcr.io/turbot/steampipe/plugins/turbot/aws:1.0",
|
||||
"turbot/aws:1.1.1": "ghcr.io/turbot/steampipe/plugins/turbot/aws:1.1.1",
|
||||
"turbot/aws": "ghcr.io/turbot/steampipe/plugins/turbot/aws:latest",
|
||||
"mycompany/my-plugin": "ghcr.io/turbot/steampipe/plugins/mycompany/my-plugin:latest",
|
||||
"mycompany/my-plugin:some-random_tag": "ghcr.io/turbot/steampipe/plugins/mycompany/my-plugin:some-random_tag",
|
||||
"dockerhub.org/myimage:mytag": "dockerhub.org/myimage:mytag",
|
||||
"ghcr.io/turbot/steampipe/plugins/turbot/aws:latest": "ghcr.io/turbot/steampipe/plugins/turbot/aws:latest",
|
||||
"hub.steampipe.io/plugins/turbot/aws:latest": "ghcr.io/turbot/steampipe/plugins/turbot/aws:latest",
|
||||
"hub.steampipe.io/plugins/someoneelse/myimage:mytag": "ghcr.io/turbot/steampipe/plugins/someoneelse/myimage:mytag",
|
||||
|
||||
"ghcr.io/turbot/steampipe/plugins/turbot/aws@1.0.0": "ghcr.io/turbot/steampipe/plugins/turbot/aws:1.0.0",
|
||||
"aws@1": "ghcr.io/turbot/steampipe/plugins/turbot/aws:1",
|
||||
"turbot/aws@1": "ghcr.io/turbot/steampipe/plugins/turbot/aws:1",
|
||||
"turbot/aws@1.0": "ghcr.io/turbot/steampipe/plugins/turbot/aws:1.0",
|
||||
"turbot/aws@1.1.1": "ghcr.io/turbot/steampipe/plugins/turbot/aws:1.1.1",
|
||||
"mycompany/my-plugin@some-random_tag": "ghcr.io/turbot/steampipe/plugins/mycompany/my-plugin:some-random_tag",
|
||||
"dockerhub.org/myimage@mytag": "dockerhub.org/myimage:mytag",
|
||||
"ghcr.io/turbot/steampipe/plugins/turbot/aws@latest": "ghcr.io/turbot/steampipe/plugins/turbot/aws:latest",
|
||||
"hub.steampipe.io/plugins/turbot/aws@latest": "ghcr.io/turbot/steampipe/plugins/turbot/aws:latest",
|
||||
"hub.steampipe.io/plugins/someoneelse/myimage@mytag": "ghcr.io/turbot/steampipe/plugins/someoneelse/myimage:mytag",
|
||||
}
|
||||
|
||||
for testCase, want := range cases {
|
||||
|
||||
t.Run(testCase, func(t *testing.T) {
|
||||
r := NewSteampipeImageRef(testCase)
|
||||
|
||||
if got := r.ActualImageRef(); got != want {
|
||||
t.Errorf("ActualImageRef failed for case '%s': expected %s, got %s", testCase, want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDisplayImageRef(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"ghcr.io/turbot/steampipe/plugins/turbot/aws:1.0.0": "hub.steampipe.io/plugins/turbot/aws@1.0.0",
|
||||
"ghcr.io/turbot/steampipe/plugins/turbot/aws@sha256:766389c9dd892132c7e7b9124f446b9599a80863d466cd1d333a167dedf2c2b1": "hub.steampipe.io/plugins/turbot/aws@sha256-766389c9dd892132c7e7b9124f446b9599a80863d466cd1d333a167dedf2c2b1",
|
||||
"aws": "hub.steampipe.io/plugins/turbot/aws@latest",
|
||||
"aws:1": "hub.steampipe.io/plugins/turbot/aws@1",
|
||||
"turbot/aws:1": "hub.steampipe.io/plugins/turbot/aws@1",
|
||||
"turbot/aws:1.0": "hub.steampipe.io/plugins/turbot/aws@1.0",
|
||||
"turbot/aws:1.1.1": "hub.steampipe.io/plugins/turbot/aws@1.1.1",
|
||||
"turbot/aws": "hub.steampipe.io/plugins/turbot/aws@latest",
|
||||
"mycompany/my-plugin": "hub.steampipe.io/plugins/mycompany/my-plugin@latest",
|
||||
"mycompany/my-plugin:some-random_tag": "hub.steampipe.io/plugins/mycompany/my-plugin@some-random_tag",
|
||||
"dockerhub.org/myimage:mytag": "dockerhub.org/myimage@mytag",
|
||||
"ghcr.io/turbot/steampipe/plugins/turbot/aws:latest": "hub.steampipe.io/plugins/turbot/aws@latest",
|
||||
"hub.steampipe.io/plugins/turbot/aws:latest": "hub.steampipe.io/plugins/turbot/aws@latest",
|
||||
"hub.steampipe.io/plugins/someoneelse/myimage:mytag": "hub.steampipe.io/plugins/someoneelse/myimage@mytag",
|
||||
|
||||
"ghcr.io/turbot/steampipe/plugins/turbot/aws@1.0.0": "hub.steampipe.io/plugins/turbot/aws@1.0.0",
|
||||
"aws@1": "hub.steampipe.io/plugins/turbot/aws@1",
|
||||
"turbot/aws@1": "hub.steampipe.io/plugins/turbot/aws@1",
|
||||
"turbot/aws@1.0": "hub.steampipe.io/plugins/turbot/aws@1.0",
|
||||
"turbot/aws@1.1.1": "hub.steampipe.io/plugins/turbot/aws@1.1.1",
|
||||
"mycompany/my-plugin@some-random_tag": "hub.steampipe.io/plugins/mycompany/my-plugin@some-random_tag",
|
||||
"dockerhub.org/myimage@mytag": "dockerhub.org/myimage@mytag",
|
||||
"ghcr.io/turbot/steampipe/plugins/turbot/aws@latest": "hub.steampipe.io/plugins/turbot/aws@latest",
|
||||
"hub.steampipe.io/plugins/turbot/aws@latest": "hub.steampipe.io/plugins/turbot/aws@latest",
|
||||
"hub.steampipe.io/plugins/someoneelse/myimage@mytag": "hub.steampipe.io/plugins/someoneelse/myimage@mytag",
|
||||
|
||||
"aws@v1": "hub.steampipe.io/plugins/turbot/aws@1",
|
||||
"turbot/aws@v1": "hub.steampipe.io/plugins/turbot/aws@1",
|
||||
"turbot/aws@v1.0": "hub.steampipe.io/plugins/turbot/aws@1.0",
|
||||
"turbot/aws@v1.1.1": "hub.steampipe.io/plugins/turbot/aws@1.1.1",
|
||||
}
|
||||
|
||||
for testCase, want := range cases {
|
||||
|
||||
t.Run(testCase, func(t *testing.T) {
|
||||
r := NewSteampipeImageRef(testCase)
|
||||
|
||||
if got := r.DisplayImageRef(); got != want {
|
||||
t.Errorf("DisplayImageRef failed for case '%s': expected %s, got %s", testCase, want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGetOrgNameAndConstraint(t *testing.T) {
|
||||
cases := map[string][3]string{
|
||||
"hub.steampipe.io/plugins/turbot/aws@latest": {"turbot", "aws", "latest"},
|
||||
"turbot/aws@latest": {"turbot", "aws", "latest"},
|
||||
"aws@latest": {"turbot", "aws", "latest"},
|
||||
"hub.steampipe.io/plugins/turbot/aws@1.0.0": {"turbot", "aws", "1.0.0"},
|
||||
"hub.steampipe.io/plugins/otherOrg/aws@latest": {"otherOrg", "aws", "latest"},
|
||||
"otherOrg/aws@latest": {"otherOrg", "aws", "latest"},
|
||||
"hub.steampipe.io/plugins/otherOrg/aws@1.0.0": {"otherOrg", "aws", "1.0.0"},
|
||||
"otherOrg/aws@1.0.0": {"otherOrg", "aws", "1.0.0"},
|
||||
"example.com/otherOrg/aws@latest": {"example.com/otherOrg", "aws", "latest"},
|
||||
"example.com/otherOrg/aws@1.0.0": {"example.com/otherOrg", "aws", "1.0.0"},
|
||||
}
|
||||
|
||||
for testCase, want := range cases {
|
||||
t.Run(testCase, func(t *testing.T) {
|
||||
r := NewSteampipeImageRef(testCase)
|
||||
org, name, constraint := r.GetOrgNameAndConstraint()
|
||||
got := [3]string{org, name, constraint}
|
||||
if got != want {
|
||||
t.Errorf("TestGetOrgNameAndSuffix failed for case '%s': expected %s, got %s", testCase, want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestIsFromSteampipeHub(t *testing.T) {
|
||||
cases := map[string]bool{
|
||||
"hub.steampipe.io/plugins/turbot/aws@latest": true,
|
||||
"turbot/aws@latest": true,
|
||||
"aws@latest": true,
|
||||
"hub.steampipe.io/plugins/turbot/aws@1.0.0": true,
|
||||
"hub.steampipe.io/plugins/otherOrg/aws@latest": true,
|
||||
"otherOrg/aws@latest": true,
|
||||
"hub.steampipe.io/plugins/otherOrg/aws@1.0.0": true,
|
||||
"otherOrg/aws@1.0.0": true,
|
||||
"example.com/otherOrg/aws@latest": false,
|
||||
"example.com/otherOrg/aws@1.0.0": false,
|
||||
}
|
||||
|
||||
for testCase, want := range cases {
|
||||
t.Run(testCase, func(t *testing.T) {
|
||||
r := NewSteampipeImageRef(testCase)
|
||||
got := r.IsFromSteampipeHub()
|
||||
if got != want {
|
||||
t.Errorf("TestIsFromSteampipeHub failed for case '%s': expected %t, got %t", testCase, want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
putils "github.com/turbot/pipe-fittings/ociinstaller"
|
||||
versionfile2 "github.com/turbot/pipe-fittings/ociinstaller/versionfile"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -35,7 +37,7 @@ func InstallPlugin(ctx context.Context, imageRef string, constraint string, sub
|
||||
}
|
||||
}()
|
||||
|
||||
ref := NewSteampipeImageRef(imageRef)
|
||||
ref := putils.NewImageRef(imageRef)
|
||||
imageDownloader := NewOciDownloader()
|
||||
|
||||
sub <- struct{}{}
|
||||
@@ -75,7 +77,7 @@ func updatePluginVersionFiles(ctx context.Context, image *SteampipeImage, constr
|
||||
defer versionFileUpdateLock.Unlock()
|
||||
|
||||
timeNow := versionfile.FormatTime(time.Now())
|
||||
v, err := versionfile.LoadPluginVersionFile(ctx)
|
||||
v, err := versionfile2.LoadPluginVersionFile(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -86,7 +88,7 @@ func updatePluginVersionFiles(ctx context.Context, image *SteampipeImage, constr
|
||||
|
||||
installedVersion, ok := v.Plugins[pluginFullName]
|
||||
if !ok {
|
||||
installedVersion = versionfile.EmptyInstalledVersion()
|
||||
installedVersion = versionfile2.EmptyInstalledVersion()
|
||||
}
|
||||
|
||||
installedVersion.Name = pluginFullName
|
||||
|
||||
@@ -3,6 +3,7 @@ package ociinstaller
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"github.com/turbot/steampipe/pkg/filepaths"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -10,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
type transformTest struct {
|
||||
ref *SteampipeImageRef
|
||||
ref *ociinstaller.ImageRef
|
||||
pluginLineContent []byte
|
||||
expectedTransformedPluginLineContent []byte
|
||||
}
|
||||
@@ -57,7 +58,7 @@ func TestAddPluginName(t *testing.T) {
|
||||
for name, test := range transformTests {
|
||||
sourcebytes := test.pluginLineContent
|
||||
expectedBytes := test.expectedTransformedPluginLineContent
|
||||
_, _, constraint := test.ref.GetOrgNameAndConstraint()
|
||||
_, _, constraint := test.ref.GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
transformed := bytes.TrimSpace(addPluginConstraintToConfig(sourcebytes, constraint))
|
||||
|
||||
if !bytes.Equal(transformed, expectedBytes) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
|
||||
type SteampipeImage struct {
|
||||
OCIDescriptor *ocispec.Descriptor
|
||||
ImageRef *SteampipeImageRef
|
||||
ImageRef *ociinstaller.ImageRef
|
||||
Config *config
|
||||
Plugin *PluginImage
|
||||
Database *DbImage
|
||||
@@ -65,7 +66,7 @@ const (
|
||||
ImageTypePlugin ImageType = "plugin"
|
||||
)
|
||||
|
||||
func (o *ociDownloader) Download(ctx context.Context, ref *SteampipeImageRef, imageType ImageType, destDir string) (*SteampipeImage, error) {
|
||||
func (o *ociDownloader) Download(ctx context.Context, ref *ociinstaller.ImageRef, imageType ImageType, destDir string) (*SteampipeImage, error) {
|
||||
var mediaTypes []string
|
||||
Image := o.newSteampipeImage()
|
||||
Image.ImageRef = ref
|
||||
|
||||
@@ -2,6 +2,7 @@ package versionfile
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
versionfile2 "github.com/turbot/pipe-fittings/ociinstaller/versionfile"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
@@ -13,15 +14,15 @@ import (
|
||||
const DatabaseStructVersion = 20220411
|
||||
|
||||
type DatabaseVersionFile struct {
|
||||
FdwExtension InstalledVersion `json:"fdw_extension"`
|
||||
EmbeddedDB InstalledVersion `json:"embedded_db"`
|
||||
StructVersion int64 `json:"struct_version"`
|
||||
FdwExtension versionfile2.InstalledVersion `json:"fdw_extension"`
|
||||
EmbeddedDB versionfile2.InstalledVersion `json:"embedded_db"`
|
||||
StructVersion int64 `json:"struct_version"`
|
||||
}
|
||||
|
||||
func NewDBVersionFile() *DatabaseVersionFile {
|
||||
return &DatabaseVersionFile{
|
||||
FdwExtension: InstalledVersion{},
|
||||
EmbeddedDB: InstalledVersion{},
|
||||
FdwExtension: versionfile2.InstalledVersion{},
|
||||
EmbeddedDB: versionfile2.InstalledVersion{},
|
||||
StructVersion: DatabaseStructVersion,
|
||||
}
|
||||
}
|
||||
@@ -48,12 +49,12 @@ func readDatabaseVersionFile(path string) (*DatabaseVersionFile, error) {
|
||||
log.Println("[ERROR]", "Error while reading DB version file", err)
|
||||
return nil, err
|
||||
}
|
||||
if data.FdwExtension == (InstalledVersion{}) {
|
||||
data.FdwExtension = InstalledVersion{}
|
||||
if data.FdwExtension == (versionfile2.InstalledVersion{}) {
|
||||
data.FdwExtension = versionfile2.InstalledVersion{}
|
||||
}
|
||||
|
||||
if data.EmbeddedDB == (InstalledVersion{}) {
|
||||
data.EmbeddedDB = InstalledVersion{}
|
||||
if data.EmbeddedDB == (versionfile2.InstalledVersion{}) {
|
||||
data.EmbeddedDB = versionfile2.InstalledVersion{}
|
||||
}
|
||||
|
||||
return &data, nil
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package versionfile
|
||||
|
||||
const InstalledVersionStructVersion = 20230502
|
||||
|
||||
type InstalledVersion struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
ImageDigest string `json:"image_digest,omitempty"`
|
||||
BinaryDigest string `json:"binary_digest,omitempty"`
|
||||
BinaryArchitecture string `json:"binary_arch,omitempty"`
|
||||
InstalledFrom string `json:"installed_from,omitempty"`
|
||||
LastCheckedDate string `json:"last_checked_date,omitempty"`
|
||||
InstallDate string `json:"install_date,omitempty"`
|
||||
StructVersion int64 `json:"struct_version"`
|
||||
}
|
||||
|
||||
func EmptyInstalledVersion() *InstalledVersion {
|
||||
i := new(InstalledVersion)
|
||||
i.StructVersion = InstalledVersionStructVersion
|
||||
return i
|
||||
}
|
||||
|
||||
// Equal compares the `Name` and `BinaryDigest`
|
||||
func (f *InstalledVersion) Equal(other *InstalledVersion) bool {
|
||||
return f.Name == other.Name && f.BinaryDigest == other.BinaryDigest
|
||||
}
|
||||
@@ -1,289 +0,0 @@
|
||||
package versionfile
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
filehelpers "github.com/turbot/go-kit/files"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/sperr"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/filepaths"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoContent = errors.New("no content")
|
||||
)
|
||||
|
||||
const (
|
||||
PluginStructVersion = 20220411
|
||||
// the name of the version files that are put in the plugin installation directories
|
||||
pluginVersionFileName = "version.json"
|
||||
)
|
||||
|
||||
type PluginVersionFile struct {
|
||||
Plugins map[string]*InstalledVersion `json:"plugins"`
|
||||
StructVersion int64 `json:"struct_version"`
|
||||
}
|
||||
|
||||
func newPluginVersionFile() *PluginVersionFile {
|
||||
return &PluginVersionFile{
|
||||
Plugins: map[string]*InstalledVersion{},
|
||||
StructVersion: PluginStructVersion,
|
||||
}
|
||||
}
|
||||
|
||||
// IsValid checks whether the struct was correctly deserialized,
|
||||
// by checking if the StructVersion is populated
|
||||
func (p *PluginVersionFile) IsValid() bool {
|
||||
return p.StructVersion > 0
|
||||
}
|
||||
|
||||
// EnsurePluginVersionFile reads the version file in the plugin directory (if exists) and overwrites it if the data in the
|
||||
// argument is different. The comparison is done using the `Name` and `BinaryDigest` properties.
|
||||
// If the file doesn't exist, or cannot be read/parsed, EnsurePluginVersionFile fails over to overwriting the data
|
||||
func (p *PluginVersionFile) EnsurePluginVersionFile(installData *InstalledVersion) error {
|
||||
pluginFolder, err := filepaths.FindPluginFolder(installData.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
versionFile := filepath.Join(pluginFolder, pluginVersionFileName)
|
||||
|
||||
// If the version file already exists, we only write to it if the incoming data is newer
|
||||
if filehelpers.FileExists(versionFile) {
|
||||
installation, err := readPluginVersionFile(versionFile)
|
||||
if err == nil && installation.Equal(installData) {
|
||||
// the new and old data match - no need to overwrite
|
||||
return nil
|
||||
}
|
||||
// in case of error, just failover to a overwrite
|
||||
}
|
||||
|
||||
theBytes, err := json.MarshalIndent(installData, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(versionFile, theBytes, 0644)
|
||||
}
|
||||
|
||||
// Save writes the config file to disk
|
||||
func (p *PluginVersionFile) Save() error {
|
||||
// set struct version
|
||||
p.StructVersion = PluginStructVersion
|
||||
versionFilePath := filepaths.PluginVersionFilePath()
|
||||
return p.write(versionFilePath)
|
||||
}
|
||||
|
||||
func (p *PluginVersionFile) write(path string) error {
|
||||
versionFileJSON, err := json.MarshalIndent(p, "", " ")
|
||||
if err != nil {
|
||||
log.Println("[ERROR]", "Error while writing version file", err)
|
||||
return err
|
||||
}
|
||||
if len(versionFileJSON) == 0 {
|
||||
log.Println("[ERROR]", "Cannot write 0 bytes to file")
|
||||
return sperr.WrapWithMessage(ErrNoContent, "cannot write versions file")
|
||||
}
|
||||
return os.WriteFile(path, versionFileJSON, 0644)
|
||||
}
|
||||
|
||||
func (p *PluginVersionFile) ensureVersionFilesInPluginDirectories() error {
|
||||
removals := []*InstalledVersion{}
|
||||
for _, installation := range p.Plugins {
|
||||
if err := p.EnsurePluginVersionFile(installation); err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
removals = append(removals, installation)
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// if we found any plugins that do not have installations, remove them from the map
|
||||
if len(removals) > 0 {
|
||||
for _, removal := range removals {
|
||||
delete(p.Plugins, removal.Name)
|
||||
}
|
||||
return p.Save()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// any plugins installed under the `local` folder are added to the plugin version file
|
||||
func (p *PluginVersionFile) AddLocalPlugins(ctx context.Context) error_helpers.ErrorAndWarnings {
|
||||
localPlugins, err := loadLocalPlugins(ctx)
|
||||
if err != nil {
|
||||
return error_helpers.NewErrorsAndWarning(err)
|
||||
}
|
||||
for name, install := range localPlugins {
|
||||
if _, ok := p.Plugins[name]; ok {
|
||||
// if the plugin is already in the global version file, skip it
|
||||
continue
|
||||
}
|
||||
p.Plugins[fmt.Sprintf("local/%s", name)] = install
|
||||
}
|
||||
return error_helpers.EmptyErrorsAndWarning()
|
||||
}
|
||||
|
||||
// to lock plugin version file loads
|
||||
var pluginLoadLock = sync.Mutex{}
|
||||
|
||||
// LoadPluginVersionFile migrates from the old version file format if necessary and loads the plugin version data
|
||||
func LoadPluginVersionFile(ctx context.Context) (*PluginVersionFile, error) {
|
||||
|
||||
// we need a lock here so that we don't hit a race condition where
|
||||
// the plugin file needs to be composed
|
||||
// if recomposition is not required, this has (almost) zero penalty
|
||||
pluginLoadLock.Lock()
|
||||
defer pluginLoadLock.Unlock()
|
||||
|
||||
versionFilePath := filepaths.PluginVersionFilePath()
|
||||
if filehelpers.FileExists(versionFilePath) {
|
||||
pluginVersions, err := readGlobalPluginVersionsFile(versionFilePath)
|
||||
|
||||
// we could read and parse out the file - all is well
|
||||
if err == nil {
|
||||
return pluginVersions, nil
|
||||
}
|
||||
}
|
||||
|
||||
// we don't have a global plugin/versions.json or it is not parseable or is empty (always recompose)
|
||||
// generate the version file from the individual version files by walking the plugin directories
|
||||
// this will return an Empty Version file if there are no version files in the plugin directories
|
||||
pluginVersions := recomposePluginVersionFile(ctx)
|
||||
|
||||
// save the recomposed file
|
||||
err := pluginVersions.Save()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pluginVersions, err
|
||||
}
|
||||
|
||||
func loadLocalPlugins(ctx context.Context) (map[string]*InstalledVersion, error) {
|
||||
localFolder := filepaths.LocalPluginPath()
|
||||
localPlugins := map[string]*InstalledVersion{}
|
||||
|
||||
// iterate over all folders underneath the local plugin directory and if the folder contains a plugin, add to the map
|
||||
pluginFolders, err := filehelpers.ListFilesWithContext(ctx, localFolder, &filehelpers.ListOptions{Flags: filehelpers.DirectoriesFlat})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, pluginFolder := range pluginFolders {
|
||||
// check if the folder contains a plugin file
|
||||
pluginName := filepath.Base(pluginFolder)
|
||||
|
||||
pluginShortName := filepaths.PluginAliasToShortName(pluginName)
|
||||
pluginLongName := filepaths.PluginAliasToLongName(pluginName)
|
||||
|
||||
pluginFiles := []string{
|
||||
pluginShortName + ".plugin",
|
||||
pluginLongName + ".plugin",
|
||||
}
|
||||
// check both short and long names
|
||||
|
||||
for _, pluginFile := range pluginFiles {
|
||||
pluginPath := filepath.Join(pluginFolder, pluginFile)
|
||||
if filehelpers.FileExists(pluginPath) {
|
||||
localPlugins[pluginName] = &InstalledVersion{
|
||||
Name: pluginPath,
|
||||
Version: "local",
|
||||
StructVersion: InstalledVersionStructVersion,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return localPlugins, nil
|
||||
}
|
||||
|
||||
// EnsureVersionFilesInPluginDirectories attempts a backfill of the individual version.json for plugins
|
||||
// this is required only once when upgrading from 0.20.x
|
||||
func EnsureVersionFilesInPluginDirectories(ctx context.Context) error {
|
||||
versions, err := LoadPluginVersionFile(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return versions.ensureVersionFilesInPluginDirectories()
|
||||
}
|
||||
|
||||
// recomposePluginVersionFile recursively traverses down the plugin direcory and tries to
|
||||
// recompose the global version file from the plugin version files
|
||||
// if there are no plugin version files, this returns a ready to use empty global version file
|
||||
func recomposePluginVersionFile(ctx context.Context) *PluginVersionFile {
|
||||
pvf := newPluginVersionFile()
|
||||
|
||||
versionFiles, err := filehelpers.ListFilesWithContext(ctx, filepaths.EnsurePluginDir(), &filehelpers.ListOptions{
|
||||
Include: []string{fmt.Sprintf("**/%s", pluginVersionFileName)},
|
||||
Flags: filehelpers.FilesRecursive,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Println("[TRACE] recomposePluginVersionFile failed - error while walking plugin directory for version files", err)
|
||||
return pvf
|
||||
}
|
||||
|
||||
for _, versionFile := range versionFiles {
|
||||
install, err := readPluginVersionFile(versionFile)
|
||||
if err != nil {
|
||||
log.Println("[TRACE] could not read file", versionFile)
|
||||
continue
|
||||
}
|
||||
pvf.Plugins[install.Name] = install
|
||||
}
|
||||
|
||||
return pvf
|
||||
}
|
||||
|
||||
func readPluginVersionFile(versionFile string) (*InstalledVersion, error) {
|
||||
data, err := os.ReadFile(versionFile)
|
||||
if err != nil {
|
||||
log.Println("[TRACE] could not read file", versionFile)
|
||||
return nil, err
|
||||
}
|
||||
install := EmptyInstalledVersion()
|
||||
if err := json.Unmarshal(data, &install); err != nil {
|
||||
// this wasn't the version file (probably) - keep going
|
||||
log.Println("[TRACE] unmarshal failed for file:", versionFile)
|
||||
return nil, err
|
||||
}
|
||||
return install, nil
|
||||
}
|
||||
|
||||
func readGlobalPluginVersionsFile(path string) (*PluginVersionFile, error) {
|
||||
file, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(file) == 0 {
|
||||
// the file exists, but is empty - return an error
|
||||
// start from scratch
|
||||
return nil, sperr.New("plugin versions.json file is empty")
|
||||
}
|
||||
|
||||
var data PluginVersionFile
|
||||
|
||||
if err := json.Unmarshal(file, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if data.Plugins == nil {
|
||||
data.Plugins = map[string]*InstalledVersion{}
|
||||
}
|
||||
|
||||
for key, installedPlugin := range data.Plugins {
|
||||
// hard code the name to the key
|
||||
installedPlugin.Name = key
|
||||
if installedPlugin.StructVersion == 0 {
|
||||
// also backfill the StructVersion in map values
|
||||
installedPlugin.StructVersion = InstalledVersionStructVersion
|
||||
}
|
||||
}
|
||||
|
||||
return &data, nil
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package versionfile
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestWrite(t *testing.T) {
|
||||
|
||||
var v PluginVersionFile
|
||||
|
||||
fileName := "test.json"
|
||||
timeNow := time.Now()
|
||||
timeNow2 := timeNow.Add(time.Minute * 10)
|
||||
v.Plugins = make(map[string]*(InstalledVersion))
|
||||
|
||||
awsPlugin := InstalledVersion{
|
||||
Name: "hub.steampipe.io/steampipe/plugin/turbot/aws@latest",
|
||||
Version: "0.0.3",
|
||||
ImageDigest: "88995cc15963225884b825b12409f798b24aa7364bbf35a83d3a5fb5db85f346",
|
||||
InstalledFrom: "hub.steampipe.io/steampipe/plugin/turbot/aws:latest",
|
||||
LastCheckedDate: timeNow2.Format(time.UnixDate),
|
||||
InstallDate: timeNow2.Format(time.UnixDate),
|
||||
}
|
||||
|
||||
v.Plugins[awsPlugin.Name] = &awsPlugin
|
||||
|
||||
googlePlugin := InstalledVersion{
|
||||
Name: "hub.steampipe.io/steampipe/plugin/turbot/google@1",
|
||||
Version: "1.0.7",
|
||||
ImageDigest: "3211232123654987313216549876516351",
|
||||
InstalledFrom: "hub.steampipe.io/steampipe/plugin/turbot/google:1",
|
||||
LastCheckedDate: timeNow2.Format(time.UnixDate),
|
||||
InstallDate: timeNow2.Format(time.UnixDate),
|
||||
}
|
||||
v.Plugins[googlePlugin.Name] = &googlePlugin
|
||||
if err := v.write(fileName); err != nil {
|
||||
t.Errorf("\nError writing file: %s", err.Error())
|
||||
}
|
||||
v2, err := readGlobalPluginVersionsFile(fileName)
|
||||
if err != nil {
|
||||
t.Errorf("\nError reading file: %s", err.Error())
|
||||
}
|
||||
|
||||
if len(v2.Plugins) != 2 {
|
||||
t.Errorf("\nexpected 2 plugins, found %d", len(v2.Plugins))
|
||||
}
|
||||
|
||||
os.Remove(fileName)
|
||||
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package plugin
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
ociinstaller2 "github.com/turbot/pipe-fittings/ociinstaller"
|
||||
versionfile2 "github.com/turbot/pipe-fittings/ociinstaller/versionfile"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -12,7 +14,6 @@ import (
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/sperr"
|
||||
"github.com/turbot/steampipe/pkg/filepaths"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller/versionfile"
|
||||
"github.com/turbot/steampipe/pkg/statushooks"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
@@ -22,7 +23,7 @@ import (
|
||||
func Remove(ctx context.Context, image string, pluginConnections map[string][]*modconfig.Connection) (*steampipeconfig.PluginRemoveReport, error) {
|
||||
statushooks.SetStatus(ctx, fmt.Sprintf("Removing plugin %s", image))
|
||||
|
||||
imageRef := ociinstaller.NewSteampipeImageRef(image)
|
||||
imageRef := ociinstaller2.NewImageRef(image)
|
||||
fullPluginName := imageRef.DisplayImageRef()
|
||||
|
||||
// are any connections using this plugin???
|
||||
@@ -40,7 +41,7 @@ func Remove(ctx context.Context, image string, pluginConnections map[string][]*m
|
||||
}
|
||||
|
||||
// update the version file
|
||||
v, err := versionfile.LoadPluginVersionFile(ctx)
|
||||
v, err := versionfile2.LoadPluginVersionFile(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -52,12 +53,12 @@ func Remove(ctx context.Context, image string, pluginConnections map[string][]*m
|
||||
|
||||
// Exists looks up the version file and reports whether a plugin is already installed
|
||||
func Exists(ctx context.Context, plugin string) (bool, error) {
|
||||
versionData, err := versionfile.LoadPluginVersionFile(ctx)
|
||||
versionData, err := versionfile2.LoadPluginVersionFile(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
imageRef := ociinstaller.NewSteampipeImageRef(plugin)
|
||||
imageRef := ociinstaller2.NewImageRef(plugin)
|
||||
|
||||
// lookup in the version data
|
||||
_, found := versionData.Plugins[imageRef.DisplayImageRef()]
|
||||
@@ -138,7 +139,7 @@ func List(ctx context.Context, pluginConnectionMap map[string][]*modconfig.Conne
|
||||
|
||||
// detectLocalPlugin returns true if the modTime of the `pluginBinary` is after the installation date as recorded in the installation data
|
||||
// this may happen when a plugin is installed from the registry, but is then compiled from source
|
||||
func detectLocalPlugin(installation *versionfile.InstalledVersion, pluginBinary string) bool {
|
||||
func detectLocalPlugin(installation *versionfile2.InstalledVersion, pluginBinary string) bool {
|
||||
installDate, err := time.Parse(time.RFC3339, installation.InstallDate)
|
||||
if err != nil {
|
||||
log.Printf("[WARN] could not parse install date for %s: %s", installation.Name, installation.InstallDate)
|
||||
|
||||
@@ -3,8 +3,9 @@ package plugin
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"github.com/turbot/pipe-fittings/utils"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
)
|
||||
|
||||
@@ -14,7 +15,7 @@ func GetInstalledPlugins(ctx context.Context) (map[string]*modconfig.PluginVersi
|
||||
installedPlugins := make(map[string]*modconfig.PluginVersionString)
|
||||
installedPluginsData, _ := List(ctx, nil)
|
||||
for _, plugin := range installedPluginsData {
|
||||
org, name, _ := ociinstaller.NewSteampipeImageRef(plugin.Name).GetOrgNameAndConstraint()
|
||||
org, name, _ := ociinstaller.NewImageRef(plugin.Name).GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
pluginShortName := fmt.Sprintf("%s/%s", org, name)
|
||||
installedPlugins[pluginShortName] = plugin.Version
|
||||
}
|
||||
|
||||
@@ -4,16 +4,17 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
utils2 "github.com/turbot/pipe-fittings/ociinstaller"
|
||||
versionfile2 "github.com/turbot/pipe-fittings/ociinstaller/versionfile"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"io"
|
||||
"log"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller/versionfile"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig"
|
||||
"github.com/turbot/steampipe/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -24,7 +25,7 @@ const (
|
||||
|
||||
// VersionCheckReport ::
|
||||
type VersionCheckReport struct {
|
||||
Plugin *versionfile.InstalledVersion
|
||||
Plugin *versionfile2.InstalledVersion
|
||||
CheckResponse versionCheckCorePayload
|
||||
CheckRequest versionCheckCorePayload
|
||||
}
|
||||
@@ -43,12 +44,12 @@ func (vr *VersionCheckReport) ShortNameWithConstraint() string {
|
||||
|
||||
// VersionChecker :: wrapper struct over the plugin version check utilities
|
||||
type VersionChecker struct {
|
||||
pluginsToCheck []*versionfile.InstalledVersion
|
||||
pluginsToCheck []*versionfile2.InstalledVersion
|
||||
signature string
|
||||
}
|
||||
|
||||
// GetUpdateReport looks up and reports the updated version of selective turbot plugins which are listed in versions.json
|
||||
func GetUpdateReport(ctx context.Context, installationID string, check []*versionfile.InstalledVersion) map[string]VersionCheckReport {
|
||||
func GetUpdateReport(ctx context.Context, installationID string, check []*versionfile2.InstalledVersion) map[string]VersionCheckReport {
|
||||
versionChecker := new(VersionChecker)
|
||||
versionChecker.signature = installationID
|
||||
|
||||
@@ -65,7 +66,7 @@ func GetUpdateReport(ctx context.Context, installationID string, check []*versio
|
||||
func GetAllUpdateReport(ctx context.Context, installationID string) map[string]VersionCheckReport {
|
||||
versionChecker := new(VersionChecker)
|
||||
versionChecker.signature = installationID
|
||||
versionChecker.pluginsToCheck = []*versionfile.InstalledVersion{}
|
||||
versionChecker.pluginsToCheck = []*versionfile2.InstalledVersion{}
|
||||
|
||||
// retrieve the plugin version data from steampipe config
|
||||
pluginVersions := steampipeconfig.GlobalConfig.PluginVersions
|
||||
@@ -81,7 +82,7 @@ func GetAllUpdateReport(ctx context.Context, installationID string) map[string]V
|
||||
|
||||
func (v *VersionChecker) reportPluginUpdates(ctx context.Context) map[string]VersionCheckReport {
|
||||
// retrieve the plugin version data from steampipe config
|
||||
versionFileData, err := versionfile.LoadPluginVersionFile(ctx)
|
||||
versionFileData, err := versionfile2.LoadPluginVersionFile(ctx)
|
||||
if err != nil {
|
||||
log.Printf("[TRACE] reportPluginUpdates could not load version file: %s", err.Error())
|
||||
return nil
|
||||
@@ -116,7 +117,7 @@ func (v *VersionChecker) reportPluginUpdates(ctx context.Context) map[string]Ver
|
||||
return reports
|
||||
}
|
||||
|
||||
func (v *VersionChecker) getLatestVersionsForPlugins(ctx context.Context, plugins []*versionfile.InstalledVersion) map[string]VersionCheckReport {
|
||||
func (v *VersionChecker) getLatestVersionsForPlugins(ctx context.Context, plugins []*versionfile2.InstalledVersion) map[string]VersionCheckReport {
|
||||
|
||||
var requestPayload []versionCheckCorePayload
|
||||
reports := map[string]VersionCheckReport{}
|
||||
@@ -148,9 +149,9 @@ func (v *VersionChecker) getLatestVersionsForPlugins(ctx context.Context, plugin
|
||||
return reports
|
||||
}
|
||||
|
||||
func (v *VersionChecker) getPayloadFromInstalledData(plugin *versionfile.InstalledVersion) versionCheckCorePayload {
|
||||
ref := ociinstaller.NewSteampipeImageRef(plugin.Name)
|
||||
org, name, constraint := ref.GetOrgNameAndConstraint()
|
||||
func (v *VersionChecker) getPayloadFromInstalledData(plugin *versionfile2.InstalledVersion) versionCheckCorePayload {
|
||||
ref := ociinstaller.NewImageRef(plugin.Name)
|
||||
org, name, constraint := ref.GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
payload := versionCheckCorePayload{
|
||||
Org: org,
|
||||
Name: name,
|
||||
@@ -172,11 +173,11 @@ func (v *VersionChecker) getVersionCheckURL() url.URL {
|
||||
func (v *VersionChecker) requestServerForLatest(ctx context.Context, payload []versionCheckCorePayload) ([]versionCheckCorePayload, error) {
|
||||
// Set a default timeout of 3 sec for the check request (in milliseconds)
|
||||
sendRequestTo := v.getVersionCheckURL()
|
||||
requestBody := utils.BuildRequestPayload(v.signature, map[string]interface{}{
|
||||
requestBody := utils2.BuildRequestPayload(v.signature, map[string]interface{}{
|
||||
"plugins": payload,
|
||||
})
|
||||
|
||||
resp, err := utils.SendRequest(ctx, v.signature, "POST", sendRequestTo, requestBody)
|
||||
resp, err := utils2.SendRequest(ctx, v.signature, "POST", sendRequestTo, requestBody)
|
||||
if err != nil {
|
||||
log.Printf("[TRACE] Could not send request")
|
||||
return nil, err
|
||||
|
||||
@@ -3,6 +3,7 @@ package pluginmanager_service
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/filepaths"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -26,7 +27,6 @@ import (
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/db/db_local"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/filepaths"
|
||||
"github.com/turbot/steampipe/pkg/pluginmanager_service/grpc"
|
||||
pb "github.com/turbot/steampipe/pkg/pluginmanager_service/grpc/proto"
|
||||
pluginshared "github.com/turbot/steampipe/pkg/pluginmanager_service/grpc/shared"
|
||||
|
||||
@@ -2,8 +2,8 @@ package pluginmanager_service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/db/db_local"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig"
|
||||
"log"
|
||||
)
|
||||
|
||||
@@ -3,6 +3,8 @@ package pluginmanager_service
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"github.com/turbot/pipe-fittings/utils"
|
||||
"log"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
@@ -14,7 +16,6 @@ import (
|
||||
"github.com/turbot/steampipe/pkg/db/db_common"
|
||||
"github.com/turbot/steampipe/pkg/db/db_local"
|
||||
"github.com/turbot/steampipe/pkg/introspection"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
pb "github.com/turbot/steampipe/pkg/pluginmanager_service/grpc/proto"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
"golang.org/x/exp/maps"
|
||||
@@ -111,7 +112,7 @@ func (m *PluginManager) handleUserLimiterChanges(_ context.Context, plugins conn
|
||||
|
||||
func (m *PluginManager) setRateLimitersForPlugin(pluginShortName string) error {
|
||||
// get running plugin for this plugin
|
||||
imageRef := ociinstaller.NewSteampipeImageRef(pluginShortName).DisplayImageRef()
|
||||
imageRef := ociinstaller.NewImageRef(pluginShortName).DisplayImageRef()
|
||||
|
||||
runningPlugin, ok := m.runningPluginMap[imageRef]
|
||||
if !ok {
|
||||
|
||||
@@ -2,7 +2,7 @@ package steampipeconfig
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@@ -14,13 +14,15 @@ import (
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
filehelpers "github.com/turbot/go-kit/files"
|
||||
"github.com/turbot/go-kit/helpers"
|
||||
pconstants "github.com/turbot/pipe-fittings/constants"
|
||||
perror_helpers "github.com/turbot/pipe-fittings/error_helpers"
|
||||
"github.com/turbot/pipe-fittings/hclhelpers"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller/versionfile"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/sperr"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/db/db_common"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/filepaths"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller/versionfile"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/options"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/parse"
|
||||
@@ -32,14 +34,14 @@ var defaultConfigFileName = "default.spc"
|
||||
var defaultConfigSampleFileName = "default.spc.sample"
|
||||
|
||||
// LoadSteampipeConfig loads the HCL connection config and workspace options
|
||||
func LoadSteampipeConfig(ctx context.Context, modLocation string, commandName string) (*SteampipeConfig, error_helpers.ErrorAndWarnings) {
|
||||
func LoadSteampipeConfig(ctx context.Context, modLocation string, commandName string) (*SteampipeConfig, perror_helpers.ErrorAndWarnings) {
|
||||
utils.LogTime("steampipeconfig.LoadSteampipeConfig start")
|
||||
defer utils.LogTime("steampipeconfig.LoadSteampipeConfig end")
|
||||
|
||||
log.Printf("[INFO] ensureDefaultConfigFile")
|
||||
|
||||
if err := ensureDefaultConfigFile(filepaths.EnsureConfigDir()); err != nil {
|
||||
return nil, error_helpers.NewErrorsAndWarning(
|
||||
return nil, perror_helpers.NewErrorsAndWarning(
|
||||
sperr.WrapWithMessage(
|
||||
err,
|
||||
"could not create default config",
|
||||
@@ -51,7 +53,7 @@ func LoadSteampipeConfig(ctx context.Context, modLocation string, commandName st
|
||||
|
||||
// LoadConnectionConfig loads the connection config but not the workspace options
|
||||
// this is called by the fdw
|
||||
func LoadConnectionConfig(ctx context.Context) (*SteampipeConfig, error_helpers.ErrorAndWarnings) {
|
||||
func LoadConnectionConfig(ctx context.Context) (*SteampipeConfig, perror_helpers.ErrorAndWarnings) {
|
||||
return LoadSteampipeConfig(ctx, "", "")
|
||||
}
|
||||
|
||||
@@ -119,14 +121,14 @@ func ensureDefaultConfigFile(configFolder string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadSteampipeConfig(ctx context.Context, modLocation string, commandName string) (steampipeConfig *SteampipeConfig, errorsAndWarnings error_helpers.ErrorAndWarnings) {
|
||||
func loadSteampipeConfig(ctx context.Context, modLocation string, commandName string) (steampipeConfig *SteampipeConfig, errorsAndWarnings perror_helpers.ErrorAndWarnings) {
|
||||
utils.LogTime("steampipeconfig.loadSteampipeConfig start")
|
||||
defer utils.LogTime("steampipeconfig.loadSteampipeConfig end")
|
||||
|
||||
errorsAndWarnings = error_helpers.NewErrorsAndWarning(nil)
|
||||
errorsAndWarnings = perror_helpers.NewErrorsAndWarning(nil)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
errorsAndWarnings = error_helpers.NewErrorsAndWarning(helpers.ToError(r))
|
||||
errorsAndWarnings = perror_helpers.NewErrorsAndWarning(helpers.ToError(r))
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -135,7 +137,7 @@ func loadSteampipeConfig(ctx context.Context, modLocation string, commandName st
|
||||
// load plugin versions
|
||||
v, err := versionfile.LoadPluginVersionFile(ctx)
|
||||
if err != nil {
|
||||
return nil, error_helpers.NewErrorsAndWarning(err)
|
||||
return nil, perror_helpers.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
// add any "local" plugins (i.e. plugins installed under the 'local' folder) into the version file
|
||||
@@ -146,7 +148,7 @@ func loadSteampipeConfig(ctx context.Context, modLocation string, commandName st
|
||||
steampipeConfig.PluginVersions = v.Plugins
|
||||
|
||||
// load config from the installation folder - load all spc files from config directory
|
||||
include := filehelpers.InclusionsFromExtensions(constants.ConnectionConfigExtensions)
|
||||
include := filehelpers.InclusionsFromExtensions(pconstants.ConnectionConfigExtensions)
|
||||
loadOptions := &loadConfigOptions{include: include}
|
||||
ew = loadConfig(ctx, filepaths.EnsureConfigDir(), steampipeConfig, loadOptions)
|
||||
if ew.GetError() != nil {
|
||||
@@ -160,7 +162,7 @@ func loadSteampipeConfig(ctx context.Context, modLocation string, commandName st
|
||||
// check workspace folder exists
|
||||
if modLocation != "" {
|
||||
if _, err := os.Stat(modLocation); os.IsNotExist(err) {
|
||||
return nil, error_helpers.NewErrorsAndWarning(fmt.Errorf("mod location '%s' does not exist", modLocation))
|
||||
return nil, perror_helpers.NewErrorsAndWarning(fmt.Errorf("mod location '%s' does not exist", modLocation))
|
||||
}
|
||||
|
||||
// only include workspace.spc from workspace directory
|
||||
@@ -221,7 +223,7 @@ type loadConfigOptions struct {
|
||||
allowedOptions []string
|
||||
}
|
||||
|
||||
func loadConfig(ctx context.Context, configFolder string, steampipeConfig *SteampipeConfig, opts *loadConfigOptions) error_helpers.ErrorAndWarnings {
|
||||
func loadConfig(ctx context.Context, configFolder string, steampipeConfig *SteampipeConfig, opts *loadConfigOptions) perror_helpers.ErrorAndWarnings {
|
||||
log.Printf("[INFO] loadConfig is loading connection config")
|
||||
// get all the config files in the directory
|
||||
configPaths, err := filehelpers.ListFilesWithContext(ctx, configFolder, &filehelpers.ListOptions{
|
||||
@@ -231,28 +233,28 @@ func loadConfig(ctx context.Context, configFolder string, steampipeConfig *Steam
|
||||
|
||||
if err != nil {
|
||||
log.Printf("[WARN] loadConfig: failed to get config file paths: %v\n", err)
|
||||
return error_helpers.NewErrorsAndWarning(err)
|
||||
return perror_helpers.NewErrorsAndWarning(err)
|
||||
}
|
||||
if len(configPaths) == 0 {
|
||||
return error_helpers.ErrorAndWarnings{}
|
||||
return perror_helpers.ErrorAndWarnings{}
|
||||
}
|
||||
|
||||
fileData, diags := parse.LoadFileData(configPaths...)
|
||||
if diags.HasErrors() {
|
||||
log.Printf("[WARN] loadConfig: failed to load all config files: %v\n", err)
|
||||
return error_helpers.DiagsToErrorsAndWarnings("Failed to load all config files", diags)
|
||||
return perror_helpers.DiagsToErrorsAndWarnings("Failed to load all config files", diags)
|
||||
}
|
||||
|
||||
body, diags := parse.ParseHclFiles(fileData)
|
||||
if diags.HasErrors() {
|
||||
return error_helpers.DiagsToErrorsAndWarnings("Failed to load all config files", diags)
|
||||
return perror_helpers.DiagsToErrorsAndWarnings("Failed to load all config files", diags)
|
||||
}
|
||||
|
||||
// do a partial decode
|
||||
content, moreDiags := body.Content(parse.ConfigBlockSchema)
|
||||
if moreDiags.HasErrors() {
|
||||
diags = append(diags, moreDiags...)
|
||||
return error_helpers.DiagsToErrorsAndWarnings("Failed to load config", diags)
|
||||
return perror_helpers.DiagsToErrorsAndWarnings("Failed to load config", diags)
|
||||
}
|
||||
|
||||
// store block types which we have found in this folder - each is only allowed once
|
||||
@@ -272,7 +274,7 @@ func loadConfig(ctx context.Context, configFolder string, steampipeConfig *Steam
|
||||
// add plugin to steampipeConfig
|
||||
// NOTE: this errors if there is a plugin block with a duplicate label
|
||||
if err := steampipeConfig.addPlugin(plugin); err != nil {
|
||||
return error_helpers.NewErrorsAndWarning(err)
|
||||
return perror_helpers.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
case modconfig.BlockTypeConnection:
|
||||
@@ -283,17 +285,17 @@ func loadConfig(ctx context.Context, configFolder string, steampipeConfig *Steam
|
||||
}
|
||||
if existingConnection, alreadyThere := steampipeConfig.Connections[connection.Name]; alreadyThere {
|
||||
err := getDuplicateConnectionError(existingConnection, connection)
|
||||
return error_helpers.NewErrorsAndWarning(err)
|
||||
return perror_helpers.NewErrorsAndWarning(err)
|
||||
}
|
||||
if ok, errorMessage := db_common.IsSchemaNameValid(connection.Name); !ok {
|
||||
return error_helpers.NewErrorsAndWarning(sperr.New("invalid connection name: '%s' in '%s'. %s ", connection.Name, block.TypeRange.Filename, errorMessage))
|
||||
return perror_helpers.NewErrorsAndWarning(sperr.New("invalid connection name: '%s' in '%s'. %s ", connection.Name, block.TypeRange.Filename, errorMessage))
|
||||
}
|
||||
steampipeConfig.Connections[connection.Name] = connection
|
||||
|
||||
case modconfig.BlockTypeOptions:
|
||||
// check this options type is permitted based on the options passed in
|
||||
if err := optionsBlockPermitted(block, optionBlockMap, opts); err != nil {
|
||||
return error_helpers.NewErrorsAndWarning(err)
|
||||
return perror_helpers.NewErrorsAndWarning(err)
|
||||
}
|
||||
opts, moreDiags := parse.DecodeOptions(block)
|
||||
if moreDiags.HasErrors() {
|
||||
@@ -323,10 +325,10 @@ func loadConfig(ctx context.Context, configFolder string, steampipeConfig *Steam
|
||||
}
|
||||
|
||||
if diags.HasErrors() {
|
||||
return error_helpers.DiagsToErrorsAndWarnings("Failed to load config", diags)
|
||||
return perror_helpers.DiagsToErrorsAndWarnings("Failed to load config", diags)
|
||||
}
|
||||
|
||||
res := error_helpers.DiagsToErrorsAndWarnings("", diags)
|
||||
res := perror_helpers.DiagsToErrorsAndWarnings("", diags)
|
||||
|
||||
log.Printf("[INFO] loadConfig calling initializePlugins")
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package steampipeconfig
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
error_helpers2 "github.com/turbot/pipe-fittings/error_helpers"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -22,10 +23,10 @@ import (
|
||||
// if CreatePseudoResources flag is set, construct hcl resources for files with specific extensions
|
||||
// NOTE: it is an error if there is more than 1 mod defined, however zero mods is acceptable
|
||||
// - a default mod will be created assuming there are any resource files
|
||||
func LoadMod(ctx context.Context, modPath string, parseCtx *parse.ModParseContext) (mod *modconfig.Mod, errorsAndWarnings error_helpers.ErrorAndWarnings) {
|
||||
func LoadMod(ctx context.Context, modPath string, parseCtx *parse.ModParseContext) (mod *modconfig.Mod, errorsAndWarnings error_helpers2.ErrorAndWarnings) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
errorsAndWarnings = error_helpers.NewErrorsAndWarning(helpers.ToError(r))
|
||||
errorsAndWarnings = error_helpers2.NewErrorsAndWarning(helpers.ToError(r))
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -41,12 +42,12 @@ func LoadMod(ctx context.Context, modPath string, parseCtx *parse.ModParseContex
|
||||
|
||||
// set the current mod on the run context
|
||||
if err := parseCtx.SetCurrentMod(mod); err != nil {
|
||||
return nil, error_helpers.NewErrorsAndWarning(err)
|
||||
return nil, error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
// load the mod dependencies
|
||||
if err := loadModDependencies(ctx, mod, parseCtx); err != nil {
|
||||
return nil, error_helpers.NewErrorsAndWarning(err)
|
||||
return nil, error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
// populate the resource maps of the current mod using the dependency mods
|
||||
@@ -59,12 +60,12 @@ func LoadMod(ctx context.Context, modPath string, parseCtx *parse.ModParseContex
|
||||
return mod, errorsAndWarnings
|
||||
}
|
||||
|
||||
func loadModDefinition(ctx context.Context, modPath string, parseCtx *parse.ModParseContext) (mod *modconfig.Mod, errorsAndWarnings error_helpers.ErrorAndWarnings) {
|
||||
errorsAndWarnings = error_helpers.ErrorAndWarnings{}
|
||||
func loadModDefinition(ctx context.Context, modPath string, parseCtx *parse.ModParseContext) (mod *modconfig.Mod, errorsAndWarnings error_helpers2.ErrorAndWarnings) {
|
||||
errorsAndWarnings = error_helpers2.ErrorAndWarnings{}
|
||||
// verify the mod folder exists
|
||||
_, err := os.Stat(modPath)
|
||||
if os.IsNotExist(err) {
|
||||
return nil, error_helpers.NewErrorsAndWarning(fmt.Errorf("mod folder %s does not exist", modPath))
|
||||
return nil, error_helpers2.NewErrorsAndWarning(fmt.Errorf("mod folder %s does not exist", modPath))
|
||||
}
|
||||
|
||||
modFilePath, exists := parse.ModfileExists(modPath)
|
||||
@@ -72,7 +73,7 @@ func loadModDefinition(ctx context.Context, modPath string, parseCtx *parse.ModP
|
||||
// load the mod definition to get the dependencies
|
||||
var res *parse.DecodeResult
|
||||
mod, res = parse.ParseModDefinition(modFilePath, parseCtx.EvalCtx)
|
||||
errorsAndWarnings = error_helpers.DiagsToErrorsAndWarnings("mod load failed", res.Diags)
|
||||
errorsAndWarnings = error_helpers2.DiagsToErrorsAndWarnings("mod load failed", res.Diags)
|
||||
if res.Diags.HasErrors() {
|
||||
return nil, errorsAndWarnings
|
||||
}
|
||||
@@ -153,7 +154,7 @@ func loadModDependency(ctx context.Context, modDependency *versionmap.ResolvedVe
|
||||
|
||||
}
|
||||
|
||||
func loadModResources(ctx context.Context, mod *modconfig.Mod, parseCtx *parse.ModParseContext) (*modconfig.Mod, error_helpers.ErrorAndWarnings) {
|
||||
func loadModResources(ctx context.Context, mod *modconfig.Mod, parseCtx *parse.ModParseContext) (*modconfig.Mod, error_helpers2.ErrorAndWarnings) {
|
||||
// if flag is set, create pseudo resources by mapping files
|
||||
var pseudoResources []modconfig.MappableResource
|
||||
var err error
|
||||
@@ -161,7 +162,7 @@ func loadModResources(ctx context.Context, mod *modconfig.Mod, parseCtx *parse.M
|
||||
// now execute any pseudo-resource creations based on file mappings
|
||||
pseudoResources, err = createPseudoResources(ctx, mod, parseCtx)
|
||||
if err != nil {
|
||||
return nil, error_helpers.NewErrorsAndWarning(err)
|
||||
return nil, error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,13 +170,13 @@ func loadModResources(ctx context.Context, mod *modconfig.Mod, parseCtx *parse.M
|
||||
sourcePaths, err := getSourcePaths(ctx, mod.ModPath, parseCtx.ListOptions)
|
||||
if err != nil {
|
||||
log.Printf("[WARN] LoadMod: failed to get mod file paths: %v\n", err)
|
||||
return nil, error_helpers.NewErrorsAndWarning(err)
|
||||
return nil, error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
// load the raw file data
|
||||
fileData, diags := parse.LoadFileData(sourcePaths...)
|
||||
if diags.HasErrors() {
|
||||
return nil, error_helpers.NewErrorsAndWarning(plugin.DiagsToError("Failed to load all mod files", diags))
|
||||
return nil, error_helpers2.NewErrorsAndWarning(plugin.DiagsToError("Failed to load all mod files", diags))
|
||||
}
|
||||
|
||||
// parse all hcl files (NOTE - this reads the CurrentMod out of ParseContext and adds to it)
|
||||
|
||||
@@ -2,6 +2,7 @@ package steampipeconfig
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
"golang.org/x/exp/maps"
|
||||
"log"
|
||||
"sort"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/inputvars"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/parse"
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package modconfig
|
||||
|
||||
import (
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"github.com/turbot/pipe-fittings/utils"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/turbot/pipe-fittings/hclhelpers"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
@@ -52,7 +53,7 @@ func (l *Plugin) IsDefault() bool {
|
||||
}
|
||||
|
||||
func (l *Plugin) FriendlyName() string {
|
||||
return ociinstaller.NewSteampipeImageRef(l.Plugin).GetFriendlyName()
|
||||
return ociinstaller.NewImageRef(l.Plugin).GetFriendlyName()
|
||||
}
|
||||
|
||||
func (l *Plugin) GetMaxMemoryBytes() int64 {
|
||||
@@ -100,5 +101,5 @@ func ResolvePluginImageRef(pluginAlias string) string {
|
||||
return pluginAlias
|
||||
}
|
||||
// ok so there is no plugin block reference - build the plugin image ref from the PluginAlias field
|
||||
return ociinstaller.NewSteampipeImageRef(pluginAlias).DisplayImageRef()
|
||||
return ociinstaller.NewImageRef(pluginAlias).DisplayImageRef()
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@ package modconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"github.com/turbot/pipe-fittings/utils"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/turbot/pipe-fittings/hclhelpers"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
)
|
||||
|
||||
type PluginVersion struct {
|
||||
@@ -55,7 +57,7 @@ func (p *PluginVersion) Initialise(block *hcl.Block) hcl.Diagnostics {
|
||||
})
|
||||
}
|
||||
// parse plugin name
|
||||
p.Org, p.Name, _ = ociinstaller.NewSteampipeImageRef(p.RawName).GetOrgNameAndConstraint()
|
||||
p.Org, p.Name, _ = ociinstaller.NewImageRef(p.RawName).GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package modconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/constants"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -11,7 +12,7 @@ import (
|
||||
"github.com/turbot/go-kit/types"
|
||||
typehelpers "github.com/turbot/go-kit/types"
|
||||
"github.com/turbot/pipe-fittings/hclhelpers"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
|
||||
"github.com/turbot/steampipe/pkg/utils"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package modconfig
|
||||
|
||||
import (
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"github.com/turbot/pipe-fittings/utils"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/turbot/pipe-fittings/hclhelpers"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -18,20 +19,20 @@ const (
|
||||
)
|
||||
|
||||
type RateLimiter struct {
|
||||
Name string `hcl:"name,label" db:"name"`
|
||||
BucketSize *int64 `hcl:"bucket_size,optional" db:"bucket_size"`
|
||||
FillRate *float32 `hcl:"fill_rate,optional" db:"fill_rate"`
|
||||
MaxConcurrency *int64 `hcl:"max_concurrency,optional" db:"max_concurrency"`
|
||||
Scope []string `hcl:"scope,optional" db:"scope"`
|
||||
Where *string `hcl:"where,optional" db:"where"`
|
||||
Plugin string `db:"plugin"`
|
||||
PluginInstance string `db:"plugin_instance"`
|
||||
FileName *string `db:"file_name" json:"-"`
|
||||
StartLineNumber *int `db:"start_line_number" json:"-"`
|
||||
EndLineNumber *int `db:"end_line_number" json:"-"`
|
||||
Status string `db:"status"`
|
||||
Source string `db:"source_type"`
|
||||
ImageRef *ociinstaller.SteampipeImageRef `db:"-" json:"-"`
|
||||
Name string `hcl:"name,label" db:"name"`
|
||||
BucketSize *int64 `hcl:"bucket_size,optional" db:"bucket_size"`
|
||||
FillRate *float32 `hcl:"fill_rate,optional" db:"fill_rate"`
|
||||
MaxConcurrency *int64 `hcl:"max_concurrency,optional" db:"max_concurrency"`
|
||||
Scope []string `hcl:"scope,optional" db:"scope"`
|
||||
Where *string `hcl:"where,optional" db:"where"`
|
||||
Plugin string `db:"plugin"`
|
||||
PluginInstance string `db:"plugin_instance"`
|
||||
FileName *string `db:"file_name" json:"-"`
|
||||
StartLineNumber *int `db:"start_line_number" json:"-"`
|
||||
EndLineNumber *int `db:"end_line_number" json:"-"`
|
||||
Status string `db:"status"`
|
||||
Source string `db:"source_type"`
|
||||
ImageRef *ociinstaller.ImageRef `db:"-" json:"-"`
|
||||
}
|
||||
|
||||
// RateLimiterFromProto converts the proto format RateLimiterDefinition into a Defintion
|
||||
@@ -116,7 +117,7 @@ func (l *RateLimiter) SetPlugin(plugin *Plugin) {
|
||||
}
|
||||
|
||||
func (l *RateLimiter) setPluginImageRef(alias string) {
|
||||
l.ImageRef = ociinstaller.NewSteampipeImageRef(alias)
|
||||
l.ImageRef = ociinstaller.NewImageRef(alias)
|
||||
l.Plugin = l.ImageRef.DisplayImageRef()
|
||||
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@ package modconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"github.com/turbot/pipe-fittings/utils"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"sort"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/turbot/pipe-fittings/hclhelpers"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/sperr"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
"github.com/turbot/steampipe/pkg/version"
|
||||
)
|
||||
|
||||
@@ -152,7 +154,7 @@ func (r *Require) validatePluginVersions(modName string, plugins map[string]*Plu
|
||||
// the mod requirement. If plugin is found nil error is returned.
|
||||
func (r *Require) searchInstalledPluginForRequirement(modName string, requirement *PluginVersion, plugins map[string]*PluginVersionString) error {
|
||||
for installedName, installed := range plugins {
|
||||
org, name, _ := ociinstaller.NewSteampipeImageRef(installedName).GetOrgNameAndConstraint()
|
||||
org, name, _ := ociinstaller.NewImageRef(installedName).GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
if org != requirement.Org || name != requirement.Name {
|
||||
// no point checking - different plugin
|
||||
continue
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/Machiel/slugify"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/pipe-fittings/constants"
|
||||
)
|
||||
|
||||
// map of file extension to factory function to create
|
||||
|
||||
@@ -3,6 +3,7 @@ package parse
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/turbot/pipe-fittings/hclhelpers"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
@@ -2,20 +2,20 @@ package parse
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"github.com/turbot/steampipe/pkg/filepaths"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/hclparse"
|
||||
"github.com/hashicorp/hcl/v2/json"
|
||||
pconstants "github.com/turbot/pipe-fittings/constants"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/filepaths"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
@@ -53,9 +53,9 @@ func ParseHclFiles(fileData map[string][]byte) (hcl.Body, hcl.Diagnostics) {
|
||||
var file *hcl.File
|
||||
var moreDiags hcl.Diagnostics
|
||||
ext := filepath.Ext(filePath)
|
||||
if ext == constants.JsonExtension {
|
||||
if ext == pconstants.JsonExtension {
|
||||
file, moreDiags = json.ParseFile(filePath)
|
||||
} else if constants.IsYamlExtension(ext) {
|
||||
} else if pconstants.IsYamlExtension(ext) {
|
||||
file, moreDiags = parseYamlFile(filePath)
|
||||
} else {
|
||||
data := fileData[filePath]
|
||||
|
||||
@@ -2,17 +2,16 @@ package steampipeconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
utils2 "github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
"github.com/turbot/steampipe/pkg/utils"
|
||||
)
|
||||
|
||||
type PluginRemoveReport struct {
|
||||
Image *ociinstaller.SteampipeImageRef
|
||||
Image *ociinstaller.ImageRef
|
||||
ShortName string
|
||||
Connections []*modconfig.Connection
|
||||
}
|
||||
@@ -23,9 +22,9 @@ func (r PluginRemoveReports) Print() {
|
||||
length := len(r)
|
||||
var staleConnections []*modconfig.Connection
|
||||
if length > 0 {
|
||||
fmt.Printf("\nUninstalled %s:\n", utils.Pluralize("plugin", length))
|
||||
fmt.Printf("\nUninstalled %s:\n", utils2.Pluralize("plugin", length))
|
||||
for _, report := range r {
|
||||
org, name, _ := report.Image.GetOrgNameAndConstraint()
|
||||
org, name, _ := report.Image.GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
fmt.Printf("* %s/%s\n", org, name)
|
||||
staleConnections = append(staleConnections, report.Connections...)
|
||||
|
||||
@@ -49,8 +48,8 @@ func (r PluginRemoveReports) Print() {
|
||||
|
||||
str := append([]string{}, fmt.Sprintf(
|
||||
"Please remove %s %s to continue using steampipe:",
|
||||
utils.Pluralize("this", len(uniqueFiles)),
|
||||
utils.Pluralize("connection", len(uniqueFiles)),
|
||||
utils2.Pluralize("this", len(uniqueFiles)),
|
||||
utils2.Pluralize("connection", len(uniqueFiles)),
|
||||
))
|
||||
|
||||
str = append(str, "")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package steampipeconfig
|
||||
|
||||
import (
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
)
|
||||
|
||||
const PostgresNotificationStructVersion = 20230306
|
||||
|
||||
@@ -2,9 +2,9 @@ package steampipeconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
"strings"
|
||||
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/utils"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package steampipeconfig
|
||||
|
||||
import (
|
||||
filepaths2 "github.com/turbot/pipe-fittings/filepaths"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
@@ -48,7 +49,7 @@ func TestFindPluginFolderTest(t *testing.T) {
|
||||
|
||||
setupFindPluginFolderTest(directories)
|
||||
for name, test := range testCasesFindPluginFolderTest {
|
||||
path, err := filepaths.FindPluginFolder(test.schema)
|
||||
path, err := filepaths2.FindPluginFolder(test.schema)
|
||||
if err != nil {
|
||||
if test.expected != "ERROR" {
|
||||
t.Errorf(`Test: '%s'' FAILED : unexpected error %v`, name, err)
|
||||
|
||||
@@ -2,6 +2,10 @@ package steampipeconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
filepaths2 "github.com/turbot/pipe-fittings/filepaths"
|
||||
utils2 "github.com/turbot/pipe-fittings/ociinstaller"
|
||||
"github.com/turbot/pipe-fittings/ociinstaller/versionfile"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -11,13 +15,9 @@ import (
|
||||
typehelpers "github.com/turbot/go-kit/types"
|
||||
"github.com/turbot/steampipe-plugin-sdk/v5/sperr"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/filepaths"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller"
|
||||
"github.com/turbot/steampipe/pkg/ociinstaller/versionfile"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/options"
|
||||
"github.com/turbot/steampipe/pkg/utils"
|
||||
)
|
||||
|
||||
// SteampipeConfig is a struct to hold Connection map and Steampipe options
|
||||
@@ -237,8 +237,8 @@ func (c *SteampipeConfig) ConnectionsForPlugin(pluginLongName string, pluginVers
|
||||
var res []*modconfig.Connection
|
||||
for _, con := range c.Connections {
|
||||
// extract constraint from plugin
|
||||
ref := ociinstaller.NewSteampipeImageRef(con.Plugin)
|
||||
org, plugin, constraint := ref.GetOrgNameAndConstraint()
|
||||
ref := ociinstaller.NewImageRef(con.Plugin)
|
||||
org, plugin, constraint := ref.GetOrgNameAndConstraint(constants.SteampipeHubOCIBase)
|
||||
longName := fmt.Sprintf("%s/%s", org, plugin)
|
||||
if longName == pluginLongName {
|
||||
if constraint == "latest" {
|
||||
@@ -322,7 +322,7 @@ func (c *SteampipeConfig) initializePlugins() {
|
||||
// and is not installed - set the plugin error
|
||||
if plugin == nil {
|
||||
// set the Plugin to the image ref of the plugin
|
||||
connection.Plugin = ociinstaller.NewSteampipeImageRef(connection.PluginAlias).DisplayImageRef()
|
||||
connection.Plugin = ociinstaller.NewImageRef(connection.PluginAlias).DisplayImageRef()
|
||||
connection.Error = fmt.Errorf(constants.ConnectionErrorPluginNotInstalled)
|
||||
log.Printf("[INFO] connection '%s' requires plugin '%s' which is not loaded and has no instance config", connection.Name, connection.PluginAlias)
|
||||
continue
|
||||
@@ -333,7 +333,7 @@ func (c *SteampipeConfig) initializePlugins() {
|
||||
pluginImageRef := plugin.Plugin
|
||||
connection.PluginAlias = plugin.Alias
|
||||
connection.Plugin = pluginImageRef
|
||||
if pluginPath, _ := filepaths.GetPluginPath(pluginImageRef, plugin.Alias); pluginPath != "" {
|
||||
if pluginPath, _ := filepaths2.GetPluginPath(pluginImageRef, plugin.Alias); pluginPath != "" {
|
||||
// plugin is installed - set the instance and the plugin path
|
||||
connection.PluginInstance = &plugin.Instance
|
||||
connection.PluginPath = &pluginPath
|
||||
@@ -432,7 +432,7 @@ func (c *SteampipeConfig) resolvePluginInstanceForConnection(connection *modconf
|
||||
func (c *SteampipeConfig) GetNonSearchPathConnections(searchPath []string) []string {
|
||||
var res []string
|
||||
//convert searchPath to map for easy lookup
|
||||
searchPathLookup := utils.SliceToLookup(searchPath)
|
||||
searchPathLookup := utils2.SliceToLookup(searchPath)
|
||||
|
||||
for connectionName, _ := range c.Connections {
|
||||
if _, inSearchPath := searchPathLookup[connectionName]; !inSearchPath {
|
||||
|
||||
@@ -3,12 +3,12 @@ package workspace
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/turbot/pipe-fittings/error_helpers"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/turbot/steampipe/pkg/constants"
|
||||
"github.com/turbot/steampipe/pkg/error_helpers"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/inputvars"
|
||||
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
||||
"github.com/turbot/terraform-components/terraform"
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
error_helpers2 "github.com/turbot/pipe-fittings/error_helpers"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -69,7 +70,7 @@ type Workspace struct {
|
||||
}
|
||||
|
||||
// LoadWorkspaceVars creates a Workspace and loads the variables
|
||||
func LoadWorkspaceVars(ctx context.Context) (*Workspace, *modconfig.ModVariableMap, error_helpers.ErrorAndWarnings) {
|
||||
func LoadWorkspaceVars(ctx context.Context) (*Workspace, *modconfig.ModVariableMap, error_helpers2.ErrorAndWarnings) {
|
||||
log.Printf("[INFO] LoadWorkspaceVars: creating workspace, loading variable and resolving variable values")
|
||||
workspacePath := viper.GetString(constants.ArgModLocation)
|
||||
|
||||
@@ -79,13 +80,13 @@ func LoadWorkspaceVars(ctx context.Context) (*Workspace, *modconfig.ModVariableM
|
||||
workspace, err := createShellWorkspace(workspacePath)
|
||||
if err != nil {
|
||||
log.Printf("[INFO] createShellWorkspace failed %s", err.Error())
|
||||
return nil, nil, error_helpers.NewErrorsAndWarning(err)
|
||||
return nil, nil, error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
// check if your workspace path is home dir and if modfile exists - if yes then warn and ask user to continue or not
|
||||
if err := HomeDirectoryModfileCheck(ctx, workspacePath); err != nil {
|
||||
log.Printf("[INFO] HomeDirectoryModfileCheck failed %s", err.Error())
|
||||
return nil, nil, error_helpers.NewErrorsAndWarning(err)
|
||||
return nil, nil, error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
inputVariables, errorsAndWarnings := workspace.PopulateVariables(ctx)
|
||||
if errorsAndWarnings.Error != nil {
|
||||
@@ -288,8 +289,8 @@ func HomeDirectoryModfileCheck(ctx context.Context, workspacePath string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Workspace) LoadWorkspaceMod(ctx context.Context, inputVariables *modconfig.ModVariableMap) error_helpers.ErrorAndWarnings {
|
||||
var errorsAndWarnings = error_helpers.ErrorAndWarnings{}
|
||||
func (w *Workspace) LoadWorkspaceMod(ctx context.Context, inputVariables *modconfig.ModVariableMap) error_helpers2.ErrorAndWarnings {
|
||||
var errorsAndWarnings = error_helpers2.ErrorAndWarnings{}
|
||||
|
||||
// build run context which we use to load the workspace
|
||||
parseCtx, err := w.getParseContext(ctx, inputVariables)
|
||||
@@ -323,7 +324,7 @@ func (w *Workspace) LoadWorkspaceMod(ctx context.Context, inputVariables *modcon
|
||||
return errorsAndWarnings
|
||||
}
|
||||
|
||||
func (w *Workspace) PopulateVariables(ctx context.Context) (*modconfig.ModVariableMap, error_helpers.ErrorAndWarnings) {
|
||||
func (w *Workspace) PopulateVariables(ctx context.Context) (*modconfig.ModVariableMap, error_helpers2.ErrorAndWarnings) {
|
||||
log.Printf("[TRACE] Workspace.PopulateVariables")
|
||||
// resolve values of all input variables
|
||||
// we WILL validate missing variables when loading
|
||||
@@ -343,14 +344,14 @@ func (w *Workspace) PopulateVariables(ctx context.Context) (*modconfig.ModVariab
|
||||
}
|
||||
// if interactive input is disabled, return the missing variables error
|
||||
if !viper.GetBool(constants.ArgInput) {
|
||||
return nil, error_helpers.NewErrorsAndWarning(missingVariablesError)
|
||||
return nil, error_helpers2.NewErrorsAndWarning(missingVariablesError)
|
||||
}
|
||||
// so we have missing variables - prompt for them
|
||||
// first hide spinner if it is there
|
||||
statushooks.Done(ctx)
|
||||
if err := promptForMissingVariables(ctx, missingVariablesError.MissingVariables, w.Path); err != nil {
|
||||
log.Printf("[TRACE] Interactive variables prompting returned error %v", err)
|
||||
return nil, error_helpers.NewErrorsAndWarning(err)
|
||||
return nil, error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
// now try to load vars again
|
||||
@@ -366,18 +367,18 @@ func (w *Workspace) PopulateVariables(ctx context.Context) (*modconfig.ModVariab
|
||||
return inputVariables, errorsAndWarnings
|
||||
}
|
||||
|
||||
func (w *Workspace) getInputVariables(ctx context.Context, validateMissing bool) (*modconfig.ModVariableMap, error_helpers.ErrorAndWarnings) {
|
||||
func (w *Workspace) getInputVariables(ctx context.Context, validateMissing bool) (*modconfig.ModVariableMap, error_helpers2.ErrorAndWarnings) {
|
||||
log.Printf("[TRACE] Workspace.getInputVariables")
|
||||
// build a run context just to use to load variable definitions
|
||||
variablesParseCtx, err := w.getParseContext(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, error_helpers.NewErrorsAndWarning(err)
|
||||
return nil, error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
// load variable definitions
|
||||
variableMap, err := steampipeconfig.LoadVariableDefinitions(ctx, w.Path, variablesParseCtx)
|
||||
if err != nil {
|
||||
return nil, error_helpers.NewErrorsAndWarning(err)
|
||||
return nil, error_helpers2.NewErrorsAndWarning(err)
|
||||
}
|
||||
|
||||
log.Printf("[INFO] loaded variable definitions: %s", variableMap)
|
||||
|
||||
@@ -3,6 +3,7 @@ package workspace
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
error_helpers2 "github.com/turbot/pipe-fittings/error_helpers"
|
||||
"log"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -115,7 +116,7 @@ func (w *Workspace) onNewIntrospectionData(ctx context.Context, client db_common
|
||||
}
|
||||
}
|
||||
|
||||
func (w *Workspace) reloadResourceMaps(ctx context.Context) (_ *modconfig.ResourceMaps, _ *modconfig.ResourceMaps, errAndWarnings error_helpers.ErrorAndWarnings) {
|
||||
func (w *Workspace) reloadResourceMaps(ctx context.Context) (_ *modconfig.ResourceMaps, _ *modconfig.ResourceMaps, errAndWarnings error_helpers2.ErrorAndWarnings) {
|
||||
w.loadLock.Lock()
|
||||
defer w.loadLock.Unlock()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user