Adding ability to scale for Redis Cache, adding tests (#2821)

* adding ability to scale for redis cache

* adding tests for redis cache, adding change in history.rst

* fixing test failures

* fixing build errors

* removing sku-capacity and sku-family and adding vm-size as variable. Adding 'getting deprecated' message for update-settings command

* fixing build

* incorporating CR comments
This commit is contained in:
Alfan T P 2017-04-17 11:08:19 -07:00 коммит произвёл Travis Prescott
Родитель bed55b19f9
Коммит 3f4409b8f3
9 изменённых файлов: 267 добавлений и 21 удалений

Просмотреть файл

@ -433,6 +433,7 @@
</Compile>
<Compile Include="command_modules\azure-cli-redis\azure\cli\command_modules\redis\custom.py" />
<Compile Include="command_modules\azure-cli-redis\azure\cli\command_modules\redis\commands.py" />
<Compile Include="command_modules\azure-cli-redis\tests\test_redis_scenario.py" />
<Compile Include="command_modules\azure-cli-redis\azure\cli\command_modules\redis\_client_factory.py" />
<Compile Include="command_modules\azure-cli-redis\azure\cli\command_modules\redis\_help.py">
<SubType>Code</SubType>

Просмотреть файл

@ -3,6 +3,9 @@
Release History
===============
* Adding update command which also adds the ability to scale for redis cache
* Deprecates the 'update-settings' command.
0.1.1b3 (2017-02-22)
++++++++++++++++++++

Просмотреть файл

@ -25,7 +25,14 @@ helps['redis import-method'] = """
helps['redis update-settings'] = """
type: command
short-summary: Update the settings of a redis cache.
short-summary: (DEPRECATED) Update the settings of a redis cache.
long-summary: |
WARNING: This command is being deprecated. Please use 'update' command
"""
helps['redis update'] = """
type: command
short-summary: Scale or update settings of a redis cache
"""
helps['redis patch-schedule'] = """

Просмотреть файл

@ -14,7 +14,6 @@ import azure.cli.core.commands.arm # pylint: disable=unused-import
from azure.mgmt.redis.models.redis_management_client_enums import (
RebootType,
RedisKeyType,
SkuFamily,
SkuName)
from azure.mgmt.redis.models import (
@ -51,15 +50,15 @@ register_cli_argument('redis', 'redis_configuration', type=JsonString)
register_cli_argument('redis', 'reboot_type', **enum_choice_list(RebootType))
register_cli_argument('redis', 'key_type', **enum_choice_list(RedisKeyType))
register_cli_argument('redis', 'shard_id', type=int)
register_cli_argument('redis', 'sku', **enum_choice_list(SkuName))
register_cli_argument('redis', 'vm_size', help='Size of redis cache to deploy. Example : values for C family (C0, C1, C2, C3, C4, C5, C6). For P family (P1, P2, P3, P4)')
register_cli_argument('redis', 'enable_non_ssl_port', action='store_true')
register_cli_argument('redis', 'shard_count', type=int)
register_cli_argument('redis', 'subnet_id')
register_cli_argument('redis import-method', 'files', nargs='+')
register_cli_argument('redis patch-schedule set', 'schedule_entries', type=ScheduleEntryList)
register_cli_argument('redis create', 'name', arg_type=name_type, completer=None)
register_cli_argument('redis create', 'sku_name', **enum_choice_list(SkuName))
register_cli_argument('redis create', 'sku_family', **enum_choice_list(SkuFamily))
register_cli_argument('redis create', 'sku_capacity', choices=[str(n) for n in range(0, 7)])
register_cli_argument('redis create', 'enable_non_ssl_port', action='store_true')
register_cli_argument('redis create', 'tenant_settings', type=JsonString)
register_cli_argument('redis create', 'shard_count', type=int)
register_cli_argument('redis create', 'subnet_id') # TODO: Create generic id completer similar to name

Просмотреть файл

@ -6,6 +6,7 @@
#pylint: disable=line-too-long
from azure.cli.core.commands import cli_command
from azure.cli.core.commands.arm import cli_generic_update_command
from azure.cli.command_modules.redis._client_factory import (cf_redis, cf_patch_schedules)
cli_command(__name__, 'redis create', 'azure.cli.command_modules.redis.custom#cli_redis_create', cf_redis)
@ -20,6 +21,10 @@ cli_command(__name__, 'redis regenerate-keys', 'azure.mgmt.redis.operations.redi
cli_command(__name__, 'redis show', 'azure.mgmt.redis.operations.redis_operations#RedisOperations.get', cf_redis)
cli_command(__name__, 'redis update-settings', 'azure.cli.command_modules.redis.custom#cli_redis_update_settings', cf_redis)
cli_generic_update_command(__name__, 'redis update', 'azure.mgmt.redis.operations.redis_operations#RedisOperations.get',
'azure.mgmt.redis.operations.redis_operations#RedisOperations.create_or_update',
cf_redis, custom_function_op='azure.cli.command_modules.redis.custom#cli_redis_update')
cli_command(__name__, 'redis patch-schedule set', 'azure.mgmt.redis.operations.patch_schedules_operations#PatchSchedulesOperations.create_or_update', cf_patch_schedules)
cli_command(__name__, 'redis patch-schedule delete', 'azure.mgmt.redis.operations.patch_schedules_operations#PatchSchedulesOperations.delete', cf_patch_schedules)
cli_command(__name__, 'redis patch-schedule show', 'azure.mgmt.redis.operations.patch_schedules_operations#PatchSchedulesOperations.get', cf_patch_schedules)

Просмотреть файл

@ -3,6 +3,9 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
from msrest.exceptions import ClientException
from azure.cli.core.util import CLIError
from azure.mgmt.redis.models import (
ImportRDBParameters,
ExportRDBParameters,
@ -10,6 +13,9 @@ from azure.mgmt.redis.models import (
Sku,
)
import azure.cli.core.azlogging as azlogging
logger = azlogging.get_az_logger(__name__)
def cli_redis_export(client, resource_group_name, name, prefix, container, file_format=None):
# pylint:disable=too-many-arguments
parameters = ExportRDBParameters(prefix, container, file_format)
@ -20,6 +26,8 @@ def cli_redis_import_method(client, resource_group_name, name, file_format, file
return client.import_method(resource_group_name, name, files, parameters)
def cli_redis_update_settings(client, resource_group_name, name, redis_configuration):
logger.warning('This command is getting deprecated. Please use "redis update" command')
existing = client.get(resource_group_name, name)
existing.redis_configuration.update(redis_configuration)
@ -39,8 +47,37 @@ def cli_redis_update_settings(client, resource_group_name, name, redis_configura
)
return client.create_or_update(resource_group_name, name, parameters=update_params)
def cli_redis_create(client, resource_group_name, name, location, sku_name, # pylint:disable=too-many-arguments
sku_family, sku_capacity, tags=None, redis_configuration=None,
def cli_redis_update(instance, sku=None, vm_size=None):
if sku != None:
instance.sku.name = sku
if vm_size != None:
instance.sku.family = vm_size[0]
instance.sku.capacity = vm_size[1:]
update_params = RedisCreateOrUpdateParameters(
instance.location,
instance.sku,
instance.tags,
instance.redis_version,
instance.redis_configuration,
instance.enable_non_ssl_port,
instance.tenant_settings,
instance.shard_count,
instance.subnet_id,
instance.static_ip,
)
return update_params
def wrong_vmsize_argument_exception_handler(ex):
# pylint:disable=line-too-long
if ("The value of the parameter 'properties.sku.family/properties.sku.capacity' is invalid" in format(ex)) or ("The value of the parameter 'properties.sku.family' is invalid" in format(ex)):
raise CLIError('Invalid VM size. Example for Valid values: For C family (C0, C1, C2, C3, C4, C5, C6), for P family (P1, P2, P3, P4)')
raise ex
def cli_redis_create(client, resource_group_name, name, location, sku, # pylint:disable=too-many-arguments
vm_size, tags=None, redis_configuration=None,
enable_non_ssl_port=None, tenant_settings=None, shard_count=None,
subnet_id=None, static_ip=None):
# pylint:disable=line-too-long
@ -48,9 +85,8 @@ def cli_redis_create(client, resource_group_name, name, location, sku_name, # py
:param resource_group_name: Name of resource group
:param name: Name of redis cache
:param location: Location
:param sku_name: What type of redis cache to deploy. Valid values: (Basic, Standard, Premium).
:param sku_family: Which family to use. Valid values: (C, P).
:param sku_capacity: What size of redis cache to deploy. Valid values for C family (0, 1, 2, 3, 4, 5, 6), for P family (1, 2, 3, 4)
:param sku: What type of redis cache to deploy. Valid values: (Basic, Standard, Premium).
:param vm_size: What size of redis cache to deploy. Valid values for C family (C0, C1, C2, C3, C4, C5, C6), for P family (P1, P2, P3, P4)
:param redis_configuration: All Redis Settings. Few possible keys rdb-backup-enabled, rdb-storage-connection-string, rdb-backup-frequency, maxmemory-delta, maxmemory-policy, notify-keyspace-events, maxmemory-samples, slowlog-log-slower-than, slowlog-max-len, list-max-ziplist-entries, list-max-ziplist-value, hash-max-ziplist-entries, hash-max-ziplist-value, set-max-intset-entries, zset-max-ziplist-entries, zset-max-ziplist-value etc.
:param enable_non_ssl_port: If the value is true, then the non-ssl redis server port (6379) will be enabled.
:param tenant_settings: Json dictionary with tenant settings
@ -60,7 +96,7 @@ def cli_redis_create(client, resource_group_name, name, location, sku_name, # py
"""
params = RedisCreateOrUpdateParameters(
location,
Sku(sku_name, sku_family, sku_capacity),
Sku(sku, vm_size[0], vm_size[1:]),
tags,
None, # Version is deprecated and ignored
redis_configuration,
@ -70,5 +106,7 @@ def cli_redis_create(client, resource_group_name, name, location, sku_name, # py
subnet_id,
static_ip)
return client.create_or_update(resource_group_name, name, params)
try:
return client.create_or_update(resource_group_name, name, params)
except ClientException as err:
wrong_vmsize_argument_exception_handler(err)

Просмотреть файл

@ -0,0 +1,176 @@
interactions:
- request:
body: '{"location": "westus", "tags": {"use": "az-test"}}'
headers:
Accept: [application/json]
Accept-Encoding: ['gzip, deflate']
CommandName: [group create]
Connection: [keep-alive]
Content-Length: ['50']
Content-Type: [application/json; charset=utf-8]
User-Agent: [python/3.6.1 (Windows-10-10.0.14393-SP0) requests/2.9.1 msrest/0.4.7
msrest_azure/0.4.7 resourcemanagementclient/0.30.2 Azure-SDK-For-Python
AZURECLI/2.0.2+dev]
accept-language: [en-US]
method: PUT
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001?api-version=2016-09-01
response:
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001","name":"clitest.rg000001","location":"westus","tags":{"use":"az-test"},"properties":{"provisioningState":"Succeeded"}}'}
headers:
cache-control: [no-cache]
content-length: ['326']
content-type: [application/json; charset=utf-8]
date: ['Thu, 13 Apr 2017 17:18:10 GMT']
expires: ['-1']
pragma: [no-cache]
strict-transport-security: [max-age=31536000; includeSubDomains]
x-ms-ratelimit-remaining-subscription-writes: ['1199']
status: {code: 201, message: Created}
- request:
body: '{"location": "WestUS", "properties": {"sku": {"name": "Basic", "family":
"C", "capacity": 0}}}'
headers:
Accept: [application/json]
Accept-Encoding: ['gzip, deflate']
CommandName: [redis create]
Connection: [keep-alive]
Content-Length: ['94']
Content-Type: [application/json; charset=utf-8]
User-Agent: [python/3.6.1 (Windows-10-10.0.14393-SP0) requests/2.9.1 msrest/0.4.7
msrest_azure/0.4.7 redismanagementclient/1.0.0 Azure-SDK-For-Python AZURECLI/2.0.2+dev]
accept-language: [en-US]
method: PUT
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Cache/Redis/cli000002?api-version=2016-04-01
response:
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Cache/Redis/cli000002","location":"West
US","name":"cli000002","type":"Microsoft.Cache/Redis","tags":{},"properties":{"provisioningState":"Creating","redisVersion":"3.2","sku":{"name":"Basic","family":"C","capacity":0},"enableNonSslPort":false,"redisConfiguration":{"maxclients":"256","maxmemory-reserved":"2","maxfragmentationmemory-reserved":"12","maxmemory-delta":"2"},"accessKeys":{"primaryKey":"lr7S+XpwKd7wmVgX60N9Ajz6RNPTf+0VlsPNaWXKUYY=","secondaryKey":"lakNGov3L8Ki919D/yxR1ATPCEl6TlQON5iaeqO4Eaw="},"hostName":"cli000002.redis.cache.windows.net","port":6379,"sslPort":6380}}'}
headers:
cache-control: [no-cache]
content-length: ['798']
content-type: [application/json; charset=utf-8]
date: ['Thu, 13 Apr 2017 17:18:13 GMT']
expires: ['-1']
location: ['https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Cache/redis/cli000002?api-version=2016-04-01']
pragma: [no-cache]
server: [Microsoft-HTTPAPI/2.0]
strict-transport-security: [max-age=31536000; includeSubDomains]
x-ms-ratelimit-remaining-subscription-writes: ['1199']
x-rp-server-mvid: [5a0a88c0-0183-48c7-85e3-df64396b7fab]
status: {code: 201, message: Created}
- request:
body: null
headers:
Accept: [application/json]
Accept-Encoding: ['gzip, deflate']
CommandName: [redis show]
Connection: [keep-alive]
Content-Type: [application/json; charset=utf-8]
User-Agent: [python/3.6.1 (Windows-10-10.0.14393-SP0) requests/2.9.1 msrest/0.4.7
msrest_azure/0.4.7 redismanagementclient/1.0.0 Azure-SDK-For-Python AZURECLI/2.0.2+dev]
accept-language: [en-US]
method: GET
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Cache/Redis/cli000002?api-version=2016-04-01
response:
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Cache/Redis/cli000002","location":"West
US","name":"cli000002","type":"Microsoft.Cache/Redis","tags":{},"properties":{"provisioningState":"Creating","redisVersion":"3.2","sku":{"name":"Basic","family":"C","capacity":0},"enableNonSslPort":false,"redisConfiguration":{"maxclients":"256","maxmemory-reserved":"2","maxfragmentationmemory-reserved":"12","maxmemory-delta":"2"},"accessKeys":null,"hostName":"cli000002.redis.cache.windows.net","port":6379,"sslPort":6380}}'}
headers:
cache-control: [no-cache]
content-length: ['679']
content-type: [application/json; charset=utf-8]
date: ['Thu, 13 Apr 2017 17:18:14 GMT']
expires: ['-1']
pragma: [no-cache]
server: [Microsoft-HTTPAPI/2.0]
strict-transport-security: [max-age=31536000; includeSubDomains]
transfer-encoding: [chunked]
vary: [Accept-Encoding]
x-rp-server-mvid: [5a0a88c0-0183-48c7-85e3-df64396b7fab]
status: {code: 200, message: OK}
- request:
body: null
headers:
Accept: [application/json]
Accept-Encoding: ['gzip, deflate']
CommandName: [redis list]
Connection: [keep-alive]
Content-Type: [application/json; charset=utf-8]
User-Agent: [python/3.6.1 (Windows-10-10.0.14393-SP0) requests/2.9.1 msrest/0.4.7
msrest_azure/0.4.7 redismanagementclient/1.0.0 Azure-SDK-For-Python AZURECLI/2.0.2+dev]
accept-language: [en-US]
method: GET
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Cache/Redis/?api-version=2016-04-01
response:
body: {string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Cache/Redis/cli000002","location":"West
US","name":"cli000002","type":"Microsoft.Cache/Redis","tags":{},"properties":{"provisioningState":"Creating","redisVersion":"3.2","sku":{"name":"Basic","family":"C","capacity":0},"enableNonSslPort":false,"redisConfiguration":{"maxclients":"256","maxmemory-reserved":"2","maxfragmentationmemory-reserved":"12","maxmemory-delta":"2"},"accessKeys":null,"hostName":"cli000002.redis.cache.windows.net","port":6379,"sslPort":6380}}]}'}
headers:
cache-control: [no-cache]
content-length: ['691']
content-type: [application/json; charset=utf-8]
date: ['Thu, 13 Apr 2017 17:18:15 GMT']
expires: ['-1']
pragma: [no-cache]
server: [Microsoft-HTTPAPI/2.0]
strict-transport-security: [max-age=31536000; includeSubDomains]
transfer-encoding: [chunked]
vary: [Accept-Encoding]
x-rp-server-mvid: [5a0a88c0-0183-48c7-85e3-df64396b7fab]
status: {code: 200, message: OK}
- request:
body: null
headers:
Accept: [application/json]
Accept-Encoding: ['gzip, deflate']
CommandName: [redis list-keys]
Connection: [keep-alive]
Content-Length: ['0']
Content-Type: [application/json; charset=utf-8]
User-Agent: [python/3.6.1 (Windows-10-10.0.14393-SP0) requests/2.9.1 msrest/0.4.7
msrest_azure/0.4.7 redismanagementclient/1.0.0 Azure-SDK-For-Python AZURECLI/2.0.2+dev]
accept-language: [en-US]
method: POST
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Cache/Redis/cli000002/listKeys?api-version=2016-04-01
response:
body: {string: '{"primaryKey":"lr7S+XpwKd7wmVgX60N9Ajz6RNPTf+0VlsPNaWXKUYY=","secondaryKey":"lakNGov3L8Ki919D/yxR1ATPCEl6TlQON5iaeqO4Eaw="}'}
headers:
cache-control: [no-cache]
content-length: ['123']
content-type: [application/json; charset=utf-8]
date: ['Thu, 13 Apr 2017 17:18:17 GMT']
expires: ['-1']
pragma: [no-cache]
server: [Microsoft-HTTPAPI/2.0]
strict-transport-security: [max-age=31536000; includeSubDomains]
transfer-encoding: [chunked]
vary: [Accept-Encoding]
x-ms-ratelimit-remaining-subscription-writes: ['1199']
x-rp-server-mvid: [5a0a88c0-0183-48c7-85e3-df64396b7fab]
status: {code: 200, message: OK}
- request:
body: null
headers:
Accept: [application/json]
Accept-Encoding: ['gzip, deflate']
CommandName: [group delete]
Connection: [keep-alive]
Content-Length: ['0']
Content-Type: [application/json; charset=utf-8]
User-Agent: [python/3.6.1 (Windows-10-10.0.14393-SP0) requests/2.9.1 msrest/0.4.7
msrest_azure/0.4.7 resourcemanagementclient/0.30.2 Azure-SDK-For-Python
AZURECLI/2.0.2+dev]
accept-language: [en-US]
method: DELETE
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001?api-version=2016-09-01
response:
body: {string: ''}
headers:
cache-control: [no-cache]
content-length: ['0']
date: ['Thu, 13 Apr 2017 17:18:18 GMT']
expires: ['-1']
location: ['https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/operationresults/eyJqb2JJZCI6IlJFU09VUkNFR1JPVVBERUxFVElPTkpPQi1DTElURVNUOjJFUkc0NjQ5Qzc5M0FDODdGQzFGNkJENEQzRjRCNEQ4RENGODBEQ3w1Njg3QUMzOEYxM0I3RjBDLVdFU1RVUyIsImpvYkxvY2F0aW9uIjoid2VzdHVzIn0?api-version=2016-09-01']
pragma: [no-cache]
retry-after: ['15']
strict-transport-security: [max-age=31536000; includeSubDomains]
x-ms-ratelimit-remaining-subscription-writes: ['1199']
status: {code: 202, message: Accepted}
version: 1

Просмотреть файл

@ -27,12 +27,10 @@ class Test_RedisCache(unittest.TestCase):
def test_parse_redis_create(self):
args = mock_echo_args('redis create',
'--tenant-settings {\"hello\":1} -g wombat -n asldkj --sku-family c -l westus --sku-capacity 1 --sku-name basic') # pylint: disable=line-too-long
args = mock_echo_args('redis create', '--tenant-settings {\"hello\":1} -g wombat -n asldkj -l westus --sku basic --vm-size C1 ') # pylint: disable=line-too-long
subset = set(dict(
sku_family='C',
sku_capacity='1',
sku_name='Basic',
vm_size='C1',
sku='Basic',
name='asldkj'
).items())

Просмотреть файл

@ -0,0 +1,19 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
from azure.cli.testsdk import ScenarioTest, JMESPathCheck, ResourceGroupPreparer
class RedisCacheTests(ScenarioTest):
@ResourceGroupPreparer()
def test_create_redis_cache(self, resource_group):
name = self.create_random_name(prefix='cli', length=24)
self.cmd('az redis create -n {} -g {} -l {} --sku {} --vm-size {}'.format(
name, resource_group, 'WestUS', 'Basic','C0'))
self.cmd('az redis show -n {} -g {}'.format(name, resource_group), checks=[
JMESPathCheck('name', name),
JMESPathCheck('provisioningState', 'Creating')
])
self.cmd('az redis list -g {}'.format(resource_group))
self.cmd('az redis list-keys -n {} -g {}'.format(name, resource_group))