Move Consistency Group Snapshots out of Volumes panel
Change-Id: I2c02ff63c4e98040b3e46ded5331e706033dc746 Implements: blueprint reorganise-volumes
This commit is contained in:
parent
f85e0ffa91
commit
0b340eccc0
@ -68,7 +68,7 @@ class CreateCGroupForm(forms.SelfHandlingForm):
|
|||||||
messages.info(request, message)
|
messages.info(request, message)
|
||||||
return cgroup
|
return cgroup
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = reverse("horizon:project:volumes:index")
|
redirect = reverse("horizon:project:cg_snapshots:index")
|
||||||
msg = _('Unable to create consistency '
|
msg = _('Unable to create consistency '
|
||||||
'group "%s" from snapshot.') % data['name']
|
'group "%s" from snapshot.') % data['name']
|
||||||
exceptions.handle(request,
|
exceptions.handle(request,
|
26
openstack_dashboard/dashboards/project/cg_snapshots/panel.py
Normal file
26
openstack_dashboard/dashboards/project/cg_snapshots/panel.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Copyright 2017 Rackspace, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
import horizon
|
||||||
|
|
||||||
|
|
||||||
|
class CGSnapshots(horizon.Panel):
|
||||||
|
name = _("Consistency Group Snapshots")
|
||||||
|
slug = 'cg_snapshots'
|
||||||
|
permissions = (
|
||||||
|
('openstack.services.volume', 'openstack.services.volumev2'),
|
||||||
|
)
|
||||||
|
policy_rules = (("volume", "consistencygroup:get_all_cgsnapshots"),)
|
@ -23,7 +23,7 @@ from openstack_dashboard import policy
|
|||||||
class CreateVolumeCGroup(policy.PolicyTargetMixin, tables.LinkAction):
|
class CreateVolumeCGroup(policy.PolicyTargetMixin, tables.LinkAction):
|
||||||
name = "create_cgroup"
|
name = "create_cgroup"
|
||||||
verbose_name = _("Create Consistency Group")
|
verbose_name = _("Create Consistency Group")
|
||||||
url = "horizon:project:volumes:cg_snapshots:create_cgroup"
|
url = "horizon:project:cg_snapshots:create_cgroup"
|
||||||
classes = ("ajax-modal",)
|
classes = ("ajax-modal",)
|
||||||
policy_rules = (("volume", "consistencygroup:create"),)
|
policy_rules = (("volume", "consistencygroup:create"),)
|
||||||
|
|
||||||
@ -90,8 +90,7 @@ class CGSnapshotsTable(tables.DataTable):
|
|||||||
|
|
||||||
name = tables.Column("name",
|
name = tables.Column("name",
|
||||||
verbose_name=_("Name"),
|
verbose_name=_("Name"),
|
||||||
link="horizon:project:volumes:"
|
link="horizon:project:cg_snapshots:detail")
|
||||||
"cg_snapshots:cg_snapshot_detail")
|
|
||||||
description = tables.Column("description",
|
description = tables.Column("description",
|
||||||
verbose_name=_("Description"),
|
verbose_name=_("Description"),
|
||||||
truncate=40)
|
truncate=40)
|
||||||
@ -113,4 +112,6 @@ class CGSnapshotsTable(tables.DataTable):
|
|||||||
DeleteVolumeCGSnapshot,)
|
DeleteVolumeCGSnapshot,)
|
||||||
row_class = UpdateRow
|
row_class = UpdateRow
|
||||||
status_columns = ("status",)
|
status_columns = ("status",)
|
||||||
permissions = ['openstack.services.volume']
|
permissions = [
|
||||||
|
('openstack.services.volume', 'openstack.services.volumev2')
|
||||||
|
]
|
@ -19,14 +19,14 @@ from horizon import tabs
|
|||||||
class OverviewTab(tabs.Tab):
|
class OverviewTab(tabs.Tab):
|
||||||
name = _("Overview")
|
name = _("Overview")
|
||||||
slug = "overview"
|
slug = "overview"
|
||||||
template_name = ("project/volumes/cg_snapshots/_detail_overview.html")
|
template_name = "project/cg_snapshots/_detail_overview.html"
|
||||||
|
|
||||||
def get_context_data(self, request):
|
def get_context_data(self, request):
|
||||||
cg_snapshot = self.tab_group.kwargs['cg_snapshot']
|
cg_snapshot = self.tab_group.kwargs['cg_snapshot']
|
||||||
return {"cg_snapshot": cg_snapshot}
|
return {"cg_snapshot": cg_snapshot}
|
||||||
|
|
||||||
def get_redirect_url(self):
|
def get_redirect_url(self):
|
||||||
return reverse('horizon:project:volumes:cg_snapshots:index')
|
return reverse('horizon:project:cg_snapshots:index')
|
||||||
|
|
||||||
|
|
||||||
class CGSnapshotsDetailTabs(tabs.TabGroup):
|
class CGSnapshotsDetailTabs(tabs.TabGroup):
|
@ -12,16 +12,13 @@
|
|||||||
|
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django import http
|
from django import http
|
||||||
from django.utils.http import urlunquote
|
|
||||||
from mox3.mox import IsA # noqa
|
from mox3.mox import IsA # noqa
|
||||||
|
|
||||||
from openstack_dashboard.api import cinder
|
from openstack_dashboard.api import cinder
|
||||||
from openstack_dashboard.test import helpers as test
|
from openstack_dashboard.test import helpers as test
|
||||||
|
|
||||||
|
|
||||||
VOLUME_INDEX_URL = reverse('horizon:project:volumes:index')
|
INDEX_URL = reverse('horizon:project:cg_snapshots:index')
|
||||||
VOLUME_CG_SNAPSHOTS_TAB_URL = urlunquote(reverse(
|
|
||||||
'horizon:project:volumes:cg_snapshots_tab'))
|
|
||||||
|
|
||||||
|
|
||||||
class CGroupSnapshotTests(test.TestCase):
|
class CGroupSnapshotTests(test.TestCase):
|
||||||
@ -44,11 +41,11 @@ class CGroupSnapshotTests(test.TestCase):
|
|||||||
.AndReturn(cgroup)
|
.AndReturn(cgroup)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
url = reverse('horizon:project:volumes:cg_snapshots:create_cgroup',
|
url = reverse('horizon:project:cg_snapshots:create_cgroup',
|
||||||
args=[cg_snapshot.id])
|
args=[cg_snapshot.id])
|
||||||
res = self.client.post(url, formData)
|
res = self.client.post(url, formData)
|
||||||
self.assertNoFormErrors(res)
|
self.assertNoFormErrors(res)
|
||||||
self.assertRedirectsNoFollow(res, VOLUME_INDEX_URL)
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
|
|
||||||
@test.create_stubs({cinder: ('volume_cg_snapshot_get',
|
@test.create_stubs({cinder: ('volume_cg_snapshot_get',
|
||||||
'volume_cgroup_create_from_source',)})
|
'volume_cgroup_create_from_source',)})
|
||||||
@ -69,7 +66,7 @@ class CGroupSnapshotTests(test.TestCase):
|
|||||||
.AndRaise(self.exceptions.cinder)
|
.AndRaise(self.exceptions.cinder)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
url = reverse('horizon:project:volumes:cg_snapshots:create_cgroup',
|
url = reverse('horizon:project:cg_snapshots:create_cgroup',
|
||||||
args=[cg_snapshot.id])
|
args=[cg_snapshot.id])
|
||||||
res = self.client.post(url, formData)
|
res = self.client.post(url, formData)
|
||||||
self.assertNoFormErrors(res)
|
self.assertNoFormErrors(res)
|
||||||
@ -78,7 +75,7 @@ class CGroupSnapshotTests(test.TestCase):
|
|||||||
self.assertIn('Unable to create consistency group "%s" from snapshot.'
|
self.assertIn('Unable to create consistency group "%s" from snapshot.'
|
||||||
% new_cg_name,
|
% new_cg_name,
|
||||||
res.cookies.output().replace('\\', ''))
|
res.cookies.output().replace('\\', ''))
|
||||||
self.assertRedirectsNoFollow(res, VOLUME_INDEX_URL)
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
|
|
||||||
@test.create_stubs({cinder: ('volume_cg_snapshot_list',
|
@test.create_stubs({cinder: ('volume_cg_snapshot_list',
|
||||||
'volume_cg_snapshot_delete',)})
|
'volume_cg_snapshot_delete',)})
|
||||||
@ -93,8 +90,7 @@ class CGroupSnapshotTests(test.TestCase):
|
|||||||
|
|
||||||
form_data = {'action': 'volume_cg_snapshots__delete_cg_snapshot__%s'
|
form_data = {'action': 'volume_cg_snapshots__delete_cg_snapshot__%s'
|
||||||
% cg_snapshot.id}
|
% cg_snapshot.id}
|
||||||
res = self.client.post(VOLUME_CG_SNAPSHOTS_TAB_URL, form_data,
|
res = self.client.post(INDEX_URL, form_data, follow=True)
|
||||||
follow=True)
|
|
||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
self.assertIn("Scheduled deletion of Snapshot: %s" % cg_snapshot.name,
|
self.assertIn("Scheduled deletion of Snapshot: %s" % cg_snapshot.name,
|
||||||
[m.message for m in res.context['messages']])
|
[m.message for m in res.context['messages']])
|
||||||
@ -114,8 +110,7 @@ class CGroupSnapshotTests(test.TestCase):
|
|||||||
|
|
||||||
form_data = {'action': 'volume_cg_snapshots__delete_cg_snapshot__%s'
|
form_data = {'action': 'volume_cg_snapshots__delete_cg_snapshot__%s'
|
||||||
% cg_snapshot.id}
|
% cg_snapshot.id}
|
||||||
res = self.client.post(VOLUME_CG_SNAPSHOTS_TAB_URL, form_data,
|
res = self.client.post(INDEX_URL, form_data, follow=True)
|
||||||
follow=True)
|
|
||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
self.assertIn("Unable to delete snapshot: %s" % cg_snapshot.name,
|
self.assertIn("Unable to delete snapshot: %s" % cg_snapshot.name,
|
||||||
[m.message for m in res.context['messages']])
|
[m.message for m in res.context['messages']])
|
||||||
@ -143,7 +138,7 @@ class CGroupSnapshotTests(test.TestCase):
|
|||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
url = reverse(
|
url = reverse(
|
||||||
'horizon:project:volumes:cg_snapshots:cg_snapshot_detail',
|
'horizon:project:cg_snapshots:cg_snapshot_detail',
|
||||||
args=[cg_snapshot.id])
|
args=[cg_snapshot.id])
|
||||||
res = self.client.get(url)
|
res = self.client.get(url)
|
||||||
self.assertNoFormErrors(res)
|
self.assertNoFormErrors(res)
|
||||||
@ -159,8 +154,8 @@ class CGroupSnapshotTests(test.TestCase):
|
|||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
url = reverse(
|
url = reverse(
|
||||||
'horizon:project:volumes:cg_snapshots:cg_snapshot_detail',
|
'horizon:project:cg_snapshots:cg_snapshot_detail',
|
||||||
args=[cg_snapshot.id])
|
args=[cg_snapshot.id])
|
||||||
res = self.client.get(url)
|
res = self.client.get(url)
|
||||||
self.assertNoFormErrors(res)
|
self.assertNoFormErrors(res)
|
||||||
self.assertRedirectsNoFollow(res, VOLUME_INDEX_URL)
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
@ -12,9 +12,10 @@
|
|||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from openstack_dashboard.dashboards.project.volumes.cg_snapshots import views
|
from openstack_dashboard.dashboards.project.cg_snapshots import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
url(r'^$', views.CGSnapshotsView.as_view(), name='index'),
|
||||||
url(r'^(?P<cg_snapshot_id>[^/]+)/cg_snapshot_detail/$',
|
url(r'^(?P<cg_snapshot_id>[^/]+)/cg_snapshot_detail/$',
|
||||||
views.DetailView.as_view(),
|
views.DetailView.as_view(),
|
||||||
name='cg_snapshot_detail'),
|
name='cg_snapshot_detail'),
|
@ -16,6 +16,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import forms
|
from horizon import forms
|
||||||
|
from horizon import tables
|
||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
from horizon.utils import memoized
|
from horizon.utils import memoized
|
||||||
|
|
||||||
@ -23,17 +24,32 @@ from openstack_dashboard import api
|
|||||||
from openstack_dashboard.api import cinder
|
from openstack_dashboard.api import cinder
|
||||||
from openstack_dashboard.usage import quotas
|
from openstack_dashboard.usage import quotas
|
||||||
|
|
||||||
from openstack_dashboard.dashboards.project.volumes \
|
from openstack_dashboard.dashboards.project.cg_snapshots \
|
||||||
.cg_snapshots import forms as cg_snapshot_forms
|
import forms as cg_snapshot_forms
|
||||||
from openstack_dashboard.dashboards.project.volumes \
|
from openstack_dashboard.dashboards.project.cg_snapshots \
|
||||||
.cg_snapshots import tables as cg_snapshot_tables
|
import tables as cg_snapshot_tables
|
||||||
from openstack_dashboard.dashboards.project.volumes \
|
from openstack_dashboard.dashboards.project.cg_snapshots \
|
||||||
.cg_snapshots import tabs as cg_snapshot_tabs
|
import tabs as cg_snapshot_tabs
|
||||||
|
|
||||||
CGROUP_INFO_FIELDS = ("name",
|
CGROUP_INFO_FIELDS = ("name",
|
||||||
"description")
|
"description")
|
||||||
|
|
||||||
INDEX_URL = "horizon:project:volumes:index"
|
INDEX_URL = "horizon:project:cg_snapshots:index"
|
||||||
|
|
||||||
|
|
||||||
|
class CGSnapshotsView(tables.DataTableView):
|
||||||
|
table_class = cg_snapshot_tables.CGSnapshotsTable
|
||||||
|
page_title = _("Consistency Group Snapshots")
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
try:
|
||||||
|
cg_snapshots = api.cinder.volume_cg_snapshot_list(self.request)
|
||||||
|
except Exception:
|
||||||
|
cg_snapshots = []
|
||||||
|
exceptions.handle(self.request, _("Unable to retrieve "
|
||||||
|
"volume consistency group "
|
||||||
|
"snapshots."))
|
||||||
|
return cg_snapshots
|
||||||
|
|
||||||
|
|
||||||
class DetailView(tabs.TabView):
|
class DetailView(tabs.TabView):
|
||||||
@ -84,7 +100,7 @@ class DetailView(tabs.TabView):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_redirect_url():
|
def get_redirect_url():
|
||||||
return reverse('horizon:project:volumes:index')
|
return reverse(INDEX_URL)
|
||||||
|
|
||||||
def get_tabs(self, request, *args, **kwargs):
|
def get_tabs(self, request, *args, **kwargs):
|
||||||
cg_snapshot = self.get_data()
|
cg_snapshot = self.get_data()
|
||||||
@ -93,8 +109,8 @@ class DetailView(tabs.TabView):
|
|||||||
|
|
||||||
class CreateCGroupView(forms.ModalFormView):
|
class CreateCGroupView(forms.ModalFormView):
|
||||||
form_class = cg_snapshot_forms.CreateCGroupForm
|
form_class = cg_snapshot_forms.CreateCGroupForm
|
||||||
template_name = 'project/volumes/cg_snapshots/create.html'
|
template_name = 'project/cg_snapshots/create.html'
|
||||||
submit_url = "horizon:project:volumes:cg_snapshots:create_cgroup"
|
submit_url = "horizon:project:cg_snapshots:create_cgroup"
|
||||||
success_url = reverse_lazy('horizon:project:cgroups:index')
|
success_url = reverse_lazy('horizon:project:cgroups:index')
|
||||||
page_title = _("Create Volume Consistency Group")
|
page_title = _("Create Volume Consistency Group")
|
||||||
|
|
@ -20,8 +20,8 @@ from openstack_dashboard.test import helpers as test
|
|||||||
|
|
||||||
|
|
||||||
INDEX_URL = reverse('horizon:project:cgroups:index')
|
INDEX_URL = reverse('horizon:project:cgroups:index')
|
||||||
VOLUME_CGROUPS_SNAP_TAB_URL = urlunquote(reverse(
|
VOLUME_CGROUPS_SNAP_INDEX_URL = urlunquote(reverse(
|
||||||
'horizon:project:volumes:cg_snapshots_tab'))
|
'horizon:project:cg_snapshots:index'))
|
||||||
|
|
||||||
|
|
||||||
class ConsistencyGroupTests(test.TestCase):
|
class ConsistencyGroupTests(test.TestCase):
|
||||||
@ -296,7 +296,7 @@ class ConsistencyGroupTests(test.TestCase):
|
|||||||
args=[cgroup.id])
|
args=[cgroup.id])
|
||||||
res = self.client.post(url, formData)
|
res = self.client.post(url, formData)
|
||||||
self.assertNoFormErrors(res)
|
self.assertNoFormErrors(res)
|
||||||
self.assertRedirectsNoFollow(res, VOLUME_CGROUPS_SNAP_TAB_URL)
|
self.assertRedirectsNoFollow(res, VOLUME_CGROUPS_SNAP_INDEX_URL)
|
||||||
|
|
||||||
@test.create_stubs({cinder: ('volume_cgroup_get',
|
@test.create_stubs({cinder: ('volume_cgroup_get',
|
||||||
'volume_cgroup_create_from_source',)})
|
'volume_cgroup_create_from_source',)})
|
||||||
|
@ -190,7 +190,7 @@ class CreateSnapshotView(forms.ModalFormView):
|
|||||||
template_name = 'project/cgroups/create_snapshot.html'
|
template_name = 'project/cgroups/create_snapshot.html'
|
||||||
submit_label = _("Create Snapshot")
|
submit_label = _("Create Snapshot")
|
||||||
submit_url = "horizon:project:cgroups:create_snapshot"
|
submit_url = "horizon:project:cgroups:create_snapshot"
|
||||||
success_url = reverse_lazy('horizon:project:volumes:cg_snapshots_tab')
|
success_url = reverse_lazy('horizon:project:cg_snapshots:index')
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(CreateSnapshotView, self).get_context_data(**kwargs)
|
context = super(CreateSnapshotView, self).get_context_data(**kwargs)
|
||||||
|
@ -21,10 +21,7 @@ from horizon.tables import PagedTableMixin
|
|||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard import policy
|
|
||||||
|
|
||||||
from openstack_dashboard.dashboards.project.volumes.cg_snapshots \
|
|
||||||
import tables as cg_snapshots_tables
|
|
||||||
from openstack_dashboard.dashboards.project.volumes.volumes \
|
from openstack_dashboard.dashboards.project.volumes.volumes \
|
||||||
import tables as volume_tables
|
import tables as volume_tables
|
||||||
|
|
||||||
@ -122,32 +119,7 @@ class VolumeTab(PagedTableMixin, tabs.TableTab, VolumeTableMixIn):
|
|||||||
return volumes
|
return volumes
|
||||||
|
|
||||||
|
|
||||||
class CGSnapshotsTab(tabs.TableTab):
|
|
||||||
table_classes = (cg_snapshots_tables.CGSnapshotsTable,)
|
|
||||||
name = _("Consistency Group Snapshots")
|
|
||||||
slug = "cg_snapshots_tab"
|
|
||||||
template_name = ("horizon/common/_detail_table.html")
|
|
||||||
preload = False
|
|
||||||
|
|
||||||
def allowed(self, request):
|
|
||||||
return policy.check(
|
|
||||||
(("volume", "consistencygroup:get_all_cgsnapshots"),),
|
|
||||||
request
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_volume_cg_snapshots_data(self):
|
|
||||||
try:
|
|
||||||
cg_snapshots = api.cinder.volume_cg_snapshot_list(
|
|
||||||
self.request)
|
|
||||||
except Exception:
|
|
||||||
cg_snapshots = []
|
|
||||||
exceptions.handle(self.request, _("Unable to retrieve "
|
|
||||||
"volume consistency group "
|
|
||||||
"snapshots."))
|
|
||||||
return cg_snapshots
|
|
||||||
|
|
||||||
|
|
||||||
class VolumeAndSnapshotTabs(tabs.TabGroup):
|
class VolumeAndSnapshotTabs(tabs.TabGroup):
|
||||||
slug = "volumes_and_snapshots"
|
slug = "volumes_and_snapshots"
|
||||||
tabs = (VolumeTab, CGSnapshotsTab)
|
tabs = (VolumeTab, )
|
||||||
sticky = True
|
sticky = True
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
from django.conf.urls import include
|
from django.conf.urls import include
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from openstack_dashboard.dashboards.project.volumes.cg_snapshots \
|
|
||||||
import urls as cg_snapshots_urls
|
|
||||||
from openstack_dashboard.dashboards.project.volumes import views
|
from openstack_dashboard.dashboards.project.volumes import views
|
||||||
from openstack_dashboard.dashboards.project.volumes.volumes \
|
from openstack_dashboard.dashboards.project.volumes.volumes \
|
||||||
import urls as volume_urls
|
import urls as volume_urls
|
||||||
@ -25,12 +23,7 @@ urlpatterns = [
|
|||||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||||
url(r'^\?tab=volumes_and_snapshots__volumes_tab$',
|
url(r'^\?tab=volumes_and_snapshots__volumes_tab$',
|
||||||
views.IndexView.as_view(), name='volumes_tab'),
|
views.IndexView.as_view(), name='volumes_tab'),
|
||||||
url(r'^\?tab=volumes_and_snapshots__cg_snapshots_tab$',
|
|
||||||
views.IndexView.as_view(), name='cg_snapshots_tab'),
|
|
||||||
url(r'', include(
|
url(r'', include(
|
||||||
volume_urls,
|
volume_urls,
|
||||||
namespace='volumes')),
|
namespace='volumes')),
|
||||||
url(r'cg_snapshots/', include(
|
|
||||||
cg_snapshots_urls,
|
|
||||||
namespace='cg_snapshots')),
|
|
||||||
]
|
]
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||||
|
PANEL = 'cg_snapshots'
|
||||||
|
# The slug of the dashboard the PANEL associated with. Required.
|
||||||
|
PANEL_DASHBOARD = 'project'
|
||||||
|
# The slug of the panel group the PANEL is associated with.
|
||||||
|
PANEL_GROUP = 'volumes'
|
||||||
|
|
||||||
|
# Python panel class of the PANEL to be added.
|
||||||
|
ADD_PANEL = \
|
||||||
|
'openstack_dashboard.dashboards.project.cg_snapshots.panel.CGSnapshots'
|
Loading…
x
Reference in New Issue
Block a user