Add create cluster

This commit is contained in:
Steve Leon 2015-03-09 15:36:32 -07:00
parent 948cbf2e31
commit 3b6846680c
8 changed files with 253 additions and 5 deletions

View File

@ -50,6 +50,11 @@ def cluster_get(request, cluster_id):
return cluster
def cluster_create(request, name, nic, flavor, size, volume_size):
return cueclient(request).clusters.create(name, nic,flavor,
size, volume_size)
def delete_cluster(request, cluster_id):
return cueclient(request).clusters.delete(cluster_id)

View File

@ -27,4 +27,5 @@ urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(),
name='index'),
url(CLUSTERS % '', views.DetailView.as_view(), name='detail'),
url(r'^create$', views.CreateClusterView.as_view(), name='create'),
)

View File

@ -16,15 +16,18 @@
# Copyright [2014] Hewlett-Packard Development Company, L.P.
# limitations under the License.
import logging
from cuedashboard import api
from cuedashboard.queues.tables import ClusterTable
from cuedashboard.queues.tabs import ClusterDetailTabs
from cuedashboard.queues import workflows as cue_workflows
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from horizon import tables
from horizon import tabs as horizon_tabs
from horizon.utils import memoized
from cuedashboard.queues.tabs import ClusterDetailTabs
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
import logging
from horizon import workflows
LOG = logging.getLogger(__name__)
@ -38,6 +41,12 @@ class IndexView(tables.DataTableView):
return api.clusters_list(self.request)
class CreateClusterView(workflows.WorkflowView):
workflow_class = cue_workflows.CreateCluster
template_name = "queues/launch.html"
page_title = _("Create Cluster")
class DetailView(horizon_tabs.TabbedTableView):
tab_group_class = ClusterDetailTabs
template_name = 'queues/detail.html'
@ -63,7 +72,6 @@ class DetailView(horizon_tabs.TabbedTableView):
return cluster
def get_tabs(self, request, *args, **kwargs):
cluster = self.get_data()
return self.tab_group_class(request, cluster=cluster, **kwargs)

View File

