Adding support for Manila-based shares in Sahara

The Sahara data processing service now supports manila
shares as a location for job binaries.  Also adding a unit
test for creation of manila-based job binaries.

Change-Id: I6599aca1baabe9875f6ac3ed847cb5030f0e5bb7
Implements: bp add-manila-binary-store
This commit is contained in:
Chad Roberts 2015-07-29 11:05:58 -04:00
parent 28f4533150
commit df3557e024
5 changed files with 166 additions and 6 deletions

View File

@ -11,4 +11,6 @@ django-openstack-auth>=2.0.0
iso8601>=0.1.9
python-keystoneclient!=1.8.0,>=1.6.0
python-manilaclient>=1.3.0
python-neutronclient>=2.6.0
python-novaclient!=2.33.0,>=2.29.0
python-saharaclient>=0.10.0

View File

@ -0,0 +1,67 @@
# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Copyright 2012 OpenStack Foundation
# Copyright 2012 Nebula, Inc.
# Copyright (c) 2012 X.commerce, a business unit of eBay Inc.
#
# 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 __future__ import absolute_import
import logging
from django.conf import settings
from manilaclient.v1 import client as manila_client
from horizon import exceptions
from horizon.utils.memoized import memoized # noqa
from openstack_dashboard.api import base
LOG = logging.getLogger(__name__)
# API static values
SHARE_STATE_AVAILABLE = "available"
DEFAULT_QUOTA_NAME = 'default'
def manilaclient(request):
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', None)
try:
manila_url = base.url_for(request, 'share')
except exceptions.ServiceCatalogException:
LOG.debug('no share service configured.')
return None
c = manila_client.Client(request.user.username,
input_auth_token=request.user.token.id,
project_id=request.user.tenant_id,
service_catalog_url=manila_url,
insecure=insecure,
cacert=cacert,
http_log_debug=settings.DEBUG)
c.client.auth_token = request.user.token.id
c.client.management_url = manila_url
return c
def share_list(request, search_opts=None):
return manilaclient(request).shares.list(search_opts=search_opts)
def share_get(request, share_id):
return manilaclient(request).shares.get(share_id)

View File

