Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Network] Add AppGateway subresource tests #4137

Merged
merged 6 commits into from
Aug 7, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add more tests.
  • Loading branch information
tjprescott committed Aug 7, 2017
commit 02a9e4e5d2e11f724772d05e8256b214bcc47be7
5 changes: 5 additions & 0 deletions src/azure-cli-core/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

Release History
===============

unreleased
+++++++++++++++++++
* fixes issue where `three_state_flag` would not work correctly if custom labels were used.

2.0.12 (2017-07-27)
+++++++++++++++++++
* output sdk auth info for service principals with certificates
Expand Down
18 changes: 10 additions & 8 deletions src/azure-cli-core/azure/cli/core/commands/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,29 +131,31 @@ def enum_default(resource_type, enum_name, enum_val_name):
return None


def three_state_flag(positive_label='true', negative_label='false', invert=False):
def three_state_flag(positive_label='true', negative_label='false', invert=False, return_label=False):
""" Creates a flag-like argument that can also accept positive/negative values. This allows
consistency between create commands that typically use flags and update commands that require
positive/negative values without introducing breaking changes. Flag-like behavior always
implies the affirmative unless invert=True then invert the logic.
- positive_label: label for the positive value (ex: 'enabled')
- negative_label: label for the negative value (ex: 'disabled')
- invert: invert the boolean logic for the flag
- return_label: if true, return the corresponding label. Otherwise, return a boolean value
"""
choices = [positive_label, negative_label]

# pylint: disable=too-few-public-methods
class ThreeStateAction(argparse.Action):

def __call__(self, parser, namespace, values, option_string=None):
if invert:
if values:
values = positive_label if values.lower() == negative_label else negative_label
else:
values = values or negative_label
if not values:
values = negative_label if invert else positive_label
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I got it right, we should do the flip if the values exist, so we need a else

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the description of invert it seems we would only invert the flag behavior (i.e. the flag implies false instead of true). @devigned do you concur?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, examining the two cases where this is used, it's clear that we do need to invert the values as well. Thanks for pointing this out!

is_positive = values.lower() == positive_label.lower()
set_val = None
if return_label:
set_val = positive_label if is_positive else negative_label
else:
values = values or positive_label
setattr(namespace, self.dest, values.lower() == positive_label)
set_val = is_positive
setattr(namespace, self.dest, set_val)

