diff --git a/providers-sdk/v1/inventory/inventory.go b/providers-sdk/v1/inventory/inventory.go index 76157d12a0..c90dd36986 100644 --- a/providers-sdk/v1/inventory/inventory.go +++ b/providers-sdk/v1/inventory/inventory.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/cockroachdb/errors" + "github.com/rs/zerolog/log" "github.com/segmentio/ksuid" "go.mondoo.com/cnquery/providers-sdk/v1/vault" "google.golang.org/protobuf/proto" @@ -56,7 +57,8 @@ func InventoryFromYAML(data []byte) (*Inventory, error) { for _, asset := range res.Spec.Assets { for _, conn := range asset.Connections { if conn.Type == "" { - conn.Type = connBackendToType(conn.Backend) + log.Warn().Msg("no connection `type` provided in inventory, falling back to deprecated `backend` field") + conn.Type = ConnBackendToType(conn.Backend) } } } diff --git a/providers-sdk/v1/inventory/v8_inventory.go b/providers-sdk/v1/inventory/v8_inventory.go index 7f31fc6393..6abd2eb7ac 100644 --- a/providers-sdk/v1/inventory/v8_inventory.go +++ b/providers-sdk/v1/inventory/v8_inventory.go @@ -114,7 +114,7 @@ func (s *ProviderType) UnmarshalJSON(data []byte) error { return nil } -func connBackendToType(backend ProviderType) string { +func ConnBackendToType(backend ProviderType) string { switch backend { case ProviderType_LOCAL_OS: return "os" diff --git a/providers-sdk/v1/util/version/version.go b/providers-sdk/v1/util/version/version.go index 46f44a784a..8d011c15cf 100644 --- a/providers-sdk/v1/util/version/version.go +++ b/providers-sdk/v1/util/version/version.go @@ -4,6 +4,7 @@ package main import ( + "encoding/json" "errors" "fmt" "go/format" @@ -25,6 +26,7 @@ import ( "github.com/spf13/cobra" "go.mondoo.com/cnquery/cli/components" "go.mondoo.com/cnquery/logger" + "go.mondoo.com/cnquery/providers-sdk/v1/plugin" "golang.org/x/mod/modfile" ) @@ -192,7 +194,7 @@ func checkGoModUpdate(providerPath string, updateStrategy UpdateStrategy) { return } - err = os.WriteFile(goModPath, updatedModContent, 0644) + err = os.WriteFile(goModPath, updatedModContent, 0o644) if err != nil { log.Info().Msgf("Error writing updated go.mod file: %v", err) return @@ -226,6 +228,16 @@ func goModTidy(providerPath string) { } } +var defaultsCmd = &cobra.Command{ + Use: "defaults [PROVIDERS]", + Short: "generates the content for the defaults list of providers", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + defaults := parseDefaults(args) + fmt.Println(defaults) + }, +} + func checkUpdate(providerPath string) { conf, err := getConfig(providerPath) if err != nil { @@ -570,6 +582,48 @@ func countChangesSince(conf *providerConf, repoPath string) int { return count } +func parseDefaults(paths []string) string { + confs := []*plugin.Provider{} + for _, path := range paths { + name := filepath.Base(path) + data, err := os.ReadFile(filepath.Join(path, "dist", name+".json")) + if err != nil { + log.Fatal().Err(err).Msg("failed to read config json") + } + var v plugin.Provider + if err = json.Unmarshal(data, &v); err != nil { + log.Fatal().Err(err).Msg("failed to parse config json") + } + confs = append(confs, &v) + } + + var res strings.Builder + for i := range confs { + conf := confs[i] + var connectors strings.Builder + for j := range conf.Connectors { + conn := conf.Connectors[j] + connectors.WriteString(fmt.Sprintf(` + { + Name: %#v, + Short: %#v, + },`, conn.Name, conn.Short)) + } + + res.WriteString(fmt.Sprintf(` + "%s": { + Provider: &plugin.Provider{ + Name: "%s", + ConnectionTypes: %#v, + Connectors: []plugin.Connector{%s + }, + }, + },`, conf.Name, conf.Name, conf.ConnectionTypes, connectors.String())) + } + + return res.String() +} + var ( fastMode bool doCommit bool @@ -586,6 +640,7 @@ func init() { modUpdateCmd.PersistentFlags().BoolVar(&latestVersion, "latest", false, "update versions to latest") modUpdateCmd.PersistentFlags().BoolVar(&latestPatchVersion, "patch", false, "update versions to latest patch") rootCmd.AddCommand(updateCmd, checkCmd, modUpdateCmd, modTidyCmd) + rootCmd.AddCommand(updateCmd, checkCmd, defaultsCmd) } func main() { diff --git a/providers/defaults.go b/providers/defaults.go index 2d8512774b..e54c187609 100644 --- a/providers/defaults.go +++ b/providers/defaults.go @@ -31,242 +31,273 @@ func SetDefaultRuntime(rt *Runtime) error { // to tell users what providers are used for common connections, when there // is no other way to find out. var DefaultProviders Providers = map[string]*Provider{ - "gcp": { + "arista": { Provider: &plugin.Provider{ - Name: "gcp", + Name: "arista", + ConnectionTypes: []string{"arista"}, Connectors: []plugin.Connector{ { - Name: "gcp", - Short: "GCP Cloud", + Name: "arista", + Short: "Arista EOS", }, }, }, }, - "ipmi": { + "aws": { Provider: &plugin.Provider{ - Name: "ipmi", + Name: "aws", + ConnectionTypes: []string{"aws", "ebs"}, Connectors: []plugin.Connector{ { - Name: "ipmi", - Short: "IPMI", + Name: "aws", + Short: "aws account", }, }, }, }, - "arista": { + "azure": { Provider: &plugin.Provider{ - Name: "arista", + Name: "azure", + ConnectionTypes: []string{"azure"}, Connectors: []plugin.Connector{ { - Name: "arista", - Short: "Arista EOS", + Name: "azure", + Short: "azure", }, }, }, }, - "terraform": { + "core": { + Provider: &plugin.Provider{ + Name: "core", + ConnectionTypes: []string(nil), + Connectors: []plugin.Connector{}, + }, + }, + "equinix": { Provider: &plugin.Provider{ - Name: "terraform", + Name: "equinix", + ConnectionTypes: []string{"equinix"}, Connectors: []plugin.Connector{ { - Name: "terraform", - Short: "a terraform hcl file or directory.", + Name: "equinix", + Short: "Equinix Metal", }, }, }, }, - "os": { + "gcp": { Provider: &plugin.Provider{ - Name: "os", + Name: "gcp", + ConnectionTypes: []string{"gcp", "gcp-snapshot"}, Connectors: []plugin.Connector{ { - Name: "local", - Short: "your local system", - }, - { - Name: "ssh", - Short: "a remote system via SSH", - }, - { - Name: "winrm", - Short: "a remote system via WinRM", - }, - { - Name: "vagrant", - Short: "a Vagrant host", - }, - { - Name: "container", - Short: "a running container or container image", - }, - { - Name: "filesystem", - Short: "a mounted file system target.", + Name: "gcp", + Short: "GCP Cloud", }, }, }, }, - "vsphere": { + "github": { Provider: &plugin.Provider{ - Name: "vsphere", + Name: "github", + ConnectionTypes: []string{"github"}, Connectors: []plugin.Connector{ { - Name: "vsphere", - Short: "VMware vSphere", + Name: "github", + Short: "GitHub", }, }, }, }, - "google-workspace": { + "gitlab": { Provider: &plugin.Provider{ - Name: "google-workspace", + Name: "gitlab", + ConnectionTypes: []string{"gitlab", "gitlab-group", "gitlab-project"}, Connectors: []plugin.Connector{ { - Name: "google-workspace", - Short: "Google Workspace", + Name: "gitlab", + Short: "GitLab", }, }, }, }, - "opcua": { + "google-workspace": { Provider: &plugin.Provider{ - Name: "opcua", + Name: "google-workspace", + ConnectionTypes: []string{"google-workspace"}, Connectors: []plugin.Connector{ { - Name: "opcua", - Short: "OPC UA", + Name: "google-workspace", + Short: "Google Workspace", }, }, }, }, - "okta": { + "ipmi": { Provider: &plugin.Provider{ - Name: "okta", + Name: "ipmi", + ConnectionTypes: []string{"ipmi"}, Connectors: []plugin.Connector{ { - Name: "okta", - Short: "Okta", + Name: "ipmi", + Short: "Ipmi", }, }, }, }, - "slack": { + "k8s": { Provider: &plugin.Provider{ - Name: "slack", + Name: "k8s", + ConnectionTypes: []string{"k8s"}, Connectors: []plugin.Connector{ { - Name: "slack", - Short: "Slack Team", + Name: "k8s", + Short: "a Kubernetes cluster or local manifest file(s).", }, }, }, }, - "github": { + "ms365": { Provider: &plugin.Provider{ - Name: "github", + Name: "ms365", + ConnectionTypes: []string{"ms365"}, Connectors: []plugin.Connector{ { - Name: "github", - Short: "GitHub", + Name: "ms365", + Short: "ms365", }, }, }, }, - "equinix": { + "network": { Provider: &plugin.Provider{ - Name: "equinix", + Name: "network", + ConnectionTypes: []string{"host"}, Connectors: []plugin.Connector{ { - Name: "equinix", - Short: "Equinix Metal", + Name: "host", + Short: "a remote host", }, }, }, }, - "k8s": { + "oci": { Provider: &plugin.Provider{ - Name: "k8s", + Name: "oci", + ConnectionTypes: []string{"oci"}, Connectors: []plugin.Connector{ { - Name: "k8s", - Short: "Kubernetes cluster or local manifest file(s)", + Name: "oci", + Short: "Oracle Cloud Infrastructure", }, }, }, }, - "vcd": { + "okta": { Provider: &plugin.Provider{ - Name: "vcd", + Name: "okta", + ConnectionTypes: []string{"okta"}, Connectors: []plugin.Connector{ { - Name: "vcd", - Short: "VMware Cloud Director", + Name: "okta", + Short: "Okta", }, }, }, }, - "aws": { + "opcua": { Provider: &plugin.Provider{ - Name: "aws", + Name: "opcua", + ConnectionTypes: []string{"opcua"}, Connectors: []plugin.Connector{ { - Name: "aws", - Short: "AWS account", + Name: "opcua", + Short: "OPC UA", }, }, }, }, - "gitlab": { + "os": { Provider: &plugin.Provider{ - Name: "gitlab", + Name: "os", + ConnectionTypes: []string{"local", "ssh", "tar", "docker-snapshot", "vagrant", "docker-image", "docker-container", "docker-registry", "container-registry", "registry-image", "filesystem"}, Connectors: []plugin.Connector{ { - Name: "gitlab", - Short: "GitLab", + Name: "local", + Short: "your local system", + }, + { + Name: "ssh", + Short: "a remote system via SSH", + }, + { + Name: "winrm", + Short: "a remote system via WinRM", + }, + { + Name: "vagrant", + Short: "a Vagrant host", + }, + { + Name: "container", + Short: "a running container or container image", + }, + { + Name: "docker", + Short: "a running docker or docker image", + }, + { + Name: "filesystem", + Short: "a mounted file system target.", }, }, }, }, - "oci": { + "slack": { Provider: &plugin.Provider{ - Name: "oci", + Name: "slack", + ConnectionTypes: []string{"slack"}, Connectors: []plugin.Connector{ { - Name: "oci", - Short: "Oracle Cloud Infrastructure", + Name: "slack", + Short: "slack team", }, }, }, }, - "network": { + "terraform": { Provider: &plugin.Provider{ - Name: "network", + Name: "terraform", + ConnectionTypes: []string{"terraform-state", "terraform-plan", "terraform-hcl", "terraform-hcl-git"}, Connectors: []plugin.Connector{ { - Name: "host", - Short: "Remote host", + Name: "terraform", + Short: "a terraform hcl file or directory.", }, }, }, }, - "ms365": { + "vcd": { Provider: &plugin.Provider{ - Name: "ms365", + Name: "vcd", + ConnectionTypes: []string{"vcd"}, Connectors: []plugin.Connector{ { - Name: "ms365", - Short: "Microsoft 365", + Name: "vcd", + Short: "VMware Cloud Director", }, }, }, }, - "azure": { + "vsphere": { Provider: &plugin.Provider{ - Name: "azure", + Name: "vsphere", + ConnectionTypes: []string{"vsphere"}, Connectors: []plugin.Connector{ { - Name: "azure", - Short: "Azure", + Name: "vsphere", + Short: "VMware vSphere", }, }, }, diff --git a/providers/runtime.go b/providers/runtime.go index 7f342ab630..d9bd8a8cbe 100644 --- a/providers/runtime.go +++ b/providers/runtime.go @@ -160,7 +160,8 @@ func (r *Runtime) DetectProvider(asset *inventory.Asset) error { for i := range asset.Connections { conn := asset.Connections[i] if conn.Type == "" { - continue + log.Warn().Msg("no connection `type` provided in inventory, falling back to deprecated `backend` field") + conn.Type = inventory.ConnBackendToType(conn.Backend) } provider, err := EnsureProvider("", conn.Type, true, r.coordinator.Providers)