--- b/openstack_dashboard/dashboards/admin/networks/tests.py
+++ b/openstack_dashboard/dashboards/admin/networks/tests.py
@@ -103,6 +103,8 @@
             .AndReturn(mac_learning)
         api.neutron.is_extension_supported(IsA(http.HttpRequest),
                 'dhcp_agent_scheduler').AndReturn(True)
+        api.neutron.is_extension_supported(IsA(http.HttpRequest),
+                'dhcp_agent_scheduler').AndReturn(True)
 
         self.mox.ReplayAll()
 
@@ -186,24 +188,19 @@
             .AndReturn(mac_learning)
         api.neutron.is_extension_supported(IsA(http.HttpRequest),
                 'dhcp_agent_scheduler').AndReturn(True)
+        api.neutron.is_extension_supported(IsA(http.HttpRequest),
+                'dhcp_agent_scheduler').AndReturn(True)
 
         self.mox.ReplayAll()
 
                                            'mac-learning')\
             .AndReturn(mac_learning)
-<<<<<<< HEAD
         api.neutron.is_extension_supported(
             IsA(http.HttpRequest),
             'dhcp_agent_scheduler').AndReturn(True)
         api.neutron.is_extension_supported(
             IsA(http.HttpRequest),
             'dhcp_agent_scheduler').AndReturn(True)
-=======
-        api.neutron.is_extension_supported(IsA(http.HttpRequest),
-                'dhcp_agent_scheduler').AndReturn(True)
-        api.neutron.is_extension_supported(IsA(http.HttpRequest),
-                'dhcp_agent_scheduler').AndReturn(True)
->>>>>>> dc6b1ce... Add dropdown actions to all details pages
 
         self.mox.ReplayAll()
 
@@ -235,6 +232,12 @@
         api.neutron.is_extension_supported(IsA(http.HttpRequest),
                                            'mac-learning')\
             .AndReturn(mac_learning)
+        api.neutron.is_extension_supported(IsA(http.HttpRequest),
+                                           'dhcp_agent_scheduler')\
+            .AndReturn(True)
+        api.neutron.is_extension_supported(IsA(http.HttpRequest),
+                                           'dhcp_agent_scheduler')\
+            .AndReturn(True)
 
         self.mox.ReplayAll()
 
@@ -952,6 +955,9 @@
         api.neutron.is_extension_supported(IsA(http.HttpRequest),
                                            'mac-learning')\
             .AndReturn(mac_learning)
+        api.neutron.is_extension_supported(IsA(http.HttpRequest),
+                                           'mac-learning')\
+            .AndReturn(mac_learning)
 
         self.mox.ReplayAll()
 
--- b/openstack_dashboard/dashboards/project/stacks/views.py
+++ b/openstack_dashboard/dashboards/project/stacks/views.py
@@ -197,7 +197,11 @@
 
     def get_context_data(self, **kwargs):
         context = super(DetailView, self).get_context_data(**kwargs)
-        context["stack"] = self.get_data(self.request, **kwargs)
+        stack = self.get_data(self.request, **kwargs)
+        table = project_tables.StacksTable(self.request)
+        context["stack"] = stack
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(stack)
         return context
 
     @memoized.memoized_method
@@ -210,13 +214,16 @@
             return stack
         except Exception:
             msg = _("Unable to retrieve stack.")
-            redirect = reverse('horizon:project:stacks:index')
-            exceptions.handle(request, msg, redirect=redirect)
+            exceptions.handle(request, msg, redirect=self.get_redirect_url())
 
     def get_tabs(self, request, **kwargs):
         stack = self.get_data(request, **kwargs)
         return self.tab_group_class(request, stack=stack, **kwargs)
 
+    @staticmethod
+    def get_redirect_url():
+        return reverse('horizon:project:stacks:index')
+
 
 class ResourceView(tabs.TabView):
     tab_group_class = project_tabs.ResourceDetailTabs
@@ -308,10 +315,6 @@
     def get_redirect_url():
         return reverse('horizon:project:stacks:index')
 
-    @staticmethod
-    def get_redirect_url():
-        return reverse('horizon:project:stacks:index')
-
 
 class ResourceView(tabs.TabView):
     tab_group_class = project_tabs.ResourceDetailTabs
