Skip to content

Commit 7b4e9a8

Browse files
Ahmet OeztuerkAhmet Oeztuerk
authored andcommitted
linter fixes, new attribute localised_remote_path, update docs
localised_remote_path saves the original path where the remote share is replaced by a drive letter stop using the "logicalDrive - remoteName" as the "drive_or_name" attribute for network drives, revert it back to logicalDrive. If needed, users can set their own syntax
1 parent 451cb90 commit 7b4e9a8

File tree

5 files changed

+184
-180
lines changed

5 files changed

+184
-180
lines changed

docs/checks/commands/check_drivesize.md

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -81,40 +81,43 @@ Naemon Config
8181

8282
these can be used in filters and thresholds (along with the default attributes):
8383

84-
| Attribute | Description |
85-
| --------------- | ----------------------------------------------------------------------------------- |
86-
| drive | Technical name of drive |
87-
| name | Descriptive name of drive |
88-
| id | Drive or id of drive |
89-
| drive_or_id | Drive letter if present if not use id |
90-
| drive_or_name | Drive letter if present if not use name |
91-
| fstype | Filesystem type |
92-
| mounted | Flag wether drive is mounter (0/1) |
93-
| free | Free (human readable) bytes |
94-
| free_bytes | Number of free bytes |
95-
| free_pct | Free bytes in percent |
96-
| user_free | Number of total free bytes (from user perspective) |
97-
| user_free_pct | Number of total % free space (from user perspective) |
98-
| total_free | Number of total free bytes |
99-
| total_free_pct | Number of total % free space |
100-
| used | Used (human readable) bytes |
101-
| used_bytes | Number of used bytes |
102-
| used_pct | Used bytes in percent (from user perspective) |
103-
| user_used | Number of total used bytes (from user perspective) |
104-
| user_used_pct | Number of total % used space |
105-
| total_used | Number of total used bytes (including root reserved) |
106-
| total_used_pct | Number of total % used space (including root reserved) |
107-
| size | Total size in human readable bytes |
108-
| size_bytes | Total size in bytes |
109-
| inodes_free | Number of free inodes |
110-
| inodes_free_pct | Number of free inodes in percent |
111-
| inodes_total | Number of total free inodes |
112-
| inodes_used | Number of used inodes |
113-
| inodes_used_pct | Number of used inodes in percent |
114-
| media_type | Windows only: numeric media type of drive |
115-
| type | Windows only: type of drive, ex.: fixed, cdrom, ramdisk, remote, removable, unknown |
116-
| readable | Windows only: flag drive is readable (0/1) |
117-
| writable | Windows only: flag drive is writable (0/1) |
118-
| removable | Windows only: flag drive is removable (0/1) |
119-
| erasable | Windows only: flag wether if drive is erasable (0/1) |
120-
| hotplug | Windows only: flag drive is hotplugable (0/1) |
84+
| Attribute | Description |
85+
| --------------------- | --------------------------------------------------------------------------------------------- |
86+
| drive | Technical name of drive |
87+
| name | Descriptive name of drive |
88+
| id | Drive or id of drive |
89+
| drive_or_id | Drive letter if present if not use id |
90+
| drive_or_name | Drive letter if present if not use name |
91+
| fstype | Filesystem type |
92+
| mounted | Flag wether drive is mounter (0/1) |
93+
| free | Free (human readable) bytes |
94+
| free_bytes | Number of free bytes |
95+
| free_pct | Free bytes in percent |
96+
| user_free | Number of total free bytes (from user perspective) |
97+
| user_free_pct | Number of total % free space (from user perspective) |
98+
| total_free | Number of total free bytes |
99+
| total_free_pct | Number of total % free space |
100+
| used | Used (human readable) bytes |
101+
| used_bytes | Number of used bytes |
102+
| used_pct | Used bytes in percent (from user perspective) |
103+
| user_used | Number of total used bytes (from user perspective) |
104+
| user_used_pct | Number of total % used space |
105+
| total_used | Number of total used bytes (including root reserved) |
106+
| total_used_pct | Number of total % used space (including root reserved) |
107+
| size | Total size in human readable bytes |
108+
| size_bytes | Total size in bytes |
109+
| inodes_free | Number of free inodes |
110+
| inodes_free_pct | Number of free inodes in percent |
111+
| inodes_total | Number of total free inodes |
112+
| inodes_used | Number of used inodes |
113+
| inodes_used_pct | Number of used inodes in percent |
114+
| media_type | Windows only: numeric media type of drive |
115+
| type | Windows only: type of drive, ex.: fixed, cdrom, ramdisk, remote, removable, unknown |
116+
| readable | Windows only: flag drive is readable (0/1) |
117+
| writable | Windows only: flag drive is writable (0/1) |
118+
| removable | Windows only: flag drive is removable (0/1) |
119+
| erasable | Windows only: flag wether if drive is erasable (0/1) |
120+
| hotplug | Windows only: flag drive is hotplugable (0/1) |
121+
| remote_name | Windows only: the remote name of the drive, if it uses a network name |
122+
| persistent | Windows only: if the network drive is mounted as persistent (0/1) |
123+
| localised_remote_path | Windows only: If the path is given as a remote path, and that remote path has an assigned logical drive, this is the replaced path under that logical drive. |

