Merge "Add missing replication functionality"
This commit is contained in:
commit
282cca6ee4
@ -121,7 +121,8 @@ def instance_delete(request, instance_id):
|
|||||||
def instance_create(request, name, volume, flavor, databases=None,
|
def instance_create(request, name, volume, flavor, databases=None,
|
||||||
users=None, restore_point=None, nics=None,
|
users=None, restore_point=None, nics=None,
|
||||||
datastore=None, datastore_version=None,
|
datastore=None, datastore_version=None,
|
||||||
replica_of=None, volume_type=None):
|
replica_of=None, replica_count=None,
|
||||||
|
volume_type=None):
|
||||||
# TODO(dklyle): adding conditional to support trove without volume
|
# TODO(dklyle): adding conditional to support trove without volume
|
||||||
# support for now until API supports checking for volume support
|
# support for now until API supports checking for volume support
|
||||||
if volume > 0:
|
if volume > 0:
|
||||||
@ -140,7 +141,8 @@ def instance_create(request, name, volume, flavor, databases=None,
|
|||||||
nics=nics,
|
nics=nics,
|
||||||
datastore=datastore,
|
datastore=datastore,
|
||||||
datastore_version=datastore_version,
|
datastore_version=datastore_version,
|
||||||
replica_of=replica_of)
|
replica_of=replica_of,
|
||||||
|
replica_count=replica_count)
|
||||||
|
|
||||||
|
|
||||||
def instance_resize_volume(request, instance_id, size):
|
def instance_resize_volume(request, instance_id, size):
|
||||||
@ -165,6 +167,15 @@ def instance_detach_replica(request, instance_id):
|
|||||||
detach_replica_source=True)
|
detach_replica_source=True)
|
||||||
|
|
||||||
|
|
||||||
|
def promote_to_replica_source(request, instance_id):
|
||||||
|
return troveclient(request).instances.promote_to_replica_source(
|
||||||
|
instance_id)
|
||||||
|
|
||||||
|
|
||||||
|
def eject_replica_source(request, instance_id):
|
||||||
|
return troveclient(request).instances.eject_replica_source(instance_id)
|
||||||
|
|
||||||
|
|
||||||
def database_list(request, instance_id):
|
def database_list(request, instance_id):
|
||||||
return troveclient(request).databases.list(instance_id)
|
return troveclient(request).databases.list(instance_id)
|
||||||
|
|
||||||
|
@ -122,6 +122,26 @@ class ResizeInstanceForm(forms.SelfHandlingForm):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class PromoteToReplicaSourceForm(forms.SelfHandlingForm):
|
||||||
|
instance_id = forms.CharField(widget=forms.HiddenInput())
|
||||||
|
|
||||||
|
def handle(self, request, data):
|
||||||
|
instance_id = data.get('instance_id')
|
||||||
|
name = self.initial['replica'].name
|
||||||
|
try:
|
||||||
|
api.trove.promote_to_replica_source(request, instance_id)
|
||||||
|
messages.success(
|
||||||
|
request,
|
||||||
|
_('Promoted replica "%s" as the new replica source.') % name)
|
||||||
|
except Exception as e:
|
||||||
|
redirect = reverse("horizon:project:databases:index")
|
||||||
|
exceptions.handle(
|
||||||
|
request,
|
||||||
|
_('Unable to promote replica as the new replica source. "%s"')
|
||||||
|
% e.message, redirect=redirect)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class CreateUserForm(forms.SelfHandlingForm):
|
class CreateUserForm(forms.SelfHandlingForm):
|
||||||
instance_id = forms.CharField(widget=forms.HiddenInput())
|
instance_id = forms.CharField(widget=forms.HiddenInput())
|
||||||
name = forms.CharField(label=_("Name"))
|
name = forms.CharField(label=_("Name"))
|
||||||
|
@ -122,6 +122,49 @@ class DetachReplica(tables.BatchAction):
|
|||||||
api.trove.instance_detach_replica(request, obj_id)
|
api.trove.instance_detach_replica(request, obj_id)
|
||||||
|
|
||||||
|
|
||||||
|
class PromoteToReplicaSource(tables.LinkAction):
|
||||||
|
name = "promote_to_replica_source"
|
||||||
|
verbose_name = _("Promote to Replica Source")
|
||||||
|
url = "horizon:project:databases:promote_to_replica_source"
|
||||||
|
classes = ("ajax-modal", "btn-promote-to-replica-source")
|
||||||
|
|
||||||
|
def allowed(self, request, instance=None):
|
||||||
|
return (instance.status in ACTIVE_STATES
|
||||||
|
and hasattr(instance, 'replica_of'))
|
||||||
|
|
||||||
|
def get_link_url(self, datum):
|
||||||
|
instance_id = self.table.get_object_id(datum)
|
||||||
|
return urlresolvers.reverse(self.url, args=[instance_id])
|
||||||
|
|
||||||
|
|
||||||
|
class EjectReplicaSource(tables.BatchAction):
|
||||||
|
@staticmethod
|
||||||
|
def action_present(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Eject Replica Source",
|
||||||
|
u"Eject Replica Sources",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_past(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Ejected Replica Source",
|
||||||
|
u"Ejected Replica Sources",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
name = "eject_replica_source"
|
||||||
|
classes = ('btn-danger', 'btn-eject-replica-source')
|
||||||
|
|
||||||
|
def _allowed(self, request, instance=None):
|
||||||
|
return (instance.status != 'PROMOTE'
|
||||||
|
and hasattr(instance, 'replicas'))
|
||||||
|
|
||||||
|
def action(self, request, obj_id):
|
||||||
|
api.trove.eject_replica_source(request, obj_id)
|
||||||
|
|
||||||
|
|
||||||
class GrantAccess(tables.BatchAction):
|
class GrantAccess(tables.BatchAction):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def action_present(count):
|
def action_present(count):
|
||||||
@ -594,9 +637,11 @@ class InstancesTable(tables.DataTable):
|
|||||||
row_actions = (CreateBackup,
|
row_actions = (CreateBackup,
|
||||||
ResizeVolume,
|
ResizeVolume,
|
||||||
ResizeInstance,
|
ResizeInstance,
|
||||||
|
PromoteToReplicaSource,
|
||||||
ManageRoot,
|
ManageRoot,
|
||||||
RestartInstance,
|
EjectReplicaSource,
|
||||||
DetachReplica,
|
DetachReplica,
|
||||||
|
RestartInstance,
|
||||||
DeleteInstance)
|
DeleteInstance)
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
{% extends "horizon/common/_modal_form.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block modal-body %}
|
||||||
|
<div class="row">
|
||||||
|
<p class="col-md-12">{% trans 'Confirm the current replica is to be promoted as the new replica source.' %}</p>
|
||||||
|
<p class="col-md-12">{% trans 'This action cannot be undone.' %}</p>
|
||||||
|
<fieldset>
|
||||||
|
{% include "horizon/common/_form_fields.html" %}
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="left">
|
||||||
|
<div class="well">
|
||||||
|
<h4>{% trans "Current Replica" %}</h4>
|
||||||
|
<table class='table table-bordered'>
|
||||||
|
<tr><th>{% trans 'Name' %}</th><td>{{ replica.name|default:_("None") }}</td></tr>
|
||||||
|
<tr><th>{% trans 'Host' %}</th><td>{{ replica.ip|default:_("Unknown") }}</td></tr>
|
||||||
|
<tr><th>{% trans 'Status' %}</th><td>{{ replica.status|default:_("Unknown") }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<div class="well">
|
||||||
|
<h4>{% trans "Current Replica Source" %}</h4>
|
||||||
|
<table class='table table-bordered'>
|
||||||
|
<tr><th>{% trans 'Name' %}</th><td>{{ replica_source.name|default:_("None") }}</td></tr>
|
||||||
|
<tr><th>{% trans 'Host' %}</th><td>{{ replica_source.ip|default:_("Unknown") }}</td></tr>
|
||||||
|
<tr><th>{% trans 'Status' %}</th><td>{{ replica_source.status|default:_("Unknown") }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,5 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% include "project/databases/_promote_to_replica_source.html" %}
|
||||||
|
{% endblock %}
|
@ -90,7 +90,7 @@ class DatabaseTests(test.TestCase):
|
|||||||
def test_index_pagination(self):
|
def test_index_pagination(self):
|
||||||
# Mock database instances
|
# Mock database instances
|
||||||
databases = self.databases.list()
|
databases = self.databases.list()
|
||||||
last_record = databases[1]
|
last_record = databases[-1]
|
||||||
databases = common.Paginated(databases, next_marker="foo")
|
databases = common.Paginated(databases, next_marker="foo")
|
||||||
api.trove.instance_list(IsA(http.HttpRequest), marker=None)\
|
api.trove.instance_list(IsA(http.HttpRequest), marker=None)\
|
||||||
.AndReturn(databases)
|
.AndReturn(databases)
|
||||||
@ -241,6 +241,7 @@ class DatabaseTests(test.TestCase):
|
|||||||
replica_of=None,
|
replica_of=None,
|
||||||
users=None,
|
users=None,
|
||||||
nics=nics,
|
nics=nics,
|
||||||
|
replica_count=None,
|
||||||
volume_type=None).AndReturn(self.databases.first())
|
volume_type=None).AndReturn(self.databases.first())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
@ -307,6 +308,7 @@ class DatabaseTests(test.TestCase):
|
|||||||
replica_of=None,
|
replica_of=None,
|
||||||
users=None,
|
users=None,
|
||||||
nics=nics,
|
nics=nics,
|
||||||
|
replica_count=None,
|
||||||
volume_type=None).AndRaise(trove_exception)
|
volume_type=None).AndRaise(trove_exception)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
@ -999,6 +1001,7 @@ class DatabaseTests(test.TestCase):
|
|||||||
replica_of=self.databases.first().id,
|
replica_of=self.databases.first().id,
|
||||||
users=None,
|
users=None,
|
||||||
nics=nics,
|
nics=nics,
|
||||||
|
replica_count=2,
|
||||||
volume_type=None).AndReturn(self.databases.first())
|
volume_type=None).AndReturn(self.databases.first())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
@ -1010,8 +1013,107 @@ class DatabaseTests(test.TestCase):
|
|||||||
'datastore': 'mysql,5.5',
|
'datastore': 'mysql,5.5',
|
||||||
'initial_state': 'master',
|
'initial_state': 'master',
|
||||||
'master': self.databases.first().id,
|
'master': self.databases.first().id,
|
||||||
|
'replica_count': 2,
|
||||||
'volume_type': 'no_type'
|
'volume_type': 'no_type'
|
||||||
}
|
}
|
||||||
|
|
||||||
res = self.client.post(LAUNCH_URL, post)
|
res = self.client.post(LAUNCH_URL, post)
|
||||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
|
|
||||||
|
@test.create_stubs({
|
||||||
|
api.trove: ('promote_to_replica_source',),
|
||||||
|
views.PromoteToReplicaSourceView: ('get_initial',)})
|
||||||
|
def test_promote_replica_instance(self):
|
||||||
|
replica_source = self.databases.first()
|
||||||
|
replica = self.databases.list()[1]
|
||||||
|
|
||||||
|
initial = {'instance_id': replica_source.id,
|
||||||
|
'replica': replica,
|
||||||
|
'replica_source': replica_source}
|
||||||
|
views.PromoteToReplicaSourceView.get_initial().AndReturn(initial)
|
||||||
|
|
||||||
|
api.trove.promote_to_replica_source(
|
||||||
|
IsA(http.HttpRequest), replica_source.id)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
url = reverse('horizon:project:databases:promote_to_replica_source',
|
||||||
|
args=[replica_source.id])
|
||||||
|
form = {
|
||||||
|
'instance_id': replica_source.id
|
||||||
|
}
|
||||||
|
res = self.client.post(url, form)
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
|
|
||||||
|
@test.create_stubs({
|
||||||
|
api.trove: ('promote_to_replica_source',),
|
||||||
|
views.PromoteToReplicaSourceView: ('get_initial',)})
|
||||||
|
def test_promote_replica_instance_exception(self):
|
||||||
|
replica_source = self.databases.first()
|
||||||
|
replica = self.databases.list()[1]
|
||||||
|
|
||||||
|
initial = {'instance_id': replica_source.id,
|
||||||
|
'replica': replica,
|
||||||
|
'replica_source': replica_source}
|
||||||
|
views.PromoteToReplicaSourceView.get_initial().AndReturn(initial)
|
||||||
|
|
||||||
|
api.trove.promote_to_replica_source(
|
||||||
|
IsA(http.HttpRequest), replica_source.id).\
|
||||||
|
AndRaise(self.exceptions.trove)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
url = reverse('horizon:project:databases:promote_to_replica_source',
|
||||||
|
args=[replica_source.id])
|
||||||
|
form = {
|
||||||
|
'instance_id': replica_source.id
|
||||||
|
}
|
||||||
|
res = self.client.post(url, form)
|
||||||
|
self.assertEqual(res.status_code, 302)
|
||||||
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
|
|
||||||
|
@test.create_stubs({
|
||||||
|
api.trove: ('instance_list',
|
||||||
|
'eject_replica_source',),
|
||||||
|
})
|
||||||
|
def test_eject_replica_source(self):
|
||||||
|
databases = common.Paginated(self.databases.list())
|
||||||
|
database = databases[2]
|
||||||
|
|
||||||
|
api.trove.eject_replica_source(
|
||||||
|
IsA(http.HttpRequest), database.id)
|
||||||
|
|
||||||
|
databases = common.Paginated(self.databases.list())
|
||||||
|
api.trove.instance_list(IsA(http.HttpRequest), marker=None)\
|
||||||
|
.AndReturn(databases)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.post(
|
||||||
|
INDEX_URL,
|
||||||
|
{'action': 'databases__eject_replica_source__%s' % database.id})
|
||||||
|
|
||||||
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
|
|
||||||
|
@test.create_stubs({
|
||||||
|
api.trove: ('instance_list',
|
||||||
|
'eject_replica_source',),
|
||||||
|
})
|
||||||
|
def test_eject_replica_source_exception(self):
|
||||||
|
databases = common.Paginated(self.databases.list())
|
||||||
|
database = databases[2]
|
||||||
|
|
||||||
|
api.trove.eject_replica_source(
|
||||||
|
IsA(http.HttpRequest), database.id)\
|
||||||
|
.AndRaise(self.exceptions.trove)
|
||||||
|
|
||||||
|
databases = common.Paginated(self.databases.list())
|
||||||
|
api.trove.instance_list(IsA(http.HttpRequest), marker=None)\
|
||||||
|
.AndReturn(databases)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
res = self.client.post(
|
||||||
|
INDEX_URL,
|
||||||
|
{'action': 'databases__eject_replica_source__%s' % database.id})
|
||||||
|
|
||||||
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
|
@ -39,6 +39,9 @@ urlpatterns = patterns(
|
|||||||
name='access_detail'),
|
name='access_detail'),
|
||||||
url(INSTANCES % 'create_database', views.CreateDatabaseView.as_view(),
|
url(INSTANCES % 'create_database', views.CreateDatabaseView.as_view(),
|
||||||
name='create_database'),
|
name='create_database'),
|
||||||
|
url(INSTANCES % 'promote_to_replica_source',
|
||||||
|
views.PromoteToReplicaSourceView.as_view(),
|
||||||
|
name='promote_to_replica_source'),
|
||||||
url(INSTANCES % 'manage_root', views.ManageRootView.as_view(),
|
url(INSTANCES % 'manage_root', views.ManageRootView.as_view(),
|
||||||
name='manage_root'),
|
name='manage_root'),
|
||||||
)
|
)
|
||||||
|
@ -357,6 +357,52 @@ class ResizeInstanceView(horizon_forms.ModalFormView):
|
|||||||
return initial
|
return initial
|
||||||
|
|
||||||
|
|
||||||
|
class PromoteToReplicaSourceView(horizon_forms.ModalFormView):
|
||||||
|
form_class = forms.PromoteToReplicaSourceForm
|
||||||
|
form_id = "promote_to_replica_source_form"
|
||||||
|
modal_header = _("Promote to Replica Source")
|
||||||
|
modal_id = "promote_to_replica_source_modal"
|
||||||
|
template_name = 'project/databases/promote_to_replica_source.html'
|
||||||
|
submit_lable = _("Promote")
|
||||||
|
submit_url = 'horizon:project:databases:promote_to_replica_source'
|
||||||
|
success_url = reverse_lazy('horizon:project:databases:index')
|
||||||
|
|
||||||
|
@memoized.memoized_method
|
||||||
|
def get_object(self, *args, **kwargs):
|
||||||
|
instance_id = self.kwargs['instance_id']
|
||||||
|
try:
|
||||||
|
replica = api.trove.instance_get(self.request, instance_id)
|
||||||
|
replica_source = api.trove.instance_get(self.request,
|
||||||
|
replica.replica_of['id'])
|
||||||
|
instances = {'replica': replica,
|
||||||
|
'replica_source': replica_source}
|
||||||
|
return instances
|
||||||
|
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(PromoteToReplicaSourceView, self).get_context_data(**kwargs)
|
||||||
|
context['instance_id'] = self.kwargs['instance_id']
|
||||||
|
context['replica'] = self.get_initial().get('replica')
|
||||||
|
context['replica'].ip = \
|
||||||
|
self.get_initial().get('replica').ip[0]
|
||||||
|
context['replica_source'] = self.get_initial().get('replica_source')
|
||||||
|
context['replica_source'].ip = \
|
||||||
|
self.get_initial().get('replica_source').ip[0]
|
||||||
|
args = (self.kwargs['instance_id'],)
|
||||||
|
context['submit_url'] = reverse(self.submit_url, args=args)
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
instances = self.get_object()
|
||||||
|
return {'instance_id': self.kwargs['instance_id'],
|
||||||
|
'replica': instances['replica'],
|
||||||
|
'replica_source': instances['replica_source']}
|
||||||
|
|
||||||
|
|
||||||
class EnableRootInfo(object):
|
class EnableRootInfo(object):
|
||||||
def __init__(self, instance_id, instance_name, enabled, password=None):
|
def __init__(self, instance_id, instance_name, enabled, password=None):
|
||||||
self.id = instance_id
|
self.id = instance_id
|
||||||
|
@ -270,6 +270,17 @@ class AdvancedAction(workflows.Action):
|
|||||||
'data-switch-on': 'initial_state',
|
'data-switch-on': 'initial_state',
|
||||||
'data-initial_state-master': _('Master Instance Name')
|
'data-initial_state-master': _('Master Instance Name')
|
||||||
}))
|
}))
|
||||||
|
replica_count = forms.IntegerField(
|
||||||
|
label=_('Replica Count'),
|
||||||
|
required=False,
|
||||||
|
min_value=1,
|
||||||
|
initial=1,
|
||||||
|
help_text=_('Specify the number of replicas to be created'),
|
||||||
|
widget=forms.TextInput(attrs={
|
||||||
|
'class': 'switched',
|
||||||
|
'data-switch-on': 'initial_state',
|
||||||
|
'data-initial_state-master': _('Replica Count')
|
||||||
|
}))
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
name = _("Advanced")
|
name = _("Advanced")
|
||||||
@ -309,6 +320,7 @@ class AdvancedAction(workflows.Action):
|
|||||||
initial_state = cleaned_data.get("initial_state")
|
initial_state = cleaned_data.get("initial_state")
|
||||||
|
|
||||||
if initial_state == 'backup':
|
if initial_state == 'backup':
|
||||||
|
cleaned_data['replica_count'] = None
|
||||||
backup = self.cleaned_data['backup']
|
backup = self.cleaned_data['backup']
|
||||||
if backup:
|
if backup:
|
||||||
try:
|
try:
|
||||||
@ -336,13 +348,14 @@ class AdvancedAction(workflows.Action):
|
|||||||
else:
|
else:
|
||||||
cleaned_data['master'] = None
|
cleaned_data['master'] = None
|
||||||
cleaned_data['backup'] = None
|
cleaned_data['backup'] = None
|
||||||
|
cleaned_data['replica_count'] = None
|
||||||
|
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
|
|
||||||
class Advanced(workflows.Step):
|
class Advanced(workflows.Step):
|
||||||
action_class = AdvancedAction
|
action_class = AdvancedAction
|
||||||
contributes = ['backup', 'master']
|
contributes = ['backup', 'master', 'replica_count']
|
||||||
|
|
||||||
|
|
||||||
class LaunchInstance(workflows.Workflow):
|
class LaunchInstance(workflows.Workflow):
|
||||||
@ -417,13 +430,13 @@ class LaunchInstance(workflows.Workflow):
|
|||||||
"{name=%s, volume=%s, volume_type=%s, flavor=%s, "
|
"{name=%s, volume=%s, volume_type=%s, flavor=%s, "
|
||||||
"datastore=%s, datastore_version=%s, "
|
"datastore=%s, datastore_version=%s, "
|
||||||
"dbs=%s, users=%s, "
|
"dbs=%s, users=%s, "
|
||||||
"backups=%s, nics=%s, replica_of=%s}",
|
"backups=%s, nics=%s, replica_of=%s replica_count=%s}",
|
||||||
context['name'], context['volume'],
|
context['name'], context['volume'],
|
||||||
self._get_volume_type(context), context['flavor'],
|
self._get_volume_type(context), context['flavor'],
|
||||||
datastore, datastore_version,
|
datastore, datastore_version,
|
||||||
self._get_databases(context), self._get_users(context),
|
self._get_databases(context), self._get_users(context),
|
||||||
self._get_backup(context), self._get_nics(context),
|
self._get_backup(context), self._get_nics(context),
|
||||||
context.get('master'))
|
context.get('master'), context['replica_count'])
|
||||||
api.trove.instance_create(request,
|
api.trove.instance_create(request,
|
||||||
context['name'],
|
context['name'],
|
||||||
context['volume'],
|
context['volume'],
|
||||||
@ -435,6 +448,7 @@ class LaunchInstance(workflows.Workflow):
|
|||||||
restore_point=self._get_backup(context),
|
restore_point=self._get_backup(context),
|
||||||
nics=self._get_nics(context),
|
nics=self._get_nics(context),
|
||||||
replica_of=context.get('master'),
|
replica_of=context.get('master'),
|
||||||
|
replica_count=context['replica_count'],
|
||||||
volume_type=self._get_volume_type(
|
volume_type=self._get_volume_type(
|
||||||
context))
|
context))
|
||||||
return True
|
return True
|
||||||
|
@ -180,6 +180,39 @@ DATABASE_DATA_TWO = {
|
|||||||
"id": "4d7b3f57-44f5-41d2-8e86-36b88cad572a",
|
"id": "4d7b3f57-44f5-41d2-8e86-36b88cad572a",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DATABASE_DATA_THREE = {
|
||||||
|
"status": "ACTIVE",
|
||||||
|
"updated": "2015-01-12T22:00:09",
|
||||||
|
"name": "Test Database with Config",
|
||||||
|
"links": [],
|
||||||
|
"created": "2015-01-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": "c3369597-b53a-4bd4-bf54-41957c1291b8",
|
||||||
|
"configuration": {
|
||||||
|
"id": "0ef978d3-7c83-4192-ab86-b7a0a5010fa0",
|
||||||
|
"links": [],
|
||||||
|
"name": "config1"
|
||||||
|
},
|
||||||
|
"replicas": {
|
||||||
|
"id": "0ef978d3-7c83-4192-ab86-b7a0a5010fa0",
|
||||||
|
"links": [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BACKUP_ONE = {
|
BACKUP_ONE = {
|
||||||
"instance_id": "6ddc36d9-73db-4e23-b52e-368937d72719",
|
"instance_id": "6ddc36d9-73db-4e23-b52e-368937d72719",
|
||||||
"status": "COMPLETED",
|
"status": "COMPLETED",
|
||||||
@ -345,6 +378,8 @@ def data(TEST):
|
|||||||
DATABASE_DATA_ONE)
|
DATABASE_DATA_ONE)
|
||||||
database2 = instances.Instance(instances.Instances(None),
|
database2 = instances.Instance(instances.Instances(None),
|
||||||
DATABASE_DATA_TWO)
|
DATABASE_DATA_TWO)
|
||||||
|
database3 = instances.Instance(instances.Instances(None),
|
||||||
|
DATABASE_DATA_THREE)
|
||||||
bkup1 = backups.Backup(backups.Backups(None), BACKUP_ONE)
|
bkup1 = backups.Backup(backups.Backups(None), BACKUP_ONE)
|
||||||
bkup2 = backups.Backup(backups.Backups(None), BACKUP_TWO)
|
bkup2 = backups.Backup(backups.Backups(None), BACKUP_TWO)
|
||||||
bkup3 = backups.Backup(backups.Backups(None), BACKUP_TWO_INC)
|
bkup3 = backups.Backup(backups.Backups(None), BACKUP_TWO_INC)
|
||||||
@ -391,6 +426,7 @@ def data(TEST):
|
|||||||
|
|
||||||
TEST.databases.add(database1)
|
TEST.databases.add(database1)
|
||||||
TEST.databases.add(database2)
|
TEST.databases.add(database2)
|
||||||
|
TEST.databases.add(database3)
|
||||||
TEST.database_backups.add(bkup1)
|
TEST.database_backups.add(bkup1)
|
||||||
TEST.database_backups.add(bkup2)
|
TEST.database_backups.add(bkup2)
|
||||||
TEST.database_backups.add(bkup3)
|
TEST.database_backups.add(bkup3)
|
||||||
|
Loading…
Reference in New Issue
Block a user