--- b/openstack_dashboard/dashboards/project/volumes/volumes/views.py
+++ b/openstack_dashboard/dashboards/project/volumes/volumes/views.py
@@ -49,7 +49,7 @@
         table = project_tables.VolumesTable(self.request)
         context["volume"] = volume
         context["url"] = self.get_redirect_url()
-        context["actions"] = table.render_row_actions(datum)
+        context["actions"] = table.render_row_actions(volume)
         return context
 
     @memoized.memoized_method
--- a/openstack_dashboard/dashboards/admin/networks/views.py
+++ b/openstack_dashboard/dashboards/admin/networks/views.py
@@ -105,3 +105,2 @@
     template_name = 'project/networks/detail.html'
-    failure_url = reverse_lazy('horizon:admin:networks:index')
 
@@ -150,3 +149,2 @@
         except Exception:
-            redirect = self.failure_url
             exceptions.handle(self.request,
@@ -154,3 +152,4 @@
                                 'network "%s".') % network_id,
-                              redirect=redirect)
+                              redirect=self.get_redirect_url())
+
         return network
@@ -159,3 +158,3 @@
         context = super(DetailView, self).get_context_data(**kwargs)
-        context["network"] = self._get_data()
+        network = self._get_data()
         # Needs to exclude agents table if dhcp-agent-scheduler extension
@@ -168,4 +167,13 @@
             context['dhcp_agent_support'] = False
+
+        table = networks_tables.NetworksTable(self.request)
+        context["network"] = network
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(network)
         return context
 
+    @staticmethod
+    def get_redirect_url():
+        return reverse_lazy('horizon:admin:networks:index')
+
 
--- a/openstack_dashboard/dashboards/admin/volumes/snapshots/views.py
+++ b/openstack_dashboard/dashboards/admin/volumes/snapshots/views.py
@@ -61,3 +61,4 @@
 
-    def get_redirect_url(self):
+    @staticmethod
+    def get_redirect_url():
         return reverse('horizon:admin:volumes:index')
--- a/openstack_dashboard/dashboards/project/images/images/views.py
+++ b/openstack_dashboard/dashboards/project/images/images/views.py
@@ -35,2 +35,4 @@
 from openstack_dashboard.dashboards.project.images.images \
+    import tables as project_tables
+from openstack_dashboard.dashboards.project.images.images \
     import tabs as project_tabs
@@ -86,5 +88,13 @@
         context = super(DetailView, self).get_context_data(**kwargs)
-        context["image"] = self.get_data()
+        image = self.get_data()
+        table = project_tables.ImagesTable(self.request)
+        context["image"] = image
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(image)
         return context
 
+    @staticmethod
+    def get_redirect_url():
+        return reverse_lazy('horizon:project:images:index')
+
     @memoized.memoized_method
@@ -94,6 +104,5 @@
         except Exception:
-            url = reverse('horizon:project:images:index')
             exceptions.handle(self.request,
                               _('Unable to retrieve image details.'),
-                              redirect=url)
+                              redirect=self.get_redirect_url())
 
--- a/openstack_dashboard/dashboards/project/instances/views.py
+++ b/openstack_dashboard/dashboards/project/instances/views.py
@@ -255,3 +255,7 @@
         context = super(DetailView, self).get_context_data(**kwargs)
-        context["instance"] = self.get_data()
+        instance = self.get_data()
+        context["instance"] = instance
+        table = project_tables.InstancesTable(self.request)
+        context["url"] = reverse(self.redirect_url)
+        context["actions"] = table.render_row_actions(instance)
         return context
--- a/openstack_dashboard/dashboards/project/loadbalancers/tabs.py
+++ b/openstack_dashboard/dashboards/project/loadbalancers/tabs.py
@@ -23,3 +23,2 @@
 from openstack_dashboard.dashboards.project.loadbalancers import tables
-from openstack_dashboard.dashboards.project.loadbalancers import utils
 
@@ -96,12 +95,3 @@
     def get_context_data(self, request):
