Skip to content

Commit 068995b

Browse files
Merge pull request #4729 from zenoss/bugfix/ZEN-35479.7x
Register device config classes as unjellyable.
2 parents d47fb33 + b5b5469 commit 068995b

File tree

1 file changed

+54
-16
lines changed
  • src/Products/ZenCollector/configcache/cli

1 file changed

+54
-16
lines changed

src/Products/ZenCollector/configcache/cli/show.py

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99

1010
from __future__ import absolute_import, print_function
1111

12+
import importlib
13+
import inspect
1214
import os
1315
import sys
1416
import types
1517

18+
import importlib_metadata as metadata
19+
1620
from IPython.lib import pretty
1721
from twisted.spread.jelly import unjellyableRegistry
1822
from twisted.spread import pb
@@ -126,26 +130,29 @@ def run(self):
126130
device=self._device,
127131
)
128132
if results:
129-
for cls in set(unjellyableRegistry.values()):
130-
if isinstance(
131-
cls, (types.ClassType, types.TypeType)
132-
) and issubclass(cls, (pb.Copyable, pb.RemoteCopy)):
133-
pretty.for_type(cls, _pp_hide_passwords)
134-
else:
135-
pretty.for_type(cls, _pp_default)
136-
try:
137-
pretty.pprint(
138-
results.config, max_width=self._columns, max_seq_length=0
139-
)
140-
except IOError as ex:
141-
if ex.errno != 32: # broken pipe
142-
print(ex, file=sys.stderr)
143-
except KeyboardInterrupt as ex:
144-
print(ex, file=sys.stderr)
133+
pretty_print_device_config(results.config, self._columns)
145134
else:
146135
print(err, file=sys.stderr)
147136

148137

138+
def pretty_print_device_config(config, columns):
139+
_register_zenpack_device_config_classes()
140+
for item in set(unjellyableRegistry.values()):
141+
if isinstance(item, (types.ClassType, type)) and issubclass(
142+
item, (pb.Copyable, pb.RemoteCopy)
143+
):
144+
pretty.for_type(item, _pp_hide_passwords)
145+
else:
146+
pretty.for_type(item, _pp_default)
147+
try:
148+
pretty.pprint(config, max_width=columns, max_seq_length=0)
149+
except IOError as ex:
150+
if ex.errno != 32: # broken pipe
151+
print(ex, file=sys.stderr)
152+
except KeyboardInterrupt as ex:
153+
print(ex, file=sys.stderr)
154+
155+
149156
def _query_cache(store, service, monitor, device):
150157
query = DeviceQuery(service=service, monitor=monitor, device=device)
151158
results = store.search(query)
@@ -192,3 +199,34 @@ def _printer(obj, p, cycle, vprint):
192199

193200
def _is_output_redirected():
194201
return os.fstat(0) != os.fstat(1)
202+
203+
204+
def _register_zenpack_device_config_classes():
205+
"""
206+
Register all unregistered pb.Copyable and pb.RemoteCopy classes.
207+
"""
208+
service_modules = _identify_zenpack_hub_service_modules()
209+
for name, svcmod in service_modules.iteritems():
210+
for clsname, cls in inspect.getmembers(svcmod, inspect.isclass):
211+
if not issubclass(cls, (pb.Copyable, pb.RemoteCopy)):
212+
continue
213+
fullname = "{}.{}".format(name, clsname)
214+
if fullname not in unjellyableRegistry:
215+
pb.setUnjellyableForClass(cls, cls)
216+
217+
218+
def _identify_zenpack_hub_service_modules():
219+
service_modules = {}
220+
for ep in metadata.entry_points().get("zenoss.zenpacks", ()):
221+
paths = (
222+
p
223+
for p in metadata.files(ep.name)
224+
if "/services/" in p.as_posix()
225+
and p.suffix == ".py"
226+
and p.stem != "__init__"
227+
)
228+
for path in paths:
229+
svcmod = "{}.services.{}".format(ep.module, path.stem)
230+
svcm = importlib.import_module(svcmod)
231+
service_modules[svcm.__name__] = svcm
232+
return service_modules

0 commit comments

Comments
 (0)