Add support for Trove create database
Added a table action on the databases table that displays a create database dialog. Co-Authored-By: Duk Loi <duk@tesora.com> Change-Id: I092629080987bcdd8c54e052be2f7fa9b84259a0 Implements: blueprint trove-create-database-support
This commit is contained in:
parent
7386d021e7
commit
c6e74073ca
@ -155,6 +155,16 @@ def database_list(request, instance_id):
|
||||
return troveclient(request).databases.list(instance_id)
|
||||
|
||||
|
||||
def database_create(request, instance_id, db_name, character_set=None,
|
||||
collation=None):
|
||||
database = {'name': db_name}
|
||||
if collation:
|
||||
database['collate'] = collation
|
||||
if character_set:
|
||||
database['character_set'] = character_set
|
||||
return troveclient(request).databases.create(instance_id, [database])
|
||||
|
||||
|
||||
def database_delete(request, instance_id, db_name):
|
||||
return troveclient(request).databases.delete(instance_id, db_name)
|
||||
|
||||
|
@ -24,6 +24,33 @@ from horizon.utils import validators
|
||||
from trove_dashboard import api
|
||||
|
||||
|
||||
class CreateDatabaseForm(forms.SelfHandlingForm):
|
||||
instance_id = forms.CharField(widget=forms.HiddenInput())
|
||||
name = forms.CharField(label=_("Name"))
|
||||
character_set = forms.CharField(
|
||||
label=_("Character Set"), required=False,
|
||||
help_text=_("Optional character set for the database."))
|
||||
collation = forms.CharField(
|
||||
label=_("Collation"), required=False,
|
||||
help_text=_("Optional collation type for the database."))
|
||||
|
||||
def handle(self, request, data):
|
||||
instance = data.get('instance_id')
|
||||
try:
|
||||
api.trove.database_create(request, instance, data['name'],
|
||||
character_set=data['character_set'],
|
||||
collation=data['collation'])
|
||||
|
||||
messages.success(request,
|
||||
_('Created database "%s".') % data['name'])
|
||||
except Exception as e:
|
||||
redirect = reverse("horizon:project:databases:detail",
|
||||
args=(instance,))
|
||||
exceptions.handle(request, _('Unable to create database. %s') %
|
||||
e.message, redirect=redirect)
|
||||
return True
|
||||
|
||||
|
||||
class ResizeVolumeForm(forms.SelfHandlingForm):
|
||||
instance_id = forms.CharField(widget=forms.HiddenInput())
|
||||
orig_size = forms.IntegerField(
|
||||
|
@ -306,6 +306,30 @@ class DeleteUser(tables.DeleteAction):
|
||||
api.trove.user_delete(request, datum.instance.id, datum.name)
|
||||
|
||||
|
||||
class CreateDatabase(tables.LinkAction):
|
||||
name = "create_database"
|
||||
verbose_name = _("Create Database")
|
||||
url = "horizon:project:databases:create_database"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "plus"
|
||||
|
||||
def allowed(self, request, database=None):
|
||||
instance = self.table.kwargs['instance']
|
||||
return (instance.status in ACTIVE_STATES and
|
||||
has_database_add_perm(request))
|
||||
|
||||
def get_link_url(self, datum=None):
|
||||
instance_id = self.table.kwargs['instance_id']
|
||||
return urlresolvers.reverse(self.url, args=[instance_id])
|
||||
|
||||
|
||||
def has_database_add_perm(request):
|
||||
perms = getattr(settings, 'TROVE_ADD_DATABASE_PERMS', [])
|
||||
if perms:
|
||||
return request.user.has_perms(perms)
|
||||
return True
|
||||
|
||||
|
||||
class DeleteDatabase(tables.DeleteAction):
|
||||
@staticmethod
|
||||
def action_present(count):
|
||||
@ -533,7 +557,7 @@ class DatabaseTable(tables.DataTable):
|
||||
class Meta(object):
|
||||
name = "databases"
|
||||
verbose_name = _("Databases")
|
||||
table_actions = [DeleteDatabase]
|
||||
table_actions = [CreateDatabase, DeleteDatabase]
|
||||
row_actions = [DeleteDatabase]
|
||||
|
||||
def get_object_id(self, datum):
|
||||
|
@ -12,7 +12,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.conf import settings
|
||||
from django import template
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
@ -96,10 +95,7 @@ class DatabaseTab(tabs.TableTab):
|
||||
return data
|
||||
|
||||
def allowed(self, request):
|
||||
perms = getattr(settings, 'TROVE_ADD_DATABASE_PERMS', [])
|
||||
if perms:
|
||||
return request.user.has_perms(perms)
|
||||
return True
|
||||
return tables.has_database_add_perm(request)
|
||||
|
||||
|
||||
class BackupsTab(tabs.TableTab):
|
||||
|
@ -0,0 +1,8 @@
|
||||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<p>{% trans "Specify the name of the new database." %}</p>
|
||||
<p>{% trans "Optionally provide a character set and collation for the database." %}</p>
|
||||
{% endblock %}
|
||||
|
@ -0,0 +1,6 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block main %}
|
||||
{% include "project/databases/_create_database.html" %}
|
||||
{% endblock %}
|
||||
|
@ -18,7 +18,7 @@ import logging
|
||||
import django
|
||||
from django.core.urlresolvers import reverse
|
||||
from django import http
|
||||
from django.utils import unittest
|
||||
import unittest
|
||||
|
||||
from mox3.mox import IsA # noqa
|
||||
import six
|
||||
@ -333,6 +333,73 @@ class DatabaseTests(test.TestCase):
|
||||
database = self.databases.list()[1]
|
||||
self._test_details(database, with_designate=True)
|
||||
|
||||
def test_create_database(self):
|
||||
database = self.databases.first()
|
||||
|
||||
url = reverse('horizon:project:databases:create_database',
|
||||
args=[database.id])
|
||||
res = self.client.get(url)
|
||||
self.assertTemplateUsed(res, 'project/databases/create_database.html')
|
||||
|
||||
@test.create_stubs({api.trove: ('database_create',)})
|
||||
def test_create_new_database(self):
|
||||
new_database = {
|
||||
"status": "ACTIVE",
|
||||
"updated": "2013-08-12T22:00:09",
|
||||
"name": "NewDB",
|
||||
"links": [],
|
||||
"created": "2013-08-12T22:00:03",
|
||||
"ip": [
|
||||
"10.0.0.3",
|
||||
],
|
||||
"volume": {
|
||||
"used": 0.13,
|
||||
"size": 1,
|
||||
},
|
||||
"flavor": {
|
||||
"id": "1",
|
||||
"links": [],
|
||||
},
|
||||
"datastore": {
|
||||
"type": "mysql",
|
||||
"version": "5.5"
|
||||
},
|
||||
"id": "12345678-73db-4e23-b52e-368937d72719",
|
||||
}
|
||||
|
||||
api.trove.database_create(
|
||||
IsA(http.HttpRequest), u'id', u'NewDB', character_set=u'',
|
||||
collation=u'').AndReturn(new_database)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:databases:create_database',
|
||||
args=['id'])
|
||||
post = {
|
||||
'method': 'CreateDatabaseForm',
|
||||
'instance_id': 'id',
|
||||
'name': 'NewDB'}
|
||||
|
||||
res = self.client.post(url, post)
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertMessageCount(success=1)
|
||||
|
||||
@test.create_stubs({api.trove: ('database_create',)})
|
||||
def test_create_new_database_exception(self):
|
||||
api.trove.database_create(
|
||||
IsA(http.HttpRequest), u'id', u'NewDB', character_set=u'',
|
||||
collation=u'').AndRaise(self.exceptions.trove)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:databases:create_database',
|
||||
args=['id'])
|
||||
post = {
|
||||
'method': 'CreateDatabaseForm',
|
||||
'instance_id': 'id',
|
||||
'name': 'NewDB'}
|
||||
|
||||
res = self.client.post(url, post)
|
||||
self.assertEqual(res.status_code, 302)
|
||||
|
||||
@test.create_stubs(
|
||||
{api.trove: ('instance_get', 'flavor_get', 'users_list',
|
||||
'user_list_access', 'user_delete')})
|
||||
|
@ -37,4 +37,6 @@ urlpatterns = patterns(
|
||||
name='edit_user'),
|
||||
url(USERS % 'access_detail', views.AccessDetailView.as_view(),
|
||||
name='access_detail'),
|
||||
url(INSTANCES % 'create_database', views.CreateDatabaseView.as_view(),
|
||||
name='create_database'),
|
||||
)
|
||||
|
@ -248,6 +248,32 @@ class DetailView(horizon_tabs.TabbedTableView):
|
||||
return reverse('horizon:project:databases:index')
|
||||
|
||||
|
||||
class CreateDatabaseView(horizon_forms.ModalFormView):
|
||||
form_class = forms.CreateDatabaseForm
|
||||
form_id = "create_database_form"
|
||||
modal_header = _("Create Database")
|
||||
modal_id = "create_database_modal"
|
||||
template_name = 'project/databases/create_database.html'
|
||||
submit_label = _("Create Database")
|
||||
submit_url = 'horizon:project:databases:create_database'
|
||||
success_url = 'horizon:project:databases:detail'
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse(self.success_url,
|
||||
args=(self.kwargs['instance_id'],))
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CreateDatabaseView, self).get_context_data(**kwargs)
|
||||
context['instance_id'] = self.kwargs['instance_id']
|
||||
args = (self.kwargs['instance_id'],)
|
||||
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||
return context
|
||||
|
||||
def get_initial(self):
|
||||
instance_id = self.kwargs['instance_id']
|
||||
return {'instance_id': instance_id}
|
||||
|
||||
|
||||
class ResizeVolumeView(horizon_forms.ModalFormView):
|
||||
form_class = forms.ResizeVolumeForm
|
||||
template_name = 'project/databases/resize_volume.html'
|
||||
|
Loading…
Reference in New Issue
Block a user