-        pid = self.tab_group.kwargs['pool_id']
-        try:
-            pool = api.lbaas.pool_get(request, pid)
-        except Exception:
-            pool = []
-            exceptions.handle(request,
-                              _('Unable to retrieve pool details.'))
-        for monitor in pool.health_monitors:
-            display_name = utils.get_monitor_display_name(monitor)
-            setattr(monitor, 'display_name', display_name)
+        pool = self.tab_group.kwargs['pool']
         return {'pool': pool}
@@ -131,9 +121,3 @@
     def get_context_data(self, request):
-        mid = self.tab_group.kwargs['member_id']
-        try:
-            member = api.lbaas.member_get(request, mid)
-        except Exception:
-            member = []
-            exceptions.handle(self.tab_group.request,
-                              _('Unable to retrieve member details.'))
+        member = self.tab_group.kwargs['member']
         return {'member': member}
@@ -147,9 +131,3 @@
     def get_context_data(self, request):
-        mid = self.tab_group.kwargs['monitor_id']
-        try:
-            monitor = api.lbaas.pool_health_monitor_get(request, mid)
-        except Exception:
-            monitor = []
-            exceptions.handle(self.tab_group.request,
-                              _('Unable to retrieve monitor details.'))
+        monitor = self.tab_group.kwargs['monitor']
         return {'monitor': monitor}
--- a/openstack_dashboard/dashboards/project/loadbalancers/views.py
+++ b/openstack_dashboard/dashboards/project/loadbalancers/views.py
@@ -28,3 +28,6 @@
 from openstack_dashboard.dashboards.project.loadbalancers \
+    import tables as project_tables
+from openstack_dashboard.dashboards.project.loadbalancers \
     import tabs as project_tabs
+from openstack_dashboard.dashboards.project.loadbalancers import utils
 from openstack_dashboard.dashboards.project.loadbalancers \
@@ -117,8 +120,42 @@
 class PoolDetailsView(tabs.TabView):
-    tab_group_class = (project_tabs.PoolDetailsTabs)
+    tab_group_class = project_tabs.PoolDetailsTabs
     template_name = 'project/loadbalancers/details_tabs.html'
 
+    @memoized.memoized_method
+    def get_data(self):
+        pid = self.kwargs['pool_id']
+
+        try:
+            pool = api.lbaas.pool_get(self.request, pid)
+        except Exception:
+            pool = []
+            exceptions.handle(self.request,
+                              _('Unable to retrieve pool details.'))
+        else:
+            for monitor in pool.health_monitors:
+                display_name = utils.get_monitor_display_name(monitor)
+                setattr(monitor, 'display_name', display_name)
+
+        return pool
+
+    def get_context_data(self, **kwargs):
+        context = super(PoolDetailsView, self).get_context_data(**kwargs)
+        pool = self.get_data()
+        context['pool'] = pool
+        table = project_tables.PoolsTable(self.request)
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(pool)
+        return context
+
+    def get_tabs(self, request, *args, **kwargs):
+        pool = self.get_data()
+        return self.tab_group_class(self.request, pool=pool, **kwargs)
+
+    @staticmethod
+    def get_redirect_url():
+        return reverse_lazy("horizon:project:loadbalancers:index")
+
 
 class VipDetailsView(tabs.TabView):
-    tab_group_class = (project_tabs.VipDetailsTabs)
+    tab_group_class = project_tabs.VipDetailsTabs
     template_name = 'project/loadbalancers/details_tabs.html'
@@ -127,10 +164,62 @@
 class MemberDetailsView(tabs.TabView):
-    tab_group_class = (project_tabs.MemberDetailsTabs)
+    tab_group_class = project_tabs.MemberDetailsTabs
     template_name = 'project/loadbalancers/details_tabs.html'
 
+    @memoized.memoized_method
+    def get_data(self):
+        mid = self.kwargs['member_id']
+        try:
+            return api.lbaas.member_get(self.request, mid)
+        except Exception:
+            exceptions.handle(self.request,
+                              _('Unable to retrieve member details.'))
+
+    def get_context_data(self, **kwargs):
+        context = super(MemberDetailsView, self).get_context_data(**kwargs)
+        member = self.get_data()
+        context['member'] = member
+        table = project_tables.MembersTable(self.request)
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(member)
+        return context
+
+    def get_tabs(self, request, *args, **kwargs):
+        member = self.get_data()
+        return self.tab_group_class(request, member=member, **kwargs)
+
+    @staticmethod
+    def get_redirect_url():
+        return reverse_lazy("horizon:project:loadbalancers:index")
+
 
 class MonitorDetailsView(tabs.TabView):
