refactor the backend icon stuff to one spot
diff --git a/planetstack/core/admin.py b/planetstack/core/admin.py
index 81fdbf1..b2ecafa 100644
--- a/planetstack/core/admin.py
+++ b/planetstack/core/admin.py
@@ -26,22 +26,24 @@
 # thread locals necessary to work around a django-suit issue
 _thread_locals = threading.local()
 
-def backend_icon(obj): # backend_status, enacted, updated):
-    #return "%s %s %s" % (str(obj.updated), str(obj.enacted), str(obj.backend_status))
-    if (obj.enacted is not None) and obj.enacted >= obj.updated or obj.backend_status.startswith("1 -"):
-        return '<span style="min-width:16px;"><img src="/static/admin/img/icon_success.gif"></span>'
+ICON_URLS = {"success": "/static/admin/img/icon_success.gif",
+            "clock": "/static/admin/img/icon_clock.gif",
+            "error": "/static/admin/img/icon_error.gif"}
+
+def backend_icon(obj):
+    (icon, tooltip) = obj.get_backend_icon()
+    icon_url = ICON_URLS.get(icon, "unknown")
+
+    if tooltip:
+        return '<span style="min-width:16px;" title="%s"><img src="%s"></span>' % (tooltip, icon_url)
     else:
-        if ((obj.backend_status is not None) and obj.backend_status.startswith("0 -")) or obj.backend_status == "Provisioning in progress" or obj.backend_status=="":
-            return '<span style="min-width:16px;" title="%s"><img src="/static/admin/img/icon_clock.gif"></span>' % obj.backend_status
-        else:
-            return '<span style="min-width:16px;" title="%s"><img src="/static/admin/img/icon_error.gif"></span>' % html_escape(obj.backend_status, quote=True)
+        return '<span style="min-width:16px;"><img src="%s"></span>' % icon_url
 
 def backend_text(obj):
-    icon = backend_icon(obj)
-    if (obj.enacted is not None) and obj.enacted >= obj.updated:
-        return "%s %s" % (icon, "successfully enacted")
-    else:
-        return "%s %s" % (icon, html_escape(obj.backend_status, quote=True))
+    (icon, tooltip) = obj.get_backend_icon()
+    icon_url = ICON_URLS.get(icon, "unknown")
+
+    return '<img src="%s"> %s' % (icon_url, tooltip)
 
 class UploadTextareaWidget(AdminTextareaWidget):
     def render(self, name, value, attrs=None):
diff --git a/planetstack/core/models/plcorebase.py b/planetstack/core/models/plcorebase.py
index 5d546b7..e610d1b 100644
--- a/planetstack/core/models/plcorebase.py
+++ b/planetstack/core/models/plcorebase.py
@@ -9,6 +9,7 @@
 from django.core.exceptions import PermissionDenied
 import model_policy
 from model_autodeletion import ephemeral_models
+from cgi import escape as html_escape
 
 try:
     # This is a no-op if observer_disabled is set to 1 in the config file
@@ -108,6 +109,16 @@
             validators[field.name] = l
         return validators
 
+    def get_backend_icon(self):
+        # returns (icon_name, tooltip)
+        if (self.enacted is not None) and self.enacted >= self.updated or self.backend_status.startswith("1 -"):
+            return ("success", "successfully enacted")
+        else:
+            if ((self.backend_status is not None) and self.backend_status.startswith("0 -")) or self.backend_status == "Provisioning in progress" or self.backend_status=="":
+                return ("clock", html_escape(self.backend_status, quote=True))
+            else:
+                return ("error", html_escape(self.backend_status, quote=True))
+
 class PlCoreBase(models.Model, PlModelMixIn):
     objects = PlCoreBaseManager()
     deleted_objects = PlCoreBaseDeletionManager()
diff --git a/planetstack/core/xoslib/objects/plus.py b/planetstack/core/xoslib/objects/plus.py
index 01cb8d7..da59ac7 100644
--- a/planetstack/core/xoslib/objects/plus.py
+++ b/planetstack/core/xoslib/objects/plus.py
@@ -4,20 +4,25 @@
     stuff related to backend icons.
 """
 
+ICON_URLS = {"success": "/static/admin/img/icon_success.gif",
+            "clock": "/static/admin/img/icon_clock.gif",
+            "error": "/static/admin/img/icon_error.gif"}
+
+
+
 class PlusObjectMixin:
     def getBackendIcon(self):
-        if (self.enacted is not None) and self.enacted >= self.updated or self.backend_status.startswith("1 -"):
-            return "/static/admin/img/icon_success.gif"
-        else:
-            if ((self.backend_status is not None) and self.backend_status.startswith("0 -")) or self.backend_status == "Provisioning in progress" or self.backend_status=="":
-                return "/static/admin/img/icon_clock.gif"
-            else:
-                return "/static/admin/img/icon_error.gif"
+        (icon, tooltip) = self.get_backend_icon()
+        icon_url = ICON_URLS.get(icon, "unknown")
+        return icon_url
 
     def getBackendHtml(self):
-        if (self.enacted is not None) and self.enacted >= self.updated:
-            return '<img src="%s">' % self.getBackendIcon()
+        (icon, tooltip) = self.get_backend_icon()
+        icon_url = ICON_URLS.get(icon, "unknown")
+
+        if tooltip:
+            return '<span title="%s"><img src="%s"></span>' % (tooltip, icon_url)
         else:
-            return '<span title="%s"><img src="%s"></span>' % (self.backend_status, self.getBackendIcon())
+            return '<img src="%s">' % icon_url