@ -12,6 +12,7 @@
# limitations under the License.
import logging
import six
import uuid
from django.forms import widgets
@ -20,11 +21,11 @@ from django.template import defaultfilters
from django.utils.encoding import force_text
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon import messages
from sahara_dashboard.api import manila as manilaclient
from sahara_dashboard.api import sahara as saharaclient
LOG = logging.getLogger(__name__)
@ -72,6 +73,26 @@ class JobBinaryCreateForm(forms.SelfHandlingForm):
'data-jb_type-swift': _('URL')
}))
self.fields["job_binary_manila_share"] = forms.ChoiceField(
label=_("Share"),
required=False,
widget=forms.Select(
attrs={
'class': 'switched',
'data-switch-on': 'jb_type',
'data-jb_type-manila': _('Share')
}))
self.fields["job_binary_manila_path"] = forms.CharField(
label=_("Path"),
required=False,
widget=forms.TextInput(
attrs={
'class': 'switched',
'data-switch-on': 'jb_type',
'data-jb_type-manila': _('Path')
}))
self.fields["job_binary_internal"] = forms.ChoiceField(
label=_("Internal binary"),
required=False,
@ -147,6 +168,11 @@ class JobBinaryCreateForm(forms.SelfHandlingForm):
self.fields["job_binary_internal"].choices =\
self.populate_job_binary_internal_choices(request)
if saharaclient.base.is_service_enabled(request, 'share'):
self.fields["job_binary_type"].choices.append(("manila", "Manila"))
self.fields["job_binary_manila_share"].choices = (
self.populate_job_binary_manila_share_choices(request))
self.load_form_values()
def load_form_values(self):
@ -156,13 +182,32 @@ class JobBinaryCreateForm(forms.SelfHandlingForm):
if self.FIELD_MAP[field]:
if field == "job_binary_url":
url = getattr(jb, self.FIELD_MAP[field], None)
(type, loc) = url.split("://")
self.fields['job_binary_type'].initial = type
self.fields[field].initial = loc
self.set_initial_values_by_type(url)
else:
self.fields[field].initial = (
getattr(jb, self.FIELD_MAP[field], None))
def set_initial_values_by_type(self, url):
parsed = six.moves.urllib.parse.urlparse(url)
self.fields["job_binary_type"].initial = parsed.scheme
if parsed.scheme == "manila":
self.fields["job_binary_manila_share"].initial = parsed.netloc
self.fields["job_binary_manila_path"].initial = parsed.path
elif parsed.scheme == "swift":
self.fields["job_binary_url"].initial = (
"{0}{1}".format(parsed.netloc, parsed.path))
else:
self.fields["job_binary_url"].initial = "{0}".format(parsed.netloc)
def populate_job_binary_manila_share_choices(self, request):
try:
shares = manilaclient.share_list(request)
choices = [(s.id, s.name) for s in shares]
except Exception:
exceptions.handle(request, _("Failed to get list of shares"))
choices = []
return choices
def populate_job_binary_internal_choices(self, request):
try:
job_binaries = saharaclient.job_binary_internal_list(request)
@ -181,12 +226,18 @@ class JobBinaryCreateForm(forms.SelfHandlingForm):
def handle(self, request, context):
try:
extra = {}
jb_type = context.get("job_binary_type")
bin_url = "%s://%s" % (context["job_binary_type"],
context["job_binary_url"])
if(context["job_binary_type"] == "internal-db"):
if(jb_type == "internal-db"):
bin_url = self.handle_internal(request, context)
elif(context["job_binary_type"] == "swift"):
elif(jb_type == "swift"):
extra = self.handle_swift(request, context)
elif(jb_type == "manila"):
bin_url = "%s://%s%s" % (context["job_binary_type"],
context["job_binary_manila_share"],
context["job_binary_manila_path"])
bin_object = saharaclient.job_binary_create(
request,
@ -283,6 +334,8 @@ class JobBinaryEditForm(JobBinaryCreateForm):
'job_binary_type': None,
'job_binary_url': 'url',
'job_binary_username': None,
'job_binary_manila_share': None,
'job_binary_manila_path': None,
}
def handle(self, request, context):

View File

@ -25,6 +25,8 @@ DETAILS_URL = reverse(
'horizon:project:data_processing.job_binaries:details', args=['id'])
EDIT_URL = reverse('horizon:project:data_processing.job_binaries'
':edit-job-binary', args=['id'])
CREATE_URL = reverse(
'horizon:project:data_processing.job_binaries:create-job-binary')
class DataProcessingJobBinaryTests(test.TestCase):
@ -123,3 +125,26 @@ class DataProcessingJobBinaryTests(test.TestCase):
}
res = self.client.post(EDIT_URL, form_data)
self.assertNoFormErrors(res)
@test.create_stubs({api.manila: ('share_list', ),
api.sahara.base: ('is_service_enabled', )})
def test_create_manila(self):
share = self.mox.CreateMockAnything(
{"id": "tuvwxy56-1234-abcd-abcd-defabcdaedcb",
"name": "Test share"})
shares = [share]
api.sahara.base.is_service_enabled(IsA(http.HttpRequest), IsA(str)) \
.AndReturn(True)
api.manila.share_list(IsA(http.HttpRequest)).AndReturn(shares)
self.mox.ReplayAll()
form_data = {
"job_binary_type": "manila",
"job_binary_manila_share": share.id,
"job_binary_manila_path": "/testfile.bin",
"job_binary_name": "testmanila",
"job_binary_description": "Test manila description"
}
res = self.client.post(CREATE_URL, form_data)
self.assertNoFormErrors(res)

View File

@ -428,13 +428,26 @@ def data(TEST):
"url": "internal-db://abcdef56-1234-abcd-abcd-defabcdaedcb"
}
job_binary3_dict = {
"created_at": "2015-10-10 13:12:15.583631",
"description": "Test Manila",
"id": "abcdef56-1234-abcd-1345-defabcdaedcb",
"name": "manilashared",
"tenant_id": "429ad8447c2d47bc8e0382d244e1d1df",
"updated_at": None,
"url": "manila://tuvwxy56-1234-abcd-abcd-defabcdaedcb/testfile.bin"
}
job_binary1 = job_binaries.JobBinaries(
job_binaries.JobBinariesManager(None), job_binary1_dict)
job_binary2 = job_binaries.JobBinaries(
job_binaries.JobBinariesManager(None), job_binary2_dict)
job_binary3 = job_binaries.JobBinaries(
job_binaries.JobBinariesManager(None), job_binary3_dict)
TEST.job_binaries.add(job_binary1)
TEST.job_binaries.add(job_binary2)
TEST.job_binaries.add(job_binary3)
# Jobs.
job1_dict = {