-    tab_group_class = (project_tabs.MonitorDetailsTabs)
+    tab_group_class = project_tabs.MonitorDetailsTabs
     template_name = 'project/loadbalancers/details_tabs.html'
 
+    @memoized.memoized_method
+    def get_data(self):
+        mid = self.kwargs['monitor_id']
+        try:
+            return api.lbaas.pool_health_monitor_get(self.request, mid)
+        except Exception:
+            exceptions.handle(self.request,
+                              _('Unable to retrieve monitor details.'))
+
+    def get_context_data(self, **kwargs):
+        context = super(MonitorDetailsView, self).get_context_data(**kwargs)
+        monitor = self.get_data()
+        context['monitor'] = monitor
+        table = project_tables.MonitorsTable(self.request)
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(monitor)
+        return context
+
+    def get_tabs(self, request, *args, **kwargs):
+        monitor = self.get_data()
+        return self.tab_group_class(request, monitor=monitor, **kwargs)
+
+    @staticmethod
+    def get_redirect_url():
+        return reverse_lazy("horizon:project:loadbalancers:index")
+
 
--- a/openstack_dashboard/dashboards/project/networks/ports/tabs.py
+++ b/openstack_dashboard/dashboards/project/networks/ports/tabs.py
@@ -14,10 +14,6 @@
 
-from django.core.urlresolvers import reverse
 from django.utils.translation import ugettext_lazy as _
 
-from horizon import exceptions
 from horizon import tabs
 
-from openstack_dashboard import api
-
 
@@ -29,12 +25,3 @@
     def get_context_data(self, request):
-        port_id = self.tab_group.kwargs['port_id']
-        try:
-            port = api.neutron.port_get(self.request, port_id)
-        except Exception:
-            redirect = reverse('horizon:project:networks:index')
-            msg = _('Unable to retrieve port details.')
-            exceptions.handle(request, msg, redirect=redirect)
-        if (api.neutron.is_extension_supported(request, 'mac-learning') and
-                not hasattr(port, 'mac_state')):
-            port.mac_state = api.neutron.OFF_STATE
+        port = self.tab_group.kwargs['port']
         return {'port': port}
--- a/openstack_dashboard/dashboards/project/networks/ports/views.py
+++ b/openstack_dashboard/dashboards/project/networks/ports/views.py
@@ -27,2 +27,4 @@
 from openstack_dashboard.dashboards.project.networks.ports \
+    import tables as project_tables
+from openstack_dashboard.dashboards.project.networks.ports \
     import tabs as project_tabs
@@ -34,2 +36,38 @@
 
+    @memoized.memoized_method
+    def get_data(self):
+        port_id = self.kwargs['port_id']
+
+        try:
+            port = api.neutron.port_get(self.request, port_id)
+        except Exception:
+            port = []
+            redirect = self.get_redirect_url()
+            msg = _('Unable to retrieve port details.')
+            exceptions.handle(self.request, msg, redirect=redirect)
+
+        if (api.neutron.is_extension_supported(self.request, 'mac-learning')
+                and not hasattr(port, 'mac_state')):
+            port.mac_state = api.neutron.OFF_STATE
+
+        return port
+
+    def get_context_data(self, **kwargs):
+        context = super(DetailView, self).get_context_data(**kwargs)
+        port = self.get_data()
+        table = project_tables.PortsTable(self.request,
+                                          network_id=port.network_id)
+        context["port"] = port
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(port)
+        return context
+
+    def get_tabs(self, request, *args, **kwargs):
+        port = self.get_data()
+        return self.tab_group_class(request, port=port, **kwargs)
+
+    @staticmethod
+    def get_redirect_url():
+        return reverse('horizon:project:networks:index')
+
 