params = {
'choices': CaseInsensitiveList(choices),
Expand Down
1 change: 1 addition & 0 deletions src/command_modules/azure-cli-network/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ unreleased
+++++++++++++++++++
* `lb`: fixed issue where the certain child resource names did not resolve correctly when omitted
* `application-gateway {subresource} delete`: Fixed issue where `--no-wait` was not honored.
* `application-gateway http-settings update`: Fix issue where `--connection-draining-timeout` could not be turned off.

2.0.11 (2017-07-27)
+++++++++++++++++++
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def completer(prefix, action, parsed_args, **kwargs): # pylint: disable=unused-
subnet_name_type = CliArgumentType(options_list=('--subnet-name',), metavar='NAME', help='The subnet name.')
load_balancer_name_type = CliArgumentType(options_list=('--lb-name',), metavar='NAME', help='The load balancer name.', completer=get_resource_name_completion_list('Microsoft.Network/loadBalancers'), id_part='name')
private_ip_address_type = CliArgumentType(help='Static private IP address to use.', validator=validate_private_ip_address)
cookie_based_affinity_type = CliArgumentType(**enum_choice_list(ApplicationGatewayCookieBasedAffinity))
cookie_based_affinity_type = CliArgumentType(**three_state_flag(positive_label='Enabled', negative_label='Disabled', return_label=True))
http_protocol_type = CliArgumentType(**enum_choice_list(ApplicationGatewayProtocol))
ag_servers_type = CliArgumentType(nargs='+', help='Space separated list of IP addresses or DNS names corresponding to backend servers.', validator=get_servers_validator())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ def update_ag_backend_http_settings_collection(instance, parent, item_name, port
instance.request_timeout = timeout
if connection_draining_timeout is not None:
instance.connection_draining.enabled = bool(connection_draining_timeout)
instance.connection_draining.drain_timeout_in_sec = connection_draining_timeout
instance.connection_draining.drain_timeout_in_sec = connection_draining_timeout or 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have to set 1 when users used 0 to disable the connection_draining? A bit confusing, that you can use 1 to enable; and after you use 0 to disable, but the next read still shows 1 like things not cleaned up. A service side glitch?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. The service will say that it has to be greater than 1 (though ironically it only has to be equal to 1).

if host_name is not None:
instance.host_name = host_name
if host_name_from_backend_pool is not None:
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,66 @@ def test_network_ag_frontend_ip_private(self, resource_group):
self.cmd('network {res} delete -g {rg} --gateway-name {ag} --no-wait -n {name}'.format(**kwargs))
self.cmd('network {res} list -g {rg} --gateway-name {ag}'.format(**kwargs), checks=JMESPathCheckV2('length(@)', 1))

@ResourceGroupPreparer(name_prefix='cli_test_ag_http_listener')
def test_network_ag_http_listener(self, resource_group):

kwargs = {
'ag': 'ag1',
'rg': resource_group,
'res': 'application-gateway http-listener',
'name': 'mylistener'
}
self._create_ag(kwargs)

self.cmd('network {res} create -g {rg} --gateway-name {ag} -n {name} --no-wait --frontend-port appGatewayFrontendPort --host-name www.test.com'.format(**kwargs))
self.cmd('network {res} show -g {rg} --gateway-name {ag} -n {name}'.format(**kwargs), checks=[
JMESPathCheckV2('hostName', 'www.test.com')
])
self.cmd('network {res} update -g {rg} --gateway-name {ag} -n {name} --no-wait --host-name www.test2.com'.format(**kwargs))
self.cmd('network {res} show -g {rg} --gateway-name {ag} -n {name}'.format(**kwargs), checks=[
JMESPathCheckV2('hostName', 'www.test2.com')
])
self.cmd('network {res} list -g {rg} --gateway-name {ag}'.format(**kwargs), checks=JMESPathCheckV2('length(@)', 2))
self.cmd('network {res} delete -g {rg} --gateway-name {ag} --no-wait -n {name}'.format(**kwargs))
self.cmd('network {res} list -g {rg} --gateway-name {ag}'.format(**kwargs), checks=JMESPathCheckV2('length(@)', 1))

@ResourceGroupPreparer(name_prefix='cli_test_ag_http_settings')
def test_network_ag_http_settings(self, resource_group):

kwargs = {
'ag': 'ag1',
'rg': resource_group,
'res': 'application-gateway http-settings',
'name': 'mysettings'
}
self._create_ag(kwargs)

self.cmd('network {res} create -g {rg} --gateway-name {ag} -n {name} --no-wait --affinity-cookie-name mycookie --connection-draining-timeout 60 --cookie-based-affinity --host-name-from-backend-pool --protocol https --timeout 50 --port 70'.format(**kwargs))
self.cmd('network {res} show -g {rg} --gateway-name {ag} -n {name}'.format(**kwargs), checks=[
JMESPathCheckV2('affinityCookieName', 'mycookie'),
JMESPathCheckV2('connectionDraining.drainTimeoutInSec', 60),
JMESPathCheckV2('connectionDraining.enabled', True),
JMESPathCheckV2('cookieBasedAffinity', 'Enabled'),
JMESPathCheckV2('pickHostNameFromBackendAddress', True),
JMESPathCheckV2('port', 70),
JMESPathCheckV2('protocol', 'Https'),
JMESPathCheckV2('requestTimeout', 50)
])
self.cmd('network {res} update -g {rg} --gateway-name {ag} -n {name} --no-wait --affinity-cookie-name mycookie2 --connection-draining-timeout 0 --cookie-based-affinity disabled --host-name-from-backend-pool false --protocol http --timeout 40 --port 71'.format(**kwargs))
self.cmd('network {res} show -g {rg} --gateway-name {ag} -n {name}'.format(**kwargs), checks=[
JMESPathCheckV2('affinityCookieName', 'mycookie2'),
JMESPathCheckV2('connectionDraining.drainTimeoutInSec', 1),
JMESPathCheckV2('connectionDraining.enabled', False),
JMESPathCheckV2('cookieBasedAffinity', 'Disabled'),
JMESPathCheckV2('pickHostNameFromBackendAddress', False),
JMESPathCheckV2('port', 71),
JMESPathCheckV2('protocol', 'Http'),
JMESPathCheckV2('requestTimeout', 40)
])
self.cmd('network {res} list -g {rg} --gateway-name {ag}'.format(**kwargs), checks=JMESPathCheckV2('length(@)', 2))
self.cmd('network {res} delete -g {rg} --gateway-name {ag} --no-wait -n {name}'.format(**kwargs))
self.cmd('network {res} list -g {rg} --gateway-name {ag}'.format(**kwargs), checks=JMESPathCheckV2('length(@)', 1))


class NetworkAppGatewayPublicIpScenarioTest(ScenarioTest):

Expand Down