зеркало из https://github.com/Azure/ARO-RP.git
Update CLI integration test (#3898)
* change integration cli test * fix name prefix
This commit is contained in:
Родитель
96637dbc85
Коммит
53673d4857
|
@ -0,0 +1,119 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the Apache License 2.0.
|
||||
|
||||
from azure.cli.testsdk.preparers import RoleBasedServicePrincipalPreparer
|
||||
from azure.cli.testsdk.scenario_tests.utilities import is_text_payload
|
||||
from azure.cli.testsdk.utilities import GraphClientPasswordReplacer
|
||||
from azure.mgmt.core.tools import resource_id
|
||||
|
||||
MOCK_GUID = '00000000-0000-0000-0000-000000000001'
|
||||
MOCK_SECRET = 'fake-secret'
|
||||
|
||||
|
||||
class AROClusterServicePrincipalPreparer(RoleBasedServicePrincipalPreparer):
|
||||
def __init__(
|
||||
self,
|
||||
name_prefix="clitest",
|
||||
skip_assignment=True,
|
||||
parameter_name="client_id",
|
||||
parameter_password="client_secret",
|
||||
dev_setting_sp_name="AZURE_CLI_TEST_DEV_SP_NAME",
|
||||
dev_setting_sp_password="AZURE_CLI_TEST_DEV_SP_PASSWORD",
|
||||
key="aro_csp",
|
||||
):
|
||||
super(AROClusterServicePrincipalPreparer, self).__init__(
|
||||
name_prefix,
|
||||
skip_assignment,
|
||||
parameter_name,
|
||||
parameter_password,
|
||||
dev_setting_sp_name,
|
||||
dev_setting_sp_password,
|
||||
key,
|
||||
)
|
||||
self.client_id_to_replace = None
|
||||
self.client_secret_to_replace = None
|
||||
|
||||
def create_resource(self, name, **kwargs):
|
||||
client_id, client_secret = self._get_csp_credentials(name)
|
||||
|
||||
self.test_class_instance.kwargs[self.key] = client_id
|
||||
self.test_class_instance.kwargs["{}_pass".format(self.key)] = client_secret
|
||||
|
||||
return {
|
||||
self.parameter_name: client_id,
|
||||
self.parameter_password: client_secret,
|
||||
}
|
||||
|
||||
# Overriden because RoleBasedServicePrincipal.remove_resource does not delete
|
||||
# the underlying AAD application generated when creating the service principal
|
||||
def remove_resource(self, name, **kwargs):
|
||||
super().remove_resource(name, **kwargs)
|
||||
|
||||
if not self.dev_setting_sp_name:
|
||||
self.live_only_execute(self.cli_ctx, 'az ad app delete --id {}'.format(self.result.get('appId')))
|
||||
|
||||
def process_request(self, request):
|
||||
if self.client_id_to_replace in request.uri:
|
||||
request.uri = request.uri.replace(self.client_id_to_replace, MOCK_GUID)
|
||||
|
||||
if is_text_payload(request) and isinstance(request.body, bytes):
|
||||
request.body = self._replace_byte_keys(request.body)
|
||||
elif is_text_payload(request) and isinstance(request.body, str):
|
||||
request.body = self._replace_string_keys(request.body)
|
||||
|
||||
return request
|
||||
|
||||
def process_response(self, response):
|
||||
if is_text_payload(response) and response['body']['string']:
|
||||
response['body']['string'] = self._replace_string_keys(response['body']['string'])
|
||||
|
||||
return response
|
||||
|
||||
def _get_csp_credentials(self, name):
|
||||
if not self.live_test and not self.test_class_instance.in_recording:
|
||||
return MOCK_GUID, MOCK_SECRET
|
||||
|
||||
client_id, client_secret = self._generate_csp(name)
|
||||
|
||||
# call AbstractPreparer.moniker to make resource counts and self.resource_moniker consistent between live
|
||||
# and play-back. see SingleValueReplacer.process_request, AbstractPreparer.__call__._preparer_wrapper
|
||||
# and ScenarioTest.create_random_name. This is so that when self.create_random_name is called for the
|
||||
# first time during live or playback, it would have the same value.
|
||||
# In short, the default sp preparer in live mode does not call moniker, which leads to inconsistent counts.
|
||||
_ = self.moniker
|
||||
|
||||
self.client_id_to_replace = client_id
|
||||
self.client_secret_to_replace = client_secret
|
||||
|
||||
return client_id, client_secret
|
||||
|
||||
def _generate_csp(self, name):
|
||||
if self.dev_setting_sp_name:
|
||||
client_id = self.dev_setting_sp_name
|
||||
client_secret = self.dev_setting_sp_password
|
||||
|
||||
return client_id, client_secret
|
||||
|
||||
subscription = self.test_class_instance.get_subscription_id()
|
||||
resource_group = self.test_class_instance.kwargs.get('rg')
|
||||
command = 'az ad sp create-for-rbac -n {} --role contributor --scopes "{}"'\
|
||||
.format(name, resource_id(subscription=subscription, resource_group=resource_group))
|
||||
|
||||
try:
|
||||
self.result = self.live_only_execute(self.cli_ctx, command).get_output_in_json()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
client_id = self.result['appId']
|
||||
client_secret = self.result.get('password') or GraphClientPasswordReplacer.PWD_REPLACEMENT
|
||||
|
||||
return client_id, client_secret
|
||||
|
||||
def _replace_string_keys(self, val):
|
||||
if self.client_id_to_replace is None:
|
||||
return val
|
||||
|
||||
return val.replace(self.client_id_to_replace, MOCK_GUID).replace(self.client_secret_to_replace, MOCK_SECRET)
|
||||
|
||||
def _replace_byte_keys(self, val):
|
||||
return self._replace_string_keys(val.decode('utf-8')).encode('utf-8')
|
|
@ -2,42 +2,93 @@
|
|||
# Licensed under the Apache License 2.0.
|
||||
|
||||
import os
|
||||
from random import randint
|
||||
from unittest import mock
|
||||
|
||||
from azure_devtools.scenario_tests import AllowLargeResponse
|
||||
from azure.cli.testsdk import ResourceGroupPreparer
|
||||
from azure.cli.testsdk import ScenarioTest
|
||||
|
||||
from knack.log import get_logger
|
||||
from azext_aro.tests.latest.custom_preparers import AROClusterServicePrincipalPreparer
|
||||
from azure.cli.testsdk import ScenarioTest, ResourceGroupPreparer
|
||||
from azure.cli.testsdk.checkers import StringContainCheck
|
||||
from azure.cli.testsdk.scenario_tests import AllowLargeResponse
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
TEST_DIR = os.path.abspath(os.path.join(os.path.abspath(__file__), '..'))
|
||||
class AroScenarioTests(ScenarioTest):
|
||||
@AllowLargeResponse()
|
||||
@ResourceGroupPreparer(random_name_length=28, name_prefix='cli_test_aro', location='eastus')
|
||||
@AROClusterServicePrincipalPreparer(name_prefix='cli_test_aro')
|
||||
def test_aro_public_cluster(self, resource_group):
|
||||
from azure.mgmt.core.tools import resource_id
|
||||
|
||||
subscription = self.get_subscription_id()
|
||||
|
||||
master_subnet = self.create_random_name('dev_master', 14)
|
||||
worker_subnet = self.create_random_name('dev_worker', 14)
|
||||
name = self.create_random_name('aro', 14)
|
||||
|
||||
temp_kubeconfig_path = self.create_random_name('kubeconfig', 24) + '.tmp'
|
||||
|
||||
class AroScenarioTest(ScenarioTest):
|
||||
@ResourceGroupPreparer(name_prefix='cli_test_aro')
|
||||
def test_aro(self, resource_group):
|
||||
self.kwargs.update({
|
||||
'name': 'test1'
|
||||
'name': name,
|
||||
'resource_group': resource_group,
|
||||
'subscription': subscription,
|
||||
'master_subnet': master_subnet,
|
||||
'worker_subnet': worker_subnet,
|
||||
'master_ip_range': '10.{}.{}.0/24'.format(randint(0, 127), randint(0, 255)),
|
||||
'worker_ip_range': '10.{}.{}.0/24'.format(randint(0, 127), randint(0, 255)),
|
||||
'master_subnet_resource': resource_id(subscription=subscription, resource_group=resource_group, namespace='Microsoft.Network', type='virtualNetworks', child_type_1='subnets', name='dev-vnet', child_name_1=master_subnet),
|
||||
'worker_subnet_resource': resource_id(subscription=subscription, resource_group=resource_group, namespace='Microsoft.Network', type='virtualNetworks', child_type_1='subnets', name='dev-vnet', child_name_1=worker_subnet),
|
||||
'temp_kubeconfig_path': temp_kubeconfig_path,
|
||||
})
|
||||
|
||||
# test aro create
|
||||
self.cmd('network vnet create -g {rg} -n dev-vnet --address-prefixes 10.0.0.0/9')
|
||||
self.cmd('network vnet subnet create -g {rg} --vnet-name dev-vnet -n {master_subnet} --address-prefixes {master_ip_range} --service-endpoints Microsoft.ContainerRegistry --default-outbound false')
|
||||
self.cmd('network vnet subnet create -g {rg} --vnet-name dev-vnet -n {worker_subnet} --address-prefixes {worker_ip_range} --service-endpoints Microsoft.ContainerRegistry --default-outbound false')
|
||||
self.cmd('network vnet subnet update -g {rg} --vnet-name dev-vnet -n {master_subnet} --private-link-service-network-policies Disabled')
|
||||
|
||||
# aro validate
|
||||
with mock.patch('azure.cli.command_modules.aro._rbac._gen_uuid', side_effect=self.create_guid):
|
||||
self.cmd('aro create -g {rg} -n {name} --tags foo=doo', checks=[
|
||||
self.check('tags.foo', 'doo'),
|
||||
self.check('name', '{name}')
|
||||
self.cmd('aro validate -g {rg} -n {name} --client-id {aro_csp} --client-secret {aro_csp_pass} --master-subnet {master_subnet_resource} --worker-subnet {worker_subnet_resource} --subscription {subscription}')
|
||||
|
||||
# aro create
|
||||
with mock.patch('azure.cli.command_modules.aro._rbac._gen_uuid', side_effect=self.create_guid):
|
||||
self.cmd('aro create -g {rg} -n {name} --client-id {aro_csp} --client-secret {aro_csp_pass} --master-subnet {master_subnet_resource} --worker-subnet {worker_subnet_resource} --subscription {subscription} --tags test=create', checks=[
|
||||
self.check('tags.test', 'create'),
|
||||
self.check('name', '{name}'),
|
||||
self.check('masterProfile.subnetId', '{master_subnet_resource}'),
|
||||
self.check('workerProfiles[0].subnetId', '{worker_subnet_resource}'),
|
||||
self.check('provisioningState', 'Succeeded')
|
||||
])
|
||||
|
||||
self.cmd('aro update -g {rg} -n {name} --tags foo=boo', checks=[
|
||||
self.check('tags.foo', 'boo')
|
||||
# aro list-credentials
|
||||
self.cmd('aro list-credentials -g {rg} -n {name} --subscription {subscription}', checks=[self.check('kubeadminUsername', 'kubeadmin')])
|
||||
|
||||
# aro get-admin-kubeconfig
|
||||
try:
|
||||
self.cmd('aro get-admin-kubeconfig -g {rg} -n {name} --subscription {subscription} -f {temp_kubeconfig_path}')
|
||||
self.assertGreater(os.path.getsize(temp_kubeconfig_path), 0)
|
||||
finally:
|
||||
os.remove(temp_kubeconfig_path)
|
||||
|
||||
# aro show
|
||||
self.cmd('aro show -g {rg} -n {name} --subscription {subscription} --output table', checks=[
|
||||
StringContainCheck(name),
|
||||
StringContainCheck(resource_group),
|
||||
StringContainCheck('eastus'),
|
||||
StringContainCheck('Succeeded'),
|
||||
])
|
||||
|
||||
count = len(self.cmd('aro list').get_output_in_json())
|
||||
self.cmd('aro show -g {rg} -n {name}', checks=[
|
||||
self.check('name', '{name}'),
|
||||
self.check('resourceGroup', '{rg}'),
|
||||
self.check('tags.foo', 'boo')
|
||||
# aro list
|
||||
self.cmd('aro list -g {rg} --subscription {subscription}', checks=[
|
||||
self.check('[0].name', '{name}'),
|
||||
self.check('[0].provisioningState', 'Succeeded'),
|
||||
self.check_pattern('[0].id', '.*{name}')
|
||||
])
|
||||
|
||||
self.cmd('aro delete -g {rg} -n {name}')
|
||||
# aro update
|
||||
self.cmd('aro update -g {rg} -n {name} --subscription {subscription}', expect_failure=False)
|
||||
|
||||
final_count = len(self.cmd('aro list').get_output_in_json())
|
||||
self.assertTrue(final_count, count - 1)
|
||||
# aro delete
|
||||
self.cmd('aro delete -y -g {rg} -n {name} --subscription {subscription}', expect_failure=False)
|
||||
|
|
Загрузка…
Ссылка в новой задаче