--- a/openstack_dashboard/dashboards/project/networks/subnets/tabs.py
+++ b/openstack_dashboard/dashboards/project/networks/subnets/tabs.py
@@ -14,11 +14,6 @@
 
-from django.core.urlresolvers import reverse
 from django.utils.translation import ugettext_lazy as _
 
-from horizon import exceptions
 from horizon import tabs
 
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.networks.subnets import utils
-
 
@@ -30,13 +25,3 @@
     def get_context_data(self, request):
-        subnet_id = self.tab_group.kwargs['subnet_id']
-        try:
-            subnet = api.neutron.subnet_get(self.request, subnet_id)
-        except Exception:
-            redirect = reverse('horizon:project:networks:index')
-            msg = _('Unable to retrieve subnet details.')
-            exceptions.handle(request, msg, redirect=redirect)
-        if subnet.ip_version == 6:
-            ipv6_modes = utils.get_ipv6_modes_menu_from_attrs(
-                subnet.ipv6_ra_mode, subnet.ipv6_address_mode)
-            subnet.ipv6_modes_desc = utils.IPV6_MODE_MAP.get(ipv6_modes)
+        subnet = self.tab_group.kwargs['subnet']
         return {'subnet': subnet}
--- a/openstack_dashboard/dashboards/project/networks/subnets/views.py
+++ b/openstack_dashboard/dashboards/project/networks/subnets/views.py
@@ -28,2 +28,4 @@
 from openstack_dashboard.dashboards.project.networks.subnets \
+    import tables as project_tables
+from openstack_dashboard.dashboards.project.networks.subnets \
     import tabs as project_tabs
@@ -101 +103,37 @@
     template_name = 'project/networks/subnets/detail.html'
+
+    @memoized.memoized_method
+    def get_data(self):
+        subnet_id = self.kwargs['subnet_id']
+        try:
+            subnet = api.neutron.subnet_get(self.request, subnet_id)
+        except Exception:
+            subnet = []
+            msg = _('Unable to retrieve subnet details.')
+            exceptions.handle(self.request, msg,
+                              redirect=self.get_redirect_url())
+        else:
+            if subnet.ip_version == 6:
+                ipv6_modes = utils.get_ipv6_modes_menu_from_attrs(
+                    subnet.ipv6_ra_mode, subnet.ipv6_address_mode)
+                subnet.ipv6_modes_desc = utils.IPV6_MODE_MAP.get(ipv6_modes)
+
+        return subnet
+
+    def get_context_data(self, **kwargs):
+        context = super(DetailView, self).get_context_data(**kwargs)
+        subnet = self.get_data()
+        table = project_tables.SubnetsTable(self.request,
+                                            network_id=subnet.network_id)
+        context["subnet"] = subnet
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(subnet)
+        return context
+
+    def get_tabs(self, request, *args, **kwargs):
+        subnet = self.get_data()
+        return self.tab_group_class(request, subnet=subnet, **kwargs)
+
+    @staticmethod
+    def get_redirect_url():
+        return reverse('horizon:project:networks:index')
--- a/openstack_dashboard/dashboards/project/networks/tests.py
+++ b/openstack_dashboard/dashboards/project/networks/tests.py
@@ -1611,2 +1611,5 @@
             .AndReturn(mac_learning)
+        api.neutron.is_extension_supported(IsA(http.HttpRequest),
+                                           'mac-learning')\
+            .AndReturn(mac_learning)
         self.mox.ReplayAll()
--- a/openstack_dashboard/dashboards/project/networks/views.py
+++ b/openstack_dashboard/dashboards/project/networks/views.py
@@ -98,3 +98,2 @@
     template_name = 'project/networks/detail.html'
-    failure_url = reverse_lazy('horizon:project:networks:index')
 
@@ -134,3 +133,4 @@
                 % (network_id)
-            exceptions.handle(self.request, msg, redirect=self.failure_url)
+            exceptions.handle(self.request, msg,
+                              redirect=self.get_redirect_url())
         return network
@@ -139,3 +139,11 @@
         context = super(DetailView, self).get_context_data(**kwargs)
