[Sahara] Support Cinder availability zones

Add an optional field in the node group template page. It is used for
selecting the availability zone where to create volumes.

Change-Id: I94a92425884fe0611b9bf7439030bd226b25f72c
Implements: blueprint support-cinder-availability-zones
This commit is contained in:
Adrien Vergé 2014-10-12 16:38:52 +02:00
parent b6fcedb449
commit 734290410c
8 changed files with 104 additions and 31 deletions

View File

@ -96,18 +96,23 @@ def nodegroup_template_create(request, name, plugin_name, hadoop_version,
node_processes=None, node_configs=None,
floating_ip_pool=None, security_groups=None,
auto_security_group=False,
availability_zone=False):
return client(request).node_group_templates.create(name, plugin_name,
hadoop_version,
flavor_id, description,
volumes_per_node,
volumes_size,
node_processes,
node_configs,
floating_ip_pool,
security_groups,
auto_security_group,
availability_zone)
availability_zone=False,
volumes_availability_zone=False):
return client(request).node_group_templates.create(
name,
plugin_name,
hadoop_version,
flavor_id,
description,
volumes_per_node,
volumes_size,
node_processes,
node_configs,
floating_ip_pool,
security_groups,
auto_security_group,
availability_zone,
volumes_availability_zone)
def nodegroup_template_list(request):
@ -132,20 +137,24 @@ def nodegroup_template_update(request, ngt_id, name, plugin_name,
volumes_size=None, node_processes=None,
node_configs=None, floating_ip_pool=None,
security_groups=None, auto_security_group=False,
availability_zone=False):
return client(request).node_group_templates.update(ngt_id, name,
plugin_name,
hadoop_version,
flavor_id,
description,
volumes_per_node,
volumes_size,
node_processes,
node_configs,
floating_ip_pool,
security_groups,
auto_security_group,
availability_zone)
availability_zone=False,
volumes_availability_zone=False):
return client(request).node_group_templates.update(
ngt_id,
name,
plugin_name,
hadoop_version,
flavor_id,
description,
volumes_per_node,
volumes_size,
node_processes,
node_configs,
floating_ip_pool,
security_groups,
auto_security_group,
availability_zone,
volumes_availability_zone)
def cluster_template_create(request, name, plugin_name, hadoop_version,

View File

@ -71,6 +71,10 @@
<dd>{{ template.volumes_per_node }}</dd>
<dt>{% trans "Volumes size" %}</dt>
<dd>{{ template.volumes_size }}</dd>
{% if template.volumes_availability_zone %}
<dt>{% trans "Volumes Availability Zone" %}</dt>
<dd>{{ template.volumes_availability_zone }}</dd>
{% endif %}
{% else %}
<h6>{% trans "Ephemeral drive" %}</h6>
{% endif %}

View File

@ -61,9 +61,11 @@
if (show) {
$(".volume_per_node_field").closest(".form-group").show();
$(".volume_size_field").closest(".form-group").show();
$(".volumes_availability_zone_field").closest(".form-group").show();
} else {
$(".volume_per_node_field").closest(".form-group").hide();
$(".volume_size_field").closest(".form-group").hide();
$(".volumes_availability_zone_field").closest(".form-group").hide();
}
}

View File

@ -143,6 +143,7 @@ class DataProcessingNodeGroupTests(test.TestCase):
'flavor_id': flavor.id,
'volumes_per_node': None,
'volumes_size': None,
'volumes_availability_zone': None,
'node_processes': ['namenode'],
'node_configs': {},
'floating_ip_pool': None,
@ -165,6 +166,7 @@ class DataProcessingNodeGroupTests(test.TestCase):
'storage': 'ephemeral_drive',
'volumes_per_node': 0,
'volumes_size': 0,
'volumes_availability_zone': None,
'floating_ip_pool': None,
'security_autogroup': True,
'processes': 'HDFS:namenode'})

View File

@ -64,6 +64,8 @@ class CopyNodegroupTemplate(create_flow.ConfigureNodegroupTemplate):
g_fields["storage"].initial = storage
g_fields["volumes_per_node"].initial = volumes_per_node
g_fields["volumes_size"].initial = volumes_size
g_fields["volumes_availability_zone"].initial = \
template.volumes_availability_zone
if template.floating_ip_pool:
g_fields['floating_ip_pool'].initial = template.floating_ip_pool

