#4. zendmd: Command-line Access to the Device Management Database (DMD)
Zenoss uses the Zope database (ZODB) to store its information. Since the ZODB is an Object-Oriented DataBase, this is not organized by tables, rows and columns, but by objects. The object that Zenoss uses to store the basic model of your network is in the Device Management Database (DMD) object.
You can access the DMD through an interactive, programmable interpreter: zendmd. zendmd is the Python interpreter, with a handle to the database stored in the default namespace, and a few handy functions.
To start zendmd and see how the interpreter works, use the following commands:
$ zendmd >>> 1 + 2 3 >>> len('hello there') 11 >>> for i in range(5): ... print i 0 1 2 3 4
These are all basic Python interpreter features. zendmd adds in a reference to the root of the object tree which is known as dmd. You can see this root name in the URLs used to refer to objects when using Zenoss from the browser.
There is a built-in function that can be used to find devices.
$ zendmd >>> print dmd <DataRoot at /zport/dmd> >>> find('localhost.localdomain') <Device at /zport/dmd/Devices/Server/Linux/devices/localhost.localdomain>
The find()
function also takes wildcards:
>>> find('local*') <Device at /zport/dmd/Devices/Server/Linux/devices/localhost.localdomain>
You can perform scripting at the command prompt. For example, we can count the number of interfaces on our device:
>>> d = find('local*') len(d.os.interfaces()) 5
You can inspect the objects:
>>> d.getManageIp() '127.0.0.1' for i in d.os.interfaces(): ... for a in i.ipaddresses(): ... print a.name(), a.getIpAddress() eth0 192.168.1.148/24
You can perform low-level checks such as re-indexing all the objects:
>>> reindex()
Or check/repair relationships on all devices:
>>> for d in dmd.Devices.getSubDevices(): ... d.checkRelations(repair=True) ...
Finally, after making changes you can commit them to the database:
>>> commit()
or synch against the database and restore the old state to your interpreter, reverting any changes:
>>> synch()
Zendmd can be used to automate repetitive tasks. For example, you can enter in a large list of devices. First, create a text file containing the names of those devices:
$ cat >lotsOfDevices.txt device1 myhost.mydomain.com host2.mydomain.com ^D
Of course, the data could come from an inventory list or other database. Then, you can use the dmd to process the file:
$ zendmd for line in file('lotsOfDevices.txt'): ... d = dmd.Devices.Server.Linux.createInstance(line.strip()) ... commit() ... d.collectDevice()
You can feed zendmd commands on stdin:
$ zendmd < AddDevices.py
You can also import scripts:
$ zendmd import MyScripts MyScripts.loadDevices(dmd)
If you want to create a stand-alone command, reading the $ZENHOME/ZenModel/zendmd.py
file is a good start.
The full List of zendmd names is described below.
Table 2.1. zendmd Names and Descriptions
zendmd Name | Description |
---|---|
dmd | Device Management Database, the root persistent object |
app | The Zope Application, the root of the database |
zport | Zenoss Portal, the portal that contains Zenoss |
find() | Look up devices by name, and by address; supports wildcards |
devices | Equivalent to dmd.Devices |
sync() | Revert the objects in zendmd back to the state in the ZODB |
commit() | Push object changes to the persistent store |
abort() | Undo any object changes and refresh from persistent storage |
me | a reference to the machine running zendmd, if it can be found |
reindex() | recreates the indexes against the objects |
login() | sets the security context of the given user |
logout() | removes any security context |