-        context["network"] = self._get_data()
+        network = self._get_data()
+        context["network"] = network
+        table = project_tables.NetworksTable(self.request)
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(network)
         return context
+
+    @staticmethod
+    def get_redirect_url():
+        return reverse_lazy('horizon:project:networks:index')
--- a/openstack_dashboard/dashboards/project/routers/views.py
+++ b/openstack_dashboard/dashboards/project/routers/views.py
@@ -127,3 +127,8 @@
         context = super(DetailView, self).get_context_data(**kwargs)
-        context["router"] = self._get_data()
+        router = self._get_data()
+        table = rtables.RoutersTable(self.request)
+
+        context["router"] = router
+        context["url"] = self.failure_url
+        context["actions"] = table.render_row_actions(router)
         context['dvr_supported'] = api.neutron.get_feature_permission(
@@ -132,2 +137,3 @@
             self.request, "l3-ha", "get")
+
         return context
--- a/openstack_dashboard/dashboards/project/volumes/backups/views.py
+++ b/openstack_dashboard/dashboards/project/volumes/backups/views.py
@@ -25,2 +25,4 @@
 from openstack_dashboard.dashboards.project.volumes.backups \
+    import tables as backup_tables
+from openstack_dashboard.dashboards.project.volumes.backups \
     import tabs as backup_tabs
@@ -48,3 +50,8 @@
         context = super(BackupDetailView, self).get_context_data(**kwargs)
-        context["backup"] = self.get_data()
+        backup = self.get_data()
+        table = backup_tables.BackupsTable(self.request)
+        context["backup"] = backup
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(backup)
+
         return context
@@ -58,6 +65,5 @@
         except Exception:
-            redirect = reverse('horizon:project:volumes:index')
             exceptions.handle(self.request,
                               _('Unable to retrieve backup details.'),
-                              redirect=redirect)
+                              redirect=self.get_redirect_url())
         return backup
@@ -68,2 +74,6 @@
 
+    @staticmethod
+    def get_redirect_url():
+        return reverse('horizon:project:volumes:index')
+
 
--- a/openstack_dashboard/dashboards/project/volumes/snapshots/views.py
+++ b/openstack_dashboard/dashboards/project/volumes/snapshots/views.py
@@ -26,2 +26,4 @@
 from openstack_dashboard.dashboards.project.volumes \
+    .snapshots import tables as vol_snapshot_tables
+from openstack_dashboard.dashboards.project.volumes \
     .snapshots import tabs as vol_snapshot_tabs
@@ -64,3 +66,7 @@
         context = super(DetailView, self).get_context_data(**kwargs)
-        context["snapshot"] = self.get_data()
+        snapshot = self.get_data()
+        table = vol_snapshot_tables.VolumeSnapshotsTable(self.request)
+        context["snapshot"] = snapshot
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(snapshot)
         return context
@@ -80,3 +86,4 @@
 
-    def get_redirect_url(self):
+    @staticmethod
+    def get_redirect_url():
         return reverse('horizon:project:volumes:index')
--- a/openstack_dashboard/dashboards/project/vpn/tabs.py
+++ b/openstack_dashboard/dashboards/project/vpn/tabs.py
@@ -17,3 +17,2 @@
 
-from django.core.urlresolvers import reverse_lazy
 from django.utils.translation import ugettext_lazy as _
@@ -119,11 +118,5 @@
     template_name = "project/vpn/_ikepolicy_details.html"
-    failure_url = reverse_lazy('horizon:project:vpn:index')
 
     def get_context_data(self, request):
-        pid = self.tab_group.kwargs['ikepolicy_id']
-        try:
-            ikepolicy = api.vpn.ikepolicy_get(request, pid)
-        except Exception:
-            msg = _('Unable to retrieve IKE Policy details.')
-            exceptions.handle(request, msg, redirect=self.failure_url)
+        ikepolicy = self.tab_group.kwargs['ikepolicy']
         return {'ikepolicy': ikepolicy}
@@ -140,11 +133,5 @@
     template_name = "project/vpn/_ipsecpolicy_details.html"
-    failure_url = reverse_lazy('horizon:project:vpn:index')
 
     def get_context_data(self, request):
