blob: a0b9fe3abf284ac972dcedf4ab32dfdec3da6c04 [file] [log] [blame]
Klement Sekeraacb9b8e2017-02-14 02:55:31 +01001""" abstract vpp object and object registry """
2
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -08003import abc
4import six
Klement Sekera0e3c0de2016-09-29 14:43:44 +02005
Paul Vinciguerra6c746172018-11-26 09:57:21 -08006from six import moves
Paul Vinciguerra00671cf2018-11-25 12:47:04 -08007
Klement Sekera0e3c0de2016-09-29 14:43:44 +02008
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -08009@six.add_metaclass(abc.ABCMeta)
Klement Sekera0e3c0de2016-09-29 14:43:44 +020010class VppObject(object):
11 """ Abstract vpp object """
Klement Sekera0e3c0de2016-09-29 14:43:44 +020012
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080013 @abc.abstractmethod
Klement Sekera0e3c0de2016-09-29 14:43:44 +020014 def add_vpp_config(self):
15 """ Add the configuration for this object to vpp. """
16 pass
17
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080018 @abc.abstractmethod
Klement Sekera0e3c0de2016-09-29 14:43:44 +020019 def query_vpp_config(self):
20 """Query the vpp configuration.
21
22 :return: True if the object is configured"""
23 pass
24
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080025 @abc.abstractmethod
Klement Sekera0e3c0de2016-09-29 14:43:44 +020026 def remove_vpp_config(self):
27 """ Remove the configuration for this object from vpp. """
28 pass
29
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080030 @abc.abstractmethod
Klement Sekera0e3c0de2016-09-29 14:43:44 +020031 def object_id(self):
32 """ Return a unique string representing this object. """
33 pass
34
35
36class VppObjectRegistry(object):
37 """ Class which handles automatic configuration cleanup. """
38 _shared_state = {}
39
40 def __init__(self):
41 self.__dict__ = self._shared_state
42 if not hasattr(self, "_object_registry"):
43 self._object_registry = []
44 if not hasattr(self, "_object_dict"):
45 self._object_dict = dict()
46
Klement Sekeraacb9b8e2017-02-14 02:55:31 +010047 def register(self, obj, logger):
Klement Sekera0e3c0de2016-09-29 14:43:44 +020048 """ Register an object in the registry. """
Klement Sekeraacb9b8e2017-02-14 02:55:31 +010049 if obj.object_id() not in self._object_dict:
50 self._object_registry.append(obj)
51 self._object_dict[obj.object_id()] = obj
Klement Sekera73884482017-02-23 09:26:30 +010052 logger.debug("REG: registering %s" % obj)
Klement Sekera0e3c0de2016-09-29 14:43:44 +020053 else:
Klement Sekeraacb9b8e2017-02-14 02:55:31 +010054 logger.debug("REG: duplicate add, ignoring (%s)" % obj)
Klement Sekera0e3c0de2016-09-29 14:43:44 +020055
Klement Sekera1b686402017-03-02 11:29:19 +010056 def unregister_all(self, logger):
57 """ Remove all object registrations from registry. """
58 logger.debug("REG: removing all object registrations")
59 self._object_registry = []
60 self._object_dict = dict()
61
Klement Sekera0e3c0de2016-09-29 14:43:44 +020062 def remove_vpp_config(self, logger):
63 """
64 Remove configuration (if present) from vpp and then remove all objects
65 from the registry.
66 """
67 if not self._object_registry:
Klement Sekera10db26f2017-01-11 08:16:53 +010068 logger.info("REG: No objects registered for auto-cleanup.")
Klement Sekera0e3c0de2016-09-29 14:43:44 +020069 return
Klement Sekera10db26f2017-01-11 08:16:53 +010070 logger.info("REG: Removing VPP configuration for registered objects")
71 # remove the config in reverse order as there might be dependencies
Neale Rannsf0510722018-01-31 11:35:41 -080072 failed = []
Klement Sekeraacb9b8e2017-02-14 02:55:31 +010073 for obj in reversed(self._object_registry):
74 if obj.query_vpp_config():
75 logger.info("REG: Removing configuration for %s" % obj)
76 obj.remove_vpp_config()
Neale Rannsf0510722018-01-31 11:35:41 -080077 if obj.query_vpp_config():
78 failed.append(obj)
Klement Sekera0e3c0de2016-09-29 14:43:44 +020079 else:
Klement Sekera10db26f2017-01-11 08:16:53 +010080 logger.info(
81 "REG: Skipping removal for %s, configuration not present" %
Klement Sekeraacb9b8e2017-02-14 02:55:31 +010082 obj)
Klement Sekera1b686402017-03-02 11:29:19 +010083 self.unregister_all(logger)
Klement Sekera0e3c0de2016-09-29 14:43:44 +020084 if failed:
Klement Sekera10db26f2017-01-11 08:16:53 +010085 logger.error("REG: Couldn't remove configuration for object(s):")
Klement Sekeraacb9b8e2017-02-14 02:55:31 +010086 for obj in failed:
Paul Vinciguerra6c746172018-11-26 09:57:21 -080087 logger.error(moves.reprlib.repr(obj))
Klement Sekera0e3c0de2016-09-29 14:43:44 +020088 raise Exception("Couldn't remove configuration for object(s): %s" %
89 (", ".join(str(x) for x in failed)))