diff --git a/apps/cnquery/cmd/login.go b/apps/cnquery/cmd/login.go index 019ee26955..7346c00260 100644 --- a/apps/cnquery/cmd/login.go +++ b/apps/cnquery/cmd/login.go @@ -15,8 +15,8 @@ import ( "go.mondoo.com/cnquery/v9" "go.mondoo.com/cnquery/v9/cli/config" cli_errors "go.mondoo.com/cnquery/v9/cli/errors" - "go.mondoo.com/cnquery/v9/cli/sysinfo" cnquery_providers "go.mondoo.com/cnquery/v9/providers" + "go.mondoo.com/cnquery/v9/providers-sdk/v1/sysinfo" "go.mondoo.com/cnquery/v9/providers-sdk/v1/upstream" "go.mondoo.com/ranger-rpc" "go.mondoo.com/ranger-rpc/plugins/authentication/statictoken" @@ -61,7 +61,7 @@ func register(token string, annotations map[string]string) error { var credential *upstream.ServiceAccountCredentials // determine information about the client - sysInfo, err := sysinfo.GatherSystemInfo() + sysInfo, err := sysinfo.Get() if err != nil { return cli_errors.NewCommandError(errors.Wrap(err, "could not gather client information"), 1) } diff --git a/apps/cnquery/cmd/logout.go b/apps/cnquery/cmd/logout.go index 59e9d4eed1..968e9ed160 100644 --- a/apps/cnquery/cmd/logout.go +++ b/apps/cnquery/cmd/logout.go @@ -13,8 +13,8 @@ import ( "github.com/spf13/viper" "go.mondoo.com/cnquery/v9/cli/config" cli_errors "go.mondoo.com/cnquery/v9/cli/errors" - "go.mondoo.com/cnquery/v9/cli/sysinfo" cnquery_providers "go.mondoo.com/cnquery/v9/providers" + "go.mondoo.com/cnquery/v9/providers-sdk/v1/sysinfo" "go.mondoo.com/cnquery/v9/providers-sdk/v1/upstream" "sigs.k8s.io/yaml" ) @@ -49,7 +49,7 @@ ensure the credentials cannot be used in the future. config.DisplayUsedConfig() // determine information about the client - sysInfo, err := sysinfo.GatherSystemInfo() + sysInfo, err := sysinfo.Get() if err != nil { return errors.Wrap(err, "could not gather client information") } diff --git a/apps/cnquery/cmd/root.go b/apps/cnquery/cmd/root.go index 7cc59d2b19..478a606a93 100644 --- a/apps/cnquery/cmd/root.go +++ b/apps/cnquery/cmd/root.go @@ -18,9 +18,9 @@ import ( "go.mondoo.com/cnquery/v9/cli/config" cli_errors "go.mondoo.com/cnquery/v9/cli/errors" "go.mondoo.com/cnquery/v9/cli/providers" - "go.mondoo.com/cnquery/v9/cli/sysinfo" "go.mondoo.com/cnquery/v9/cli/theme" "go.mondoo.com/cnquery/v9/logger" + "go.mondoo.com/cnquery/v9/providers-sdk/v1/sysinfo" "go.mondoo.com/ranger-rpc" "go.mondoo.com/ranger-rpc/plugins/scope" ) diff --git a/apps/cnquery/cmd/status.go b/apps/cnquery/cmd/status.go index 5fc66cc3a7..aef64a0846 100644 --- a/apps/cnquery/cmd/status.go +++ b/apps/cnquery/cmd/status.go @@ -17,10 +17,10 @@ import ( "go.mondoo.com/cnquery/v9" "go.mondoo.com/cnquery/v9/cli/config" cli_errors "go.mondoo.com/cnquery/v9/cli/errors" - "go.mondoo.com/cnquery/v9/cli/sysinfo" "go.mondoo.com/cnquery/v9/cli/theme" "go.mondoo.com/cnquery/v9/providers" "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" + "go.mondoo.com/cnquery/v9/providers-sdk/v1/sysinfo" "go.mondoo.com/cnquery/v9/providers-sdk/v1/upstream" "go.mondoo.com/cnquery/v9/providers-sdk/v1/upstream/health" "go.mondoo.com/ranger-rpc" @@ -64,7 +64,7 @@ Status sends a ping to Mondoo Platform to verify the credentials. return cli_errors.NewCommandError(errors.Wrap(err, "failed to set up Mondoo API client"), 1) } - sysInfo, err := sysinfo.GatherSystemInfo() + sysInfo, err := sysinfo.Get() if err == nil { s.Client.Platform = sysInfo.Platform s.Client.Hostname = sysInfo.Hostname diff --git a/cli/sysinfo/sysinfo.go b/cli/sysinfo/sysinfo.go deleted file mode 100644 index 54d2487e4a..0000000000 --- a/cli/sysinfo/sysinfo.go +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) Mondoo, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sysinfo - -import ( - "errors" - - "github.com/rs/zerolog/log" - "go.mondoo.com/cnquery/v9/providers/os/resources/networkinterface" - - "go.mondoo.com/cnquery/v9" - "go.mondoo.com/cnquery/v9/cli/execruntime" - "go.mondoo.com/cnquery/v9/llx" - "go.mondoo.com/cnquery/v9/mql" - "go.mondoo.com/cnquery/v9/providers" - "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" - "go.mondoo.com/cnquery/v9/providers-sdk/v1/plugin" -) - -type sysInfoConfig struct { - runtime *providers.Runtime -} - -type SystemInfoOption func(t *sysInfoConfig) error - -func WithRuntime(r *providers.Runtime) SystemInfoOption { - return func(c *sysInfoConfig) error { - c.runtime = r - return nil - } -} - -type SystemInfo struct { - Version string `json:"version,omitempty"` - Build string `json:"build,omitempty"` - Platform *inventory.Platform `json:"platform,omitempty"` - IP string `json:"ip,omitempty"` - Hostname string `json:"platform_hostname,omitempty"` - Labels map[string]string `json:"labels,omitempty"` - PlatformId string `json:"platform_id,omitempty"` -} - -func GatherSystemInfo(opts ...SystemInfoOption) (*SystemInfo, error) { - cfg := &sysInfoConfig{} - for _, opt := range opts { - opt(cfg) - } - - log.Debug().Msg("Gathering system information") - if cfg.runtime == nil { - cfg.runtime = providers.Coordinator.NewRuntime() - - // init runtime - if _, err := providers.EnsureProvider(providers.ProviderLookup{ConnName: "local"}, true, nil); err != nil { - return nil, err - } - if err := cfg.runtime.UseProvider(providers.DefaultOsID); err != nil { - return nil, err - } - args, err := cfg.runtime.Provider.Instance.Plugin.ParseCLI(&plugin.ParseCLIReq{ - Connector: "local", - }) - if err != nil { - return nil, err - } - - if err = cfg.runtime.Connect(&plugin.ConnectReq{ - Asset: args.Asset, - }); err != nil { - return nil, err - } - } - - sysInfo := &SystemInfo{ - Version: cnquery.GetVersion(), - Build: cnquery.GetBuild(), - } - - exec := mql.New(cfg.runtime, nil) - // TODO: it is not returning it as a MQL SingleValue, therefore we need to force it with return - raw, err := exec.Exec("return asset { platform arch title family build version kind runtime labels ids }", nil) - if err != nil { - return sysInfo, err - } - - if vals, ok := raw.Value.(map[string]interface{}); ok { - sysInfo.Platform = &inventory.Platform{ - Name: llx.TRaw2T[string](vals["platform"]), - Arch: llx.TRaw2T[string](vals["arch"]), - Title: llx.TRaw2T[string](vals["title"]), - Family: llx.TRaw2TArr[string](vals["family"]), - Build: llx.TRaw2T[string](vals["build"]), - Version: llx.TRaw2T[string](vals["version"]), - Kind: llx.TRaw2T[string](vals["kind"]), - Runtime: llx.TRaw2T[string](vals["runtime"]), - Labels: llx.TRaw2TMap[string](vals["labels"]), - } - - platformID := llx.TRaw2TArr[string](vals["ids"]) - if len(platformID) > 0 { - sysInfo.PlatformId = platformID[0] - } - } else { - return sysInfo, errors.New("returned asset detection type is incorrect") - } - - // determine hostname - osRaw, err := exec.Exec("return os.hostname", nil) - if err != nil { - return sysInfo, err - } - - if hostname, ok := osRaw.Value.(string); ok { - sysInfo.Hostname = hostname - } - - // determine ip address - // TODO: move this to MQL and expose that information in the graph - ipAddr, err := networkinterface.GetOutboundIP() - if err == nil { - sysInfo.IP = ipAddr.String() - } - - // detect the execution runtime - execEnv := execruntime.Detect() - sysInfo.Labels = map[string]string{ - "environment": execEnv.Id, - } - - return sysInfo, nil -} diff --git a/providers-sdk/v1/sysinfo/sysinfo.go b/providers-sdk/v1/sysinfo/sysinfo.go new file mode 100644 index 0000000000..a7e9617f67 --- /dev/null +++ b/providers-sdk/v1/sysinfo/sysinfo.go @@ -0,0 +1,78 @@ +// Copyright (c) Mondoo, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package sysinfo + +import ( + "errors" + + "github.com/rs/zerolog/log" + + "go.mondoo.com/cnquery/v9" + "go.mondoo.com/cnquery/v9/cli/execruntime" + "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" + "go.mondoo.com/cnquery/v9/providers/os/connection/local" + "go.mondoo.com/cnquery/v9/providers/os/detector" + "go.mondoo.com/cnquery/v9/providers/os/id" + "go.mondoo.com/cnquery/v9/providers/os/id/hostname" + "go.mondoo.com/cnquery/v9/providers/os/resources/networkinterface" +) + +type SystemInfo struct { + Version string `json:"version,omitempty"` + Build string `json:"build,omitempty"` + Platform *inventory.Platform `json:"platform,omitempty"` + IP string `json:"ip,omitempty"` + Hostname string `json:"platform_hostname,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + PlatformId string `json:"platform_id,omitempty"` +} + +func Get() (*SystemInfo, error) { + log.Debug().Msg("Gathering system information") + + sysInfo := &SystemInfo{ + Version: cnquery.GetVersion(), + Build: cnquery.GetBuild(), + } + + asset := inventory.Asset{ + Connections: []*inventory.Config{{ + Type: "local", + Discover: &inventory.Discovery{Targets: []string{"none"}}, + }}, + } + + conn := local.NewConnection(0, &inventory.Config{ + Type: "local", + }, &asset) + + fingerprint, err := id.IdentifyPlatform(conn, asset.Platform, asset.IdDetector) + if err == nil { + if len(fingerprint.PlatformIDs) > 0 { + sysInfo.PlatformId = fingerprint.PlatformIDs[0] + } + } + + var ok bool + sysInfo.Platform, ok = detector.DetectOS(conn) + if !ok { + return nil, errors.New("failed to detect the OS") + } + + sysInfo.Hostname, _ = hostname.Hostname(conn, sysInfo.Platform) + + // determine ip address + ipAddr, err := networkinterface.GetOutboundIP() + if err == nil { + sysInfo.IP = ipAddr.String() + } + + // detect the execution runtime + execEnv := execruntime.Detect() + sysInfo.Labels = map[string]string{ + "environment": execEnv.Id, + } + + return sysInfo, nil +} diff --git a/providers/aws/connection/awsec2ebsconn/provider.go b/providers/aws/connection/awsec2ebsconn/provider.go index 4668950a22..4f3927d168 100644 --- a/providers/aws/connection/awsec2ebsconn/provider.go +++ b/providers/aws/connection/awsec2ebsconn/provider.go @@ -19,7 +19,7 @@ import ( "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" "go.mondoo.com/cnquery/v9/providers-sdk/v1/util/convert" awsec2ebstypes "go.mondoo.com/cnquery/v9/providers/aws/connection/awsec2ebsconn/types" - "go.mondoo.com/cnquery/v9/providers/os/connection" + "go.mondoo.com/cnquery/v9/providers/os/connection/fs" "go.mondoo.com/cnquery/v9/providers/os/connection/shared" "go.mondoo.com/cnquery/v9/providers/os/connection/snapshot" "go.mondoo.com/cnquery/v9/providers/os/detector" @@ -34,7 +34,7 @@ const ( type AwsEbsConnection struct { id uint32 asset *inventory.Asset - FsProvider *connection.FileSystemConnection + FsProvider *fs.FileSystemConnection scannerRegionEc2svc *ec2.Client targetRegionEc2svc *ec2.Client config aws.Config @@ -182,7 +182,7 @@ func NewAwsEbsConnection(id uint32, conf *inventory.Config, asset *inventory.Ass log.Debug().Interface("info", c.target).Str("type", c.targetType).Msg("target") // Create and initialize fs provider conf.Options["path"] = volumeMounter.ScanDir - fsConn, err := connection.NewFileSystemConnection(id, &inventory.Config{ + fsConn, err := fs.NewConnection(id, &inventory.Config{ Type: "filesystem", Path: volumeMounter.ScanDir, PlatformId: conf.PlatformId, diff --git a/providers/azure/connection/azureinstancesnapshot/lun.go b/providers/azure/connection/azureinstancesnapshot/lun.go index be0b4df753..417bb5a275 100644 --- a/providers/azure/connection/azureinstancesnapshot/lun.go +++ b/providers/azure/connection/azureinstancesnapshot/lun.go @@ -11,7 +11,7 @@ import ( "github.com/cockroachdb/errors" "github.com/rs/zerolog/log" - "go.mondoo.com/cnquery/v9/providers/os/connection" + "go.mondoo.com/cnquery/v9/providers/os/connection/local" ) type deviceInfo struct { @@ -52,7 +52,7 @@ func (a *azureScannerInstance) getAvailableLun(mountedDevices []deviceInfo) (int // https://learn.microsoft.com/en-us/azure/virtual-machines/linux/azure-to-guest-disk-mapping // for more information. we want to find the LUNs of the data disks and their mount location -func getMountedDevices(localConn *connection.LocalConnection) ([]deviceInfo, error) { +func getMountedDevices(localConn *local.LocalConnection) ([]deviceInfo, error) { cmd, err := localConn.RunCommand("lsscsi --brief") if err != nil { return nil, err diff --git a/providers/azure/connection/azureinstancesnapshot/provider.go b/providers/azure/connection/azureinstancesnapshot/provider.go index 6c75ebb03a..bce7ad20d7 100644 --- a/providers/azure/connection/azureinstancesnapshot/provider.go +++ b/providers/azure/connection/azureinstancesnapshot/provider.go @@ -16,7 +16,8 @@ import ( "go.mondoo.com/cnquery/v9/providers-sdk/v1/vault" "go.mondoo.com/cnquery/v9/providers/azure/connection/auth" "go.mondoo.com/cnquery/v9/providers/azure/connection/shared" - "go.mondoo.com/cnquery/v9/providers/os/connection" + "go.mondoo.com/cnquery/v9/providers/os/connection/fs" + "go.mondoo.com/cnquery/v9/providers/os/connection/local" "go.mondoo.com/cnquery/v9/providers/os/connection/snapshot" "go.mondoo.com/cnquery/v9/providers/os/detector" "go.mondoo.com/cnquery/v9/providers/os/id/azcompute" @@ -44,7 +45,7 @@ type mountInfo struct { diskName string } -func determineScannerInstanceInfo(localConn *connection.LocalConnection, token azcore.TokenCredential) (*azureScannerInstance, error) { +func determineScannerInstanceInfo(localConn *local.LocalConnection, token azcore.TokenCredential) (*azureScannerInstance, error) { pf, detected := detector.DetectOS(localConn) if !detected { return nil, errors.New("could not detect platform") @@ -117,7 +118,7 @@ func NewAzureSnapshotConnection(id uint32, conf *inventory.Config, asset *invent if err != nil { return nil, err } - localConn := connection.NewLocalConnection(id, conf, asset) + localConn := local.NewConnection(id, conf, asset) // check if we run on an azure instance scanner, err := determineScannerInstanceInfo(localConn, token) @@ -230,7 +231,7 @@ func NewAzureSnapshotConnection(id uint32, conf *inventory.Config, asset *invent conf.Options["path"] = volumeMounter.ScanDir // create and initialize fs provider - fsConn, err := connection.NewFileSystemConnection(id, &inventory.Config{ + fsConn, err := fs.NewConnection(id, &inventory.Config{ Path: volumeMounter.ScanDir, PlatformId: conf.PlatformId, Options: conf.Options, @@ -260,7 +261,7 @@ func NewAzureSnapshotConnection(id uint32, conf *inventory.Config, asset *invent } type AzureSnapshotConnection struct { - *connection.FileSystemConnection + *fs.FileSystemConnection opts map[string]string volumeMounter *snapshot.VolumeMounter snapshotCreator *SnapshotCreator diff --git a/providers/builtin_dev.go b/providers/builtin_dev.go index fb26f76bad..16de569017 100644 --- a/providers/builtin_dev.go +++ b/providers/builtin_dev.go @@ -26,5 +26,4 @@ func init() { // }, // Config: &osconf.Config, // } - } diff --git a/providers/gcp/connection/gcpinstancesnapshot/provider.go b/providers/gcp/connection/gcpinstancesnapshot/provider.go index 87cced6d06..713a282271 100644 --- a/providers/gcp/connection/gcpinstancesnapshot/provider.go +++ b/providers/gcp/connection/gcpinstancesnapshot/provider.go @@ -12,7 +12,8 @@ import ( "go.mondoo.com/cnquery/v9/mrn" "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" "go.mondoo.com/cnquery/v9/providers/gcp/connection/shared" - "go.mondoo.com/cnquery/v9/providers/os/connection" + "go.mondoo.com/cnquery/v9/providers/os/connection/fs" + "go.mondoo.com/cnquery/v9/providers/os/connection/local" "go.mondoo.com/cnquery/v9/providers/os/connection/snapshot" "go.mondoo.com/cnquery/v9/providers/os/detector" "go.mondoo.com/cnquery/v9/providers/os/id/gce" @@ -45,7 +46,7 @@ type mountInfo struct { func determineScannerInstanceInfo(id uint32, conf *inventory.Config, asset *inventory.Asset) (*scannerInstance, error) { // FIXME: need to pass conf - localConn := connection.NewLocalConnection(id, conf, asset) + localConn := local.NewConnection(id, conf, asset) pf, detected := detector.DetectOS(localConn) if !detected { return nil, errors.New("could not detect platform") @@ -215,7 +216,7 @@ func NewGcpSnapshotConnection(id uint32, conf *inventory.Config, asset *inventor conf.Options["path"] = volumeMounter.ScanDir // create and initialize fs provider - fsConn, err := connection.NewFileSystemConnection(id, &inventory.Config{ + fsConn, err := fs.NewConnection(id, &inventory.Config{ Path: volumeMounter.ScanDir, PlatformId: conf.PlatformId, Options: conf.Options, @@ -252,7 +253,7 @@ func NewGcpSnapshotConnection(id uint32, conf *inventory.Config, asset *inventor } type GcpSnapshotConnection struct { - *connection.FileSystemConnection + *fs.FileSystemConnection opts map[string]string // the type of object we're targeting (instance, disk, snapshot) targetType string diff --git a/providers/ms365/connection/connection.go b/providers/ms365/connection/connection.go index cbb1df8cd6..8b98320e86 100644 --- a/providers/ms365/connection/connection.go +++ b/providers/ms365/connection/connection.go @@ -12,7 +12,7 @@ import ( "github.com/pkg/errors" "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" "go.mondoo.com/cnquery/v9/providers-sdk/v1/vault" - "go.mondoo.com/cnquery/v9/providers/os/connection" + "go.mondoo.com/cnquery/v9/providers/os/connection/local" "go.mondoo.com/cnquery/v9/providers/os/connection/shared" "go.mondoo.com/cnquery/v9/providers/os/resources/powershell" ) @@ -120,7 +120,7 @@ func (p *Ms365Connection) runPowershellScript(script string) (*shared.Command, e } func (p *Ms365Connection) runCmd(cmd string) (*shared.Command, error) { - cmdR := connection.CommandRunner{} + cmdR := local.CommandRunner{} if runtime.GOOS == "windows" { cmdR.Shell = []string{"powershell", "-c"} } else { diff --git a/providers/os/connection/docker_snapshot.go b/providers/os/connection/docker_snapshot.go index 9b091316c8..50fe685a74 100644 --- a/providers/os/connection/docker_snapshot.go +++ b/providers/os/connection/docker_snapshot.go @@ -12,10 +12,6 @@ import ( "go.mondoo.com/cnquery/v9/providers/os/connection/shared" ) -const ( - DockerSnapshot shared.ConnectionType = "docker-snapshot" -) - var _ shared.Connection = &DockerSnapshotConnection{} type DockerSnapshotConnection struct { @@ -82,9 +78,9 @@ func (p *DockerSnapshotConnection) ID() uint32 { } func (p *DockerSnapshotConnection) Name() string { - return string(DockerSnapshot) + return string(shared.Type_DockerSnapshot) } func (p *DockerSnapshotConnection) Type() shared.ConnectionType { - return DockerSnapshot + return shared.Type_DockerSnapshot } diff --git a/providers/os/connection/filesystem.go b/providers/os/connection/fs/filesystem.go similarity index 91% rename from providers/os/connection/filesystem.go rename to providers/os/connection/fs/filesystem.go index 7ce3bca6a2..57aa22fcd4 100644 --- a/providers/os/connection/filesystem.go +++ b/providers/os/connection/fs/filesystem.go @@ -1,7 +1,7 @@ // Copyright (c) Mondoo, Inc. // SPDX-License-Identifier: BUSL-1.1 -package connection +package fs import ( "errors" @@ -14,10 +14,6 @@ import ( "go.mondoo.com/cnquery/v9/providers/os/fs" ) -const ( - FileSystem shared.ConnectionType = "filesystem" -) - var _ shared.Connection = &FileSystemConnection{} func NewFileSystemConnectionWithClose(id uint32, conf *inventory.Config, asset *inventory.Asset, closeFN func()) (*FileSystemConnection, error) { @@ -44,7 +40,7 @@ func NewFileSystemConnectionWithClose(id uint32, conf *inventory.Config, asset * }, nil } -func NewFileSystemConnection(id uint32, conf *inventory.Config, asset *inventory.Asset) (*FileSystemConnection, error) { +func NewConnection(id uint32, conf *inventory.Config, asset *inventory.Asset) (*FileSystemConnection, error) { return NewFileSystemConnectionWithClose(id, conf, asset, nil) } @@ -111,11 +107,11 @@ func (c *FileSystemConnection) ID() uint32 { } func (c *FileSystemConnection) Name() string { - return string(FileSystem) + return string(shared.Type_FileSystem) } func (c *FileSystemConnection) Type() shared.ConnectionType { - return FileSystem + return shared.Type_FileSystem } func (c *FileSystemConnection) Asset() *inventory.Asset { diff --git a/providers/os/connection/filesystem_test.go b/providers/os/connection/fs/filesystem_test.go similarity index 83% rename from providers/os/connection/filesystem_test.go rename to providers/os/connection/fs/filesystem_test.go index f5fcef0323..83a30c8fbc 100644 --- a/providers/os/connection/filesystem_test.go +++ b/providers/os/connection/fs/filesystem_test.go @@ -1,7 +1,7 @@ // Copyright (c) Mondoo, Inc. // SPDX-License-Identifier: BUSL-1.1 -package connection_test +package fs_test import ( "testing" @@ -10,14 +10,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" - "go.mondoo.com/cnquery/v9/providers/os/connection" + "go.mondoo.com/cnquery/v9/providers/os/connection/fs" "go.mondoo.com/cnquery/v9/providers/os/connection/fs/fsutil" "go.mondoo.com/cnquery/v9/providers/os/detector" ) func TestOsDetection(t *testing.T) { - conn, err := connection.NewFileSystemConnection(0, &inventory.Config{ - Path: "./fs/testdata/centos8", + conn, err := fs.NewConnection(0, &inventory.Config{ + Path: "./testdata/centos8", }, nil) require.NoError(t, err) @@ -29,8 +29,8 @@ func TestOsDetection(t *testing.T) { } func TestMountedDirectoryFile(t *testing.T) { - conn, err := connection.NewFileSystemConnection(0, &inventory.Config{ - Path: "./fs/testdata/centos8", + conn, err := fs.NewConnection(0, &inventory.Config{ + Path: "./testdata/centos8", }, nil) require.NoError(t, err) @@ -67,8 +67,8 @@ func TestMountedDirectoryFile(t *testing.T) { } func TestRunCommandReturnsErr(t *testing.T) { - conn, err := connection.NewFileSystemConnection(0, &inventory.Config{ - Path: "./fs/testdata/centos8", + conn, err := fs.NewConnection(0, &inventory.Config{ + Path: "./testdata/centos8", }, nil) require.NoError(t, err) diff --git a/providers/os/connection/fs/fsutil/hash_test.go b/providers/os/connection/fs/fsutil/hash_test.go index 5a2c3b3487..dafdb644e3 100644 --- a/providers/os/connection/fs/fsutil/hash_test.go +++ b/providers/os/connection/fs/fsutil/hash_test.go @@ -8,14 +8,14 @@ import ( "github.com/spf13/afero" "github.com/stretchr/testify/assert" - "go.mondoo.com/cnquery/v9/providers/os/connection" "go.mondoo.com/cnquery/v9/providers/os/connection/fs/fsutil" + "go.mondoo.com/cnquery/v9/providers/os/connection/local" ) func TestFileResource(t *testing.T) { path := "/tmp/test_hash" - conn := connection.NewLocalConnection(0, nil, nil) + conn := local.NewConnection(0, nil, nil) assert.NotNil(t, conn) fs := conn.FileSystem() diff --git a/providers/os/connection/owner_unix.go b/providers/os/connection/fs/owner_unix.go similarity index 95% rename from providers/os/connection/owner_unix.go rename to providers/os/connection/fs/owner_unix.go index 8e4639b217..796aff1fb5 100644 --- a/providers/os/connection/owner_unix.go +++ b/providers/os/connection/fs/owner_unix.go @@ -4,7 +4,7 @@ //go:build !windows // +build !windows -package connection +package fs import ( "os" diff --git a/providers/os/connection/owner_windows.go b/providers/os/connection/fs/owner_windows.go similarity index 92% rename from providers/os/connection/owner_windows.go rename to providers/os/connection/fs/owner_windows.go index 66d18a1a96..7393ee7104 100644 --- a/providers/os/connection/owner_windows.go +++ b/providers/os/connection/fs/owner_windows.go @@ -4,7 +4,7 @@ //go:build windows // +build windows -package connection +package fs import "os" diff --git a/providers/os/connection/local.go b/providers/os/connection/local/local.go similarity index 95% rename from providers/os/connection/local.go rename to providers/os/connection/local/local.go index d6b12470b7..00871649ff 100644 --- a/providers/os/connection/local.go +++ b/providers/os/connection/local/local.go @@ -1,7 +1,7 @@ // Copyright (c) Mondoo, Inc. // SPDX-License-Identifier: BUSL-1.1 -package connection +package local import ( "bytes" @@ -18,10 +18,6 @@ import ( "go.mondoo.com/cnquery/v9/providers/os/connection/ssh/cat" ) -const ( - Local shared.ConnectionType = "local" -) - type LocalConnection struct { shell []string fs afero.Fs @@ -31,7 +27,7 @@ type LocalConnection struct { asset *inventory.Asset } -func NewLocalConnection(id uint32, conf *inventory.Config, asset *inventory.Asset) *LocalConnection { +func NewConnection(id uint32, conf *inventory.Config, asset *inventory.Asset) *LocalConnection { // expect unix shell by default res := LocalConnection{ id: id, @@ -61,7 +57,7 @@ func (p *LocalConnection) Name() string { } func (p *LocalConnection) Type() shared.ConnectionType { - return Local + return shared.Type_Local } func (p *LocalConnection) Asset() *inventory.Asset { diff --git a/providers/os/connection/local_unix.go b/providers/os/connection/local/local_unix.go similarity index 96% rename from providers/os/connection/local_unix.go rename to providers/os/connection/local/local_unix.go index 7b72384460..9c14d11687 100644 --- a/providers/os/connection/local_unix.go +++ b/providers/os/connection/local/local_unix.go @@ -4,7 +4,7 @@ //go:build !windows // +build !windows -package connection +package local import ( "os" diff --git a/providers/os/connection/local_windows.go b/providers/os/connection/local/local_windows.go similarity index 92% rename from providers/os/connection/local_windows.go rename to providers/os/connection/local/local_windows.go index df7879d41a..f89e69b41b 100644 --- a/providers/os/connection/local_windows.go +++ b/providers/os/connection/local/local_windows.go @@ -4,7 +4,7 @@ //go:build windows // +build windows -package connection +package local import "os" diff --git a/providers/os/connection/shared/shared.go b/providers/os/connection/shared/shared.go index a2e60ade77..bd6b294336 100644 --- a/providers/os/connection/shared/shared.go +++ b/providers/os/connection/shared/shared.go @@ -18,6 +18,19 @@ import ( type ConnectionType string +// Note: We generally prefer to have the types close with their connections, +// however the detectors would then have to pull in every connection as a +// dependency with all their code, just to check if the type is e.g. local +// or ssh. Keeping them in shared is more annoying (coding-wise), but +// keeps the dependency-graph very small. +const ( + Type_Local ConnectionType = "local" + Type_SSH ConnectionType = "ssh" + Type_Tar ConnectionType = "tar" + Type_FileSystem ConnectionType = "filesystem" + Type_DockerSnapshot ConnectionType = "docker-snapshot" +) + type Connection interface { RunCommand(command string) (*Command, error) FileInfo(path string) (FileInfoDetails, error) diff --git a/providers/os/connection/snapshot/localcmd.go b/providers/os/connection/snapshot/localcmd.go index 7a17b51b2d..34c6f763f0 100644 --- a/providers/os/connection/snapshot/localcmd.go +++ b/providers/os/connection/snapshot/localcmd.go @@ -4,7 +4,7 @@ package snapshot import ( - "go.mondoo.com/cnquery/v9/providers/os/connection" + "go.mondoo.com/cnquery/v9/providers/os/connection/local" "go.mondoo.com/cnquery/v9/providers/os/connection/shared" ) @@ -13,7 +13,7 @@ type LocalCommandRunner struct { } func (r *LocalCommandRunner) RunCommand(command string) (*shared.Command, error) { - c := connection.CommandRunner{Shell: r.shell} + c := local.CommandRunner{Shell: r.shell} args := []string{} res, err := c.Exec(command, args) diff --git a/providers/os/connection/ssh.go b/providers/os/connection/ssh.go index d7ba4ec39f..0943f3fed1 100644 --- a/providers/os/connection/ssh.go +++ b/providers/os/connection/ssh.go @@ -36,10 +36,6 @@ import ( "golang.org/x/crypto/ssh/knownhosts" ) -const ( - SSH shared.ConnectionType = "ssh" -) - type SshConnection struct { id uint32 conf *inventory.Config @@ -126,7 +122,7 @@ func (c *SshConnection) Name() string { } func (c *SshConnection) Type() shared.ConnectionType { - return SSH + return shared.Type_SSH } func (p *SshConnection) Asset() *inventory.Asset { diff --git a/providers/os/connection/tar.go b/providers/os/connection/tar.go index 10012f2762..ea8265b7e7 100644 --- a/providers/os/connection/tar.go +++ b/providers/os/connection/tar.go @@ -24,10 +24,9 @@ import ( ) const ( - Tar shared.ConnectionType = "tar" - OPTION_FILE = "path" - FLATTENED_IMAGE = "flattened_path" - COMPRESSED_IMAGE = "compressed_path" + OPTION_FILE = "path" + FLATTENED_IMAGE = "flattened_path" + COMPRESSED_IMAGE = "compressed_path" ) type TarConnection struct { @@ -54,11 +53,11 @@ func (p *TarConnection) ID() uint32 { } func (p *TarConnection) Name() string { - return string(Tar) + return string(shared.Type_Tar) } func (p *TarConnection) Type() shared.ConnectionType { - return Tar + return shared.Type_Tar } func (p *TarConnection) Asset() *inventory.Asset { diff --git a/providers/os/connection/vagrant.go b/providers/os/connection/vagrant.go index 594cab01ff..84577b8f5c 100644 --- a/providers/os/connection/vagrant.go +++ b/providers/os/connection/vagrant.go @@ -9,6 +9,7 @@ import ( "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" "go.mondoo.com/cnquery/v9/providers-sdk/v1/vault" + "go.mondoo.com/cnquery/v9/providers/os/connection/local" "go.mondoo.com/cnquery/v9/providers/os/connection/shared" "go.mondoo.com/cnquery/v9/providers/os/connection/vagrant" "go.mondoo.com/cnquery/v9/providers/os/id/ids" @@ -53,7 +54,7 @@ func resolveVagrantSshConf(id uint32, conf *inventory.Config, root *inventory.As // For now, we do not provide the conf to the local connection // conf might include sudo, which is only intended for the actual vagrant connection // local currently does not need it. Quite the contrary, it cause issues. - localProvider := NewLocalConnection(id, nil, root) + localProvider := local.NewConnection(id, nil, root) // we run status first, since vagrant ssh-config does not return a proper state // if in a multi-vm setup not all vms are running diff --git a/providers/os/detector/detector.go b/providers/os/detector/detector.go index da10671ba9..35f0a4fca4 100644 --- a/providers/os/detector/detector.go +++ b/providers/os/detector/detector.go @@ -7,12 +7,11 @@ import ( "runtime" "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" - "go.mondoo.com/cnquery/v9/providers/os/connection" "go.mondoo.com/cnquery/v9/providers/os/connection/shared" ) func DetectOS(conn shared.Connection) (*inventory.Platform, bool) { - if conn.Type() == connection.Local && runtime.GOOS == "windows" { + if conn.Type() == shared.Type_Local && runtime.GOOS == "windows" { return WindowsFamily.Resolve(conn) } return OperatingSystems.Resolve(conn) diff --git a/providers/os/fsutil/hash_test.go b/providers/os/fsutil/hash_test.go index 836c3e64c7..efb103239c 100644 --- a/providers/os/fsutil/hash_test.go +++ b/providers/os/fsutil/hash_test.go @@ -9,14 +9,14 @@ import ( "github.com/spf13/afero" "github.com/stretchr/testify/assert" "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" - "go.mondoo.com/cnquery/v9/providers/os/connection" + "go.mondoo.com/cnquery/v9/providers/os/connection/local" "go.mondoo.com/cnquery/v9/providers/os/fsutil" ) func TestFileResource(t *testing.T) { path := "/tmp/test_hash" - conn := connection.NewLocalConnection(0, &inventory.Config{ + conn := local.NewConnection(0, &inventory.Config{ Path: path, }, &inventory.Asset{}) diff --git a/providers/os/id/awsec2/awsec2.go b/providers/os/id/awsec2/awsec2.go index 91ce5a3197..d2e02be816 100644 --- a/providers/os/id/awsec2/awsec2.go +++ b/providers/os/id/awsec2/awsec2.go @@ -9,7 +9,6 @@ import ( "github.com/aws/aws-sdk-go-v2/config" "github.com/cockroachdb/errors" "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" - "go.mondoo.com/cnquery/v9/providers/os/connection" "go.mondoo.com/cnquery/v9/providers/os/connection/mock" "go.mondoo.com/cnquery/v9/providers/os/connection/shared" ) @@ -27,7 +26,7 @@ func Resolve(conn shared.Connection, pf *inventory.Platform) (InstanceIdentifier cfg, err := config.LoadDefaultConfig(context.Background()) if err != nil { // for local environments we must have a config, or it won't work - if conn.Type() == connection.Local { + if conn.Type() == shared.Type_Local { return nil, errors.Wrap(err, "cannot not determine AWS environment") } @@ -35,7 +34,7 @@ func Resolve(conn shared.Connection, pf *inventory.Platform) (InstanceIdentifier return NewCommandInstanceMetadata(conn, pf, nil), nil } - if conn.Type() == connection.Local { + if conn.Type() == shared.Type_Local { // TODO: Dom: Since a mocked local is not considered local in the original // code, we are not testing this code path. Also the original only had // mock and non-mock, where the v9 plugin system introduces hybrid modes. diff --git a/providers/os/provider/platform.go b/providers/os/id/platform.go similarity index 95% rename from providers/os/provider/platform.go rename to providers/os/id/platform.go index a067562a18..c1a85cef0d 100644 --- a/providers/os/provider/platform.go +++ b/providers/os/id/platform.go @@ -1,7 +1,7 @@ // Copyright (c) Mondoo, Inc. // SPDX-License-Identifier: BUSL-1.1 -package provider +package id import ( "errors" @@ -9,7 +9,6 @@ import ( "github.com/rs/zerolog/log" "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" - "go.mondoo.com/cnquery/v9/providers/os/connection" "go.mondoo.com/cnquery/v9/providers/os/connection/shared" "go.mondoo.com/cnquery/v9/providers/os/detector" "go.mondoo.com/cnquery/v9/providers/os/id/awsec2" @@ -27,7 +26,7 @@ type PlatformFingerprint struct { Runtime string Kind string RelatedAssets []PlatformFingerprint - activeIdDetectors []string + ActiveIdDetectors []string } type PlatformInfo struct { @@ -52,15 +51,15 @@ func IdentifyPlatform(conn shared.Connection, p *inventory.Platform, idDetectors if len(idDetectors) == 0 { // fallback to default id detectors switch conn.Type() { - case connection.Local: + case shared.Type_Local: idDetectors = []string{ids.IdDetector_Hostname, ids.IdDetector_CloudDetect} - case connection.SSH: + case shared.Type_SSH: idDetectors = []string{ids.IdDetector_Hostname, ids.IdDetector_CloudDetect, ids.IdDetector_SshHostkey} - case connection.Tar, connection.FileSystem, connection.DockerSnapshot: + case shared.Type_Tar, shared.Type_FileSystem, shared.Type_DockerSnapshot: idDetectors = []string{ids.IdDetector_Hostname} } } - fingerprint.activeIdDetectors = idDetectors + fingerprint.ActiveIdDetectors = idDetectors for i := range idDetectors { idDetector := idDetectors[i] diff --git a/providers/os/provider/provider.go b/providers/os/provider/provider.go index 67aa9b62aa..d7dff74362 100644 --- a/providers/os/provider/provider.go +++ b/providers/os/provider/provider.go @@ -17,8 +17,11 @@ import ( "go.mondoo.com/cnquery/v9/providers-sdk/v1/upstream" "go.mondoo.com/cnquery/v9/providers-sdk/v1/vault" "go.mondoo.com/cnquery/v9/providers/os/connection" + "go.mondoo.com/cnquery/v9/providers/os/connection/fs" + "go.mondoo.com/cnquery/v9/providers/os/connection/local" "go.mondoo.com/cnquery/v9/providers/os/connection/mock" "go.mondoo.com/cnquery/v9/providers/os/connection/shared" + "go.mondoo.com/cnquery/v9/providers/os/id" "go.mondoo.com/cnquery/v9/providers/os/resources" "go.mondoo.com/cnquery/v9/providers/os/resources/discovery/container_registry" "go.mondoo.com/cnquery/v9/providers/os/resources/discovery/docker_engine" @@ -319,13 +322,13 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba switch conf.Type { case LocalConnectionType: s.lastConnectionID++ - conn = connection.NewLocalConnection(s.lastConnectionID, conf, asset) + conn = local.NewConnection(s.lastConnectionID, conf, asset) - fingerprint, err := IdentifyPlatform(conn, asset.Platform, asset.IdDetector) + fingerprint, err := id.IdentifyPlatform(conn, asset.Platform, asset.IdDetector) if err == nil { asset.Name = fingerprint.Name asset.PlatformIds = fingerprint.PlatformIDs - asset.IdDetector = fingerprint.activeIdDetectors + asset.IdDetector = fingerprint.ActiveIdDetectors } case SshConnectionType: @@ -335,13 +338,13 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba return nil, err } - fingerprint, err := IdentifyPlatform(conn, asset.Platform, asset.IdDetector) + fingerprint, err := id.IdentifyPlatform(conn, asset.Platform, asset.IdDetector) if err == nil { if conn.Asset().Connections[0].Runtime != "vagrant" { asset.Name = fingerprint.Name } asset.PlatformIds = fingerprint.PlatformIDs - asset.IdDetector = fingerprint.activeIdDetectors + asset.IdDetector = fingerprint.ActiveIdDetectors } case TarConnectionType: @@ -351,11 +354,11 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba return nil, err } - fingerprint, err := IdentifyPlatform(conn, asset.Platform, asset.IdDetector) + fingerprint, err := id.IdentifyPlatform(conn, asset.Platform, asset.IdDetector) if err == nil { asset.Name = fingerprint.Name asset.PlatformIds = fingerprint.PlatformIDs - asset.IdDetector = fingerprint.activeIdDetectors + asset.IdDetector = fingerprint.ActiveIdDetectors } case DockerSnapshotConnectionType: @@ -365,11 +368,11 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba return nil, err } - fingerprint, err := IdentifyPlatform(conn, asset.Platform, asset.IdDetector) + fingerprint, err := id.IdentifyPlatform(conn, asset.Platform, asset.IdDetector) if err == nil { asset.Name = fingerprint.Name asset.PlatformIds = fingerprint.PlatformIDs - asset.IdDetector = fingerprint.activeIdDetectors + asset.IdDetector = fingerprint.ActiveIdDetectors } case VagrantConnectionType: @@ -403,18 +406,18 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba case FilesystemConnectionType: s.lastConnectionID++ - conn, err = connection.NewFileSystemConnection(s.lastConnectionID, conf, asset) + conn, err = fs.NewConnection(s.lastConnectionID, conf, asset) if err != nil { return nil, err } // This is a workaround to set Google COS platform IDs when scanned from inside k8s - pID, err := conn.(*connection.FileSystemConnection).Identifier() + pID, err := conn.(*fs.FileSystemConnection).Identifier() if err != nil { - fingerprint, err := IdentifyPlatform(conn, asset.Platform, asset.IdDetector) + fingerprint, err := id.IdentifyPlatform(conn, asset.Platform, asset.IdDetector) if err == nil { asset.Name = fingerprint.Name asset.PlatformIds = fingerprint.PlatformIDs - asset.IdDetector = fingerprint.activeIdDetectors + asset.IdDetector = fingerprint.ActiveIdDetectors } } else { // In this case asset.Name should already be set via the inventory diff --git a/providers/os/resources/networkinterface/interface.go b/providers/os/resources/networkinterface/interface.go index 8fd65dbe6f..d317906a0d 100644 --- a/providers/os/resources/networkinterface/interface.go +++ b/providers/os/resources/networkinterface/interface.go @@ -16,7 +16,6 @@ import ( "github.com/cockroachdb/errors" "github.com/rs/zerolog/log" "go.mondoo.com/cnquery/v9/providers-sdk/v1/inventory" - "go.mondoo.com/cnquery/v9/providers/os/connection" "go.mondoo.com/cnquery/v9/providers/os/connection/shared" "go.mondoo.com/cnquery/v9/providers/os/resources/powershell" ) @@ -51,7 +50,7 @@ func (r *InterfaceResource) Interfaces() ([]Interface, error) { } log.Debug().Strs("families", asset.Platform.Family).Msg("check if platform is supported for network interface") - if r.conn.Type() == connection.Local { + if r.conn.Type() == shared.Type_Local { handler := &GoNativeInterfaceHandler{} return handler.Interfaces() } else if asset.Platform.Name == "macos" {