Fix handling of UUID-typed flavor ids
Change the type of flavor_id hidden field in EditFlavor form from IntegerField to CharField since flavor id is a string representation of UUID now. Additionally change the type of similar hidden fields in CreateExtraSpec and EditExtraSpec forms. Remove flavor id generation from form handling code. Id generation should be done only in corresponding OpenStack components (nova, etc.). Since nova supports flavor id autogeneration and 'flavorid' parameter of FlavorManager.create() in novaclient is optional, remove 'flavorid' parameter from api.nova.flavor_create(). Change flavor ids in test data from strings containing integers to UUID-like strings to make them correspond to real data. Update flavor tests to make them compatible with new api.nova.flavor_create() signature. Remove conversions of flavor id to int from all tests. In particular, update test_index_flavor_get_exception() to make it generate unique UUID flavor ids instead of integers. Fixes bug #1076761 Change-Id: Iaa308578981f0379ff61a9dd42620eaf0ab1d605
This commit is contained in:
parent
8243f755a3
commit
155e3ae7c3
@ -195,10 +195,9 @@ def server_vnc_console(request, instance_id, console_type='novnc'):
|
|||||||
console_type)['console'])
|
console_type)['console'])
|
||||||
|
|
||||||
|
|
||||||
def flavor_create(request, name, memory, vcpu, disk, flavor_id, ephemeral=0):
|
def flavor_create(request, name, memory, vcpu, disk, ephemeral=0):
|
||||||
return novaclient(request).flavors.create(name, int(memory), int(vcpu),
|
return novaclient(request).flavors.create(name, memory, vcpu,
|
||||||
int(disk), flavor_id,
|
disk, ephemeral=ephemeral)
|
||||||
ephemeral=int(ephemeral))
|
|
||||||
|
|
||||||
|
|
||||||
def flavor_delete(request, flavor_id):
|
def flavor_delete(request, flavor_id):
|
||||||
|
@ -33,7 +33,7 @@ LOG = logging.getLogger(__name__)
|
|||||||
class CreateExtraSpec(forms.SelfHandlingForm):
|
class CreateExtraSpec(forms.SelfHandlingForm):
|
||||||
key = forms.CharField(max_length="25", label=_("Key"))
|
key = forms.CharField(max_length="25", label=_("Key"))
|
||||||
value = forms.CharField(max_length="25", label=_("Value"))
|
value = forms.CharField(max_length="25", label=_("Value"))
|
||||||
flavor_id = forms.IntegerField(widget=forms.widgets.HiddenInput)
|
flavor_id = forms.CharField(widget=forms.widgets.HiddenInput)
|
||||||
|
|
||||||
def handle(self, request, data):
|
def handle(self, request, data):
|
||||||
try:
|
try:
|
||||||
@ -51,7 +51,7 @@ class CreateExtraSpec(forms.SelfHandlingForm):
|
|||||||
class EditExtraSpec(forms.SelfHandlingForm):
|
class EditExtraSpec(forms.SelfHandlingForm):
|
||||||
key = forms.CharField(max_length="25", label=_("Key"))
|
key = forms.CharField(max_length="25", label=_("Key"))
|
||||||
value = forms.CharField(max_length="25", label=_("Value"))
|
value = forms.CharField(max_length="25", label=_("Value"))
|
||||||
flavor_id = forms.IntegerField(widget=forms.widgets.HiddenInput)
|
flavor_id = forms.CharField(widget=forms.widgets.HiddenInput)
|
||||||
|
|
||||||
def handle(self, request, data):
|
def handle(self, request, data):
|
||||||
flavor_id = data['flavor_id']
|
flavor_id = data['flavor_id']
|
||||||
|
@ -37,7 +37,7 @@ class FlavorExtrasTests(test.BaseAdminViewTests):
|
|||||||
|
|
||||||
# GET to display the flavor_name
|
# GET to display the flavor_name
|
||||||
api.nova.flavor_extra_set(IsA(http.HttpRequest),
|
api.nova.flavor_extra_set(IsA(http.HttpRequest),
|
||||||
int(flavor.id),
|
flavor.id,
|
||||||
{'k1': 'v1'})
|
{'k1': 'v1'})
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import uuid
|
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
@ -65,7 +64,6 @@ class CreateFlavor(forms.SelfHandlingForm):
|
|||||||
data['memory_mb'],
|
data['memory_mb'],
|
||||||
data['vcpus'],
|
data['vcpus'],
|
||||||
data['disk_gb'],
|
data['disk_gb'],
|
||||||
uuid.uuid4(),
|
|
||||||
ephemeral=data['eph_gb'])
|
ephemeral=data['eph_gb'])
|
||||||
msg = _('Created flavor "%s".') % data['name']
|
msg = _('Created flavor "%s".') % data['name']
|
||||||
messages.success(request, msg)
|
messages.success(request, msg)
|
||||||
@ -75,7 +73,7 @@ class CreateFlavor(forms.SelfHandlingForm):
|
|||||||
|
|
||||||
|
|
||||||
class EditFlavor(CreateFlavor):
|
class EditFlavor(CreateFlavor):
|
||||||
flavor_id = forms.IntegerField(widget=forms.widgets.HiddenInput)
|
flavor_id = forms.CharField(widget=forms.widgets.HiddenInput)
|
||||||
|
|
||||||
def clean_name(self):
|
def clean_name(self):
|
||||||
return self.cleaned_data['name']
|
return self.cleaned_data['name']
|
||||||
@ -92,16 +90,14 @@ class EditFlavor(CreateFlavor):
|
|||||||
# This is in the same try/except block as the delete call
|
# This is in the same try/except block as the delete call
|
||||||
# because if the delete fails the API will error out because
|
# because if the delete fails the API will error out because
|
||||||
# active flavors can't have the same name.
|
# active flavors can't have the same name.
|
||||||
new_flavor_id = uuid.uuid4()
|
|
||||||
flavor = api.nova.flavor_create(request,
|
flavor = api.nova.flavor_create(request,
|
||||||
data['name'],
|
data['name'],
|
||||||
data['memory_mb'],
|
data['memory_mb'],
|
||||||
data['vcpus'],
|
data['vcpus'],
|
||||||
data['disk_gb'],
|
data['disk_gb'],
|
||||||
new_flavor_id,
|
|
||||||
ephemeral=data['eph_gb'])
|
ephemeral=data['eph_gb'])
|
||||||
if (len(extras_dict) > 0):
|
if (len(extras_dict) > 0):
|
||||||
api.nova.flavor_extra_set(request, new_flavor_id, extras_dict)
|
api.nova.flavor_extra_set(request, flavor.id, extras_dict)
|
||||||
msg = _('Updated flavor "%s".') % data['name']
|
msg = _('Updated flavor "%s".') % data['name']
|
||||||
messages.success(request, msg)
|
messages.success(request, msg)
|
||||||
return flavor
|
return flavor
|
||||||
|
@ -21,7 +21,6 @@ class FlavorsTests(test.BaseAdminViewTests):
|
|||||||
flavor.ram,
|
flavor.ram,
|
||||||
flavor.vcpus,
|
flavor.vcpus,
|
||||||
flavor.disk,
|
flavor.disk,
|
||||||
IsA(uuid.uuid4()),
|
|
||||||
ephemeral=eph).AndReturn(flavor)
|
ephemeral=eph).AndReturn(flavor)
|
||||||
api.nova.flavor_list(IsA(http.HttpRequest))
|
api.nova.flavor_list(IsA(http.HttpRequest))
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
@ -55,15 +54,14 @@ class FlavorsTests(test.BaseAdminViewTests):
|
|||||||
|
|
||||||
# POST
|
# POST
|
||||||
api.nova.flavor_get(IsA(http.HttpRequest), flavor.id).AndReturn(flavor)
|
api.nova.flavor_get(IsA(http.HttpRequest), flavor.id).AndReturn(flavor)
|
||||||
api.nova.flavor_get_extras(IsA(http.HttpRequest), int(flavor.id))\
|
api.nova.flavor_get_extras(IsA(http.HttpRequest), flavor.id)\
|
||||||
.AndReturn(extras)
|
.AndReturn(extras)
|
||||||
api.nova.flavor_delete(IsA(http.HttpRequest), int(flavor.id))
|
api.nova.flavor_delete(IsA(http.HttpRequest), flavor.id)
|
||||||
api.nova.flavor_create(IsA(http.HttpRequest),
|
api.nova.flavor_create(IsA(http.HttpRequest),
|
||||||
flavor.name,
|
flavor.name,
|
||||||
flavor.ram,
|
flavor.ram,
|
||||||
flavor.vcpus + 1,
|
flavor.vcpus + 1,
|
||||||
flavor.disk,
|
flavor.disk,
|
||||||
IsA(uuid.uuid4()),
|
|
||||||
ephemeral=eph).AndReturn(flavor)
|
ephemeral=eph).AndReturn(flavor)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
|
||||||
from django import http
|
from django import http
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.utils.datastructures import SortedDict
|
from django.utils.datastructures import SortedDict
|
||||||
@ -76,10 +78,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
|
|||||||
servers = self.servers.list()
|
servers = self.servers.list()
|
||||||
flavors = self.flavors.list()
|
flavors = self.flavors.list()
|
||||||
tenants = self.tenants.list()
|
tenants = self.tenants.list()
|
||||||
max_id = max([int(flavor.id) for flavor in flavors])
|
# UUIDs generated using indexes are unlikely to match
|
||||||
for server in servers:
|
# any of existing flavor ids and are guaranteed to be deterministic.
|
||||||
max_id += 1
|
for i, server in enumerate(servers):
|
||||||
server.flavor["id"] = max_id
|
server.flavor['id'] = str(uuid.UUID(int=i))
|
||||||
|
|
||||||
api.nova.server_list(IsA(http.HttpRequest),
|
api.nova.server_list(IsA(http.HttpRequest),
|
||||||
all_tenants=True).AndReturn(servers)
|
all_tenants=True).AndReturn(servers)
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
|
||||||
from django import http
|
from django import http
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.utils.http import urlencode
|
from django.utils.http import urlencode
|
||||||
@ -90,10 +92,10 @@ class InstanceTests(test.TestCase):
|
|||||||
def test_index_flavor_get_exception(self):
|
def test_index_flavor_get_exception(self):
|
||||||
servers = self.servers.list()
|
servers = self.servers.list()
|
||||||
flavors = self.flavors.list()
|
flavors = self.flavors.list()
|
||||||
max_id = max([int(flavor.id) for flavor in flavors])
|
# UUIDs generated using indexes are unlikely to match
|
||||||
for server in servers:
|
# any of existing flavor ids and are guaranteed to be deterministic.
|
||||||
max_id += 1
|
for i, server in enumerate(servers):
|
||||||
server.flavor["id"] = max_id
|
server.flavor['id'] = str(uuid.UUID(int=i))
|
||||||
|
|
||||||
api.server_list(IsA(http.HttpRequest)).AndReturn(servers)
|
api.server_list(IsA(http.HttpRequest)).AndReturn(servers)
|
||||||
api.flavor_list(IsA(http.HttpRequest)).AndReturn(flavors)
|
api.flavor_list(IsA(http.HttpRequest)).AndReturn(flavors)
|
||||||
|
@ -198,14 +198,14 @@ def data(TEST):
|
|||||||
|
|
||||||
# Flavors
|
# Flavors
|
||||||
flavor_1 = flavors.Flavor(flavors.FlavorManager(None),
|
flavor_1 = flavors.Flavor(flavors.FlavorManager(None),
|
||||||
{'id': "1",
|
{'id': "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
|
||||||
'name': 'm1.tiny',
|
'name': 'm1.tiny',
|
||||||
'vcpus': 1,
|
'vcpus': 1,
|
||||||
'disk': 0,
|
'disk': 0,
|
||||||
'ram': 512,
|
'ram': 512,
|
||||||
'OS-FLV-EXT-DATA:ephemeral': 0})
|
'OS-FLV-EXT-DATA:ephemeral': 0})
|
||||||
flavor_2 = flavors.Flavor(flavors.FlavorManager(None),
|
flavor_2 = flavors.Flavor(flavors.FlavorManager(None),
|
||||||
{'id': "2",
|
{'id': "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
|
||||||
'name': 'm1.massive',
|
'name': 'm1.massive',
|
||||||
'vcpus': 1000,
|
'vcpus': 1000,
|
||||||
'disk': 1024,
|
'disk': 1024,
|
||||||
|
@ -6,7 +6,7 @@ set -o errexit
|
|||||||
# Increment me any time the environment should be rebuilt.
|
# Increment me any time the environment should be rebuilt.
|
||||||
# This includes dependncy changes, directory renames, etc.
|
# This includes dependncy changes, directory renames, etc.
|
||||||
# Simple integer secuence: 1, 2, 3...
|
# Simple integer secuence: 1, 2, 3...
|
||||||
environment_version=28
|
environment_version=29
|
||||||
#--------------------------------------------------------#
|
#--------------------------------------------------------#
|
||||||
|
|
||||||
function usage {
|
function usage {
|
||||||
|
@ -6,7 +6,7 @@ netaddr
|
|||||||
python-cinderclient
|
python-cinderclient
|
||||||
python-glanceclient<2
|
python-glanceclient<2
|
||||||
python-keystoneclient
|
python-keystoneclient
|
||||||
python-novaclient
|
python-novaclient>=2.10.0,<3
|
||||||
python-quantumclient>=2.0
|
python-quantumclient>=2.0
|
||||||
python-swiftclient>1.1,<2
|
python-swiftclient>1.1,<2
|
||||||
pytz
|
pytz
|
||||||
|
Loading…
Reference in New Issue
Block a user