@ -0,0 +1,168 @@
# Copyright 2013 Rackspace Hosting
#
# 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.
import logging
from django.conf import settings
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon.utils import memoized
from horizon import workflows
from openstack_dashboard import api
from cuedashboard.api import cluster_create
from openstack_dashboard.dashboards.project.instances \
import utils as instance_utils
LOG = logging.getLogger(__name__)
class SetInstanceDetailsAction(workflows.Action):
name = forms.CharField(max_length=80, label=_("Cluster Name"))
flavor = forms.ChoiceField(label=_("Flavor"),
help_text=_("Size of image to launch."))
size = forms.IntegerField(label=_("Size"),
min_value=0,
initial=1,
help_text=_("Size of cluster."))
volume = forms.IntegerField(label=_("Volume Size"),
min_value=0,
initial=1,
help_text=_("Size of the volume in GB."))
class Meta(object):
name = _("Details")
help_text_template = "queues/_launch_details_help.html"
@memoized.memoized_method
def flavors(self, request):
try:
return api.nova.flavor_list(request)
except Exception:
LOG.exception("Exception while obtaining flavors list")
redirect = reverse("horizon:project:queues:index")
exceptions.handle(request,
_('Unable to obtain flavors.'),
redirect=redirect)
def populate_flavor_choices(self, request, context):
flavors = self.flavors(request)
if flavors:
return instance_utils.sort_flavor_list(request, flavors)
return []
TROVE_ADD_USER_PERMS = getattr(settings, 'TROVE_ADD_USER_PERMS', [])
TROVE_ADD_DATABASE_PERMS = getattr(settings, 'TROVE_ADD_DATABASE_PERMS', [])
TROVE_ADD_PERMS = TROVE_ADD_USER_PERMS + TROVE_ADD_DATABASE_PERMS
class SetClusterDetails(workflows.Step):
action_class = SetInstanceDetailsAction
contributes = ("name", "volume", "flavor", "size")
class SetNetworkAction(workflows.Action):
network = forms.MultipleChoiceField(label=_("Networks"),
widget=forms.CheckboxSelectMultiple(),
error_messages={
'required': _(
"At least one network must"
" be specified.")},
help_text=_("Create cluster with"
" these networks"))
def __init__(self, request, *args, **kwargs):
super(SetNetworkAction, self).__init__(request, *args, **kwargs)
network_list = self.fields["network"].choices
if len(network_list) == 1:
self.fields['network'].initial = [network_list[0][0]]
class Meta(object):
name = _("Networking")
permissions = ('openstack.services.network',)
help_text = _("Select networks for your cluster.")
def populate_network_choices(self, request, context):
try:
tenant_id = self.request.user.tenant_id
networks = api.neutron.network_list_for_tenant(request, tenant_id)
network_list = [(network.id, network.name_or_id)
for network in networks]
except Exception:
network_list = []
exceptions.handle(request,
_('Unable to retrieve networks.'))
return network_list
class SetNetwork(workflows.Step):
action_class = SetNetworkAction
template_name = "project/databases/_launch_networks.html"
contributes = ("network_id",)
def contribute(self, data, context):
if data:
networks = self.workflow.request.POST.getlist("network")
# If no networks are explicitly specified, network list
# contains an empty string, so remove it.
networks = [n for n in networks if n != '']
if networks:
#TODO
#Choosing the first networks until Cue
#supports more than one networks.
context['network_id'] = networks[0]
return context
class CreateCluster(workflows.Workflow):
slug = "create_cluster"
name = _("Create Cluster")
finalize_button_name = _("Create")
success_message = _('Created cluster named "%(name)s".')
failure_message = _('Unable to create cluster named "%(name)s".')
success_url = "horizon:project:queues:index"
default_steps = (SetClusterDetails,
SetNetwork)
def __init__(self, request=None, context_seed=None, entry_point=None,
*args, **kwargs):
super(CreateCluster, self).__init__(request, context_seed,
entry_point, *args, **kwargs)
self.attrs['autocomplete'] = (
settings.HORIZON_CONFIG.get('password_autocomplete'))
def format_status_message(self, message):
name = self.context.get('name', 'unknown cluster')
return message % {"name": name}
def handle(self, request, context):
try:
LOG.info("Launching message queue cluster with parameters "
"{name=%s, volume=%s, flavor=%s, size=%s, nics=%s}",
context['name'], context['volume'], context['flavor'],
context['size'], context['network_id'])
cluster_create(request, context['name'], context['network_id'],
context['flavor'], context['size'], context['volume'])
return True
except Exception:
exceptions.handle(request)
return False

View File

@ -0,0 +1,4 @@
{% load i18n %}
<p>{% blocktrans %}Specify the details for creating a message queue cluster.{% endblocktrans %}</p>
<p>{% blocktrans %}<strong>Please note:</strong> The cluster size must be at least 3{% endblocktrans %}</p>

View File

@ -0,0 +1,46 @@
{% load i18n %}
<noscript><h3>{{ step }}</h3></noscript>
<table class="table-fixed" id="networkListSortContainer">
<tbody>
<tr>
<td class="actions">
<label id="selected_network_label">{% trans "Selected networks" %}</label>
<ul id="selected_network" class="networklist">
</ul>
<label>{% trans "Available networks" %}</label>
<ul id="available_network" class="networklist">
</ul>
</td>
<td class="help_text">
{% include "queues/_launch_network_help.html" %}
</td>
</tr>
</tbody>
</table>
<table class="table-fixed" id="networkListIdContainer">
<tbody>
<tr>
<td class="actions">
<div id="networkListId">
{% include "horizon/common/_form_fields.html" %}
</div>
</td>
<td class="help_text">
{{ step.get_help_text }}
</td>
</tr>
</tbody>
</table>
<script>
if (typeof $ !== 'undefined') {
horizon.instances.workflow_init($(".workflow"));
} else {
addHorizonLoadEvent(function() {
horizon.instances.workflow_init($(".workflow"));
});
}
</script>

View File

@ -0,0 +1,9 @@
{% load i18n %}
<p>
{% blocktrans %}
Move networks from 'Available Networks' to 'Selected Networks' by
clicking the button, or dragging and dropping. You can change the
NIC order by dragging and dropping as well.
{% endblocktrans %}
</p>

View File

@ -0,0 +1,7 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Create Cluster" %}{% endblock %}
{% block main %}
{% include 'horizon/common/_workflow.html' %}
{% endblock %}