-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: fstab parser * allow "rootfs" * nil-check FileSystem * feat: path param * handle wrong connection type * docs * Update providers/os/resources/os.lr Co-authored-by: Letha <[email protected]> * man ref --------- Co-authored-by: Letha <[email protected]>
- Loading branch information
1 parent
241213e
commit 971a960
Showing
7 changed files
with
581 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Copyright (c) Mondoo, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
package resources | ||
|
||
import ( | ||
"bufio" | ||
"errors" | ||
"io" | ||
"strconv" | ||
"strings" | ||
|
||
"go.mondoo.com/cnquery/v11/llx" | ||
"go.mondoo.com/cnquery/v11/providers-sdk/v1/plugin" | ||
"go.mondoo.com/cnquery/v11/providers/os/connection/shared" | ||
) | ||
|
||
func initFstab(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) { | ||
if x, ok := args["path"]; ok { | ||
path, ok := x.Value.(string) | ||
if !ok || path == "" { | ||
path = "/etc/fstab" | ||
} | ||
|
||
f, err := CreateResource(runtime, "fstab", map[string]*llx.RawData{ | ||
"path": llx.StringData(path), | ||
}) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
args["path"] = llx.StringData(path) | ||
return args, f, nil | ||
} | ||
|
||
args["path"] = llx.StringData("/etc/fstab") | ||
return args, nil, nil | ||
} | ||
|
||
func (f *mqlFstab) entries() ([]any, error) { | ||
conn, ok := f.MqlRuntime.Connection.(shared.Connection) | ||
if !ok { | ||
return nil, errors.New("wrong connection type") | ||
} | ||
|
||
fs := conn.FileSystem() | ||
if fs == nil { | ||
return nil, errors.New("filesystem not available") | ||
} | ||
|
||
fstabFile, err := fs.Open(f.GetPath().Data) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer fstabFile.Close() | ||
|
||
entries, err := ParseFstab(fstabFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
resources := []any{} | ||
for _, entry := range entries { | ||
resource, err := CreateResource(f.MqlRuntime, "fstab.entry", map[string]*llx.RawData{ | ||
"device": llx.StringData(entry.Device), | ||
"mountpoint": llx.StringData(entry.Mountpoint), | ||
"fstype": llx.StringData(entry.Fstype), | ||
"options": llx.StringData(entry.Options), | ||
"dump": llx.IntDataPtr(entry.Dump), | ||
"fsck": llx.IntDataPtr(entry.Fsck), | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
resources = append(resources, resource) | ||
} | ||
|
||
return resources, nil | ||
} | ||
|
||
type FstabEntry struct { | ||
Device string | ||
Mountpoint string | ||
Fstype string | ||
Options string | ||
Dump *int | ||
Fsck *int | ||
} | ||
|
||
func ParseFstab(file io.Reader) ([]FstabEntry, error) { | ||
scanner := bufio.NewScanner(file) | ||
scanner.Split(bufio.ScanLines) | ||
|
||
var entries []FstabEntry | ||
for scanner.Scan() { | ||
line := scanner.Text() | ||
// Skip comments and empty lines | ||
if line == "" || line[0] == '#' { | ||
continue | ||
} | ||
|
||
record := strings.Fields(line) | ||
if len(record) < 4 { | ||
return nil, errors.New("invalid fstab entry") | ||
} | ||
|
||
var dump *int | ||
if len(record) >= 5 { | ||
_dump, err := strconv.Atoi(record[4]) | ||
if err != nil { | ||
return nil, err | ||
} | ||
dump = &_dump | ||
} | ||
|
||
var fsck *int | ||
if len(record) >= 6 { | ||
_fsck, err := strconv.Atoi(record[5]) | ||
if err != nil { | ||
return nil, err | ||
} | ||
fsck = &_fsck | ||
} | ||
|
||
entry := FstabEntry{ | ||
Device: record[0], | ||
Mountpoint: record[1], | ||
Fstype: record[2], | ||
Options: record[3], | ||
Dump: dump, | ||
Fsck: fsck, | ||
} | ||
|
||
entries = append(entries, entry) | ||
} | ||
|
||
return entries, nil | ||
} | ||
|
||
func (e *mqlFstabEntry) id() (string, error) { | ||
return e.Device.Data, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
// Copyright (c) Mondoo, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
package resources | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"k8s.io/utils/ptr" | ||
) | ||
|
||
func TestFstabEntries(t *testing.T) { | ||
t.Run("valid", func(t *testing.T) { | ||
testdata := `# <device> <dir> <type> <options> <dump> <fsck> | ||
UUID=0a3407de-014b-458b-b5c1-848e92a327a3 / ext4 defaults 0 1 | ||
UUID=f9fe0b69-a280-415d-a03a-a32752370dee none swap defaults 0 0 | ||
UUID=b411dc99-f0a0-4c87-9e05-184977be8539 /home ext4 defaults 0 2` | ||
|
||
reader := strings.NewReader(testdata) | ||
entries, err := ParseFstab(reader) | ||
|
||
require.NoError(t, err) | ||
require.Len(t, entries, 3) | ||
|
||
require.Equal(t, FstabEntry{ | ||
Device: "UUID=0a3407de-014b-458b-b5c1-848e92a327a3", | ||
Mountpoint: "/", | ||
Fstype: "ext4", | ||
Options: "defaults", | ||
Dump: ptr.To(0), | ||
Fsck: ptr.To(1), | ||
}, entries[0]) | ||
require.Equal(t, FstabEntry{ | ||
Device: "UUID=f9fe0b69-a280-415d-a03a-a32752370dee", | ||
Mountpoint: "none", | ||
Fstype: "swap", | ||
Options: "defaults", | ||
Dump: ptr.To(0), | ||
Fsck: ptr.To(0), | ||
}, entries[1]) | ||
require.Equal(t, FstabEntry{ | ||
Device: "UUID=b411dc99-f0a0-4c87-9e05-184977be8539", | ||
Mountpoint: "/home", | ||
Fstype: "ext4", | ||
Options: "defaults", | ||
Dump: ptr.To(0), | ||
Fsck: ptr.To(2), | ||
}, entries[2]) | ||
}) | ||
|
||
t.Run("short", func(t *testing.T) { | ||
testdata := `# <device> <dir> <type> <options> | ||
UUID=0a3407de-014b-458b-b5c1-848e92a327a3 / ext4 defaults | ||
UUID=f9fe0b69-a280-415d-a03a-a32752370dee none swap defaults | ||
UUID=b411dc99-f0a0-4c87-9e05-184977be8539 /home ext4 defaults` | ||
|
||
reader := strings.NewReader(testdata) | ||
entries, err := ParseFstab(reader) | ||
|
||
require.NoError(t, err) | ||
require.Len(t, entries, 3) | ||
|
||
require.Equal(t, FstabEntry{ | ||
Device: "UUID=0a3407de-014b-458b-b5c1-848e92a327a3", | ||
Mountpoint: "/", | ||
Fstype: "ext4", | ||
Options: "defaults", | ||
}, entries[0]) | ||
require.Equal(t, FstabEntry{ | ||
Device: "UUID=f9fe0b69-a280-415d-a03a-a32752370dee", | ||
Mountpoint: "none", | ||
Fstype: "swap", | ||
Options: "defaults", | ||
}, entries[1]) | ||
require.Equal(t, FstabEntry{ | ||
Device: "UUID=b411dc99-f0a0-4c87-9e05-184977be8539", | ||
Mountpoint: "/home", | ||
Fstype: "ext4", | ||
Options: "defaults", | ||
}, entries[2]) | ||
}) | ||
|
||
t.Run("valid (with tabs)", func(t *testing.T) { | ||
testdata := `# <device> <dir> <type> <options> <dump> <fsck> | ||
LABEL=cloudimg-rootfs / ext4 discard,commit=30,errors=remount-ro 0 1 | ||
LABEL=BOOT /boot ext4 defaults 0 2 | ||
LABEL=UEFI /boot/efi vfat umask=0077 0 1` | ||
|
||
reader := strings.NewReader(testdata) | ||
entries, err := ParseFstab(reader) | ||
|
||
require.NoError(t, err) | ||
require.Len(t, entries, 3) | ||
|
||
require.Equal(t, FstabEntry{ | ||
Device: "LABEL=cloudimg-rootfs", | ||
Mountpoint: "/", | ||
Fstype: "ext4", | ||
Options: "discard,commit=30,errors=remount-ro", | ||
Dump: ptr.To(0), | ||
Fsck: ptr.To(1), | ||
}, entries[0]) | ||
require.Equal(t, FstabEntry{ | ||
Device: "LABEL=BOOT", | ||
Mountpoint: "/boot", | ||
Fstype: "ext4", | ||
Options: "defaults", | ||
Dump: ptr.To(0), | ||
Fsck: ptr.To(2), | ||
}, entries[1]) | ||
require.Equal(t, FstabEntry{ | ||
Device: "LABEL=UEFI", | ||
Mountpoint: "/boot/efi", | ||
Fstype: "vfat", | ||
Options: "umask=0077", | ||
Dump: ptr.To(0), | ||
Fsck: ptr.To(1), | ||
}, entries[2]) | ||
}) | ||
|
||
t.Run("invalid (too short)", func(t *testing.T) { | ||
testdata := `# <device> <dir> <type> | ||
UUID=0a3407de-014b-458b-b5c1-848e92a327a3 / ext4 | ||
UUID=f9fe0b69-a280-415d-a03a-a32752370dee none swap | ||
UUID=b411dc99-f0a0-4c87-9e05-184977be8539 /home ext4` | ||
|
||
reader := strings.NewReader(testdata) | ||
entries, err := ParseFstab(reader) | ||
|
||
require.Error(t, err) | ||
require.Nil(t, entries) | ||
}) | ||
|
||
t.Run("invalid (not numeric dump)", func(t *testing.T) { | ||
testdata := `# <device> <dir> <type> <options> <dump> <fsck> | ||
UUID=0a3407de-014b-458b-b5c1-848e92a327a3 / ext4 defaults 0 1 | ||
UUID=f9fe0b69-a280-415d-a03a-a32752370dee none swap defaults 0 0 | ||
UUID=b411dc99-f0a0-4c87-9e05-184977be8539 /home ext4 defaults A 2` // note the 'A' here | ||
|
||
reader := strings.NewReader(testdata) | ||
entries, err := ParseFstab(reader) | ||
|
||
require.Error(t, err) | ||
require.Nil(t, entries) | ||
}) | ||
|
||
t.Run("invalid (not numeric fsck)", func(t *testing.T) { | ||
testdata := `# <device> <dir> <type> <options> <dump> <fsck> | ||
UUID=0a3407de-014b-458b-b5c1-848e92a327a3 / ext4 defaults 0 1 | ||
UUID=f9fe0b69-a280-415d-a03a-a32752370dee none swap defaults 0 0 | ||
UUID=b411dc99-f0a0-4c87-9e05-184977be8539 /home ext4 defaults 0 A` // note the 'A' here | ||
|
||
reader := strings.NewReader(testdata) | ||
entries, err := ParseFstab(reader) | ||
|
||
require.Error(t, err) | ||
require.Nil(t, entries) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.