-        pid = self.tab_group.kwargs['ipsecpolicy_id']
-        try:
-            ipsecpolicy = api.vpn.ipsecpolicy_get(request, pid)
-        except Exception:
-            msg = _('Unable to retrieve IPSec Policy details.')
-            exceptions.handle(request, msg, redirect=self.failure_url)
+        ipsecpolicy = self.tab_group.kwargs['ipsecpolicy']
         return {'ipsecpolicy': ipsecpolicy}
@@ -161,17 +148,5 @@
     template_name = "project/vpn/_vpnservice_details.html"
-    failure_url = reverse_lazy('horizon:project:vpn:index')
 
     def get_context_data(self, request):
-        sid = self.tab_group.kwargs['vpnservice_id']
-        try:
-            vpnservice = api.vpn.vpnservice_get(request, sid)
-        except Exception:
-            msg = _('Unable to retrieve VPN Service details.')
-            exceptions.handle(request, msg, redirect=self.failure_url)
-        try:
-            connections = api.vpn.ipsecsiteconnection_list(
-                request, vpnservice_id=sid)
-            vpnservice.vpnconnections = connections
-        except Exception:
-            vpnservice.vpnconnections = []
+        vpnservice = self.tab_group.kwargs['vpnservice']
         return {'vpnservice': vpnservice}
@@ -188,12 +163,6 @@
     template_name = "project/vpn/_ipsecsiteconnection_details.html"
-    failure_url = reverse_lazy('horizon:project:vpn:index')
 
     def get_context_data(self, request):
-        cid = self.tab_group.kwargs['ipsecsiteconnection_id']
-        try:
-            ipsecsiteconn = api.vpn.ipsecsiteconnection_get(request, cid)
-        except Exception:
-            msg = _('Unable to retrieve IPSec Site Connection details.')
-            exceptions.handle(request, msg, redirect=self.failure_url)
-        return {'ipsecsiteconnection': ipsecsiteconn}
+        ipsecsiteconnection = self.tab_group.kwargs['ipsecsiteconnection']
+        return {'ipsecsiteconnection': ipsecsiteconnection}
 
--- a/openstack_dashboard/dashboards/project/vpn/views.py
+++ b/openstack_dashboard/dashboards/project/vpn/views.py
@@ -31,2 +31,3 @@
     import forms as vpn_forms
+from openstack_dashboard.dashboards.project.vpn import tables as vpn_tables
 from openstack_dashboard.dashboards.project.vpn import tabs as vpn_tabs
@@ -124,20 +125,142 @@
 class IKEPolicyDetailsView(tabs.TabView):
-    tab_group_class = (vpn_tabs.IKEPolicyDetailsTabs)
+    tab_group_class = vpn_tabs.IKEPolicyDetailsTabs
     template_name = 'project/vpn/details_tabs.html'
 
+    @memoized.memoized_method
+    def get_data(self):
+        pid = self.kwargs['ikepolicy_id']
+        try:
+            return api.vpn.ikepolicy_get(self.request, pid)
+        except Exception:
+            msg = _('Unable to retrieve IKE Policy details.')
+            exceptions.handle(self.request, msg,
+                              redirect=self.get_redirect_url())
+
+    def get_context_data(self, **kwargs):
+        context = super(IKEPolicyDetailsView, self).get_context_data(**kwargs)
+        ikepolicy = self.get_data()
+        table = vpn_tables.IKEPoliciesTable(self.request)
+        context["ikepolicy"] = ikepolicy
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(ikepolicy)
+        return context
+
+    def get_tabs(self, request, *args, **kwargs):
+        ikepolicy = self.get_data()
+        return self.tab_group_class(request, ikepolicy=ikepolicy, **kwargs)
+
+    @staticmethod
+    def get_redirect_url():
+        return reverse_lazy('horizon:project:vpn:index')
+
 
 class IPSecPolicyDetailsView(tabs.TabView):
-    tab_group_class = (vpn_tabs.IPSecPolicyDetailsTabs)
+    tab_group_class = vpn_tabs.IPSecPolicyDetailsTabs
     template_name = 'project/vpn/details_tabs.html'
 
