Added all validators for main Controller.
Change-Id: Iea65e7e9f111593a7c009e6315f1d4f821535a35
This commit is contained in:
@@ -53,6 +53,9 @@ LOG = logging.getLogger(__name__)
|
||||
"""
|
||||
|
||||
|
||||
Validator = common.Validator
|
||||
|
||||
|
||||
class AvailabilityZoneDescriber(common.UniversalDescriber):
|
||||
|
||||
KIND = 'az'
|
||||
|
@@ -36,7 +36,7 @@ from ec2api.api import route_table
|
||||
from ec2api.api import security_group
|
||||
from ec2api.api import snapshot
|
||||
from ec2api.api import subnet
|
||||
from ec2api.api import tag as tag_api
|
||||
from ec2api.api import tag
|
||||
from ec2api.api import volume
|
||||
from ec2api.api import vpc
|
||||
from ec2api import exception
|
||||
@@ -374,16 +374,16 @@ class CloudController(object):
|
||||
This action doesn't apply to security groups for use in EC2-Classic.
|
||||
"""
|
||||
|
||||
@module_and_param_types(instance, 'ami_id', 'dummy', 'dummy',
|
||||
@module_and_param_types(instance, 'ami_id', 'int', 'int',
|
||||
'str255', 'sg_ids',
|
||||
'str255s', 'dummy', 'dummy',
|
||||
'security_group_strs', 'str', 'str',
|
||||
'dummy', 'ami_id', 'ami_id',
|
||||
'dummy', 'dummy',
|
||||
'subnet_id', 'dummy',
|
||||
'dummy',
|
||||
'subnet_id', 'bool',
|
||||
'str',
|
||||
'ip', 'str64',
|
||||
'dummy', 'dummy',
|
||||
'dummy', 'dummy',
|
||||
'dummy')
|
||||
'bool')
|
||||
def run_instances(self, context, image_id, min_count, max_count,
|
||||
key_name=None, security_group_id=None,
|
||||
security_group=None, user_data=None, instance_type=None,
|
||||
@@ -514,7 +514,7 @@ class CloudController(object):
|
||||
"""
|
||||
|
||||
@module_and_param_types(instance, 'i_ids', 'filter',
|
||||
'dummy', 'dummy')
|
||||
'int', 'str')
|
||||
def describe_instances(self, context, instance_id=None, filter=None,
|
||||
max_results=None, next_token=None):
|
||||
"""Describes one or more of your instances.
|
||||
@@ -551,7 +551,7 @@ class CloudController(object):
|
||||
true if the request succeeds.
|
||||
"""
|
||||
|
||||
@module_and_param_types(instance, 'i_ids', 'dummy')
|
||||
@module_and_param_types(instance, 'i_ids', 'bool')
|
||||
def stop_instances(self, context, instance_id, force=False):
|
||||
"""Stops one or more instances.
|
||||
|
||||
@@ -598,6 +598,7 @@ class CloudController(object):
|
||||
Specified attribute.
|
||||
"""
|
||||
|
||||
@module_and_param_types(key_pair, 'str255s', 'filter')
|
||||
def describe_key_pairs(self, context, key_name=None, filter=None):
|
||||
"""Describes one or more of your key pairs.
|
||||
|
||||
@@ -609,8 +610,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
Specified keypairs.
|
||||
"""
|
||||
return key_pair.describe_key_pairs(context, key_name, filter)
|
||||
|
||||
@module_and_param_types(key_pair, 'str255')
|
||||
def create_key_pair(self, context, key_name):
|
||||
"""Creates a 2048-bit RSA key pair with the specified name.
|
||||
|
||||
@@ -621,8 +622,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
Created keypair.
|
||||
"""
|
||||
return key_pair.create_key_pair(context, key_name)
|
||||
|
||||
@module_and_param_types(key_pair, 'str255')
|
||||
def delete_key_pair(self, context, key_name):
|
||||
"""Deletes the specified key pair.
|
||||
|
||||
@@ -633,8 +634,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
Returns true if the request succeeds.
|
||||
"""
|
||||
return key_pair.delete_key_pair(context, key_name)
|
||||
|
||||
@module_and_param_types(key_pair, 'str255', 'str')
|
||||
def import_key_pair(self, context, key_name, public_key_material):
|
||||
"""Imports the public key from an existing RSA key pair.
|
||||
|
||||
@@ -647,9 +648,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
Imported keypair.
|
||||
"""
|
||||
return key_pair.import_key_pair(context, key_name,
|
||||
public_key_material)
|
||||
|
||||
@module_and_param_types(availability_zone, 'strs', 'filter')
|
||||
def describe_availability_zones(self, context, zone_name=None,
|
||||
filter=None):
|
||||
"""Describes one or more of the available Availability Zones.
|
||||
@@ -662,10 +662,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
Specified availability zones.
|
||||
"""
|
||||
return availability_zone.describe_availability_zones(context,
|
||||
zone_name,
|
||||
filter)
|
||||
|
||||
@module_and_param_types(availability_zone, 'strs', 'filter')
|
||||
def describe_regions(self, context, region_name=None, filter=None):
|
||||
"""Describes one or more regions that are currently available to you.
|
||||
|
||||
@@ -677,10 +675,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
Specified regions.
|
||||
"""
|
||||
return availability_zone.describe_regions(context,
|
||||
region_name,
|
||||
filter)
|
||||
|
||||
@module_and_param_types(instance, 'i_id')
|
||||
def get_password_data(self, context, instance_id):
|
||||
"""Retrieves the encrypted administrator password for Windows instance.
|
||||
|
||||
@@ -694,8 +690,8 @@ class CloudController(object):
|
||||
The password is encrypted using the key pair that you specified when
|
||||
you launched the instance.
|
||||
"""
|
||||
return instance.get_password_data(context, instance_id)
|
||||
|
||||
@module_and_param_types(instance, 'i_id')
|
||||
def get_console_output(self, context, instance_id):
|
||||
"""Gets the console output for the specified instance.
|
||||
|
||||
@@ -706,8 +702,10 @@ class CloudController(object):
|
||||
Returns:
|
||||
The console output of the instance, timestamp and instance id.
|
||||
"""
|
||||
return instance.get_console_output(context, instance_id)
|
||||
|
||||
@module_and_param_types(volume, 'str', 'int',
|
||||
'snap_id', 'str', 'int',
|
||||
'bool', 'str')
|
||||
def create_volume(self, context, availability_zone=None, size=None,
|
||||
snapshot_id=None, volume_type=None, iops=None,
|
||||
encrypted=None, kms_key_id=None):
|
||||
@@ -741,10 +739,8 @@ class CloudController(object):
|
||||
You can create a new empty volume or restore a volume from an EBS
|
||||
snapshot.
|
||||
"""
|
||||
return volume.create_volume(context, availability_zone, size,
|
||||
snapshot_id, volume_type, iops,
|
||||
encrypted, kms_key_id)
|
||||
|
||||
@module_and_param_types(volume, 'vol_id', 'i_id', 'str')
|
||||
def attach_volume(self, context, volume_id, instance_id, device):
|
||||
"""Attaches an EBS volume to a running or stopped instance.
|
||||
|
||||
@@ -759,8 +755,8 @@ class CloudController(object):
|
||||
|
||||
The instance and volume must be in the same Availability Zone.
|
||||
"""
|
||||
return volume.attach_volume(context, volume_id, instance_id, device)
|
||||
|
||||
@module_and_param_types(volume, 'vol_id', 'i_id', 'str')
|
||||
def detach_volume(self, context, volume_id, instance_id=None, device=None,
|
||||
force=None):
|
||||
"""Detaches an EBS volume from an instance.
|
||||
@@ -778,9 +774,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
Information about the detachment.
|
||||
"""
|
||||
return volume.detach_volume(context, volume_id, instance_id, device,
|
||||
force)
|
||||
|
||||
@module_and_param_types(volume, 'vol_id')
|
||||
def delete_volume(self, context, volume_id):
|
||||
"""Deletes the specified EBS volume.
|
||||
|
||||
@@ -793,8 +788,9 @@ class CloudController(object):
|
||||
|
||||
The volume must be in the available state.
|
||||
"""
|
||||
return volume.delete_volume(context, volume_id)
|
||||
|
||||
@module_and_param_types(volume, 'vol_ids', 'filter',
|
||||
'int', 'str')
|
||||
def describe_volumes(self, context, volume_id=None, filter=None,
|
||||
max_results=None, next_token=None):
|
||||
"""Describes the specified EBS volumes.
|
||||
@@ -812,9 +808,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
A list of volumes.
|
||||
"""
|
||||
return volume.describe_volumes(context, volume_id, filter,
|
||||
max_results, next_token)
|
||||
|
||||
@module_and_param_types(snapshot, 'vol_id', 'str')
|
||||
def create_snapshot(self, context, volume_id, description=None):
|
||||
"""Creates a snapshot of an EBS volume.
|
||||
|
||||
@@ -826,8 +821,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
Information about the snapshot.
|
||||
"""
|
||||
return snapshot.create_snapshot(context, volume_id, description)
|
||||
|
||||
@module_and_param_types(snapshot, 'snap_id')
|
||||
def delete_snapshot(self, context, snapshot_id):
|
||||
"""Deletes the specified snapshot.
|
||||
|
||||
@@ -838,8 +833,9 @@ class CloudController(object):
|
||||
Returns:
|
||||
Returns true if the request succeeds.
|
||||
"""
|
||||
return snapshot.delete_snapshot(context, snapshot_id)
|
||||
|
||||
@module_and_param_types(snapshot, 'snap_ids', 'strs',
|
||||
'strs', 'filter')
|
||||
def describe_snapshots(self, context, snapshot_id=None, owner=None,
|
||||
restorable_by=None, filter=None):
|
||||
"""Describes one or more of the snapshots available to you.
|
||||
@@ -859,9 +855,9 @@ class CloudController(object):
|
||||
Returns:
|
||||
A list of snapshots.
|
||||
"""
|
||||
return snapshot.describe_snapshots(context, snapshot_id, owner,
|
||||
restorable_by, filter)
|
||||
|
||||
@module_and_param_types(image, 'i_id', 'str', 'str',
|
||||
'bool', 'dummy')
|
||||
def create_image(self, context, instance_id, name=None, description=None,
|
||||
no_reboot=False, block_device_mapping=None):
|
||||
"""Creates an EBS-backed AMI from an EBS-backed instance.
|
||||
@@ -900,6 +896,11 @@ class CloudController(object):
|
||||
return image.create_image(context, instance_id, name, description,
|
||||
no_reboot, block_device_mapping)
|
||||
|
||||
@module_and_param_types(image, 'str', 'str',
|
||||
'str', 'str',
|
||||
'str', 'dummy',
|
||||
'str', 'ami_id',
|
||||
'ami_id', 'str')
|
||||
def register_image(self, context, name=None, image_location=None,
|
||||
description=None, architecture=None,
|
||||
root_device_name=None, block_device_mapping=None,
|
||||
@@ -946,12 +947,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
The ID of the new AMI.
|
||||
"""
|
||||
return image.register_image(context, name, image_location,
|
||||
description, architecture,
|
||||
root_device_name, block_device_mapping,
|
||||
virtualization_type, kernel_id,
|
||||
ramdisk_id, sriov_net_support)
|
||||
|
||||
@module_and_param_types(image, 'ami_id')
|
||||
def deregister_image(self, context, image_id):
|
||||
"""Deregisters the specified AMI.
|
||||
|
||||
@@ -962,8 +959,9 @@ class CloudController(object):
|
||||
Returns:
|
||||
true if the request succeeds.
|
||||
"""
|
||||
return image.deregister_image(context, image_id)
|
||||
|
||||
@module_and_param_types(image, 'strs', 'ami_ids',
|
||||
'strs', 'filter')
|
||||
def describe_images(self, context, executable_by=None, image_id=None,
|
||||
owner=None, filter=None):
|
||||
"""Describes one or more of the images available to you.
|
||||
@@ -982,9 +980,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
A list of images.
|
||||
"""
|
||||
return image.describe_images(context, executable_by, image_id,
|
||||
owner, filter)
|
||||
|
||||
@module_and_param_types(image, 'ami_id', 'str')
|
||||
def describe_image_attribute(self, context, image_id, attribute):
|
||||
"""Describes the specified attribute of the specified AMI.
|
||||
|
||||
@@ -1001,6 +998,10 @@ class CloudController(object):
|
||||
"""
|
||||
return image.describe_image_attribute(context, image_id, attribute)
|
||||
|
||||
@module_and_param_types(image, 'ami_id', 'str',
|
||||
'strs', 'str',
|
||||
'dummy', 'dummy',
|
||||
'dummy', 'dummy', 'dummy')
|
||||
def modify_image_attribute(self, context, image_id, attribute,
|
||||
user_group, operation_type,
|
||||
description=None, launch_permission=None,
|
||||
@@ -1027,11 +1028,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
true if the request succeeds.
|
||||
"""
|
||||
return image.modify_image_attribute(context, image_id, attribute,
|
||||
user_group, operation_type,
|
||||
description, launch_permission,
|
||||
product_code, user_id, value)
|
||||
|
||||
@module_and_param_types(tag, 'ec2_ids', 'dummy')
|
||||
def create_tags(self, context, resource_id, tag):
|
||||
"""Adds or overwrites one or more tags for the specified resources.
|
||||
|
||||
@@ -1045,8 +1043,8 @@ class CloudController(object):
|
||||
Returns:
|
||||
true if the request succeeds.
|
||||
"""
|
||||
return tag_api.create_tags(context, resource_id, tag)
|
||||
|
||||
@module_and_param_types(tag, 'ec2_ids', 'dummy')
|
||||
def delete_tags(self, context, resource_id, tag=None):
|
||||
"""Deletes the specified tags from the specified resources.
|
||||
|
||||
@@ -1065,8 +1063,9 @@ class CloudController(object):
|
||||
its value. If you specify this parameter with an empty string as the
|
||||
value, we delete the key only if its value is an empty string.
|
||||
"""
|
||||
return tag_api.delete_tags(context, resource_id, tag)
|
||||
|
||||
@module_and_param_types(tag, 'filter', 'int',
|
||||
'str')
|
||||
def describe_tags(self, context, filter=None, max_results=None,
|
||||
next_token=None):
|
||||
"""Describes one or more of the tags for your EC2 resources.
|
||||
@@ -1083,7 +1082,6 @@ class CloudController(object):
|
||||
Returns:
|
||||
A list of tags.
|
||||
"""
|
||||
return tag_api.describe_tags(context, filter, max_results, next_token)
|
||||
|
||||
|
||||
class VpcCloudController(CloudController):
|
||||
|
@@ -40,20 +40,32 @@ class Validator(object):
|
||||
self.action = action
|
||||
self.params = params
|
||||
|
||||
def multi(self, items, validation_func):
|
||||
validator.validate_list(items, self.param_name)
|
||||
for item in items:
|
||||
validation_func(item)
|
||||
|
||||
def dummy(self, value):
|
||||
pass
|
||||
|
||||
def bool(self, value):
|
||||
validator.validate_bool(value, self.param_name)
|
||||
|
||||
def int(self, value):
|
||||
validator.validate_int(value, self.param_name)
|
||||
|
||||
def str(self, value):
|
||||
validator.validate_str(value, self.param_name)
|
||||
|
||||
def strs(self, values):
|
||||
self.multi(values, self.str)
|
||||
|
||||
def str64(self, value):
|
||||
validator.validate_str(value, self.param_name, 64)
|
||||
|
||||
def str255(self, value):
|
||||
validator.validate_str(value, self.param_name, 255)
|
||||
|
||||
def multi(self, items, validation_func):
|
||||
validator.validate_list(items, self.param_name)
|
||||
for item in items:
|
||||
validation_func(item)
|
||||
|
||||
def str255s(self, values):
|
||||
self.multi(values, self.str255)
|
||||
|
||||
@@ -75,9 +87,12 @@ class Validator(object):
|
||||
def filter(self, filter):
|
||||
validator.validate_filter(filter)
|
||||
|
||||
def ec2_id(self, id, prefices):
|
||||
def ec2_id(self, id, prefices=[]):
|
||||
validator.validate_ec2_id(id, self.param_name, prefices)
|
||||
|
||||
def ec2_ids(self, ids):
|
||||
self.multi(ids, self.ec2_id)
|
||||
|
||||
def i_id(self, id):
|
||||
self.ec2_id(id, ['i'])
|
||||
|
||||
@@ -88,7 +103,7 @@ class Validator(object):
|
||||
self.ec2_id(id, ['ami', 'ari', 'aki'])
|
||||
|
||||
def ami_ids(self, ids):
|
||||
self.multi(ids, self.aki_id)
|
||||
self.multi(ids, self.ami_id)
|
||||
|
||||
def sg_id(self, id):
|
||||
self.ec2_id(id, ['sg'])
|
||||
@@ -141,6 +156,18 @@ class Validator(object):
|
||||
def sg_ids(self, ids):
|
||||
self.multi(ids, self.sg_id)
|
||||
|
||||
def snap_id(self, id):
|
||||
self.ec2_id(id, ['snap'])
|
||||
|
||||
def snap_ids(self, ids):
|
||||
self.multi(ids, self.snap_id)
|
||||
|
||||
def vol_id(self, id):
|
||||
self.ec2_id(id, ['vol'])
|
||||
|
||||
def vol_ids(self, ids):
|
||||
self.multi(ids, self.vol_id)
|
||||
|
||||
def security_group_str(self, value):
|
||||
validator.validate_security_group_str(value, self.param_name,
|
||||
self.params.get('vpc_id'))
|
||||
|
@@ -74,6 +74,13 @@ rpcapi_opts = [
|
||||
CONF.register_opts(rpcapi_opts)
|
||||
|
||||
|
||||
"""Volume related API implementation
|
||||
"""
|
||||
|
||||
|
||||
Validator = common.Validator
|
||||
|
||||
|
||||
CONTAINER_TO_KIND = {'aki': 'aki',
|
||||
'ari': 'ari',
|
||||
'ami': 'ami',
|
||||
|
@@ -31,6 +31,9 @@ LOG = logging.getLogger(__name__)
|
||||
"""
|
||||
|
||||
|
||||
Validator = common.Validator
|
||||
|
||||
|
||||
class KeyPairDescriber(common.UniversalDescriber):
|
||||
|
||||
KIND = 'kp'
|
||||
|
@@ -23,6 +23,13 @@ from ec2api import exception
|
||||
from ec2api.openstack.common.gettextutils import _
|
||||
|
||||
|
||||
"""Snapshot related API implementation
|
||||
"""
|
||||
|
||||
|
||||
Validator = common.Validator
|
||||
|
||||
|
||||
def create_snapshot(context, volume_id, description=None):
|
||||
volume = ec2utils.get_db_item(context, 'vol', volume_id)
|
||||
cinder = clients.cinder(context)
|
||||
|
@@ -19,6 +19,13 @@ from ec2api import exception
|
||||
from ec2api.openstack.common.gettextutils import _
|
||||
|
||||
|
||||
"""Tag related API implementation
|
||||
"""
|
||||
|
||||
|
||||
Validator = common.Validator
|
||||
|
||||
|
||||
RESOURCE_TYPES = {
|
||||
'dopt': 'dhcp-options',
|
||||
'ami': 'image',
|
||||
|
@@ -40,6 +40,14 @@ def validate_bool(val, parameter_name):
|
||||
reason=_("Expected a boolean value for parameter %s") % parameter_name)
|
||||
|
||||
|
||||
def validate_int(val, parameter_name):
|
||||
if isinstance(val, int):
|
||||
return True
|
||||
raise exception.ValidationError(
|
||||
reason=(_("Expected an integer value for parameter %s") %
|
||||
parameter_name))
|
||||
|
||||
|
||||
def validate_list(items, parameter_name):
|
||||
if not isinstance(items, list):
|
||||
raise exception.InvalidParameterValue(
|
||||
@@ -129,7 +137,7 @@ def validate_ec2_id(val, parameter_name, prefices):
|
||||
try:
|
||||
prefix, value = val.rsplit('-', 1)
|
||||
int(value, 16)
|
||||
if prefix in prefices:
|
||||
if not prefices or prefix in prefices:
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
|
@@ -23,6 +23,13 @@ from ec2api import exception
|
||||
from ec2api.openstack.common.gettextutils import _
|
||||
|
||||
|
||||
"""Volume related API implementation
|
||||
"""
|
||||
|
||||
|
||||
Validator = common.Validator
|
||||
|
||||
|
||||
def create_volume(context, availability_zone=None, size=None,
|
||||
snapshot_id=None, volume_type=None, iops=None,
|
||||
encrypted=None, kms_key_id=None):
|
||||
|
@@ -34,7 +34,7 @@ class AvailabilityZoneCase(base.ApiTestCase):
|
||||
fakes.NovaAvailabilityZone(fakes.OS_AVAILABILITY_ZONE),
|
||||
fakes.NovaAvailabilityZone(fakes.OS_AVAILABILITY_ZONE_INTERNAL)]
|
||||
resp = self.execute('DescribeAvailabilityZones',
|
||||
{'zoneName': 'verbose'})
|
||||
{'zoneName.1': 'verbose'})
|
||||
self.assertEqual(200, resp['http_status_code'])
|
||||
self.assertEqual(len(resp['availabilityZoneInfo']), 7)
|
||||
self.nova_availability_zones.list.assert_called_once()
|
||||
|
@@ -176,11 +176,9 @@ class InstanceTestCase(base.ApiTestCase):
|
||||
'security_group_id': [fakes.ID_EC2_SECURITY_GROUP_1,
|
||||
fakes.ID_EC2_SECURITY_GROUP_2]})
|
||||
do_check({'SubnetId': fakes.ID_EC2_SUBNET_1,
|
||||
'PrivateIpAddress.1': fakes.IP_FIRST_SUBNET_1,
|
||||
'PrivateIpAddress.2': fakes.IP_LAST_SUBNET_1},
|
||||
'PrivateIpAddress': fakes.IP_FIRST_SUBNET_1},
|
||||
create_network_interface_kwargs={
|
||||
'private_ip_address': [fakes.IP_FIRST_SUBNET_1,
|
||||
fakes.IP_LAST_SUBNET_1]})
|
||||
'private_ip_address': fakes.IP_FIRST_SUBNET_1})
|
||||
|
||||
do_check({'NetworkInterface.1.SubnetId': fakes.ID_EC2_SUBNET_1,
|
||||
'NetworkInterface.1.SecurityGroupId.1':
|
||||
|
@@ -41,7 +41,7 @@ class KeyPairCase(base.ApiTestCase):
|
||||
self.assertEqual('InvalidKeyPair.Duplicate', resp['Error']['Code'])
|
||||
resp = self.execute('CreateKeyPair', {'KeyName': 'k' * 256})
|
||||
self.assertEqual(400, resp['http_status_code'])
|
||||
self.assertEqual('InvalidParameterValue', resp['Error']['Code'])
|
||||
self.assertEqual('ValidationError', resp['Error']['Code'])
|
||||
self.nova_key_pairs.create.side_effect = (
|
||||
nova_exception.OverLimit(413))
|
||||
resp = self.execute('CreateKeyPair', {'KeyName': fakes.NAME_KEY_PAIR})
|
||||
@@ -95,7 +95,7 @@ class KeyPairCase(base.ApiTestCase):
|
||||
def test_describe_key_pairs_invalid(self):
|
||||
self.nova_key_pairs.list.return_value = [fakes.NovaKeyPair(
|
||||
fakes.OS_KEY_PAIR)]
|
||||
resp = self.execute('DescribeKeyPairs', {'KeyName': 'badname'})
|
||||
resp = self.execute('DescribeKeyPairs', {'KeyName.1': 'badname'})
|
||||
self.assertEqual(404, resp['http_status_code'])
|
||||
self.assertEqual('InvalidKeyPair.NotFound', resp['Error']['Code'])
|
||||
self.nova_key_pairs.list.assert_called_once()
|
||||
|
@@ -189,7 +189,7 @@ class TagTestCase(base.ApiTestCase):
|
||||
filter_fields = ['resource-type', 'resource-id', 'key', 'value']
|
||||
filter_param = dict(('Filter.%s.Name' % num, field)
|
||||
for num, field in enumerate(filter_fields))
|
||||
filter_param.update(dict(('Filter.%s.Value' % num, 'fake')
|
||||
filter_param.update(dict(('Filter.%s.Value.1' % num, 'fake')
|
||||
for num, field in enumerate(filter_fields)))
|
||||
resp = self.execute('DescribeTags', filter_param)
|
||||
self.assertEqual({'http_status_code': 200,
|
||||
|
Reference in New Issue
Block a user