View File

@ -28,6 +28,8 @@ from openstack_dashboard.dashboards.project.data_processing.utils \
import workflow_helpers
from openstack_dashboard.dashboards.project.instances \
import utils as nova_utils
from openstack_dashboard.dashboards.project.volumes \
import utils as cinder_utils
LOG = logging.getLogger(__name__)
@ -70,6 +72,13 @@ class GeneralConfigAction(workflows.Action):
widget=forms.TextInput(attrs={"class": "volume_size_field"})
)
volumes_availability_zone = forms.ChoiceField(
label=_("Volumes Availability Zone"),
help_text=_("Create volumes in this availability zone."),
required=False,
widget=forms.Select(attrs={"class": "volumes_availability_zone_field"})
)
hidden_configure_field = forms.CharField(
required=False,
widget=forms.HiddenInput(attrs={"class": "hidden_configure_field"}))
@ -137,6 +146,13 @@ class GeneralConfigAction(workflows.Action):
if az.zoneState['available']])
return az_list
def populate_volumes_availability_zone_choices(self, request, context):
az_list = [(None, _('No availability zone specified'))]
az_list.extend([(az.zoneName, az.zoneName)
for az in cinder_utils.availability_zone_list(request)
if az.zoneState['available']])
return az_list
def get_help_text(self):
extra = dict()
plugin, hadoop_version = (
@ -275,10 +291,13 @@ class ConfigureNodegroupTemplate(workflow_helpers.ServiceParametersWorkflow,
volumes_per_node = None
volumes_size = None
volumes_availability_zone = None
if context["general_storage"] == "cinder_volume":
volumes_per_node = context["general_volumes_per_node"]
volumes_size = context["general_volumes_size"]
volumes_availability_zone = \
context["general_volumes_availability_zone"]
saharaclient.nodegroup_template_create(
request,
@ -289,6 +308,7 @@ class ConfigureNodegroupTemplate(workflow_helpers.ServiceParametersWorkflow,
flavor_id=context["general_flavor"],
volumes_per_node=volumes_per_node,
volumes_size=volumes_size,
volumes_availability_zone=volumes_availability_zone,
node_processes=processes,
node_configs=configs_dict,
floating_ip_pool=context.get("general_floating_ip_pool"),

View File

@ -0,0 +1,29 @@
# 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 _
from horizon import exceptions
from openstack_dashboard import api
def availability_zone_list(request):
"""Utility method to retrieve a list of availability zones."""
try:
if api.cinder.extension_supported(request, 'AvailabilityZones'):
return api.cinder.availability_zone_list(request)
return []
except Exception:
exceptions.handle(request,
_('Unable to retrieve volumes availability zones.'))
return []

View File

@ -126,7 +126,8 @@ def data(TEST):
"volume_mount_prefix": "/volumes/disk",
"volumes_per_node": 0,
"volumes_size": 0,
"security_groups": []
"security_groups": [],
"volumes_availability_zone": None,
}
ngt1 = node_group_templates.NodeGroupTemplate(
@ -165,7 +166,8 @@ def data(TEST):
"updated_at": None,
"volume_mount_prefix": "/volumes/disk",
"volumes_per_node": 0,
"volumes_size": 0
"volumes_size": 0,
"volumes_availability_zone": None,
},
{
"count": 2,
@ -183,7 +185,8 @@ def data(TEST):
"updated_at": None,
"volume_mount_prefix": "/volumes/disk",
"volumes_per_node": 0,
"volumes_size": 0
"volumes_size": 0,
"volumes_availability_zone": None,
}
],
"plugin_name": "vanilla",
@ -243,7 +246,8 @@ def data(TEST):
"volume_mount_prefix": "/volumes/disk",
"volumes_per_node": 0,
"volumes_size": 0,
"security_groups": []
"security_groups": [],
"volumes_availability_zone": None,
},
{
"count": 2,
@ -284,7 +288,8 @@ def data(TEST):
"volume_mount_prefix": "/volumes/disk",
"volumes_per_node": 0,
"volumes_size": 0,
"security_groups": ["b7857890-09bf-4ee0-a0d5-322d7a6978bf"]
"security_groups": ["b7857890-09bf-4ee0-a0d5-322d7a6978bf"],
"volumes_availability_zone": None,
}
],
"plugin_name": "vanilla",