+    @memoized.memoized_method
+    def get_data(self):
+        pid = self.kwargs['ipsecpolicy_id']
+        try:
+            return api.vpn.ipsecpolicy_get(self.request, pid)
+        except Exception:
+            msg = _('Unable to retrieve IPSec Policy details.')
+            exceptions.handle(self.request, msg,
+                              redirect=self.get_redirect_url())
+
+    def get_context_data(self, **kwargs):
+        context = super(IPSecPolicyDetailsView, self).get_context_data(
+            **kwargs)
+        ipsecpolicy = self.get_data()
+        table = vpn_tables.IPSecPoliciesTable(self.request)
+        context["ipsecpolicy"] = ipsecpolicy
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(ipsecpolicy)
+        return context
+
+    def get_tabs(self, request, *args, **kwargs):
+        ipsecpolicy = self.get_data()
+        return self.tab_group_class(request, ipsecpolicy=ipsecpolicy, **kwargs)
+
+    @staticmethod
+    def get_redirect_url():
+        return reverse_lazy('horizon:project:vpn:index')
+
 
 class VPNServiceDetailsView(tabs.TabView):
-    tab_group_class = (vpn_tabs.VPNServiceDetailsTabs)
+    tab_group_class = vpn_tabs.VPNServiceDetailsTabs
     template_name = 'project/vpn/details_tabs.html'
 
+    @memoized.memoized_method
+    def get_data(self):
+        sid = self.kwargs['vpnservice_id']
+
+        try:
+            vpnservice = api.vpn.vpnservice_get(self.request, sid)
+        except Exception:
+            vpnservice = []
+            msg = _('Unable to retrieve VPN Service details.')
+            exceptions.handle(self.request, msg,
+                              redirect=self.get_redirect_url())
+        try:
+            connections = api.vpn.ipsecsiteconnection_list(
+                self.request, vpnservice_id=sid)
+            vpnservice.vpnconnections = connections
+        except Exception:
+            vpnservice.vpnconnections = []
+
+        return vpnservice
+
+    def get_context_data(self, **kwargs):
+        context = super(VPNServiceDetailsView, self).get_context_data(**kwargs)
+        vpnservice = self.get_data()
+        table = vpn_tables.VPNServicesTable(self.request)
+        context["vpnservice"] = vpnservice
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(vpnservice)
+        return context
+
+    def get_tabs(self, request, *args, **kwargs):
+        vpnservice = self.get_data()
+        return self.tab_group_class(request, vpnservice=vpnservice, **kwargs)
+
+    @staticmethod
+    def get_redirect_url():
+        return reverse_lazy('horizon:project:vpn:index')
+
 
 class IPSecSiteConnectionDetailsView(tabs.TabView):
-    tab_group_class = (vpn_tabs.IPSecSiteConnectionDetailsTabs)
+    tab_group_class = vpn_tabs.IPSecSiteConnectionDetailsTabs
     template_name = 'project/vpn/details_tabs.html'
 
+    @memoized.memoized_method
+    def get_data(self):
+        cid = self.kwargs['ipsecsiteconnection_id']
+        try:
+            return api.vpn.ipsecsiteconnection_get(self.request, cid)
+        except Exception:
+            msg = _('Unable to retrieve IPSec Site Connection details.')
+            exceptions.handle(self.request, msg,
+                              redirect=self.get_redirect_url())
+
+    def get_context_data(self, **kwargs):
+        context = super(IPSecSiteConnectionDetailsView, self).get_context_data(
+            **kwargs)
+        ipsecsiteconnection = self.get_data()
+        table = vpn_tables.IPSecSiteConnectionsTable(self.request)
+        context["ipsecsiteconnection"] = ipsecsiteconnection
+        context["url"] = self.get_redirect_url()
+        context["actions"] = table.render_row_actions(ipsecsiteconnection)
+        return context
+
+    def get_tabs(self, request, *args, **kwargs):
+        ipsecsiteconnection = self.get_data()
+        return self.tab_group_class(request,
+                                    ipsecsiteconnection=ipsecsiteconnection,
+                                    **kwargs)
+
+    @staticmethod
+    def get_redirect_url():
+        return reverse_lazy('horizon:project:vpn:index')
+
 
