I’ve observed the following behavior when monitoring NetApp filer with CheckMK: if multiple LUNs share the same name (e.g., “k.lun”), CheckMK creates only a single service, even though they reside on different volumes.
All underlying volumes are detected and displayed correctly as services. For the LUNs named “k.lun”, however, only one service is created because CheckMK’s plugin appears to use only the LUN name itself.
For clarity, here is an excerpt of the volumes on NetApp:
netapp34 /vol/cp1c02bin/k.lun online mapped windows_2019 20 GB
netapp34 /vol/ke3c02bin/k.lun online mapped windows_2019 20 GB
netapp34 /vol/sk1Ndat/a/k.lun online mapped windows_2019 1.20 TB
netapp34 /vol/sk3c02bin/k.lun online mapped windows_2019 20 GB
netapp34 /vol/sp1c02bin/k.lun online mapped windows_2019 30 GB
netapp34 /vol/sp3c02bin/k.lun online mapped windows_2019 50 GB
In CheckMK, you can see all the volume names (for example, /vol/cp1c02bin, /vol/ke3c02bin, etc.), but for every LUN called “k.lun” only one service is created since the plugin only takes the final segment of the path. As a result, some LUNs’ usage or status aren’t monitored individually.
I checked the NetApp plugin source, specifically the file lib/python3/cmk/plugins/netapp/models.py. Within, I found the LunModel class:
class LunModel(BaseModel):
"""
api: /api/storage/luns
doc: https://docs.netapp.com/us-en/ontap-restmap-9131//lun.html#lun-copy-get-iter
============
OLD -> NEW:
============
"path" -> name
"size" -> space.size
"size-used" -> space.used
"online" -> enabled
"read-only" -> status.read_only
"vserver" -> svm.name
"volume" -> location.volume.name
============
"""
name: str
space_size: int
space_used: int | None = None
enabled: bool
read_only: bool | None = None
svm_name: str
volume_name: str
def size(self) -> float:
return self.space_size / MEGA
def free_space(self) -> float:
if self.space_used is None:
raise ValueError("space_used must be available to calculate free space")
return (self.space_size - self.space_used) / MEGA
def item_name(self) -> str:
return self.name.rsplit("/", 1)[-1]
I think the critical part is the method:
def item_name(self) -> str:
return self.name.rsplit("/", 1)[-1]
This splits the full path (name) on the / character and returns only the last segment (i.e., k.lun) as the service label. Because multiple LUNs use the same name, they collide in CheckMK’s inventory.
A straightforward workaround is to use the entire name (i.e., the full path) as the unique service identifier instead of just the final segment. For example, you could change the method to:
- def item_name(self) -> str:
- return self.name.rsplit("/", 1)[-1]
+ def item_name(self) -> str:
+ return self.name
With this adjustment, CheckMK would no longer register each service simply as “k.lun,” but rather as the full path, such as:
/vol/cp1c02bin/k.lun
/vol/ke3c02bin/k.lun
…
That ensures that identically named LUNs appear as distinct services, preventing CheckMK from “losing” any of them.
Anyone having the same issues? How do you work around this?