Skip to content

Commit e1319bf

Browse files
authored
✨ IBM cloud detect (#5589)
Enhance our cloud detect package to detect IBM instances. This change follows the patterns already implemented for AWS, GCP, Azure, and VMware. Note that IBM Cloud doesn't have the Metadata service turned on by default, users must opt-in to have it available. Only those instances are the ones we will detect. Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>
1 parent bae003b commit e1319bf

14 files changed

Lines changed: 1216 additions & 3 deletions

File tree

providers/os/id/azure/azure.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const (
2020

2121
func Detect(conn shared.Connection, pf *inventory.Platform) (string, string, []string) {
2222
sysVendor := ""
23-
if pf.IsFamily("linux") {
23+
if pf.IsFamily(inventory.FAMILY_LINUX) {
2424
// Fetching the product version from the smbios manager is slow
2525
// because it iterates through files we don't need to check. This
2626
// is an optimization for our sshfs. Also, be aware that on linux,

providers/os/id/clouddetect/clouddetect.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"go.mondoo.com/cnquery/v11/providers/os/id/aws"
1313
"go.mondoo.com/cnquery/v11/providers/os/id/azure"
1414
"go.mondoo.com/cnquery/v11/providers/os/id/gcp"
15+
"go.mondoo.com/cnquery/v11/providers/os/id/ibm"
1516
"go.mondoo.com/cnquery/v11/providers/os/id/vmware"
1617
)
1718

@@ -32,13 +33,15 @@ var (
3233
GCP CloudProviderType = "GCP"
3334
AZURE CloudProviderType = "AZURE"
3435
VMWARE CloudProviderType = "VMWARE"
36+
IBM CloudProviderType = "IBM"
3537
)
3638

3739
var detectors = map[CloudProviderType]detectorFunc{
3840
AWS: aws.Detect,
3941
GCP: gcp.Detect,
4042
AZURE: azure.Detect,
4143
VMWARE: vmware.Detect,
44+
IBM: ibm.Detect,
4245
}
4346

4447
// PlatformInfo contains platform information gathered from one of our cloud detectors.

providers/os/id/gcp/gcp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const (
2020

2121
func Detect(conn shared.Connection, p *inventory.Platform) (string, string, []string) {
2222
productName := ""
23-
if p.IsFamily("linux") {
23+
if p.IsFamily(inventory.FAMILY_LINUX) {
2424
// Fetching the product version from the smbios manager is slow
2525
// because it iterates through files we don't need to check. This
2626
// is an optimization for our sshfs. Also, be aware that on linux,

providers/os/id/ibm/ibm.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright (c) Mondoo, Inc.
2+
// SPDX-License-Identifier: BUSL-1.1
3+
4+
package ibm
5+
6+
import (
7+
"strings"
8+
9+
"github.com/rs/zerolog/log"
10+
"github.com/spf13/afero"
11+
"go.mondoo.com/cnquery/v11/providers-sdk/v1/inventory"
12+
"go.mondoo.com/cnquery/v11/providers/os/connection/shared"
13+
"go.mondoo.com/cnquery/v11/providers/os/id/ibmcompute"
14+
"go.mondoo.com/cnquery/v11/providers/os/resources/smbios"
15+
)
16+
17+
var identifierFilesLinux = []string{
18+
"/sys/class/dmi/id/chassis_vendor",
19+
"/sys/class/dmi/id/uevent",
20+
"/sys/class/dmi/id/modalias",
21+
}
22+
23+
func Detect(conn shared.Connection, pf *inventory.Platform) (string, string, []string) {
24+
sysVendor := ""
25+
if pf.IsFamily(inventory.FAMILY_LINUX) && pf.Name != "aix" {
26+
// Fetching the product version from the smbios manager is slow
27+
// because it iterates through files we don't need to check. This
28+
// is an optimization for our sshfs. Also, be aware that on linux,
29+
// you may not have access to all the smbios things under /sys, so
30+
// you want to make sure to only check some files for detection
31+
//
32+
// NOTE: The smbios implementation for AIX systems use the command
33+
// `prtconf` which is exactly what we need and performant.
34+
for _, identityFile := range identifierFilesLinux {
35+
content, err := afero.ReadFile(conn.FileSystem(), identityFile)
36+
if err == nil {
37+
sysVendor = string(content)
38+
break
39+
}
40+
log.Debug().Err(err).Msgf("unable to read %s", identityFile)
41+
}
42+
} else {
43+
smbiosMgr, err := smbios.ResolveManager(conn, pf)
44+
if err != nil {
45+
log.Debug().Err(err).Msg("failed to resolve smbios manager")
46+
return "", "", nil
47+
}
48+
49+
info, err := smbiosMgr.Info()
50+
if err != nil {
51+
log.Debug().Err(err).Msg("failed to query smbios")
52+
return "", "", nil
53+
}
54+
55+
sysVendor = info.SysInfo.Vendor
56+
}
57+
58+
if strings.Contains(sysVendor, "IBM") {
59+
mdsvc, err := ibmcompute.Resolve(conn, pf)
60+
if err != nil {
61+
log.Debug().Err(err).Msg("failed to get metadata resolver")
62+
return "", "", nil
63+
}
64+
id, err := mdsvc.Identify()
65+
if err == nil {
66+
return id.InstanceID, id.InstanceName, id.PlatformMrns
67+
}
68+
log.Debug().Err(err).
69+
Strs("platform", pf.GetFamily()).
70+
Msg("failed to get IBM platform id")
71+
}
72+
73+
return "", "", nil
74+
}

providers/os/id/ibm/ibm_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) Mondoo, Inc.
2+
// SPDX-License-Identifier: BUSL-1.1
3+
4+
package ibm_test
5+
6+
import (
7+
"testing"
8+
9+
subject "go.mondoo.com/cnquery/v11/providers/os/id/ibm"
10+
11+
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
13+
"go.mondoo.com/cnquery/v11/providers-sdk/v1/inventory"
14+
"go.mondoo.com/cnquery/v11/providers/os/connection/mock"
15+
"go.mondoo.com/cnquery/v11/providers/os/detector"
16+
)
17+
18+
func TestDetectLinuxInstance(t *testing.T) {
19+
conn, err := mock.New(0, "./testdata/instance_linux.toml", &inventory.Asset{})
20+
require.NoError(t, err)
21+
platform, ok := detector.DetectOS(conn)
22+
require.True(t, ok)
23+
24+
identifier, name, relatedIdentifiers := subject.Detect(conn, platform)
25+
26+
assert.Equal(t,
27+
"//platformid.api.mondoo.app/runtime/ibm/compute/v1/accounts/bbb1e1386b1c419f929ecf7499b20ab6/location/us-east-2/instances/0767_596409db-cb61-4d33-9550-6b86b503ed12",
28+
identifier,
29+
)
30+
assert.Equal(t, "salim-test", name)
31+
require.Len(t, relatedIdentifiers, 1)
32+
assert.Equal(t,
33+
"//platformid.api.mondoo.app/runtime/ibm/compute/v1/accounts/bbb1e1386b1c419f929ecf7499b20ab6",
34+
relatedIdentifiers[0],
35+
)
36+
}
37+
38+
func TestDetectAIXInstance(t *testing.T) {
39+
conn, err := mock.New(0, "./testdata/instance_unix_aix.toml", &inventory.Asset{})
40+
require.NoError(t, err)
41+
platform, ok := detector.DetectOS(conn)
42+
require.True(t, ok)
43+
44+
identifier, name, relatedIdentifiers := subject.Detect(conn, platform)
45+
46+
assert.Equal(t,
47+
"//platformid.api.mondoo.app/runtime/ibm/compute/v1/accounts/bbb1e1386b1c419f929ecf7499b20ab6/location/us-east-2/instances/0767_596409db-cb61-4d33-9550-6b86b503ed12",
48+
identifier,
49+
)
50+
assert.Equal(t, "salim-test", name)
51+
require.Len(t, relatedIdentifiers, 1)
52+
assert.Equal(t,
53+
"//platformid.api.mondoo.app/runtime/ibm/compute/v1/accounts/bbb1e1386b1c419f929ecf7499b20ab6",
54+
relatedIdentifiers[0],
55+
)
56+
}
57+
58+
func TestDetectInstanceWithoutMetadataService(t *testing.T) {
59+
conn, err := mock.New(0, "./testdata/instance_no_metadata.toml", &inventory.Asset{})
60+
require.NoError(t, err)
61+
platform, ok := detector.DetectOS(conn)
62+
require.True(t, ok)
63+
64+
// If the metadata service in the IBM cloud instance is not turned on, we can't detect much
65+
66+
identifier, name, relatedIdentifiers := subject.Detect(conn, platform)
67+
assert.Empty(t, identifier)
68+
assert.Empty(t, name)
69+
require.Empty(t, relatedIdentifiers)
70+
}

0 commit comments

Comments
 (0)