pkg/snclient/check_drivesize.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ func (l *CheckDrivesize) Build() *CheckData {
149149

150150
{name: "remote_name", description: "Windows only: the remote name of the drive, if it uses a network name"},
151151
{name: "persistent", description: "Windows only: if the network drive is mounted as persistent (0/1)"},
152+
{name: "localised_remote_path", description: "Windows only: If the path is given as a remote path, and that remote path has an assigned logical drive," +
153+
" this is the replaced path under that logical drive."},
152154
},
153155
exampleDefault: l.getExample(),
154156
exampleArgs: `'warn=used_pct > 90' 'crit=used_pct > 95'`,

pkg/snclient/check_drivesize_windows.go

Lines changed: 42 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func (l *CheckDrivesize) getExample() string {
4747
}
4848

4949
// Terminology
50-
// Disk : Phyiscal Hardware like a HDD, SSD, Usb Stick. A block device that ca be used to store raw bytes -> \\.\PhysicalDrive0
50+
// Disk : Physical Hardware like a HDD, SSD, Usb Stick. A block device that ca be used to store raw bytes -> \\.\PhysicalDrive0
5151
// Partition: Is written into the disk in a partition table. It exists independently of volumes, may not be used by Windows
5252
// Volume: A logical abstraction of a storage, formatted with a file system. It can be a virtual file, a RAID disk or one partition -> \\?\Volume{GUID}\
5353
// Drive: This term is not defined well. Here, it means a logical access point with an assigned drive letter.
@@ -65,13 +65,13 @@ func (l *CheckDrivesize) getRequiredDrives(paths []string, parentFallback bool)
6565
switch drive {
6666
case "*", "all":
6767
l.setVolumes(requiredDrives)
68-
err := l.setDrives2(requiredDrives)
68+
err := l.setDrives(requiredDrives)
6969
if err != nil {
7070
return nil, err
7171
}
7272
l.setShares(requiredDrives)
7373
case "all-drives":
74-
err := l.setDrives2(requiredDrives)
74+
err := l.setDrives(requiredDrives)
7575
if err != nil {
7676
return nil, err
7777
}
@@ -259,12 +259,14 @@ func (l *CheckDrivesize) setMediaType(drive map[string]string) error {
259259
return nil
260260
}
261261

262-
// Uses GetVolumeInformaton syscall
263-
// Works on network drives
262+
// uses GetVolumeInformaton syscall, works on network drives
263+
//
264+
//nolint:funlen //no need to split this
264265
func (l *CheckDrivesize) setDeviceInfo(drive map[string]string) {
265266
driveType, err := GetDriveType(drive["drive_or_id"])
266267
if err != nil {
267268
log.Warnf("Error when getting the drive type of drive %s: %s", drive["drive_or_id"], err.Error())
269+
268270
return
269271
}
270272
drive["type"] = driveType.toString()
@@ -342,46 +344,15 @@ func (l *CheckDrivesize) setDeviceInfo(drive map[string]string) {
342344
}
343345
}
344346

345-
func (l *CheckDrivesize) setDrives(requiredDisks map[string]map[string]string) (err error) {
346-
// For discovering available disks, psutil for go is used.
347-
partitions, err := disk.Partitions(true)
348-
349-
if err != nil && len(partitions) == 0 {
350-
// in case even a single drive is locked by BitLocker, then
351-
// the disk.Partitions returns an error.
352-
// "This drive is locked by BitLocker Drive Encryption. You must unlock this drive from Control Panel"
353-
// but there can still be valid elements in partitions,
354-
// so abort here only if partitions is empty.
355-
return &PartitionDiscoveryError{err: err}
356-
}
357-
358-
for _, partition := range partitions {
359-
drive := strings.TrimSuffix(partition.Device, "\\") + "\\"
360-
entry, ok := requiredDisks[drive]
361-
if !ok {
362-
entry = make(map[string]string)
363-
}
364-
entry["drive"] = drive
365-
entry["drive_or_id"] = drive
366-
entry["drive_or_name"] = drive
367-
entry["letter"] = fmt.Sprintf("%c", drive[0])
368-
entry["fstype"] = partition.Fstype
369-
requiredDisks[drive] = entry
370-
}
371-
372-
return nil
373-
}
374-
375347
// adds all logical drives to the requiredDisks
376-
func (l *CheckDrivesize) setDrives2(requiredDrives map[string]map[string]string) (err error) {
348+
// this function is better suited for usage with-network drives. gopsutil has disk.Partitions, but that does not work with network drives
349+
func (l *CheckDrivesize) setDrives(requiredDrives map[string]map[string]string) (err error) {
377350
logicalDrives, err := GetLogicalDriveStrings(1024)
378351
if err != nil {
379352
log.Debug("Error when getting logical drive strings: %s", err.Error())
380353
}
381354

382355
for _, logicalDrive := range logicalDrives {
383-
// logicalDrive := strings.TrimSuffix(logicalDrive, "\\")
384-
385356
entry, ok := requiredDrives[logicalDrive]
386357
if !ok {
387358
entry = make(map[string]string)
@@ -390,7 +361,6 @@ func (l *CheckDrivesize) setDrives2(requiredDrives map[string]map[string]string)
390361
entry["drive_or_id"] = logicalDrive
391362
entry["drive_or_name"] = logicalDrive
392363
entry["letter"] = fmt.Sprintf("%c", logicalDrive[0])
393-
// entry["fstype"] = partition.Fstype
394364
requiredDrives[logicalDrive] = entry
395365
}
396366

@@ -431,7 +401,7 @@ func (l *CheckDrivesize) setVolumes(requiredDrives map[string]map[string]string)
431401
volumeGUIDPaths = append(volumeGUIDPaths, syscall.UTF16ToString(volumeGUIDPathBuffer))
432402
}
433403

434-
// Windows syscall findFirstVolume, findNextVolume... give GUID paths to to volumes e.g:
404+
// Windows syscall findFirstVolume, findNextVolume... give GUID paths to volumes e.g:
435405
// "\\\\?\\Volume{a6b8f57e-dac6-4bac-8dc2-fac22cd740cf}\\"
436406
// They need to be translated
437407
for _, volumeGUIDPath := range volumeGUIDPaths {
@@ -491,13 +461,13 @@ func (l *CheckDrivesize) setVolume(requiredDisks map[string]map[string]string, v
491461
// This function is called when a custom path needs to be added
492462
// This is used if folders are given
493463
// c:/, d:/volume, f:/folder/with/slash
464+
//
465+
//nolint:funlen // can not split this function up
494466
func (l *CheckDrivesize) setCustomPath(path string, requiredDisks map[string]map[string]string, parentFallback bool) (err error) {
495467
path = strings.ReplaceAll(path, "/", "\\")
496-
497468
// if its a network share path, discover existing shares and match it with a drive[remote_path]
498469
// then we replace path argument in-place, replacing the network path with the logical drive it is assigned to
499470
if isNetworkSharePath(path) {
500-
501471
discoveredNetworkShares := map[string]map[string]string{}
502472
l.setShares(discoveredNetworkShares)
503473

@@ -512,7 +482,9 @@ func (l *CheckDrivesize) setCustomPath(path string, requiredDisks map[string]map
512482
// pathExample2 = \\SERVER\SHARENAME\FOO\BAR -> X:\FOO\BAR
513483
pathReplaced := strings.Replace(path, drive["remote_name"], drive["drive"], 1)
514484
requiredDisks[key]["drive"] = pathReplaced
515-
requiredDisks[key]["drive_or_name"] = fmt.Sprintf("%s - (%s)", path, pathReplaced)
485+
// It is better to let users set their own detailSyntax or okSyntax, we give them the attributes for it
486+
// requiredDisks[key]["drive_or_name"] = fmt.Sprintf("%s - (%s)", path, pathReplaced)
487+
requiredDisks[key]["localised_remote_path"] = pathReplaced
516488

517489
return nil
518490
}
@@ -524,7 +496,7 @@ func (l *CheckDrivesize) setCustomPath(path string, requiredDisks map[string]map
524496
case 1, 2:
525497
path = strings.TrimSuffix(path, ":") + ":"
526498
availDisks := map[string]map[string]string{}
527-
err = l.setDrives2(availDisks)
499+
err = l.setDrives(availDisks)
528500
for driveOrID := range availDisks {
529501
if strings.EqualFold(driveOrID, path+"\\") {
530502
requiredDisks[path] = utils.CloneStringMap(availDisks[driveOrID])
@@ -600,40 +572,40 @@ func (l *CheckDrivesize) setShares(requiredDisks map[string]map[string]string) {
600572
}
601573

602574
for _, logicalDrive := range logicalDrives {
603-
//log.Debugf("Logical Drive: %s", logicalDrive)
604-
605575
driveType, err := GetDriveType(logicalDrive)
606576
if err != nil {
607577
log.Debug("Error when getting the drive type for logical drive %s network drives: %s", logicalDrive, err.Error())
608-
} else {
609-
//log.Debugf("Drive Type: %d", driveType)
610-
}
611578

612-
if driveType == DRIVE_REMOTE {
579+
continue
580+
}
581+
if driveType == DriveRemote {
613582
remoteName, err := NetGetConnection(logicalDrive[0 : len(logicalDrive)-1])
614583
if err != nil {
615584
log.Debug("Error when getting the connection for logical drive %s : %s", logicalDrive, err.Error())
585+
586+
continue
587+
}
588+
log.Debugf("Logical Drive: %s, Drive Type: %d, Remote name: %s", logicalDrive, driveType, remoteName)
589+
// modify existing drive if its there
590+
// if its not, add it new
591+
drive, ok := requiredDisks[logicalDrive]
592+
if !ok {
593+
drive = make(map[string]string)
594+
}
595+
drive["id"] = remoteName
596+
drive["drive"] = logicalDrive
597+
drive["drive_or_id"] = logicalDrive
598+
// It is better to let users set their own detailSyntax or okSyntax, we give them the attributes for it
599+
drive["drive_or_name"] = logicalDrive
600+
drive["localised_remote_path"] = remoteName
601+
drive["letter"] = logicalDrive
602+
drive["remote_name"] = remoteName
603+
if isNetworkDrivePersistent(logicalDrive) {
604+
drive["persistent"] = "1"
616605
} else {
617-
log.Debugf("Remote name: %s", remoteName)
618-
// modify existing drive if its there
619-
// if its not, add it yourself
620-
drive, ok := requiredDisks[logicalDrive]
621-
if !ok {
622-
drive = make(map[string]string)
623-
}
624-
drive["id"] = remoteName
625-
drive["drive"] = logicalDrive
626-
drive["drive_or_id"] = logicalDrive
627-
drive["drive_or_name"] = fmt.Sprintf("%s - (%s)", logicalDrive, remoteName)
628-
drive["letter"] = logicalDrive
629-
drive["remote_name"] = remoteName
630-
if isNetworkDrivePersistent(logicalDrive) {
631-
drive["persistent"] = "1"
632-
} else {
633-
drive["persistent"] = "0"
634-
}
635-
requiredDisks[logicalDrive] = drive
606+
drive["persistent"] = "0"
636607
}
608+
requiredDisks[logicalDrive] = drive
637609
}
638610
}
639611
}
@@ -646,12 +618,12 @@ func isNetworkDrivePersistent(driveLetter string) (isPersistent bool) {
646618
log.Debug("Error when discovering persistent network drives: %s", err.Error())
647619
}
648620
for _, drive := range persistentNetworkDrives {
649-
//log.Debugf("Found persistent network drive %s", drive.DriveLetter)
650621
if drive.DriveLetter == driveLetter {
651622
return true
652623
}
653624
}
654625
log.Debugf("Found no persistent network drive with driveLetter %s", driveLetter)
626+
655627
return false
656628
}
657629

0 commit comments

Comments
 (0)