diff --git a/changelog.txt b/changelog.txt index 25223a60..6686d308 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,11 +4,12 @@ jc changelog - Add OSX support for the ifconfig parser - Add OSX support for the arp parser - Add OSX support for the df parser +- Add OSX support for the mount parser - Add tests for ls on OSX - Add tests for dig on OSX - Add tests for ps on OSX - Add universal parsers to refactor repetitive code -- Updated ifconfig parser to output state as an array +- Updated ifconfig parser to output 'state' as an array 20191117 v1.5.1 - Add ss parser diff --git a/jc/parsers/mount.py b/jc/parsers/mount.py index 1b199a98..06949e27 100644 --- a/jc/parsers/mount.py +++ b/jc/parsers/mount.py @@ -6,7 +6,7 @@ Usage: Compatibility: - 'linux' + 'linux', 'darwin' Example: @@ -82,6 +82,51 @@ def process(proc_data): return proc_data +def osx_parse(data): + output = [] + + for entry in data: + output_line = {} + + filesystem = entry.split(' on ') + filesystem = filesystem[0] + output_line['filesystem'] = filesystem + + mount_point = entry.split(' on ') + mount_point = mount_point[1].split(' (') + mount_point = mount_point[0] + output_line['mount_point'] = mount_point + + options = entry.split('(', maxsplit=1) + options = options[1].rstrip(')') + options = options.split(', ') + output_line['options'] = options + + output.append(output_line) + + return output + + +def linux_parse(data): + output = [] + + for entry in data: + output_line = {} + parsed_line = entry.split() + + output_line['filesystem'] = parsed_line[0] + output_line['mount_point'] = parsed_line[2] + output_line['type'] = parsed_line[4] + + options = parsed_line[5].lstrip('(').rstrip(')').split(',') + + output_line['options'] = options + + output.append(output_line) + + return output + + def parse(data, raw=False, quiet=False): """ Main text parsing function @@ -98,32 +143,23 @@ def parse(data, raw=False, quiet=False): """ # compatible options: linux, darwin, cygwin, win32, aix, freebsd - compatible = ['linux'] + compatible = ['linux', 'darwin'] if not quiet: jc.utils.compatibility(__name__, compatible) - raw_output = [] - linedata = data.splitlines() # Clear any blank lines cleandata = list(filter(None, linedata)) if cleandata: - for entry in cleandata: - output_line = {} - parsed_line = entry.split() + # check for OSX output + if cleandata[0].find(' type ') == -1: + raw_output = osx_parse(cleandata) - output_line['filesystem'] = parsed_line[0] - output_line['mount_point'] = parsed_line[2] - output_line['type'] = parsed_line[4] - - access = parsed_line[5].lstrip('(').rstrip(')').split(',') - - output_line['options'] = access - - raw_output.append(output_line) + else: + raw_output = linux_parse(cleandata) if raw: return raw_output diff --git a/tests/fixtures/osx-10.14.6/mount.json b/tests/fixtures/osx-10.14.6/mount.json new file mode 100644 index 00000000..c307f8f6 --- /dev/null +++ b/tests/fixtures/osx-10.14.6/mount.json @@ -0,0 +1 @@ +[{"filesystem": "/dev/disk1s1", "mount_point": "/", "options": ["apfs", "local", "journaled"]}, {"filesystem": "devfs", "mount_point": "/dev", "options": ["devfs", "local", "nobrowse"]}, {"filesystem": "/dev/disk1s4", "mount_point": "/private/var/vm", "options": ["apfs", "local", "noexec", "journaled", "noatime", "nobrowse"]}, {"filesystem": "map -hosts", "mount_point": "/net", "options": ["autofs", "nosuid", "automounted", "nobrowse"]}, {"filesystem": "map auto_home", "mount_point": "/home", "options": ["autofs", "automounted", "nobrowse"]}, {"filesystem": "/dev/disk1s3", "mount_point": "/Volumes/Recovery", "options": ["apfs", "local", "journaled", "nobrowse"]}] diff --git a/tests/fixtures/osx-10.14.6/mount.out b/tests/fixtures/osx-10.14.6/mount.out new file mode 100644 index 00000000..b0608bc2 --- /dev/null +++ b/tests/fixtures/osx-10.14.6/mount.out @@ -0,0 +1,6 @@ +/dev/disk1s1 on / (apfs, local, journaled) +devfs on /dev (devfs, local, nobrowse) +/dev/disk1s4 on /private/var/vm (apfs, local, noexec, journaled, noatime, nobrowse) +map -hosts on /net (autofs, nosuid, automounted, nobrowse) +map auto_home on /home (autofs, automounted, nobrowse) +/dev/disk1s3 on /Volumes/Recovery (apfs, local, journaled, nobrowse) diff --git a/tests/fixtures/osx-10.14.6/mount2.json b/tests/fixtures/osx-10.14.6/mount2.json new file mode 100644 index 00000000..d5c29c82 --- /dev/null +++ b/tests/fixtures/osx-10.14.6/mount2.json @@ -0,0 +1 @@ +[{"filesystem": "/dev/disk1s1", "mount_point": "/", "options": ["apfs", "local", "journaled"]}, {"filesystem": "devfs", "mount_point": "/dev", "options": ["devfs", "local", "nobrowse"]}, {"filesystem": "/dev/disk1s4", "mount_point": "/private/var/vm", "options": ["apfs", "local", "noexec", "journaled", "noatime", "nobrowse"]}, {"filesystem": "map -hosts", "mount_point": "/net", "options": ["autofs", "nosuid", "automounted", "nobrowse"]}, {"filesystem": "map auto_home", "mount_point": "/home", "options": ["autofs", "automounted", "nobrowse"]}, {"filesystem": "//brazil@MyCloudEX2Ultra._afpovertcp._tcp.local/brazil", "mount_point": "/Volumes/brazil", "options": ["afpfs", "nodev", "nosuid", "mounted by kelly"]}, {"filesystem": "/dev/disk1s3", "mount_point": "/Volumes/Recovery", "options": ["apfs", "local", "journaled", "nobrowse"]}] diff --git a/tests/fixtures/osx-10.14.6/mount2.out b/tests/fixtures/osx-10.14.6/mount2.out new file mode 100755 index 00000000..432ded5d --- /dev/null +++ b/tests/fixtures/osx-10.14.6/mount2.out @@ -0,0 +1,7 @@ +/dev/disk1s1 on / (apfs, local, journaled) +devfs on /dev (devfs, local, nobrowse) +/dev/disk1s4 on /private/var/vm (apfs, local, noexec, journaled, noatime, nobrowse) +map -hosts on /net (autofs, nosuid, automounted, nobrowse) +map auto_home on /home (autofs, automounted, nobrowse) +//brazil@MyCloudEX2Ultra._afpovertcp._tcp.local/brazil on /Volumes/brazil (afpfs, nodev, nosuid, mounted by kelly) +/dev/disk1s3 on /Volumes/Recovery (apfs, local, journaled, nobrowse) diff --git a/tests/test_mount.py b/tests/test_mount.py index 7fb10045..2c01948e 100644 --- a/tests/test_mount.py +++ b/tests/test_mount.py @@ -16,6 +16,12 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/mount.out'), 'r') as f: self.ubuntu_18_4_mount = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/mount.out'), 'r') as f: + self.osx_10_14_6_mount = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/mount2.out'), 'r') as f: + self.osx_10_14_6_mount2 = f.read() + # output with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/mount.json'), 'r') as f: self.centos_7_7_mount_json = json.loads(f.read()) @@ -23,6 +29,12 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/mount.json'), 'r') as f: self.ubuntu_18_4_mount_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/mount.json'), 'r') as f: + self.osx_10_14_6_mount_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/mount2.json'), 'r') as f: + self.osx_10_14_6_mount2_json = json.loads(f.read()) + def test_mount_centos_7_7(self): """ Test 'mount' on Centos 7.7 @@ -35,6 +47,18 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.mount.parse(self.ubuntu_18_4_mount, quiet=True), self.ubuntu_18_4_mount_json) + def test_mount_osx_10_14_6(self): + """ + Test 'mount' on OSX 10.14.6 + """ + self.assertEqual(jc.parsers.mount.parse(self.osx_10_14_6_mount, quiet=True), self.osx_10_14_6_mount_json) + + def test_mount2_osx_10_14_6(self): + """ + Test 'mount' on OSX 10.14.6 #2 + """ + self.assertEqual(jc.parsers.mount.parse(self.osx_10_14_6_mount2, quiet=True), self.osx_10_14_6_mount2_json) + if __name__ == '__main__': unittest.main()