commit 88b1dc128f732c90bb15c0ad92629d3d3cf438b4 Author: Ivan Kolodyazhny Date: Mon Sep 28 19:08:13 2020 +0300 Edit instance name feature implementation Change-Id: I29afd16c74087256788b3dc9f88d4e8eec4cba85 diff --git a/releasenotes/notes/rename-instance-2bd17bdec7e1a488.yaml b/releasenotes/notes/rename-instance-2bd17bdec7e1a488.yaml new file mode 100644 index 0000000..2b4bdd7 --- /dev/null +++ b/releasenotes/notes/rename-instance-2bd17bdec7e1a488.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Users can rename database instances via dashboard. diff --git a/trove_dashboard/api/trove.py b/trove_dashboard/api/trove.py index 42e8291..a11d307 100644 --- a/trove_dashboard/api/trove.py +++ b/trove_dashboard/api/trove.py @@ -192,6 +192,10 @@ def instance_restart(request, instance_id): return troveclient(request).instances.restart(instance_id) +def instance_rename(request, instance_id, name): + return troveclient(request).instances.update(instance_id, name=name) + + def instance_detach_replica(request, instance_id): return troveclient(request).instances.edit(instance_id, detach_replica_source=True) diff --git a/trove_dashboard/content/databases/forms.py b/trove_dashboard/content/databases/forms.py index 0e3ccb9..17c69a0 100644 --- a/trove_dashboard/content/databases/forms.py +++ b/trove_dashboard/content/databases/forms.py @@ -281,3 +281,28 @@ class AttachConfigurationForm(forms.SelfHandlingForm): 'group.'), redirect=redirect) return True + + +class RenameInstanceForm(forms.SelfHandlingForm): + instance_id = forms.CharField(widget=forms.HiddenInput()) + instance_name = forms.CharField(label=_("Name")) + + def __init__(self, request, *args, **kwargs): + super(RenameInstanceForm, self).__init__(request, *args, **kwargs) + instance_id = kwargs.get('initial', {}).get('instance_id') + self.fields['instance_id'].initial = instance_id + + def handle(self, request, data): + instance_id = data.get('instance_id') + instance_name = data.get('instance_name') + try: + api.trove.instance_rename(request, instance_id, instance_name) + + messages.success(request, _('Instance "%s" successfully renamed.') + % instance_name) + except Exception: + redirect = reverse("horizon:project:databases:index") + exceptions.handle(request, _('Unable to rename instance "%s".' + % instance_id), + redirect=redirect) + return True diff --git a/trove_dashboard/content/databases/tables.py b/trove_dashboard/content/databases/tables.py index 6c12826..ad69fdf 100644 --- a/trove_dashboard/content/databases/tables.py +++ b/trove_dashboard/content/databases/tables.py @@ -629,6 +629,17 @@ class StopDatabase(tables.BatchAction): return request.user.is_superuser and instance.status in ACTIVE_STATES +class RenameInstance(tables.LinkAction): + name = "edit_instance" + verbose_name = _("Rename Instance") + url = "horizon:project:databases:edit_instance" + classes = ("btn-attach-config", "ajax-modal") + + def allowed(self, request, instance=None): + return (instance.status in ACTIVE_STATES and + not hasattr(instance, 'configuration')) + + class InstancesTable(tables.DataTable): STATUS_CHOICES = ( ("ACTIVE", True), @@ -695,6 +706,7 @@ class InstancesTable(tables.DataTable): row_class = UpdateRow table_actions = (LaunchLink, DeleteInstance) row_actions = (CreateBackup, + RenameInstance, ResizeVolume, ResizeInstance, PromoteToReplicaSource, diff --git a/trove_dashboard/content/databases/templates/databases/_rename_instance.html b/trove_dashboard/content/databases/templates/databases/_rename_instance.html new file mode 100644 index 0000000..c11d69b --- /dev/null +++ b/trove_dashboard/content/databases/templates/databases/_rename_instance.html @@ -0,0 +1,6 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} + +{% block modal-body-right %} +

{% trans "Update instance name." %}

+{% endblock %} diff --git a/trove_dashboard/content/databases/templates/databases/rename_instance.html b/trove_dashboard/content/databases/templates/databases/rename_instance.html new file mode 100644 index 0000000..bd8892b --- /dev/null +++ b/trove_dashboard/content/databases/templates/databases/rename_instance.html @@ -0,0 +1,5 @@ +{% extends "base.html" %} + +{% block main %} + {% include "project/databases/_rename_instance.html" %} +{% endblock %} \ No newline at end of file diff --git a/trove_dashboard/content/databases/urls.py b/trove_dashboard/content/databases/urls.py index 4c0fe39..87147f5 100644 --- a/trove_dashboard/content/databases/urls.py +++ b/trove_dashboard/content/databases/urls.py @@ -28,6 +28,8 @@ urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index'), url(r'^launch$', views.LaunchInstanceView.as_view(), name='launch'), url(INSTANCES % '', views.DetailView.as_view(), name='detail'), + url(INSTANCES % 'edit_instance', views.RenameInstanceView.as_view(), + name='edit_instance'), url(INSTANCES % 'resize_volume', views.ResizeVolumeView.as_view(), name='resize_volume'), url(INSTANCES % 'resize_instance', views.ResizeInstanceView.as_view(), diff --git a/trove_dashboard/content/databases/views.py b/trove_dashboard/content/databases/views.py index de51365..70ca712 100644 --- a/trove_dashboard/content/databases/views.py +++ b/trove_dashboard/content/databases/views.py @@ -95,6 +95,41 @@ class LaunchInstanceView(horizon_workflows.WorkflowView): return initial +class RenameInstanceView(horizon_forms.ModalFormView): + form_class = forms.RenameInstanceForm + form_id = "attach_config_form" + modal_header = _("Rename Instance") + modal_id = "edit_instance_modal" + template_name = "project/databases/rename_instance.html" + submit_label = "Update" + submit_url = 'horizon:project:databases:edit_instance' + success_url = reverse_lazy('horizon:project:databases:index') + + @memoized.memoized_method + def get_object(self, *args, **kwargs): + instance_id = self.kwargs['instance_id'] + try: + return api.trove.instance_get(self.request, instance_id) + except Exception: + msg = _('Unable to retrieve instance details.') + redirect = reverse('horizon:project:databases:index') + exceptions.handle(self.request, msg, redirect=redirect) + + def get_context_data(self, **kwargs): + context = (super(RenameInstanceView, 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 = self.get_object() + return {'instance_id': self.kwargs['instance_id'], + 'instance_name': instance.name, + 'datastore_version': instance.datastore.get('version', '')} + + class DBAccess(object): def __init__(self, name, access): self.name = name