зеркало из https://github.com/Azure/azure-cli.git
Upgrade SDK reference and update metric commands (#4986)
1. Remove azure-monitor SDK reference 2. Upgrade azure-mgmt-monitor reference to 0.4.0 3. Update diagnostics settings 4. Update and refresh monitor action-group commands 5. Refresh the monitor activity-log list command and tests 6. Refresh the metric alert command and tests 7. Refresh the autoscale command 8. Refresh the diagnostic-settings command 9. Refresh the log-profiles command 10.Move custom commands under operations module 11.BREAKING CHANGE: Update metrics command to support multi-dimension metrics 12.Improve metric list table output
This commit is contained in:
Родитель
7b46ee4e6e
Коммит
9b7005681e
|
@ -365,7 +365,7 @@ class LongRunningOperation(object): # pylint: disable=too-few-public-methods
|
|||
def _generate_template_progress(self, correlation_id): # pylint: disable=no-self-use
|
||||
""" gets the progress for template deployments """
|
||||
from azure.cli.core.commands.client_factory import get_mgmt_service_client
|
||||
from azure.monitor import MonitorClient
|
||||
from azure.mgmt.monitor import MonitorManagementClient
|
||||
|
||||
if correlation_id is not None: # pylint: disable=too-many-nested-blocks
|
||||
formatter = "eventTimestamp ge {}"
|
||||
|
@ -376,7 +376,7 @@ class LongRunningOperation(object): # pylint: disable=too-few-public-methods
|
|||
|
||||
odata_filters = "{} and {} eq '{}'".format(odata_filters, 'correlationId', correlation_id)
|
||||
|
||||
activity_log = get_mgmt_service_client(self.cli_ctx, MonitorClient).activity_logs.list(filter=odata_filters)
|
||||
activity_log = get_mgmt_service_client(MonitorManagementClient).activity_logs.list(filter=odata_filters)
|
||||
|
||||
results = []
|
||||
max_events = 50 # default max value for events in list_activity_log
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
Release History
|
||||
===============
|
||||
|
||||
0.0.13
|
||||
++++++
|
||||
* Update managed SDK reference to 0.4.0
|
||||
* Remove data plane SDK reference
|
||||
* BREAKING CHANGE: Add multi-dimension support to metrics command
|
||||
|
||||
0.0.12
|
||||
++++++
|
||||
* Add activity-log alert commands
|
||||
|
|
|
@ -24,7 +24,7 @@ def cf_autoscale(kwargs):
|
|||
|
||||
|
||||
def cf_diagnostics(kwargs):
|
||||
return cf_monitor(kwargs).service_diagnostic_settings
|
||||
return cf_monitor(kwargs).diagnostic_settings
|
||||
|
||||
|
||||
def cf_log_profiles(kwargs):
|
||||
|
@ -39,24 +39,17 @@ def cf_activity_log_alerts(kwargs):
|
|||
return cf_monitor(kwargs).activity_log_alerts
|
||||
|
||||
|
||||
# DATA CLIENT FACTORIES
|
||||
def cf_monitor_data(_):
|
||||
from azure.monitor import MonitorClient
|
||||
from azure.cli.core.commands.client_factory import get_mgmt_service_client
|
||||
return get_mgmt_service_client(MonitorClient)
|
||||
|
||||
|
||||
def cf_metrics(kwargs):
|
||||
return cf_monitor_data(kwargs).metrics
|
||||
return cf_monitor(kwargs).metrics
|
||||
|
||||
|
||||
def cf_metric_def(kwargs):
|
||||
return cf_monitor_data(kwargs).metric_definitions
|
||||
return cf_monitor(kwargs).metric_definitions
|
||||
|
||||
|
||||
def cf_activity_log(kwargs):
|
||||
return cf_monitor_data(kwargs).activity_logs
|
||||
return cf_monitor(kwargs).activity_logs
|
||||
|
||||
|
||||
def cf_event_categories(kwargs):
|
||||
return cf_monitor_data(kwargs).event_categories
|
||||
return cf_monitor(kwargs).event_categories
|
||||
|
|
|
@ -12,7 +12,9 @@ def monitor_exception_handler(ex):
|
|||
# work around for issue: https://github.com/Azure/azure-sdk-for-python/issues/1556
|
||||
error_payload = ex.response.json()
|
||||
if 'Code' in error_payload and 'Message' in error_payload:
|
||||
raise CLIError('Operation failed. {}. [Code: {}]'.format(error_payload['Message'], error_payload['Code']))
|
||||
message = '{}.'.format(error_payload['Message']) if error_payload['Message'] else 'Operation failed.'
|
||||
code = '[Code: "{}"]'.format(error_payload['Code']) if error_payload['Code'] else ''
|
||||
raise CLIError('{} {}'.format(message, code))
|
||||
else:
|
||||
raise CLIError(ex)
|
||||
else:
|
||||
|
|
|
@ -12,8 +12,6 @@ helps['monitor'] = """
|
|||
short-summary: Manage the Azure Monitor Service.
|
||||
"""
|
||||
|
||||
# region Alerts
|
||||
|
||||
helps['monitor alert'] = """
|
||||
type: group
|
||||
short-summary: Manage metric-based alert rules.
|
||||
|
@ -126,10 +124,6 @@ helps['monitor alert list-incidents'] = """
|
|||
short-summary: List all incidents for an alert rule.
|
||||
"""
|
||||
|
||||
# endregion
|
||||
|
||||
# region Metrics
|
||||
|
||||
helps['monitor metrics'] = """
|
||||
type: group
|
||||
short-summary: View Azure resource metrics.
|
||||
|
@ -137,12 +131,70 @@ helps['monitor metrics'] = """
|
|||
|
||||
helps['monitor metrics list'] = """
|
||||
type: command
|
||||
short-summary: List metric values for a resource.
|
||||
short-summary: List the metric values for a resource.
|
||||
parameters:
|
||||
- name: --aggregation
|
||||
type: string
|
||||
short-summary: The list of aggregation types (space separated) to retrieve.
|
||||
- name: --interval
|
||||
type: string
|
||||
short-summary: The interval of the metric query. In ISO 8601 duration format, eg "PT1M"
|
||||
- name: --start-time
|
||||
type: string
|
||||
short-summary: The start time of the query. In ISO format with explicit indication of timezone,
|
||||
1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500. Defaults to 1 Hour prior to the current time.
|
||||
- name: --end-time
|
||||
type: string
|
||||
short-summary: The end time of the query. In ISO format with explicit indication of timezone,
|
||||
1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500. Defaults to current time.
|
||||
- name: --filter
|
||||
type: string
|
||||
short-summary: A string used to reduce the set of metric data returned. eg. "BlobType eq '*'"
|
||||
- name: --metadata
|
||||
short-summary: Returns the metadata values instead of metric data
|
||||
- name: --dimension
|
||||
type: string
|
||||
short-summary: The list of dimensions (space separated) the metrics are queried into.
|
||||
examples:
|
||||
- name: List a VM's CPU usage for the past hour
|
||||
text: >
|
||||
az monitor metrics list --resource <resource id> --metric "Percentage CPU"
|
||||
- name: List success E2E latency of a storage account and split the data series based on API name
|
||||
text: >
|
||||
az monitor metrics list --resource <resource id> --metric SuccessE2ELatency \\
|
||||
--dimension ApiName
|
||||
- name: List success E2E latency of a storage account and split the data series based on both API name and geo type
|
||||
text: >
|
||||
az monitor metrics list --resource <resource id> --metric SuccessE2ELatency \\
|
||||
--dimension ApiName GeoType
|
||||
- name: List success E2E latency of a storage account and split the data series based on both API name and geo type using "--filter" parameter
|
||||
text: >
|
||||
az monitor metrics list --resource <resource id> --metric SuccessE2ELatency \\
|
||||
--filter "ApiName eq '*' and GeoType eq '*'"
|
||||
- name: List success E2E latency of a storage account and split the data series based on both API name and geo type. Limits the api name to 'DeleteContainer'
|
||||
text: >
|
||||
az monitor metrics list --resource <resource id> --metric SuccessE2ELatency \\
|
||||
--filter "ApiName eq 'DeleteContainer' and GeoType eq '*'"
|
||||
Filter string reference: https://docs.microsoft.com/en-us/rest/api/monitor/metrics/list
|
||||
- name: List transactions of a storage account per day since 2017-01-01
|
||||
text: >
|
||||
az monitor metrics list --resource <resource id> --metric Transactions \\
|
||||
--start-time 2017-01-01T00:00:00Z \\
|
||||
--interval PT24H
|
||||
- name: List the metadata values for a storage account under transaction metric's api name dimension since 2017
|
||||
text: >
|
||||
az monitor metrics list --resource <resource id> --metric Transactions \\
|
||||
--filter "ApiName eq '*'" \\
|
||||
--start-time 2017-01-01T00:00:00Z
|
||||
"""
|
||||
|
||||
helps['monitor metrics list-definitions'] = """
|
||||
type: command
|
||||
short-summary: List metric definitions for a resource.
|
||||
short-summary: Lists the metric definitions for the resource.
|
||||
parameters:
|
||||
- name: --metric-names
|
||||
type: string
|
||||
short-summary: The list of the metrics definitions to be shown.
|
||||
"""
|
||||
|
||||
# endregion
|
||||
|
@ -172,6 +224,10 @@ helps['monitor diagnostic-settings create'] = """
|
|||
- name: --logs
|
||||
type: string
|
||||
short-summary: JSON encoded list of logs settings. Use @{file} to load from a file.
|
||||
- name: --event-hub-name
|
||||
type: string
|
||||
short-summary: The name of the event hub. If none is specified, the default event hub will be
|
||||
selected.
|
||||
- name: --metrics
|
||||
type: string
|
||||
short-summary: JSON encoded list of metric settings. Use @{file} to load from a file.
|
||||
|
|
|
@ -10,24 +10,34 @@ from azure.cli.core.commands import register_cli_argument, register_extra_cli_ar
|
|||
from azure.cli.core.commands.parameters import location_type, tags_type, get_three_state_flag
|
||||
from azure.cli.core.commands.validators import get_default_location_from_resource_group
|
||||
|
||||
from azure.cli.command_modules.monitor.actions import \
|
||||
(AlertAddAction, AlertRemoveAction, ConditionAction, period_type)
|
||||
from azure.cli.command_modules.monitor.custom import operator_map, aggregation_map
|
||||
from azure.cli.command_modules.monitor.validators import \
|
||||
(validate_diagnostic_settings, get_target_resource_validator)
|
||||
from azure.mgmt.monitor.models.monitor_management_client_enums import \
|
||||
(ConditionOperator, TimeAggregationOperator)
|
||||
from azure.mgmt.monitor.models import (LogProfileResource, RetentionPolicy)
|
||||
from azure.cli.command_modules.monitor.operations.actions import (AlertAddAction, AlertRemoveAction, ConditionAction,
|
||||
period_type)
|
||||
from azure.cli.command_modules.monitor.util import get_operator_map, get_aggregation_map
|
||||
from azure.cli.command_modules.monitor.validators import validate_diagnostic_settings, get_target_resource_validator
|
||||
from azure.mgmt.monitor.models.monitor_management_client_enums import ConditionOperator, TimeAggregationOperator
|
||||
from azure.mgmt.monitor.models import LogProfileResource, RetentionPolicy
|
||||
|
||||
from knack.arguments import CLIArgumentType, enum_choice_list
|
||||
|
||||
# pylint: disable=line-too-long
|
||||
|
||||
|
||||
def register_resource_parameter_context(context, dest, arg_group=None, required=True):
|
||||
context.register(dest, options_list='--resource', arg_group=arg_group, required=required,
|
||||
validator=get_target_resource_validator(dest, required), help="Name or ID of the target resource.")
|
||||
context.extra('namespace', options_list='--resource-namespace', arg_group=arg_group,
|
||||
help="Target resource provider namespace.")
|
||||
context.extra('parent', options_list='--resource-parent', arg_group=arg_group,
|
||||
help="Target resource parent path, if applicable.")
|
||||
context.extra('resource_type', options_list='--resource-type', arg_group=arg_group,
|
||||
help="Target resource type. Can also accept namespace/type format "
|
||||
"(Ex: 'Microsoft.Compute/virtualMachines)')")
|
||||
context.extra('resource_group_name', options_list=('--resource-group', '-g'), arg_group='Target Resource')
|
||||
|
||||
|
||||
def register_resource_parameter(command, dest, arg_group=None, required=True):
|
||||
""" Helper method to add the extra parameters needed to support specifying name or ID
|
||||
for target resources. """
|
||||
register_cli_argument(command, dest, options_list=['--{}'.format(dest)], arg_group=arg_group, required=required, validator=get_target_resource_validator(dest, required), help="Name or ID of the target resource.")
|
||||
""" Helper method to add the extra parameters needed to support specifying name or ID for target resources. """
|
||||
register_cli_argument(command, dest, options_list=['--{}'.format(dest)], arg_group=arg_group, required=required, validator=get_target_resource_validator(dest, required, preserve_resource_group_parameter=True), help="Name or ID of the target resource.")
|
||||
register_extra_cli_argument(command, 'namespace', options_list=['--{}-namespace'.format(dest)], arg_group=arg_group, help="Target resource provider namespace.")
|
||||
register_extra_cli_argument(command, 'parent', options_list=['--{}-parent'.format(dest)], arg_group=arg_group, help="Target resource parent path, if applicable.")
|
||||
register_extra_cli_argument(command, 'resource_type', options_list=['--{}-type'.format(dest)], arg_group=arg_group, help="Target resource type. Can also accept namespace/type format (Ex: 'Microsoft.Compute/virtualMachines)')")
|
||||
|
@ -62,9 +72,9 @@ register_cli_argument('monitor alert update', 'add_actions', options_list=['--ad
|
|||
register_cli_argument('monitor alert update', 'remove_actions', options_list=['--remove-action', '-r'], nargs='+', action=AlertRemoveAction, arg_group='Action')
|
||||
register_cli_argument('monitor alert update', 'condition', action=ConditionAction, nargs='+', arg_group='Condition')
|
||||
register_cli_argument('monitor alert update', 'metric', arg_group='Condition')
|
||||
register_cli_argument('monitor alert update', 'operator', arg_group='Condition', **enum_choice_list(operator_map.keys()))
|
||||
register_cli_argument('monitor alert update', 'operator', arg_group='Condition', **enum_choice_list(get_operator_map().keys()))
|
||||
register_cli_argument('monitor alert update', 'threshold', arg_group='Condition')
|
||||
register_cli_argument('monitor alert update', 'aggregation', arg_group='Condition', **enum_choice_list(aggregation_map.keys()))
|
||||
register_cli_argument('monitor alert update', 'aggregation', arg_group='Condition', **enum_choice_list(get_aggregation_map().keys()))
|
||||
register_cli_argument('monitor alert update', 'period', type=period_type, arg_group='Condition')
|
||||
register_resource_parameter('monitor alert update', 'target', 'Target Resource', required=False)
|
||||
|
||||
|
@ -76,13 +86,26 @@ register_cli_argument('monitor alert list-incidents', 'rule_name', options_list=
|
|||
|
||||
# endregion
|
||||
|
||||
# region Metrics
|
||||
with ParametersContext(command='monitor metrics list-definitions') as c:
|
||||
register_resource_parameter_context(c, dest='resource_uri', arg_group='Target Resource')
|
||||
|
||||
for item in ['list', 'list-definitions']:
|
||||
register_resource_parameter('monitor metrics {}'.format(item), 'resource', 'Target Resource')
|
||||
register_cli_argument('monitor metrics {}'.format(item), 'resource_group_name', arg_group='Target Resource')
|
||||
with ParametersContext(command='monitor metrics list') as c:
|
||||
from .validators import (process_metric_timespan, process_metric_aggregation, process_metric_result_type,
|
||||
process_metric_dimension)
|
||||
from azure.mgmt.monitor.models.monitor_management_client_enums import AggregationType
|
||||
register_resource_parameter_context(c, dest='resource_uri', arg_group='Target Resource')
|
||||
c.extra('start_time', options_list='--start-time', validator=process_metric_timespan, arg_group='Time')
|
||||
c.extra('end_time', options_list='--end-time', arg_group='Time')
|
||||
c.extra('metadata', options_list='--metadata', action='store_true', validator=process_metric_result_type)
|
||||
c.extra('dimension', options_list='--dimension', nargs='*', validator=process_metric_dimension)
|
||||
c.argument('interval', arg_group='Time')
|
||||
c.argument('aggregation', nargs='*', validator=process_metric_aggregation,
|
||||
**enum_choice_list(t for t in AggregationType if t.name != 'none'))
|
||||
c.ignore('timespan')
|
||||
c.ignore('result_type')
|
||||
c.ignore('top')
|
||||
c.ignore('orderby')
|
||||
|
||||
# endregion
|
||||
with ParametersContext(command='monitor autoscale-settings') as c:
|
||||
c.register_alias('name', ('--azure-resource-name',))
|
||||
c.register_alias('autoscale_setting_name', ('--name', '-n'))
|
||||
|
@ -108,8 +131,7 @@ with ParametersContext(command='monitor diagnostic-settings') as c:
|
|||
|
||||
with ParametersContext(command='monitor diagnostic-settings create') as c:
|
||||
c.register_alias('resource_group', ('--resource-group', '-g'))
|
||||
c.register_alias('target_resource_id', ('--resource-id',),
|
||||
validator=validate_diagnostic_settings)
|
||||
c.register_alias('target_resource_id', ('--resource-id',), validator=validate_diagnostic_settings)
|
||||
c.register('logs', ('--logs',), type=get_json_object)
|
||||
c.register('metrics', ('--metrics',), type=get_json_object)
|
||||
c.argument('tags', nargs='*')
|
||||
|
@ -135,12 +157,6 @@ with ParametersContext(command='monitor log-profiles create') as c:
|
|||
help="Space separated list of regions for which Activity Log events "
|
||||
"should be stored.")
|
||||
|
||||
with ParametersContext(command='monitor metric-definitions list') as c:
|
||||
c.argument('metric_names', nargs='+')
|
||||
|
||||
with ParametersContext(command='monitor metrics list') as c:
|
||||
c.argument('metric_names', nargs='+', required=True)
|
||||
|
||||
with ParametersContext(command='monitor activity-log list') as c:
|
||||
c.register_alias('resource_group', ('--resource-group', '-g'))
|
||||
c.argument('select', None, nargs='+')
|
||||
|
@ -159,7 +175,7 @@ register_cli_argument('monitor action-group', 'action_group_name', options_list=
|
|||
|
||||
with ParametersContext(command='monitor action-group create') as c:
|
||||
from .validators import process_action_group_detail_for_creation
|
||||
from .actions import ActionGroupReceiverParameterAction
|
||||
from .operations.actions import ActionGroupReceiverParameterAction
|
||||
|
||||
c.extra('receivers', options_list=('--action', '-a'), nargs='+', arg_group='Actions',
|
||||
action=ActionGroupReceiverParameterAction, validator=process_action_group_detail_for_creation)
|
||||
|
@ -181,7 +197,7 @@ register_cli_argument('monitor activity-log alert', 'activity_log_alert_name', o
|
|||
id_part='name')
|
||||
|
||||
with ParametersContext(command='monitor activity-log alert create') as c:
|
||||
from .activity_log_alerts import webhook_prop_type, process_condition_parameter
|
||||
from .operations.activity_log_alerts import webhook_prop_type, process_condition_parameter
|
||||
c.register('disable', options_list='--disable', action='store_true')
|
||||
c.register('scopes', options_list=('--scope', '-s'), nargs='+')
|
||||
c.register('condition', options_list=('--condition', '-c'), nargs='+', validator=process_condition_parameter)
|
||||
|
@ -194,12 +210,12 @@ with ParametersContext(command='monitor activity-log alert update-condition') as
|
|||
c.register('remove_conditions', options_list=('--remove-condition', '-r'), nargs='+')
|
||||
|
||||
with ParametersContext(command='monitor activity-log alert update') as c:
|
||||
from .activity_log_alerts import process_condition_parameter
|
||||
from .operations.activity_log_alerts import process_condition_parameter
|
||||
c.register('condition', options_list=('--condition', '-c'), nargs='+', validator=process_condition_parameter)
|
||||
c.register('enabled', options_list='--enabled', **three_state_flag())
|
||||
|
||||
with ParametersContext(command='monitor activity-log alert action-group add') as c:
|
||||
from .activity_log_alerts import webhook_prop_type
|
||||
from .operations.activity_log_alerts import webhook_prop_type
|
||||
c.register('reset', options_list='--reset', action='store_true')
|
||||
c.register('action_group_ids', options_list=('--action-group', '-a'), nargs='+')
|
||||
c.register('webhook_properties', options_list=('--webhook-properties', '-w'), arg_type=webhook_prop_type)
|
||||
|
|
|
@ -3,134 +3,115 @@
|
|||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
# 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.core.profiles import supported_api_version, PROFILE_TYPE
|
||||
from ._client_factory import (cf_alert_rules, cf_metrics, cf_metric_def, cf_alert_rule_incidents, cf_log_profiles,
|
||||
cf_autoscale, cf_diagnostics, cf_activity_log, cf_action_groups, cf_activity_log_alerts,
|
||||
cf_event_categories)
|
||||
from ._exception_handler import monitor_exception_handler, missing_resource_handler
|
||||
|
||||
from .transformers import (action_group_list_table)
|
||||
|
||||
if not supported_api_version(PROFILE_TYPE, max_api='2017-03-09-profile'):
|
||||
def monitor_command(*args, **kwargs):
|
||||
cli_command(*args, exception_handler=monitor_exception_handler, **kwargs)
|
||||
from azure.cli.core.sdk.util import ServiceGroup, create_service_adapter
|
||||
from ._client_factory import (cf_alert_rules, cf_metrics, cf_metric_def, cf_alert_rule_incidents, cf_log_profiles,
|
||||
cf_autoscale, cf_diagnostics, cf_activity_log, cf_action_groups,
|
||||
cf_activity_log_alerts, cf_event_categories)
|
||||
from ._exception_handler import monitor_exception_handler, missing_resource_handler
|
||||
|
||||
# MANAGEMENT COMMANDS
|
||||
from .transformers import (action_group_list_table)
|
||||
|
||||
custom_path = 'azure.cli.command_modules.monitor.custom#'
|
||||
def service_adapter(module_name, class_name):
|
||||
return create_service_adapter('azure.mgmt.monitor.operations.{}'.format(module_name), class_name)
|
||||
|
||||
# region Alerts
|
||||
def custom_path(module_name):
|
||||
return '.'.join(__name__.split('.')[:-1]) + '.operations.{}#'.format(module_name) + '{}'
|
||||
|
||||
ar_path = 'azure.mgmt.monitor.operations.alert_rules_operations#AlertRulesOperations.'
|
||||
|
||||
monitor_command(__name__, 'monitor alert create', custom_path + 'create_metric_rule', cf_alert_rules)
|
||||
monitor_command(__name__, 'monitor alert delete', ar_path + 'delete', cf_alert_rules)
|
||||
monitor_command(__name__, 'monitor alert show', ar_path + 'get', cf_alert_rules)
|
||||
monitor_command(__name__, 'monitor alert list', ar_path + 'list_by_resource_group', cf_alert_rules)
|
||||
_cli_generic_update_command(__name__, 'monitor alert update',
|
||||
ar_path + 'get', ar_path + 'create_or_update', cf_alert_rules,
|
||||
custom_function_op=custom_path + 'update_metric_rule',
|
||||
exception_handler=monitor_exception_handler)
|
||||
|
||||
ari_path = 'azure.mgmt.monitor.operations.alert_rule_incidents_operations#AlertRuleIncidentsOperations.'
|
||||
monitor_command(__name__, 'monitor alert show-incident', ari_path + 'get', cf_alert_rule_incidents)
|
||||
monitor_command(__name__, 'monitor alert list-incidents', ari_path + 'list_by_alert_rule', cf_alert_rule_incidents)
|
||||
|
||||
# endregion
|
||||
|
||||
# region Metrics
|
||||
|
||||
monitor_command(__name__, 'monitor metrics list', custom_path + 'list_metrics', cf_metrics)
|
||||
monitor_command(__name__, 'monitor metrics list-definitions', custom_path + 'list_metric_definitions', cf_metric_def)
|
||||
|
||||
# endregion
|
||||
|
||||
# region Log Profiles
|
||||
|
||||
lp_path = 'azure.mgmt.monitor.operations.log_profiles_operations#LogProfilesOperations.'
|
||||
monitor_command(__name__, 'monitor log-profiles create', lp_path + 'create_or_update', cf_log_profiles)
|
||||
monitor_command(__name__, 'monitor log-profiles delete', lp_path + 'delete', cf_log_profiles)
|
||||
monitor_command(__name__, 'monitor log-profiles show', lp_path + 'get', cf_log_profiles)
|
||||
monitor_command(__name__, 'monitor log-profiles list', lp_path + 'list', cf_log_profiles)
|
||||
_cli_generic_update_command(__name__, 'monitor log-profiles update',
|
||||
lp_path + 'get', lp_path + 'create_or_update', cf_log_profiles,
|
||||
exception_handler=monitor_exception_handler)
|
||||
|
||||
# endregion
|
||||
|
||||
# region Diagnostic Settings
|
||||
|
||||
diag_path = 'azure.mgmt.monitor.operations.service_diagnostic_settings_operations#ServiceDiagnosticSettingsOperations.'
|
||||
monitor_command(__name__, 'monitor diagnostic-settings create', custom_path + 'create_diagnostics_settings', cf_diagnostics)
|
||||
monitor_command(__name__, 'monitor diagnostic-settings show', diag_path + 'get', cf_diagnostics)
|
||||
_cli_generic_update_command(__name__, 'monitor diagnostic-settings update',
|
||||
diag_path + 'get', diag_path + 'create_or_update', cf_diagnostics,
|
||||
exception_handler=monitor_exception_handler)
|
||||
|
||||
# endregion
|
||||
|
||||
# region Autoscale
|
||||
|
||||
autoscale_path = 'azure.mgmt.monitor.operations.autoscale_settings_operations#AutoscaleSettingsOperations.'
|
||||
|
||||
monitor_command(__name__, 'monitor autoscale-settings create', autoscale_path + 'create_or_update', cf_autoscale)
|
||||
monitor_command(__name__, 'monitor autoscale-settings delete', autoscale_path + 'delete', cf_autoscale)
|
||||
monitor_command(__name__, 'monitor autoscale-settings show', autoscale_path + 'get', cf_autoscale)
|
||||
monitor_command(__name__, 'monitor autoscale-settings list', autoscale_path + 'list_by_resource_group', cf_autoscale)
|
||||
monitor_command(__name__, 'monitor autoscale-settings get-parameters-template', custom_path + 'scaffold_autoscale_settings_parameters', cf_autoscale)
|
||||
_cli_generic_update_command(__name__, 'monitor autoscale-settings update',
|
||||
autoscale_path + 'get', autoscale_path + 'create_or_update', cf_autoscale,
|
||||
exception_handler=monitor_exception_handler)
|
||||
|
||||
# endregion
|
||||
|
||||
# region Activity Log
|
||||
|
||||
monitor_command(__name__, 'monitor activity-log list', custom_path + 'list_activity_log', cf_activity_log)
|
||||
|
||||
# endregion
|
||||
|
||||
action_group_operations = create_service_adapter(
|
||||
'azure.mgmt.monitor.operations.action_groups_operations', 'ActionGroupsOperations')
|
||||
ag_custom_path = '.'.join(__name__.split('.')[:-1] + ['action_groups']) + '#{}'
|
||||
|
||||
with ServiceGroup(__name__, cf_action_groups, action_group_operations, ag_custom_path) as s:
|
||||
with ServiceGroup(__name__, cf_action_groups, service_adapter('action_groups_operations', 'ActionGroupsOperations'),
|
||||
custom_path('action_groups')) as s:
|
||||
with s.group('monitor action-group') as c:
|
||||
c.command('show', 'get', table_transformer=action_group_list_table)
|
||||
c.command('create', 'create_or_update', table_transformer=action_group_list_table)
|
||||
c.command('delete', 'delete')
|
||||
c.command('enable-receiver', 'enable_receiver', table_transformer=action_group_list_table)
|
||||
c.command('enable-receiver', 'enable_receiver', table_transformer=action_group_list_table,
|
||||
exception_handler=monitor_exception_handler)
|
||||
c.custom_command('list', 'list_action_groups', table_transformer=action_group_list_table)
|
||||
c.generic_update_command('update', 'get', 'create_or_update', 'update_action_groups',
|
||||
setter_arg_name='action_group',
|
||||
table_transformer=action_group_list_table,
|
||||
setter_arg_name='action_group', table_transformer=action_group_list_table,
|
||||
exception_handler=monitor_exception_handler)
|
||||
|
||||
activity_log_alerts_operations = create_service_adapter(
|
||||
'azure.mgmt.monitor.operations.activity_log_alerts_operations', 'ActivityLogAlertsOperations')
|
||||
ala_custom_path = '.'.join(__name__.split('.')[:-1] + ['activity_log_alerts']) + '#{}'
|
||||
with ServiceGroup(__name__, cf_activity_log, custom_path=custom_path('activity_log')) as s:
|
||||
with s.group('monitor activity-log') as c:
|
||||
c.custom_command('list', 'list_activity_log')
|
||||
|
||||
with ServiceGroup(__name__, cf_activity_log_alerts, activity_log_alerts_operations, ala_custom_path) as s:
|
||||
with ServiceGroup(__name__, cf_activity_log_alerts,
|
||||
service_adapter('activity_log_alerts_operations', 'ActivityLogAlertsOperations'),
|
||||
custom_path('activity_log_alerts')) as s:
|
||||
with s.group('monitor activity-log alert') as c:
|
||||
c.custom_command('list', 'list_activity_logs_alert')
|
||||
c.custom_command('create', 'create', exception_handler=monitor_exception_handler)
|
||||
c.command('show', 'get', exception_handler=missing_resource_handler)
|
||||
c.command('delete', 'delete', exception_handler=missing_resource_handler)
|
||||
c.generic_update_command('update', 'get', 'create_or_update', 'update',
|
||||
setter_arg_name='activity_log_alert',
|
||||
exception_handler=monitor_exception_handler)
|
||||
setter_arg_name='activity_log_alert', exception_handler=monitor_exception_handler)
|
||||
c.custom_command('action-group add', 'add_action_group', exception_handler=monitor_exception_handler)
|
||||
c.custom_command('action-group remove', 'remove_action_group', exception_handler=monitor_exception_handler)
|
||||
c.custom_command('scope add', 'add_scope', exception_handler=monitor_exception_handler)
|
||||
c.custom_command('scope remove', 'remove_scope', exception_handler=monitor_exception_handler)
|
||||
|
||||
with ServiceGroup(__name__, cf_event_categories,
|
||||
create_service_adapter('azure.monitor.operations.event_categories_operations',
|
||||
'EventCategoriesOperations'),
|
||||
ala_custom_path) as s:
|
||||
service_adapter('event_categories_operations', 'EventCategoriesOperations'),
|
||||
custom_path('activity_log_alerts')) as s:
|
||||
with s.group('monitor activity-log') as c:
|
||||
c.command('list-categories', 'list')
|
||||
|
||||
with ServiceGroup(__name__, cf_alert_rules, service_adapter('alert_rules_operations', 'AlertRulesOperations'),
|
||||
custom_path('metric_alert')) as s:
|
||||
with s.group('monitor alert') as c:
|
||||
c.custom_command('create', 'create_metric_rule')
|
||||
c.command('delete', 'delete')
|
||||
c.command('show', 'get')
|
||||
c.command('list', 'list_by_resource_group')
|
||||
c.generic_update_command('update', 'get', 'create_or_update', 'update_metric_rule',
|
||||
exception_handler=monitor_exception_handler)
|
||||
|
||||
with ServiceGroup(__name__, cf_alert_rule_incidents,
|
||||
service_adapter('alert_rule_incidents_operations', 'AlertRuleIncidentsOperations'),
|
||||
custom_path('metric_alert')) as s:
|
||||
with s.group('monitor alert') as c:
|
||||
c.command('show-incident', 'get')
|
||||
c.command('list-incidents', 'list_by_alert_rule')
|
||||
|
||||
with ServiceGroup(__name__, cf_autoscale,
|
||||
service_adapter('autoscale_settings_operations', 'AutoscaleSettingsOperations'),
|
||||
custom_path('autoscale_settings')) as s:
|
||||
with s.group('monitor autoscale-settings') as c:
|
||||
c.command('create', 'create_or_update')
|
||||
c.command('delete', 'delete')
|
||||
c.command('show', 'get')
|
||||
c.command('list', 'list_by_resource_group')
|
||||
c.custom_command('get-parameters-template', 'scaffold_autoscale_settings_parameters')
|
||||
c.generic_update_command('update', 'get', 'create_or_update', exception_handler=monitor_exception_handler)
|
||||
|
||||
with ServiceGroup(__name__, cf_diagnostics,
|
||||
service_adapter('diagnostic_settings_operations', 'DiagnosticSettingsOperations'),
|
||||
custom_path('diagnostics_settings')) as s:
|
||||
with s.group('monitor diagnostic-settings') as c:
|
||||
c.custom_command('create', 'create_diagnostics_settings')
|
||||
c.command('show', 'get')
|
||||
c.generic_update_command('update', 'get', 'create_or_update', exception_handler=monitor_exception_handler)
|
||||
|
||||
with ServiceGroup(__name__, cf_log_profiles,
|
||||
service_adapter('log_profiles_operations', 'LogProfilesOperations')) as s:
|
||||
with s.group('monitor log-profiles') as c:
|
||||
c.command('create', 'create_or_update')
|
||||
c.command('delete', 'delete')
|
||||
c.command('show', 'get')
|
||||
c.command('list', 'list')
|
||||
c.generic_update_command('update', 'get', 'create_or_update', exception_handler=monitor_exception_handler)
|
||||
|
||||
with ServiceGroup(__name__, cf_metrics, service_adapter('metrics_operations', 'MetricsOperations')) as s:
|
||||
from .transformers import metrics_table
|
||||
|
||||
with s.group('monitor metrics') as c:
|
||||
c.command('list', 'list', table_transformer=metrics_table)
|
||||
|
||||
with ServiceGroup(__name__, cf_metric_def,
|
||||
service_adapter('metric_definitions_operations', 'MetricDefinitionsOperations')) as s:
|
||||
from .transformers import metrics_definitions_table
|
||||
|
||||
with s.group('monitor metrics') as c:
|
||||
c.command('list-definitions', 'list', table_transformer=metrics_definitions_table)
|
||||
|
|
|
@ -1,381 +0,0 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
from __future__ import print_function
|
||||
import datetime
|
||||
import os
|
||||
from azure.cli.core.util import get_file_json, CLIError
|
||||
from azure.mgmt.monitor.models import ConditionOperator, TimeAggregationOperator
|
||||
|
||||
# 1 hour in milliseconds
|
||||
DEFAULT_QUERY_TIME_RANGE = 3600000
|
||||
|
||||
# ISO format with explicit indication of timezone
|
||||
DATE_TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
|
||||
|
||||
# region Alerts
|
||||
|
||||
operator_map = {
|
||||
'>': ConditionOperator.greater_than.value,
|
||||
'>=': ConditionOperator.greater_than_or_equal.value,
|
||||
'<': ConditionOperator.less_than,
|
||||
'<=': ConditionOperator.less_than_or_equal
|
||||
}
|
||||
|
||||
|
||||
aggregation_map = {
|
||||
'avg': TimeAggregationOperator.average.value,
|
||||
'min': TimeAggregationOperator.minimum.value,
|
||||
'max': TimeAggregationOperator.maximum.value,
|
||||
'total': TimeAggregationOperator.total.value,
|
||||
'last': TimeAggregationOperator.last.value
|
||||
}
|
||||
|
||||
|
||||
def _parse_actions(actions):
|
||||
""" Actions come in as a combined list. This method separates the webhook actions into a
|
||||
separate collection and combines any number of email actions into a single email collection
|
||||
and a single value for `email_service_owners`. If any email action contains a True value
|
||||
for `send_to_service_owners` then it is assumed the entire value should be True. """
|
||||
from azure.mgmt.monitor.models import RuleEmailAction, RuleWebhookAction
|
||||
actions = actions or []
|
||||
email_service_owners = None
|
||||
webhooks = [x for x in actions if isinstance(x, RuleWebhookAction)]
|
||||
custom_emails = set()
|
||||
for action in actions:
|
||||
if isinstance(action, RuleEmailAction):
|
||||
if action.send_to_service_owners:
|
||||
email_service_owners = True
|
||||
custom_emails = custom_emails | set(action.custom_emails)
|
||||
return list(custom_emails), webhooks, email_service_owners
|
||||
|
||||
|
||||
def _parse_action_removals(actions):
|
||||
""" Separates the combined list of keys to remove into webhooks and emails. """
|
||||
flattened = list(set([x for sublist in actions for x in sublist]))
|
||||
emails = []
|
||||
webhooks = []
|
||||
for item in flattened:
|
||||
if item.startswith('http://') or item.startswith('https://'):
|
||||
webhooks.append(item)
|
||||
else:
|
||||
emails.append(item)
|
||||
return emails, webhooks
|
||||
|
||||
|
||||
def create_metric_rule(client, resource_group_name, rule_name, target, condition,
|
||||
description=None, disabled=False, location=None, tags=None,
|
||||
email_service_owners=False, actions=None):
|
||||
from azure.mgmt.monitor.models import AlertRuleResource, RuleEmailAction
|
||||
condition.data_source.resource_uri = target
|
||||
custom_emails, webhooks, _ = _parse_actions(actions)
|
||||
actions = [RuleEmailAction(email_service_owners, custom_emails)] + (webhooks or [])
|
||||
rule = AlertRuleResource(location, rule_name, not disabled,
|
||||
condition, tags, description, actions)
|
||||
return client.create_or_update(resource_group_name, rule_name, rule)
|
||||
|
||||
|
||||
def update_metric_rule(instance, target=None, condition=None, description=None, enabled=None,
|
||||
metric=None, operator=None, threshold=None, aggregation=None, period=None,
|
||||
tags=None, email_service_owners=None, add_actions=None, remove_actions=None):
|
||||
# Update general properties
|
||||
if description is not None:
|
||||
instance.description = description
|
||||
if enabled is not None:
|
||||
instance.is_enabled = enabled
|
||||
if tags is not None:
|
||||
instance.tags = tags
|
||||
|
||||
# Update conditions
|
||||
if condition is not None:
|
||||
target = target or instance.condition.data_source.resource_uri
|
||||
instance.condition = condition
|
||||
|
||||
if metric is not None:
|
||||
instance.condition.data_source.metric_name = metric
|
||||
if operator is not None:
|
||||
instance.condition.operator = operator_map[operator]
|
||||
if threshold is not None:
|
||||
instance.condition.threshold = threshold
|
||||
if aggregation is not None:
|
||||
instance.condition.time_aggregation = aggregation_map[aggregation]
|
||||
if period is not None:
|
||||
instance.condition.window_size = period
|
||||
|
||||
if target is not None:
|
||||
instance.condition.data_source.resource_uri = target
|
||||
|
||||
# Update actions
|
||||
emails, webhooks, curr_email_service_owners = _parse_actions(instance.actions)
|
||||
|
||||
# process removals
|
||||
if remove_actions is not None:
|
||||
removed_emails, removed_webhooks = _parse_action_removals(remove_actions)
|
||||
emails = [x for x in emails if x not in removed_emails]
|
||||
webhooks = [x for x in webhooks if x.service_uri not in removed_webhooks]
|
||||
|
||||
# process additions
|
||||
if add_actions is not None:
|
||||
added_emails, added_webhooks, _ = _parse_actions(add_actions)
|
||||
emails = list(set(emails) | set(added_emails))
|
||||
webhooks = webhooks + added_webhooks
|
||||
|
||||
# Replace the existing actions array. This potentially restructures rules that were created
|
||||
# via other methods (Portal, ARM template). However, the functionality of these rules should
|
||||
# be the same.
|
||||
from azure.mgmt.monitor.models import RuleEmailAction
|
||||
if email_service_owners is None:
|
||||
email_service_owners = curr_email_service_owners
|
||||
actions = [RuleEmailAction(email_service_owners, emails)] + webhooks
|
||||
instance.actions = actions
|
||||
|
||||
return instance
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def list_metric_definitions(client, resource, resource_group_name=None, metric_names=None):
|
||||
'''Commands to manage metric definitions.
|
||||
:param str resource_id: The identifier of the resource
|
||||
:param str metric_names: The list of metric names
|
||||
'''
|
||||
odata_filter = _metric_names_filter_builder(metric_names)
|
||||
metric_definitions = client.list(resource, filter=odata_filter)
|
||||
return list(metric_definitions)
|
||||
|
||||
|
||||
def _metric_names_filter_builder(metric_names=None):
|
||||
'''Build up OData filter string from metric_names
|
||||
'''
|
||||
filters = []
|
||||
if metric_names:
|
||||
for metric_name in metric_names:
|
||||
filters.append("name.value eq '{}'".format(metric_name))
|
||||
return ' or '.join(filters)
|
||||
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def list_metrics(client, resource, time_grain, resource_group_name=None,
|
||||
start_time=None, end_time=None, metric_names=None):
|
||||
'''Lists the metric values for a resource.
|
||||
:param str resource_id: The identifier of the resource
|
||||
:param str time_grain: The time grain. Granularity of the metric data returned in ISO 8601
|
||||
duration format, eg "PT1M"
|
||||
:param str start_time: The start time of the query. In ISO format with explicit indication of
|
||||
timezone: 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500. Defaults to
|
||||
1 Hour prior to the current time.
|
||||
:param str end_time: The end time of the query. In ISO format with explicit indication of
|
||||
timezone: 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500. Defaults to
|
||||
current time.
|
||||
:param str metric_names: The space separated list of metric names
|
||||
'''
|
||||
odata_filter = _metrics_odata_filter_builder(time_grain, start_time, end_time, metric_names)
|
||||
metrics = client.list(resource, filter=odata_filter)
|
||||
return list(metrics)
|
||||
|
||||
|
||||
def _metrics_odata_filter_builder(time_grain, start_time=None, end_time=None,
|
||||
metric_names=None):
|
||||
'''Build up OData filter string
|
||||
'''
|
||||
filters = []
|
||||
metrics_filter = _metric_names_filter_builder(metric_names)
|
||||
if metrics_filter:
|
||||
filters.append('({})'.format(metrics_filter))
|
||||
|
||||
if time_grain:
|
||||
filters.append("timeGrain eq duration'{}'".format(time_grain))
|
||||
|
||||
filters.append(_validate_time_range_and_add_defaults(start_time, end_time))
|
||||
return ' and '.join(filters)
|
||||
|
||||
|
||||
def _validate_time_range_and_add_defaults(start_time, end_time,
|
||||
formatter='startTime eq {} and endTime eq {}'):
|
||||
end_time = _validate_end_time(end_time)
|
||||
start_time = _validate_start_time(start_time, end_time)
|
||||
time_range = formatter.format(start_time.strftime('%Y-%m-%dT%H:%M:%SZ'),
|
||||
end_time.strftime('%Y-%m-%dT%H:%M:%SZ'))
|
||||
return time_range
|
||||
|
||||
|
||||
def _validate_end_time(end_time):
|
||||
result_time = datetime.datetime.utcnow()
|
||||
if isinstance(end_time, str):
|
||||
result_time = datetime.datetime.strptime(end_time, DATE_TIME_FORMAT)
|
||||
return result_time
|
||||
|
||||
|
||||
def _validate_start_time(start_time, end_time):
|
||||
if not isinstance(end_time, datetime.datetime):
|
||||
raise ValueError("Input '{}' is not valid datetime. Valid example: 2000-12-31T12:59:59Z"
|
||||
.format(end_time))
|
||||
|
||||
result_time = end_time - datetime.timedelta(seconds=DEFAULT_QUERY_TIME_RANGE)
|
||||
|
||||
if isinstance(start_time, str):
|
||||
result_time = datetime.datetime.strptime(start_time, DATE_TIME_FORMAT)
|
||||
|
||||
now = datetime.datetime.utcnow()
|
||||
if result_time > now:
|
||||
raise ValueError("start_time '{}' is later than Now {}.".format(start_time, now))
|
||||
|
||||
return result_time
|
||||
|
||||
|
||||
def list_activity_log(client, filters=None, correlation_id=None, resource_group=None,
|
||||
resource_id=None, resource_provider=None, start_time=None, end_time=None,
|
||||
caller=None, status=None, max_events=50, select=None):
|
||||
'''Provides the list of activity log.
|
||||
:param str filters: The OData filter for the list activity logs. If this argument is provided
|
||||
OData Filter Arguments will be ignored
|
||||
:param str correlation_id: The correlation id of the query
|
||||
:param str resource_group: The resource group
|
||||
:param str resource_id: The identifier of the resource
|
||||
:param str resource_provider: The resource provider
|
||||
:param str start_time: The start time of the query. In ISO format with explicit indication of
|
||||
timezone: 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500. Defaults to
|
||||
1 Hour prior to the current time.
|
||||
:param str end_time: The end time of the query. In ISO format with explicit indication of
|
||||
timezone: 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500. Defaults to
|
||||
current time.
|
||||
:param str caller: The caller to look for when querying
|
||||
:param str status: The status value to query (ex: Failed)
|
||||
:param str max_events: The maximum number of records to be returned by the command
|
||||
:param str select: The list of event names
|
||||
'''
|
||||
if filters:
|
||||
odata_filters = filters
|
||||
else:
|
||||
collection = [correlation_id, resource_group, resource_id, resource_provider]
|
||||
if not _single(collection):
|
||||
raise CLIError("usage error: [--correlation-id ID | --resource-group NAME | "
|
||||
"--resource-id ID | --resource-provider PROVIDER]")
|
||||
|
||||
odata_filters = _build_activity_log_odata_filter(correlation_id, resource_group,
|
||||
resource_id, resource_provider,
|
||||
start_time, end_time,
|
||||
caller, status)
|
||||
|
||||
if max_events:
|
||||
max_events = int(max_events)
|
||||
|
||||
select_filters = _activity_log_select_filter_builder(select)
|
||||
activity_log = client.list(filter=odata_filters, select=select_filters)
|
||||
return _limit_results(activity_log, max_events)
|
||||
|
||||
|
||||
def _single(collection):
|
||||
return len([x for x in collection if x]) == 1
|
||||
|
||||
|
||||
def _build_activity_log_odata_filter(correlation_id=None, resource_group=None, resource_id=None,
|
||||
resource_provider=None, start_time=None, end_time=None,
|
||||
caller=None, status=None):
|
||||
'''Builds odata filter string.
|
||||
:param str correlation_id: The correlation id of the query
|
||||
:param str resource_group: The resource group
|
||||
:param str resource_id: The identifier of the resource
|
||||
:param str resource_provider: The resource provider
|
||||
:param str start_time: The start time of the query. In ISO format with explicit indication of
|
||||
timezone: 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500
|
||||
:param str end_time: The end time of the query. In ISO format with explicit indication of
|
||||
timezone: 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500.
|
||||
:param str caller: The caller to look for when querying
|
||||
:param str status: The status value to query (ex: Failed)
|
||||
'''
|
||||
formatter = "eventTimestamp ge {} and eventTimestamp le {}"
|
||||
odata_filters = _validate_time_range_and_add_defaults(start_time, end_time,
|
||||
formatter=formatter)
|
||||
|
||||
if correlation_id:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'correlation_id',
|
||||
correlation_id, 'correlationId')
|
||||
elif resource_group:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'resource_group',
|
||||
resource_group, 'resourceGroupName')
|
||||
elif resource_id:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'resource_id',
|
||||
resource_id, 'resourceId')
|
||||
elif resource_provider:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'resource_provider',
|
||||
resource_provider, 'resourceProvider')
|
||||
if caller:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'caller',
|
||||
caller, 'caller')
|
||||
if status:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'status',
|
||||
status, 'status')
|
||||
|
||||
return odata_filters
|
||||
|
||||
|
||||
def _activity_log_select_filter_builder(events=None):
|
||||
'''Build up select filter string from events
|
||||
'''
|
||||
if events:
|
||||
return ' , '.join(events)
|
||||
return None
|
||||
|
||||
|
||||
def _build_odata_filter(default_filter, field_name, field_value, field_label):
|
||||
if not field_value:
|
||||
raise CLIError('Value for {} can not be empty.'.format(field_name))
|
||||
|
||||
return _add_condition(default_filter, field_label, field_value)
|
||||
|
||||
|
||||
def _add_condition(default_filter, field_label, field_value):
|
||||
if not field_value:
|
||||
return default_filter
|
||||
|
||||
return "{} and {} eq '{}'".format(default_filter, field_label, field_value)
|
||||
|
||||
|
||||
def _limit_results(paged, limit):
|
||||
results = []
|
||||
for index, item in enumerate(paged):
|
||||
if index < limit:
|
||||
results.append(item)
|
||||
else:
|
||||
break
|
||||
return list(results)
|
||||
|
||||
|
||||
def scaffold_autoscale_settings_parameters(client): # pylint: disable=unused-argument
|
||||
'''Scaffold fully formed autoscale-settings' parameters as json template
|
||||
'''
|
||||
# Autoscale settings parameter scaffold file path
|
||||
curr_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
autoscale_settings_parameter_file_path = os.path.join(
|
||||
curr_dir, 'autoscale-parameters-template.json')
|
||||
|
||||
return _load_autoscale_settings_parameters(autoscale_settings_parameter_file_path)
|
||||
|
||||
|
||||
def _load_autoscale_settings_parameters(file_path):
|
||||
if not os.path.exists(file_path):
|
||||
raise CLIError('File {} not found.'.format(file_path))
|
||||
|
||||
return get_file_json(file_path)
|
||||
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def create_diagnostics_settings(client, target_resource_id, resource_group=None, logs=None,
|
||||
metrics=None, namespace=None, rule_name=None, tags=None,
|
||||
service_bus_rule_id=None, storage_account=None, workspace=None):
|
||||
from azure.mgmt.monitor.models.service_diagnostic_settings_resource import \
|
||||
ServiceDiagnosticSettingsResource
|
||||
|
||||
# https://github.com/Azure/azure-rest-api-specs/issues/1058
|
||||
parameters = ServiceDiagnosticSettingsResource(location='',
|
||||
storage_account_id=storage_account,
|
||||
service_bus_rule_id=service_bus_rule_id,
|
||||
metrics=metrics,
|
||||
logs=logs,
|
||||
workspace_id=workspace,
|
||||
tags=tags)
|
||||
|
||||
return client.create_or_update(target_resource_id, parameters)
|
|
@ -7,7 +7,7 @@ import argparse
|
|||
import re
|
||||
|
||||
from knack.util import CLIError
|
||||
from azure.cli.command_modules.monitor.custom import operator_map, aggregation_map
|
||||
from ..util import get_aggregation_map, get_operator_map
|
||||
|
||||
|
||||
def period_type(value):
|
||||
|
@ -49,9 +49,9 @@ class ConditionAction(argparse.Action):
|
|||
if len(values) < 5:
|
||||
raise CLIError('usage error: --condition METRIC {>,>=,<,<=} THRESHOLD {avg,min,max,total,last} DURATION')
|
||||
metric_name = ' '.join(values[:-4])
|
||||
operator = operator_map[values[-4]]
|
||||
operator = get_operator_map()[values[-4]]
|
||||
threshold = int(values[-3])
|
||||
aggregation = aggregation_map[values[-2].lower()]
|
||||
aggregation = get_aggregation_map()[values[-2].lower()]
|
||||
window = period_type(values[-1])
|
||||
metric = RuleMetricDataSource(None, metric_name) # target URI will be filled in later
|
||||
condition = ThresholdRuleCondition(operator, threshold, metric, window, aggregation)
|
|
@ -0,0 +1,115 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# 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.core.util import CLIError
|
||||
from ..util import validate_time_range_and_add_defaults
|
||||
|
||||
|
||||
def list_activity_log(client, filters=None, correlation_id=None, resource_group=None, resource_id=None,
|
||||
resource_provider=None, start_time=None, end_time=None, caller=None, status=None, max_events=50,
|
||||
select=None):
|
||||
"""Provides the list of activity log.
|
||||
:param str filters: The OData filter for the list activity logs. If this argument is provided
|
||||
OData Filter Arguments will be ignored
|
||||
:param str correlation_id: The correlation id of the query
|
||||
:param str resource_group: The resource group
|
||||
:param str resource_id: The identifier of the resource
|
||||
:param str resource_provider: The resource provider
|
||||
:param str start_time: The start time of the query. In ISO format with explicit indication of
|
||||
timezone: 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500. Defaults to
|
||||
1 Hour prior to the current time.
|
||||
:param str end_time: The end time of the query. In ISO format with explicit indication of
|
||||
timezone: 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500. Defaults to
|
||||
current time.
|
||||
:param str caller: The caller to look for when querying
|
||||
:param str status: The status value to query (ex: Failed)
|
||||
:param str max_events: The maximum number of records to be returned by the command
|
||||
:param str select: The list of event names
|
||||
"""
|
||||
if filters:
|
||||
odata_filters = filters
|
||||
else:
|
||||
collection = [correlation_id, resource_group, resource_id, resource_provider]
|
||||
if not _single(collection):
|
||||
raise CLIError("usage error: [--correlation-id ID | --resource-group NAME | "
|
||||
"--resource-id ID | --resource-provider PROVIDER]")
|
||||
|
||||
odata_filters = _build_activity_log_odata_filter(correlation_id, resource_group, resource_id, resource_provider,
|
||||
start_time, end_time, caller, status)
|
||||
|
||||
if max_events:
|
||||
max_events = int(max_events)
|
||||
|
||||
select_filters = _activity_log_select_filter_builder(select)
|
||||
activity_log = client.list(filter=odata_filters, select=select_filters)
|
||||
return _limit_results(activity_log, max_events)
|
||||
|
||||
|
||||
def _build_activity_log_odata_filter(correlation_id=None, resource_group=None, resource_id=None, resource_provider=None,
|
||||
start_time=None, end_time=None, caller=None, status=None):
|
||||
"""Builds odata filter string.
|
||||
:param str correlation_id: The correlation id of the query
|
||||
:param str resource_group: The resource group
|
||||
:param str resource_id: The identifier of the resource
|
||||
:param str resource_provider: The resource provider
|
||||
:param str start_time: The start time of the query. In ISO format with explicit indication of
|
||||
timezone: 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500
|
||||
:param str end_time: The end time of the query. In ISO format with explicit indication of
|
||||
timezone: 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500.
|
||||
:param str caller: The caller to look for when querying
|
||||
:param str status: The status value to query (ex: Failed)
|
||||
"""
|
||||
formatter = "eventTimestamp ge {} and eventTimestamp le {}"
|
||||
odata_filters = validate_time_range_and_add_defaults(start_time, end_time, formatter=formatter)
|
||||
|
||||
if correlation_id:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'correlation_id', correlation_id, 'correlationId')
|
||||
elif resource_group:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'resource_group', resource_group, 'resourceGroupName')
|
||||
elif resource_id:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'resource_id', resource_id, 'resourceId')
|
||||
elif resource_provider:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'resource_provider', resource_provider, 'resourceProvider')
|
||||
if caller:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'caller', caller, 'caller')
|
||||
if status:
|
||||
odata_filters = _build_odata_filter(odata_filters, 'status', status, 'status')
|
||||
|
||||
return odata_filters
|
||||
|
||||
|
||||
def _activity_log_select_filter_builder(events=None):
|
||||
"""Build up select filter string from events"""
|
||||
if events:
|
||||
return ' , '.join(events)
|
||||
return None
|
||||
|
||||
|
||||
def _build_odata_filter(default_filter, field_name, field_value, field_label):
|
||||
if not field_value:
|
||||
raise CLIError('Value for {} can not be empty.'.format(field_name))
|
||||
|
||||
return _add_condition(default_filter, field_label, field_value)
|
||||
|
||||
|
||||
def _add_condition(default_filter, field_label, field_value):
|
||||
if not field_value:
|
||||
return default_filter
|
||||
|
||||
return "{} and {} eq '{}'".format(default_filter, field_label, field_value)
|
||||
|
||||
|
||||
def _single(collection):
|
||||
return len([x for x in collection if x]) == 1
|
||||
|
||||
|
||||
def _limit_results(paged, limit):
|
||||
results = []
|
||||
for index, item in enumerate(paged):
|
||||
if index < limit:
|
||||
results.append(item)
|
||||
else:
|
||||
break
|
||||
return list(results)
|
|
@ -0,0 +1,21 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def scaffold_autoscale_settings_parameters(client): # pylint: disable=unused-argument
|
||||
"""Scaffold fully formed autoscale-settings' parameters as json template """
|
||||
|
||||
import os.path
|
||||
from azure.cli.core.util import CLIError, get_file_json
|
||||
|
||||
# Autoscale settings parameter scaffold file path
|
||||
curr_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
autoscale_settings_parameter_file_path = os.path.join(
|
||||
curr_dir, 'autoscale-parameters-template.json')
|
||||
|
||||
if not os.path.exists(autoscale_settings_parameter_file_path):
|
||||
raise CLIError('File {} not found.'.format(autoscale_settings_parameter_file_path))
|
||||
|
||||
return get_file_json(autoscale_settings_parameter_file_path)
|
|
@ -0,0 +1,18 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def create_diagnostics_settings(client, target_resource_id, resource_group=None, logs=None, metrics=None,
|
||||
namespace=None, rule_name=None, tags=None, event_hub_name=None, storage_account=None,
|
||||
workspace=None):
|
||||
from azure.mgmt.monitor.models.diagnostic_settings_resource import DiagnosticSettingsResource
|
||||
|
||||
# https://github.com/Azure/azure-rest-api-specs/issues/1058
|
||||
parameters = DiagnosticSettingsResource(storage_account_id=storage_account,
|
||||
event_hub_name=event_hub_name, metrics=metrics, logs=logs,
|
||||
workspace_id=workspace)
|
||||
|
||||
return client.create_or_update(target_resource_id, parameters)
|
|
@ -0,0 +1,105 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
from ..util import get_operator_map, get_aggregation_map
|
||||
|
||||
|
||||
def create_metric_rule(client, resource_group_name, rule_name, target, condition, description=None, disabled=False,
|
||||
location=None, tags=None, email_service_owners=False, actions=None):
|
||||
from azure.mgmt.monitor.models import AlertRuleResource, RuleEmailAction
|
||||
condition.data_source.resource_uri = target
|
||||
custom_emails, webhooks, _ = _parse_actions(actions)
|
||||
actions = [RuleEmailAction(email_service_owners, custom_emails)] + (webhooks or [])
|
||||
rule = AlertRuleResource(location, rule_name, not disabled, condition, tags, description, actions)
|
||||
return client.create_or_update(resource_group_name, rule_name, rule)
|
||||
|
||||
|
||||
def update_metric_rule(instance, target=None, condition=None, description=None, enabled=None, metric=None,
|
||||
operator=None, threshold=None, aggregation=None, period=None, tags=None,
|
||||
email_service_owners=None, add_actions=None, remove_actions=None):
|
||||
# Update general properties
|
||||
if description is not None:
|
||||
instance.description = description
|
||||
if enabled is not None:
|
||||
instance.is_enabled = enabled
|
||||
if tags is not None:
|
||||
instance.tags = tags
|
||||
|
||||
# Update conditions
|
||||
if condition is not None:
|
||||
target = target or instance.condition.data_source.resource_uri
|
||||
instance.condition = condition
|
||||
|
||||
if metric is not None:
|
||||
instance.condition.data_source.metric_name = metric
|
||||
if operator is not None:
|
||||
instance.condition.operator = get_operator_map()[operator]
|
||||
if threshold is not None:
|
||||
instance.condition.threshold = threshold
|
||||
if aggregation is not None:
|
||||
instance.condition.time_aggregation = get_aggregation_map()[aggregation]
|
||||
if period is not None:
|
||||
instance.condition.window_size = period
|
||||
|
||||
if target is not None:
|
||||
instance.condition.data_source.resource_uri = target
|
||||
|
||||
# Update actions
|
||||
emails, webhooks, curr_email_service_owners = _parse_actions(instance.actions)
|
||||
|
||||
# process removals
|
||||
if remove_actions is not None:
|
||||
removed_emails, removed_webhooks = _parse_action_removals(remove_actions)
|
||||
emails = [x for x in emails if x not in removed_emails]
|
||||
webhooks = [x for x in webhooks if x.service_uri not in removed_webhooks]
|
||||
|
||||
# process additions
|
||||
if add_actions is not None:
|
||||
added_emails, added_webhooks, _ = _parse_actions(add_actions)
|
||||
emails = list(set(emails) | set(added_emails))
|
||||
webhooks = webhooks + added_webhooks
|
||||
|
||||
# Replace the existing actions array. This potentially restructures rules that were created
|
||||
# via other methods (Portal, ARM template). However, the functionality of these rules should
|
||||
# be the same.
|
||||
from azure.mgmt.monitor.models import RuleEmailAction
|
||||
if email_service_owners is None:
|
||||
email_service_owners = curr_email_service_owners
|
||||
actions = [RuleEmailAction(email_service_owners, emails)] + webhooks
|
||||
instance.actions = actions
|
||||
|
||||
return instance
|
||||
|
||||
|
||||
def _parse_actions(actions):
|
||||
""" Actions come in as a combined list. This method separates the webhook actions into a
|
||||
separate collection and combines any number of email actions into a single email collection
|
||||
and a single value for `email_service_owners`. If any email action contains a True value
|
||||
for `send_to_service_owners` then it is assumed the entire value should be True. """
|
||||
from azure.mgmt.monitor.models import RuleEmailAction, RuleWebhookAction
|
||||
actions = actions or []
|
||||
email_service_owners = None
|
||||
webhooks = [x for x in actions if isinstance(x, RuleWebhookAction)]
|
||||
custom_emails = set()
|
||||
for action in actions:
|
||||
if isinstance(action, RuleEmailAction):
|
||||
if action.send_to_service_owners:
|
||||
email_service_owners = True
|
||||
custom_emails = custom_emails | set(action.custom_emails)
|
||||
return list(custom_emails), webhooks, email_service_owners
|
||||
|
||||
|
||||
def _parse_action_removals(actions):
|
||||
""" Separates the combined list of keys to remove into webhooks and emails. """
|
||||
flattened = list(set([x for sublist in actions for x in sublist]))
|
||||
emails = []
|
||||
webhooks = []
|
||||
for item in flattened:
|
||||
if item.startswith('http://') or item.startswith('https://'):
|
||||
webhooks.append(item)
|
||||
else:
|
||||
emails.append(item)
|
||||
return emails, webhooks
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -8,9 +8,9 @@ interactions:
|
|||
Connection: [keep-alive]
|
||||
Content-Length: ['58']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 resourcemanagementclient/1.2.0rc3 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 resourcemanagementclient/1.2.1 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: PUT
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001?api-version=2017-05-10
|
||||
|
@ -20,11 +20,11 @@ interactions:
|
|||
cache-control: [no-cache]
|
||||
content-length: ['336']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:14 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:18 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1198']
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1199']
|
||||
status: {code: 201, message: Created}
|
||||
- request:
|
||||
body: '{"location": "global", "properties": {"groupShortName": "cliactiongro",
|
||||
|
@ -37,24 +37,23 @@ interactions:
|
|||
Connection: [keep-alive]
|
||||
Content-Length: ['155']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: PUT
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002?api-version=2017-04-01
|
||||
response:
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":null,"properties":{"groupShortName":"cliactiongro","enabled":true,"emailReceivers":[],"smsReceivers":[],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[]},"identity":null}'}
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":null,"properties":{"groupShortName":"cliactiongro","enabled":true,"emailReceivers":[],"smsReceivers":[],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[],"automationRunbookReceivers":[]},"identity":null}'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['537']
|
||||
content-length: ['569']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:15 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:20 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1198']
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1199']
|
||||
status: {code: 201, message: Created}
|
||||
- request:
|
||||
body: null
|
||||
|
@ -64,19 +63,18 @@ interactions:
|
|||
CommandName: [monitor action-group list]
|
||||
Connection: [keep-alive]
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: GET
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups?api-version=2017-04-01
|
||||
response:
|
||||
body: {string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":null,"properties":{"groupShortName":"cliactiongro","enabled":true,"emailReceivers":[],"smsReceivers":[],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[]},"identity":null}]}'}
|
||||
body: {string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":null,"properties":{"groupShortName":"cliactiongro","enabled":true,"emailReceivers":[],"smsReceivers":[],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[],"automationRunbookReceivers":[]},"identity":null}]}'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['549']
|
||||
content-length: ['581']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:16 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:20 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
|
@ -92,19 +90,18 @@ interactions:
|
|||
CommandName: [monitor action-group update]
|
||||
Connection: [keep-alive]
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: GET
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002?api-version=2017-04-01
|
||||
response:
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":null,"properties":{"groupShortName":"cliactiongro","enabled":true,"emailReceivers":[],"smsReceivers":[],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[]},"identity":null}'}
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":null,"properties":{"groupShortName":"cliactiongro","enabled":true,"emailReceivers":[],"smsReceivers":[],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[],"automationRunbookReceivers":[]},"identity":null}'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['537']
|
||||
content-length: ['569']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:17 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:21 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
|
@ -123,19 +120,18 @@ interactions:
|
|||
Connection: [keep-alive]
|
||||
Content-Length: ['179']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: PUT
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002?api-version=2017-04-01
|
||||
response:
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":{"owner":"alice"},"properties":{"groupShortName":"new_name","enabled":true,"emailReceivers":[],"smsReceivers":[],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[]},"identity":null}'}
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":{"owner":"alice"},"properties":{"groupShortName":"new_name","enabled":true,"emailReceivers":[],"smsReceivers":[],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[],"automationRunbookReceivers":[]},"identity":null}'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['546']
|
||||
content-length: ['578']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:19 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:23 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
|
@ -152,19 +148,18 @@ interactions:
|
|||
CommandName: [monitor action-group update]
|
||||
Connection: [keep-alive]
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: GET
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002?api-version=2017-04-01
|
||||
response:
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":null,"properties":{"groupShortName":"cliactiongro","enabled":true,"emailReceivers":[],"smsReceivers":[],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[]},"identity":null}'}
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":{"owner":"alice"},"properties":{"groupShortName":"new_name","enabled":true,"emailReceivers":[],"smsReceivers":[],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[],"automationRunbookReceivers":[]},"identity":null}'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['537']
|
||||
content-length: ['578']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:19 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:23 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
|
@ -173,37 +168,37 @@ interactions:
|
|||
vary: [Accept-Encoding]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: '{"location": "Global", "properties": {"groupShortName": "cliactiongro",
|
||||
"enabled": true, "emailReceivers": [{"name": "alice", "emailAddress": "alice@example.com"}],
|
||||
"smsReceivers": [{"name": "alice_sms", "countryCode": "1", "phoneNumber": "5551234567"}],
|
||||
"webhookReceivers": [{"name": "alice_web", "serviceUri": "https://www.example.com/alert?name=alice"}]}}'
|
||||
body: '{"location": "Global", "tags": {"owner": "alice"}, "properties": {"groupShortName":
|
||||
"new_name", "enabled": true, "emailReceivers": [{"name": "alice", "emailAddress":
|
||||
"alice@example.com"}], "smsReceivers": [{"name": "alice_sms", "countryCode":
|
||||
"1", "phoneNumber": "5551234567"}], "webhookReceivers": [{"name": "alice_web",
|
||||
"serviceUri": "https://www.example.com/alert?name=alice"}]}}'
|
||||
headers:
|
||||
Accept: [application/json]
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
CommandName: [monitor action-group update]
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['358']
|
||||
Content-Length: ['382']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: PUT
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002?api-version=2017-04-01
|
||||
response:
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":null,"properties":{"groupShortName":"cliactiongro","enabled":true,"emailReceivers":[{"name":"alice","emailAddress":"alice@example.com","status":"Enabled"}],"smsReceivers":[{"name":"alice_sms","countryCode":"1","phoneNumber":"5551234567","status":"Enabled"}],"webhookReceivers":[{"name":"alice_web","serviceUri":"https://www.example.com/alert?name=alice"}],"itsmReceivers":[],"azureAppPushReceivers":[]},"identity":null}'}
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":{"owner":"alice"},"properties":{"groupShortName":"new_name","enabled":true,"emailReceivers":[{"name":"alice","emailAddress":"alice@example.com","status":"Enabled"}],"smsReceivers":[{"name":"alice_sms","countryCode":"1","phoneNumber":"5551234567","status":"Enabled"}],"webhookReceivers":[{"name":"alice_web","serviceUri":"https://www.example.com/alert?name=alice"}],"itsmReceivers":[],"azureAppPushReceivers":[],"automationRunbookReceivers":[]},"identity":null}'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['767']
|
||||
content-length: ['808']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:22 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:25 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
transfer-encoding: [chunked]
|
||||
vary: [Accept-Encoding]
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1198']
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1199']
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
|
@ -213,19 +208,18 @@ interactions:
|
|||
CommandName: [monitor action-group update]
|
||||
Connection: [keep-alive]
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: GET
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002?api-version=2017-04-01
|
||||
response:
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":null,"properties":{"groupShortName":"cliactiongro","enabled":true,"emailReceivers":[{"name":"alice","emailAddress":"alice@example.com","status":"Enabled"}],"smsReceivers":[{"name":"alice_sms","countryCode":"1","phoneNumber":"5551234567","status":"Enabled"}],"webhookReceivers":[{"name":"alice_web","serviceUri":"https://www.example.com/alert?name=alice"}],"itsmReceivers":[],"azureAppPushReceivers":[]},"identity":null}'}
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":{"owner":"alice"},"properties":{"groupShortName":"new_name","enabled":true,"emailReceivers":[{"name":"alice","emailAddress":"alice@example.com","status":"Enabled"}],"smsReceivers":[{"name":"alice_sms","countryCode":"1","phoneNumber":"5551234567","status":"Enabled"}],"webhookReceivers":[{"name":"alice_web","serviceUri":"https://www.example.com/alert?name=alice"}],"itsmReceivers":[],"azureAppPushReceivers":[],"automationRunbookReceivers":[]},"identity":null}'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['767']
|
||||
content-length: ['808']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:23 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:25 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
|
@ -234,30 +228,29 @@ interactions:
|
|||
vary: [Accept-Encoding]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: '{"location": "Global", "properties": {"groupShortName": "cliactiongro",
|
||||
"enabled": true, "emailReceivers": [{"name": "alice", "emailAddress": "alice@example.com"}],
|
||||
"smsReceivers": [{"name": "alice_sms", "countryCode": "1", "phoneNumber": "5551234567"}],
|
||||
"webhookReceivers": []}}'
|
||||
body: '{"location": "Global", "tags": {"owner": "alice"}, "properties": {"groupShortName":
|
||||
"new_name", "enabled": true, "emailReceivers": [{"name": "alice", "emailAddress":
|
||||
"alice@example.com"}], "smsReceivers": [{"name": "alice_sms", "countryCode":
|
||||
"1", "phoneNumber": "5551234567"}], "webhookReceivers": []}}'
|
||||
headers:
|
||||
Accept: [application/json]
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
CommandName: [monitor action-group update]
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['279']
|
||||
Content-Length: ['303']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: PUT
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002?api-version=2017-04-01
|
||||
response:
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":null,"properties":{"groupShortName":"cliactiongro","enabled":true,"emailReceivers":[{"name":"alice","emailAddress":"alice@example.com","status":"Enabled"}],"smsReceivers":[{"name":"alice_sms","countryCode":"1","phoneNumber":"5551234567","status":"Enabled"}],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[]},"identity":null}'}
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002","type":"Microsoft.Insights/ActionGroups","name":"cliactiongrouptest000002","location":"Global","kind":null,"tags":{"owner":"alice"},"properties":{"groupShortName":"new_name","enabled":true,"emailReceivers":[{"name":"alice","emailAddress":"alice@example.com","status":"Enabled"}],"smsReceivers":[{"name":"alice_sms","countryCode":"1","phoneNumber":"5551234567","status":"Enabled"}],"webhookReceivers":[],"itsmReceivers":[],"azureAppPushReceivers":[],"automationRunbookReceivers":[]},"identity":null}'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['691']
|
||||
content-length: ['732']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:23 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:27 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
|
@ -275,9 +268,8 @@ interactions:
|
|||
Connection: [keep-alive]
|
||||
Content-Length: ['28']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: POST
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002/subscribe?api-version=2017-04-01
|
||||
|
@ -287,12 +279,12 @@ interactions:
|
|||
cache-control: [no-cache]
|
||||
content-length: ['42']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:25 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:27 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1196']
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1198']
|
||||
status: {code: 404, message: Not Found}
|
||||
- request:
|
||||
body: '{"receiverName": "alice"}'
|
||||
|
@ -303,9 +295,8 @@ interactions:
|
|||
Connection: [keep-alive]
|
||||
Content-Length: ['25']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: POST
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002/subscribe?api-version=2017-04-01
|
||||
|
@ -315,12 +306,12 @@ interactions:
|
|||
cache-control: [no-cache]
|
||||
content-length: ['48']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:25 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:28 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1195']
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1199']
|
||||
status: {code: 409, message: Conflict}
|
||||
- request:
|
||||
body: null
|
||||
|
@ -331,9 +322,8 @@ interactions:
|
|||
Connection: [keep-alive]
|
||||
Content-Length: ['0']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: DELETE
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups/cliactiongrouptest000002?api-version=2017-04-01
|
||||
|
@ -342,7 +332,7 @@ interactions:
|
|||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['0']
|
||||
date: ['Mon, 16 Oct 2017 18:10:26 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:30 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
|
@ -357,9 +347,8 @@ interactions:
|
|||
CommandName: [monitor action-group list]
|
||||
Connection: [keep-alive]
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 monitormanagementclient/0.3.0 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: GET
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/microsoft.insights/actionGroups?api-version=2017-04-01
|
||||
|
@ -369,7 +358,7 @@ interactions:
|
|||
cache-control: [no-cache]
|
||||
content-length: ['12']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 16 Oct 2017 18:10:28 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:31 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-IIS/8.5]
|
||||
|
@ -386,9 +375,9 @@ interactions:
|
|||
Connection: [keep-alive]
|
||||
Content-Length: ['0']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.2 (Darwin-16.7.0-x86_64-i386-64bit) requests/2.18.4
|
||||
msrest/0.4.16 msrest_azure/0.4.14 resourcemanagementclient/1.2.0rc3 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.18+dev]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.19
|
||||
msrest_azure/0.4.17 resourcemanagementclient/1.2.1 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.22]
|
||||
accept-language: [en-US]
|
||||
method: DELETE
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001?api-version=2017-05-10
|
||||
|
@ -397,9 +386,9 @@ interactions:
|
|||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['0']
|
||||
date: ['Mon, 16 Oct 2017 18:10:29 GMT']
|
||||
date: ['Sun, 26 Nov 2017 05:21:32 GMT']
|
||||
expires: ['-1']
|
||||
location: ['https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/operationresults/eyJqb2JJZCI6IlJFU09VUkNFR1JPVVBERUxFVElPTkpPQi1DTElURVNUOjJFUkdWM1hKSkJJUEVTTzZZUzZaTFpGNjU1VDZMRENBM0ZBUjZXRHxCNjc1NDE1N0VDN0Y2RUM4LVNPVVRIQ0VOVFJBTFVTIiwiam9iTG9jYXRpb24iOiJzb3V0aGNlbnRyYWx1cyJ9?api-version=2017-05-10']
|
||||
location: ['https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/operationresults/eyJqb2JJZCI6IlJFU09VUkNFR1JPVVBERUxFVElPTkpPQi1DTElURVNUOjJFUkc2UVlDUFdNTUhLVFJOVFI3WDQyQkFXTllDRVBSU0FTNU9IT3xGQkUzQjI0NTc0NzYyQTE3LVNPVVRIQ0VOVFJBTFVTIiwiam9iTG9jYXRpb24iOiJzb3V0aGNlbnRyYWx1cyJ9?api-version=2017-05-10']
|
||||
pragma: [no-cache]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1198']
|
||||
|
|
|
@ -0,0 +1,235 @@
|
|||
interactions:
|
||||
- request:
|
||||
body: '{"location": "southcentralus", "tags": {"use": "az-test"}}'
|
||||
headers:
|
||||
Accept: [application/json]
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
CommandName: [group create]
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['58']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.18
|
||||
msrest_azure/0.4.16 resourcemanagementclient/1.2.1 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.21]
|
||||
accept-language: [en-US]
|
||||
method: PUT
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001?api-version=2017-05-10
|
||||
response:
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001","name":"clitest.rg000001","location":"southcentralus","tags":{"use":"az-test"},"properties":{"provisioningState":"Succeeded"}}'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['336']
|
||||
content-type: [application/json; charset=utf-8]
|
||||
date: ['Mon, 13 Nov 2017 18:22:01 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: '{"sku": {"name": "Standard_LRS"}, "kind": "Storage", "location": "westus",
|
||||
"properties": {"supportsHttpsTrafficOnly": false}}'
|
||||
headers:
|
||||
Accept: [application/json]
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
CommandName: [storage account create]
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['125']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.18
|
||||
msrest_azure/0.4.16 storagemanagementclient/1.4.0 Azure-SDK-For-Python AZURECLI/2.0.21]
|
||||
accept-language: [en-US]
|
||||
method: PUT
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002?api-version=2017-06-01
|
||||
response:
|
||||
body: {string: ''}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['0']
|
||||
date: ['Mon, 13 Nov 2017 18:22:12 GMT']
|
||||
expires: ['-1']
|
||||
location: ['https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Storage/locations/westus/asyncoperations/b3183cfc-8f5e-4304-8422-924e23aaa1e4?monitor=true&api-version=2017-06-01']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-Azure-Storage-Resource-Provider/1.0, Microsoft-HTTPAPI/2.0]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1199']
|
||||
status: {code: 202, message: Accepted}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: [application/json]
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
CommandName: [storage account create]
|
||||
Connection: [keep-alive]
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.18
|
||||
msrest_azure/0.4.16 storagemanagementclient/1.4.0 Azure-SDK-For-Python AZURECLI/2.0.21]
|
||||
accept-language: [en-US]
|
||||
method: GET
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Storage/locations/westus/asyncoperations/b3183cfc-8f5e-4304-8422-924e23aaa1e4?monitor=true&api-version=2017-06-01
|
||||
response:
|
||||
body: {string: ''}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['0']
|
||||
date: ['Mon, 13 Nov 2017 18:22:30 GMT']
|
||||
expires: ['-1']
|
||||
location: ['https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Storage/locations/westus/asyncoperations/b3183cfc-8f5e-4304-8422-924e23aaa1e4?monitor=true&api-version=2017-06-01']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-Azure-Storage-Resource-Provider/1.0, Microsoft-HTTPAPI/2.0]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
status: {code: 202, message: Accepted}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: [application/json]
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
CommandName: [storage account create]
|
||||
Connection: [keep-alive]
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.18
|
||||
msrest_azure/0.4.16 storagemanagementclient/1.4.0 Azure-SDK-For-Python AZURECLI/2.0.21]
|
||||
accept-language: [en-US]
|
||||
method: GET
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Storage/locations/westus/asyncoperations/b3183cfc-8f5e-4304-8422-924e23aaa1e4?monitor=true&api-version=2017-06-01
|
||||
response:
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","kind":"Storage","location":"westus","name":"clitest000002","properties":{"creationTime":"2017-11-13T18:22:03.5722474Z","encryption":{"keySource":"Microsoft.Storage","services":{"blob":{"enabled":true,"lastEnabledTime":"2017-11-13T18:22:03.6042322Z"},"file":{"enabled":true,"lastEnabledTime":"2017-11-13T18:22:03.6042322Z"}}},"networkAcls":{"bypass":"AzureServices","defaultAction":"Allow","ipRules":[],"virtualNetworkRules":[]},"primaryEndpoints":{"blob":"https://clitest000002.blob.core.windows.net/","file":"https://clitest000002.file.core.windows.net/","queue":"https://clitest000002.queue.core.windows.net/","table":"https://clitest000002.table.core.windows.net/"},"primaryLocation":"westus","provisioningState":"Succeeded","statusOfPrimary":"available","supportsHttpsTrafficOnly":false},"sku":{"name":"Standard_LRS","tier":"Standard"},"tags":{},"type":"Microsoft.Storage/storageAccounts"}
|
||||
|
||||
'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['1170']
|
||||
content-type: [application/json]
|
||||
date: ['Mon, 13 Nov 2017 18:22:47 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-Azure-Storage-Resource-Provider/1.0, Microsoft-HTTPAPI/2.0]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
transfer-encoding: [chunked]
|
||||
vary: [Accept-Encoding]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: [application/json]
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
CommandName: [storage account keys list]
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['0']
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.18
|
||||
msrest_azure/0.4.16 storagemanagementclient/1.4.0 Azure-SDK-For-Python AZURECLI/2.0.21]
|
||||
accept-language: [en-US]
|
||||
method: POST
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/listKeys?api-version=2017-06-01
|
||||
response:
|
||||
body: {string: '{"keys":[{"keyName":"key1","permissions":"Full","value":"tWFFM0SVLoJRYFzziPGs42xP3wkTPYaoA98xRLOQkKpnY+dFZF22vCU9YOR+NvjIUYjBJP6+CX/hDXuri4W+WQ=="},{"keyName":"key2","permissions":"Full","value":"82ki0XUSk2uT5R4g16VA8bowLwu91yqr7mP3kb9oXb7vAPJGHzttx9is9cVqLvoX3LJfz4dZIRnWcPZclJFEaw=="}]}
|
||||
|
||||
'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['289']
|
||||
content-type: [application/json]
|
||||
date: ['Mon, 13 Nov 2017 18:22:49 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-Azure-Storage-Resource-Provider/1.0, Microsoft-HTTPAPI/2.0]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
transfer-encoding: [chunked]
|
||||
vary: [Accept-Encoding]
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1199']
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: [application/json]
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
CommandName: [storage account show]
|
||||
Connection: [keep-alive]
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.18
|
||||
msrest_azure/0.4.16 storagemanagementclient/1.4.0 Azure-SDK-For-Python AZURECLI/2.0.21]
|
||||
accept-language: [en-US]
|
||||
method: GET
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002?api-version=2017-06-01
|
||||
response:
|
||||
body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","kind":"Storage","location":"westus","name":"clitest000002","properties":{"creationTime":"2017-11-13T18:22:03.5722474Z","encryption":{"keySource":"Microsoft.Storage","services":{"blob":{"enabled":true,"lastEnabledTime":"2017-11-13T18:22:03.6042322Z"},"file":{"enabled":true,"lastEnabledTime":"2017-11-13T18:22:03.6042322Z"}}},"networkAcls":{"bypass":"AzureServices","defaultAction":"Allow","ipRules":[],"virtualNetworkRules":[]},"primaryEndpoints":{"blob":"https://clitest000002.blob.core.windows.net/","file":"https://clitest000002.file.core.windows.net/","queue":"https://clitest000002.queue.core.windows.net/","table":"https://clitest000002.table.core.windows.net/"},"primaryLocation":"westus","provisioningState":"Succeeded","statusOfPrimary":"available","supportsHttpsTrafficOnly":false},"sku":{"name":"Standard_LRS","tier":"Standard"},"tags":{},"type":"Microsoft.Storage/storageAccounts"}
|
||||
|
||||
'}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['1170']
|
||||
content-type: [application/json]
|
||||
date: ['Mon, 13 Nov 2017 18:22:49 GMT']
|
||||
expires: ['-1']
|
||||
pragma: [no-cache]
|
||||
server: [Microsoft-Azure-Storage-Resource-Provider/1.0, Microsoft-HTTPAPI/2.0]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
transfer-encoding: [chunked]
|
||||
vary: [Accept-Encoding]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: [application/json]
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
CommandName: [monitor metrics list-definitions]
|
||||
Connection: [keep-alive]
|
||||
Content-Type: [application/json; charset=utf-8]
|
||||
User-Agent: [python/3.6.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.18
|
||||
msrest_azure/0.4.16 monitormanagementclient/0.4.0 Azure-SDK-For-Python AZURECLI/2.0.21]
|
||||
accept-language: [en-US]
|
||||
method: GET
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricDefinitions?api-version=2017-05-01-preview
|
||||
response:
|
||||
body: {string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricdefinitions/UsedCapacity","resourceId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","category":"Capacity","name":{"value":"UsedCapacity","localizedValue":"Used
|
||||
capacity"},"isDimensionRequired":false,"unit":"Bytes","primaryAggregationType":"Average","metricAvailabilities":[{"timeGrain":"PT1M","retention":"P93D"},{"timeGrain":"PT1H","retention":"P93D"}]},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricdefinitions/Transactions","resourceId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","category":"Transaction","name":{"value":"Transactions","localizedValue":"Transactions"},"isDimensionRequired":false,"unit":"Count","primaryAggregationType":"Total","metricAvailabilities":[{"timeGrain":"PT1M","retention":"P93D"},{"timeGrain":"PT1H","retention":"P93D"}],"dimensions":[{"value":"ResponseType","localizedValue":"Response
|
||||
type"},{"value":"GeoType","localizedValue":"Geo type"},{"value":"ApiName","localizedValue":"API
|
||||
name"}]},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricdefinitions/Ingress","resourceId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","category":"Transaction","name":{"value":"Ingress","localizedValue":"Ingress"},"isDimensionRequired":false,"unit":"Bytes","primaryAggregationType":"Total","metricAvailabilities":[{"timeGrain":"PT1M","retention":"P93D"},{"timeGrain":"PT1H","retention":"P93D"}],"dimensions":[{"value":"GeoType","localizedValue":"Geo
|
||||
type"},{"value":"ApiName","localizedValue":"API name"}]},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricdefinitions/Egress","resourceId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","category":"Transaction","name":{"value":"Egress","localizedValue":"Egress"},"isDimensionRequired":false,"unit":"Bytes","primaryAggregationType":"Total","metricAvailabilities":[{"timeGrain":"PT1M","retention":"P93D"},{"timeGrain":"PT1H","retention":"P93D"}],"dimensions":[{"value":"GeoType","localizedValue":"Geo
|
||||
type"},{"value":"ApiName","localizedValue":"API name"}]},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricdefinitions/SuccessServerLatency","resourceId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","category":"Transaction","name":{"value":"SuccessServerLatency","localizedValue":"Success
|
||||
Server Latency"},"isDimensionRequired":false,"unit":"MilliSeconds","primaryAggregationType":"Average","metricAvailabilities":[{"timeGrain":"PT1M","retention":"P93D"},{"timeGrain":"PT1H","retention":"P93D"}],"dimensions":[{"value":"GeoType","localizedValue":"Geo
|
||||
type"},{"value":"ApiName","localizedValue":"API name"}]},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricdefinitions/SuccessE2ELatency","resourceId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","category":"Transaction","name":{"value":"SuccessE2ELatency","localizedValue":"Success
|
||||
E2E Latency"},"isDimensionRequired":false,"unit":"MilliSeconds","primaryAggregationType":"Average","metricAvailabilities":[{"timeGrain":"PT1M","retention":"P93D"},{"timeGrain":"PT1H","retention":"P93D"}],"dimensions":[{"value":"GeoType","localizedValue":"Geo
|
||||
type"},{"value":"ApiName","localizedValue":"API name"}]},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricdefinitions/Availability","resourceId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","category":"Transaction","name":{"value":"Availability","localizedValue":"Availability"},"isDimensionRequired":false,"unit":"Percent","primaryAggregationType":"Average","metricAvailabilities":[{"timeGrain":"PT1M","retention":"P93D"},{"timeGrain":"PT1H","retention":"P93D"}],"dimensions":[{"value":"GeoType","localizedValue":"Geo
|
||||
type"},{"value":"ApiName","localizedValue":"API name"}]}]}'}
|
||||
headers:
|
||||
__handlingserverid__: [shoeboxproxyprod_shoeboxproxyprod-black_MetricsMP_IN_6]
|
||||
cache-control: [no-cache]
|
||||
content-length: ['6213']
|
||||
content-type: [application/json]
|
||||
date: ['Mon, 13 Nov 2017 18:22:49 GMT']
|
||||
server: [Microsoft-IIS/8.5]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
transfer-encoding: [chunked]
|
||||
vary: ['Accept-Encoding,Accept-Encoding']
|
||||
x-powered-by: [ASP.NET]
|
||||
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.3 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.18
|
||||
msrest_azure/0.4.16 resourcemanagementclient/1.2.1 Azure-SDK-For-Python
|
||||
AZURECLI/2.0.21]
|
||||
accept-language: [en-US]
|
||||
method: DELETE
|
||||
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001?api-version=2017-05-10
|
||||
response:
|
||||
body: {string: ''}
|
||||
headers:
|
||||
cache-control: [no-cache]
|
||||
content-length: ['0']
|
||||
date: ['Mon, 13 Nov 2017 18:22:51 GMT']
|
||||
expires: ['-1']
|
||||
location: ['https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/operationresults/eyJqb2JJZCI6IlJFU09VUkNFR1JPVVBERUxFVElPTkpPQi1DTElURVNUOjJFUkdUTk5SV1c2NjNTTUlaNUhVMkFDTEtCNEhTNjczWjRRN0tCV3xBOEI1NDJGMjk3OEQ1Rjk2LVNPVVRIQ0VOVFJBTFVTIiwiam9iTG9jYXRpb24iOiJzb3V0aGNlbnRyYWx1cyJ9?api-version=2017-05-10']
|
||||
pragma: [no-cache]
|
||||
strict-transport-security: [max-age=31536000; includeSubDomains]
|
||||
x-ms-ratelimit-remaining-subscription-writes: ['1199']
|
||||
status: {code: 202, message: Accepted}
|
||||
version: 1
|
|
@ -0,0 +1,70 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
import unittest
|
||||
import re
|
||||
from azure.cli.core.util import CLIError
|
||||
from azure.cli.command_modules.monitor.operations.activity_log import (_build_activity_log_odata_filter,
|
||||
_activity_log_select_filter_builder,
|
||||
_build_odata_filter)
|
||||
|
||||
|
||||
class TestActivityLogODataBuilderComponents(unittest.TestCase):
|
||||
def test_build_activity_logs_odata_filter(self):
|
||||
correlation_id = '1234-34567-56789-34567'
|
||||
resource_group = 'test'
|
||||
resource_id = '/subscriptions/xxxx-xxxx-xxxx-xxx/resourceGroups/testrg/providers/Microsoft.Web/sites/testwebapp'
|
||||
resource_provider = 'Microsoft.Web'
|
||||
caller = 'contoso@contoso.com'
|
||||
status = 'RunsSucceeded'
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(correlation_id)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(correlationId eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(resource_group=resource_group)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(resourceGroupName eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(resource_id=resource_id)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(resourceId eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(resource_provider=resource_provider)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(resourceProvider eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(caller=caller)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(caller eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(status=status)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(status eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
def test_activity_logs_select_filter_builder(self):
|
||||
select_output = _activity_log_select_filter_builder()
|
||||
assert select_output is None
|
||||
|
||||
events = ['channels']
|
||||
select_output = _activity_log_select_filter_builder(events)
|
||||
assert select_output == '{}'.format(events[0])
|
||||
|
||||
events = ['eventDataId', 'eventSource']
|
||||
select_output = _activity_log_select_filter_builder(events)
|
||||
assert select_output == '{} , {}'.format(events[0], events[1])
|
||||
|
||||
def test_build_odata_filter(self):
|
||||
default_filter = "timeGrain eq duration'PT1M'"
|
||||
field_name = 'correlation_id'
|
||||
field_value = '1234-34567-56789-34567'
|
||||
field_label = 'correlationId'
|
||||
|
||||
filter_output = _build_odata_filter(default_filter, field_name, field_value, field_label)
|
||||
regex = r'^({} and {} eq \'{}\')$'.format(default_filter, field_label, field_value)
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
with self.assertRaises(CLIError):
|
||||
_build_odata_filter(default_filter, field_name, None, field_label)
|
|
@ -0,0 +1,23 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
from time import sleep
|
||||
from azure.cli.testsdk import LiveScenarioTest, ResourceGroupPreparer, StorageAccountPreparer
|
||||
|
||||
|
||||
# This is a live test because the start and end time can't be determined dynamically
|
||||
class TestActivityLogScenarios(LiveScenarioTest):
|
||||
@ResourceGroupPreparer(location='southcentralus')
|
||||
@StorageAccountPreparer()
|
||||
def test_activity_log_list_scenario(self, resource_group):
|
||||
|
||||
for count in range(3):
|
||||
logs = self.cmd('monitor activity-log list --resource-group {}'.format(resource_group)).get_output_in_json()
|
||||
if len(logs) > 0:
|
||||
break
|
||||
|
||||
sleep(2 ** count) # Wait 1, 2, and 4 seconds incrementally to let the activity log catch up.
|
||||
else:
|
||||
self.assertTrue(False, 'After three try the command fails to retrieve any activity log.')
|
|
@ -1,175 +0,0 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
import unittest
|
||||
try:
|
||||
import unittest.mock as mock
|
||||
except ImportError:
|
||||
import mock
|
||||
import re
|
||||
from knack.util import CLIError
|
||||
from azure.cli.command_modules.monitor.custom import (_metric_names_filter_builder,
|
||||
_metrics_odata_filter_builder,
|
||||
_build_activity_log_odata_filter,
|
||||
_activity_log_select_filter_builder,
|
||||
_build_odata_filter,
|
||||
scaffold_autoscale_settings_parameters)
|
||||
|
||||
|
||||
class FilterBuilderTests(unittest.TestCase):
|
||||
|
||||
def test_metric_names_filter_builder(self):
|
||||
metric_names = None
|
||||
filter_output = _metric_names_filter_builder(metric_names)
|
||||
assert filter_output == ''
|
||||
|
||||
metric_names = ['ActionsCompleted']
|
||||
filter_output = _metric_names_filter_builder(metric_names)
|
||||
assert filter_output == "name.value eq '{}'".format(metric_names[0])
|
||||
|
||||
metric_names = ['RunsSucceeded', 'ActionsCompleted']
|
||||
filter_output = _metric_names_filter_builder(metric_names)
|
||||
assert filter_output == 'name.value eq \'{}\' or name.value eq \'{}\''.format(
|
||||
metric_names[0], metric_names[1])
|
||||
|
||||
def test_metrics_odata_filter_builder(self):
|
||||
filter_output = _metrics_odata_filter_builder('PT1M')
|
||||
regex = r'^(timeGrain eq duration).*(startTime eq).*(endTime eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _metrics_odata_filter_builder('PT1M', '1970-01-01T00:00:00Z')
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _metrics_odata_filter_builder('PT1M', end_time='1970-01-01T00:00:00Z')
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
metric_names = ['ActionsCompleted']
|
||||
regex = r'^(\(name.value eq).*(timeGrain eq duration).*(startTime eq).*(endTime eq).*$'
|
||||
filter_output = _metrics_odata_filter_builder('PT1M', metric_names=metric_names)
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
def test_build_activity_logs_odata_filter(self):
|
||||
correlation_id = '1234-34567-56789-34567'
|
||||
resource_group = 'test'
|
||||
resource_id = '/subscriptions/xxxx-xxxx-xxxx-xxx/resourceGroups/testrg/providers/' \
|
||||
'Microsoft.Web/sites/testwebapp'
|
||||
resource_provider = 'Microsoft.Web'
|
||||
caller = 'contoso@contoso.com'
|
||||
status = 'RunsSucceeded'
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(correlation_id)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(correlationId eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(resource_group=resource_group)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(resourceGroupName eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(resource_id=resource_id)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(resourceId eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(resource_provider=resource_provider)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(resourceProvider eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(caller=caller)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(caller eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
filter_output = _build_activity_log_odata_filter(status=status)
|
||||
regex = r'^(eventTimestamp ge).*(eventTimestamp le).*(status eq).*$'
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
def test_activity_logs_select_filter_builder(self):
|
||||
select_output = _activity_log_select_filter_builder()
|
||||
assert select_output is None
|
||||
|
||||
events = ['channels']
|
||||
select_output = _activity_log_select_filter_builder(events)
|
||||
assert select_output == '{}'.format(events[0])
|
||||
|
||||
events = ['eventDataId', 'eventSource']
|
||||
select_output = _activity_log_select_filter_builder(events)
|
||||
assert select_output == '{} , {}'.format(events[0], events[1])
|
||||
|
||||
def test_build_odata_filter(self):
|
||||
default_filter = "timeGrain eq duration'PT1M'"
|
||||
field_name = 'correlation_id'
|
||||
field_value = '1234-34567-56789-34567'
|
||||
field_label = 'correlationId'
|
||||
|
||||
filter_output = _build_odata_filter(default_filter, field_name, field_value, field_label)
|
||||
regex = r'^({} and {} eq \'{}\')$'.format(default_filter, field_label, field_value)
|
||||
assert bool(re.search(regex, filter_output))
|
||||
|
||||
with self.assertRaises(CLIError):
|
||||
_build_odata_filter(default_filter, field_name, None, field_label)
|
||||
|
||||
def test_scaffold_autoscale_settings_parameters(self):
|
||||
template = scaffold_autoscale_settings_parameters(None)
|
||||
if not template or not isinstance(template, dict):
|
||||
assert False
|
||||
|
||||
|
||||
def _mock_get_subscription_id():
|
||||
return '00000000-0000-0000-0000-000000000000'
|
||||
|
||||
|
||||
class MonitorNameOrIdTest(unittest.TestCase):
|
||||
|
||||
def _build_namespace(self, name_or_id=None, resource_group=None, provider_namespace=None, parent=None, resource_type=None):
|
||||
from argparse import Namespace
|
||||
ns = Namespace()
|
||||
ns.name_or_id = name_or_id
|
||||
ns.resource_group_name = resource_group
|
||||
ns.namespace = provider_namespace
|
||||
ns.parent = parent
|
||||
ns.resource_type = resource_type
|
||||
return ns
|
||||
|
||||
@mock.patch('azure.cli.core.commands.client_factory.get_subscription_id', _mock_get_subscription_id)
|
||||
def test_monitor_resource_id(self):
|
||||
from azure.cli.command_modules.monitor.validators import get_target_resource_validator
|
||||
validator = get_target_resource_validator('name_or_id', True)
|
||||
|
||||
id = '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/vm1'
|
||||
|
||||
# must supply name or ID
|
||||
ns = self._build_namespace()
|
||||
with self.assertRaises(CLIError):
|
||||
validator(ns)
|
||||
|
||||
# must only supply ID or name parameters
|
||||
ns = self._build_namespace(id, 'my-rg', 'blahblah', 'stuff')
|
||||
with self.assertRaises(CLIError):
|
||||
validator(ns)
|
||||
|
||||
# error on invalid ID
|
||||
ns = self._build_namespace('bad-id')
|
||||
with self.assertRaises(CLIError):
|
||||
validator(ns)
|
||||
|
||||
# allow Provider/Type syntax (same as resource commands)
|
||||
ns = self._build_namespace('vm1', 'my-rg', None, None, 'Microsoft.Compute/virtualMachines')
|
||||
validator(ns)
|
||||
self.assertEqual(ns.name_or_id, id)
|
||||
|
||||
# allow Provider and Type separate
|
||||
ns = self._build_namespace('vm1', 'my-rg', 'Microsoft.Compute', None, 'virtualMachines')
|
||||
validator(ns)
|
||||
self.assertEqual(ns.name_or_id, id)
|
||||
|
||||
# verify works with parent
|
||||
id = '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-rg/providers/Microsoft.Compute/fakeType/type1/anotherFakeType/type2/virtualMachines/vm1'
|
||||
ns = self._build_namespace('vm1', 'my-rg', 'Microsoft.Compute', 'fakeType/type1/anotherFakeType/type2', 'virtualMachines')
|
||||
validator(ns)
|
||||
self.assertEqual(ns.name_or_id, id)
|
||||
|
||||
# verify extra parameters are removed
|
||||
self.assertFalse(hasattr(ns, 'resource_name'))
|
||||
self.assertFalse(hasattr(ns, 'namespace'))
|
||||
self.assertFalse(hasattr(ns, 'parent'))
|
||||
self.assertFalse(hasattr(ns, 'resource_type'))
|
|
@ -1,105 +0,0 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
import unittest
|
||||
|
||||
from azure.cli.testsdk import ScenarioTest, JMESPathCheck, ResourceGroupPreparer
|
||||
|
||||
|
||||
class MonitorTests(ScenarioTest):
|
||||
|
||||
@ResourceGroupPreparer(name_prefix='cli_test_monitor')
|
||||
def test_monitor(self, resource_group):
|
||||
|
||||
vm = 'vm1'
|
||||
|
||||
vm_json = self.cmd('vm create -g {} -n {} --image UbuntuLTS --admin-password TestPassword11!! --admin-username testadmin --authentication-type password'.format(resource_group, vm)).get_output_in_json()
|
||||
vm_id = vm_json['id']
|
||||
|
||||
# catalog command--so just don't fail
|
||||
self.cmd('monitor metrics list-definitions --resource {} -g {} --resource-type Microsoft.Compute/virtualMachines'.format(vm, resource_group))
|
||||
|
||||
# test alert commands
|
||||
rule1 = 'rule1'
|
||||
rule2 = 'rule2'
|
||||
rule3 = 'rule3'
|
||||
webhook1 = 'https://alert.contoso.com?apiKey=value'
|
||||
webhook2 = 'https://contoso.com/alerts'
|
||||
self.cmd('monitor alert create -g {} -n {} --target {} --condition "Percentage CPU > 90 avg 5m"'.format(resource_group, rule1, vm_id), checks=[
|
||||
JMESPathCheck('actions[0].customEmails', []),
|
||||
JMESPathCheck('actions[0].sendToServiceOwners', False),
|
||||
JMESPathCheck('alertRuleResourceName', rule1),
|
||||
JMESPathCheck('condition.dataSource.metricName', 'Percentage CPU'),
|
||||
JMESPathCheck('condition.dataSource.resourceUri', vm_id),
|
||||
JMESPathCheck('condition.threshold', 90.0),
|
||||
JMESPathCheck('condition.timeAggregation', 'Average'),
|
||||
JMESPathCheck('condition.windowSize', '0:05:00'),
|
||||
])
|
||||
self.cmd('monitor alert create -g {} -n {} --target {} --target-namespace Microsoft.Compute --target-type virtualMachines --disabled --condition "Percentage CPU >= 60 avg 1h" --description "Test Rule 2" -a email test1@contoso.com test2@contoso.com test3@contoso.com'.format(resource_group, rule2, vm), checks=[
|
||||
JMESPathCheck('length(actions[0].customEmails)', 3),
|
||||
JMESPathCheck('actions[0].sendToServiceOwners', False),
|
||||
JMESPathCheck('alertRuleResourceName', rule2),
|
||||
JMESPathCheck('condition.dataSource.metricName', 'Percentage CPU'),
|
||||
JMESPathCheck('condition.dataSource.resourceUri', vm_id),
|
||||
JMESPathCheck('condition.threshold', 60.0),
|
||||
JMESPathCheck('condition.timeAggregation', 'Average'),
|
||||
JMESPathCheck('condition.windowSize', '1:00:00'),
|
||||
JMESPathCheck('isEnabled', False),
|
||||
JMESPathCheck('description', 'Test Rule 2')
|
||||
])
|
||||
self.cmd('monitor alert create -g {} -n {} --target {} --condition "Percentage CPU >= 99 avg 5m" --action webhook {} --action webhook {} apiKey=value'.format(resource_group, rule3, vm_id, webhook1, webhook2), checks=[
|
||||
JMESPathCheck('alertRuleResourceName', rule3),
|
||||
JMESPathCheck('condition.dataSource.metricName', 'Percentage CPU'),
|
||||
JMESPathCheck('condition.dataSource.resourceUri', vm_id),
|
||||
JMESPathCheck('condition.operator', 'GreaterThanOrEqual'),
|
||||
JMESPathCheck('condition.threshold', 99.0),
|
||||
JMESPathCheck('condition.timeAggregation', 'Average'),
|
||||
JMESPathCheck('condition.windowSize', '0:05:00'),
|
||||
JMESPathCheck('isEnabled', True),
|
||||
JMESPathCheck('description', 'Percentage CPU >= 99 avg 5m')
|
||||
])
|
||||
self.cmd('monitor alert show -g {} -n {}'.format(resource_group, rule1), checks=[
|
||||
JMESPathCheck('alertRuleResourceName', rule1)
|
||||
])
|
||||
|
||||
self.cmd('monitor alert delete -g {} -n {}'.format(resource_group, rule2))
|
||||
self.cmd('monitor alert delete -g {} -n {}'.format(resource_group, rule3))
|
||||
self.cmd('monitor alert list -g {}'.format(resource_group), checks=[
|
||||
JMESPathCheck('length(@)', 1)
|
||||
])
|
||||
|
||||
def _check_emails(actions, emails_to_verify, email_service_owners=None):
|
||||
emails = next((x for x in actions if x['odatatype'].endswith('RuleEmailAction')), None)
|
||||
custom_emails = emails['customEmails']
|
||||
if emails_to_verify is not None:
|
||||
self.assertEqual(str(emails_to_verify.sort()), str(custom_emails.sort()))
|
||||
if email_service_owners is not None:
|
||||
self.assertEqual(emails['sendToServiceOwners'], email_service_owners)
|
||||
|
||||
def _check_webhooks(actions, uris_to_check):
|
||||
webhooks = [x['serviceUri'] for x in actions if x['odatatype'].endswith('RuleWebhookAction')]
|
||||
if uris_to_check is not None:
|
||||
self.assertEqual(webhooks.sort(), uris_to_check.sort())
|
||||
|
||||
# test updates
|
||||
result = self.cmd('monitor alert update -g {} -n {} -a email test1@contoso.com -a webhook {} --operator ">=" --threshold 85'.format(resource_group, rule1, webhook1), checks=[
|
||||
JMESPathCheck('condition.operator', 'GreaterThanOrEqual'),
|
||||
JMESPathCheck('condition.threshold', 85.0),
|
||||
]).get_output_in_json()
|
||||
_check_emails(result['actions'], ['test1@contoso.com'], None)
|
||||
_check_webhooks(result['actions'], [webhook1])
|
||||
|
||||
result = self.cmd('monitor alert update -g {} -n {} -r email test1@contoso.com -a email test2@contoso.com -a email test3@contoso.com'.format(resource_group, rule1)).get_output_in_json()
|
||||
_check_emails(result['actions'], ['test1@contoso.com', 'test2@contoso.com', 'test3@contoso.com'], None)
|
||||
|
||||
result = self.cmd('monitor alert update -g {} -n {} --email-service-owners'.format(resource_group, rule1)).get_output_in_json()
|
||||
_check_emails(result['actions'], None, True)
|
||||
|
||||
self.cmd('monitor alert update -g {} -n {} --email-service-owners False --remove-action webhook {} --add-action webhook {}'.format(resource_group, rule1, webhook1, webhook2))
|
||||
_check_webhooks(result['actions'], [webhook2])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -44,7 +44,7 @@ class TestActionGroupScenarios(ScenarioTest):
|
|||
JMESPathCheck('length(webhookReceivers)', 0)])
|
||||
|
||||
self.cmd('monitor action-group enable-receiver -n nonexist --action-group {} -g {}'
|
||||
.format(action_group_name, resource_group))
|
||||
.format(action_group_name, resource_group), expect_failure=True)
|
||||
|
||||
self.cmd('monitor action-group enable-receiver -n alice --action-group {} -g {}'
|
||||
.format(action_group_name, resource_group))
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# 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 MonitorTests(ScenarioTest):
|
||||
@ResourceGroupPreparer(name_prefix='cli_test_monitor')
|
||||
def test_metric_alert_basic_scenarios(self, resource_group):
|
||||
vm = 'vm1'
|
||||
vm_json = self.cmd('vm create -g {} -n {} --image UbuntuLTS --admin-password TestPassword11!! --admin-username '
|
||||
'testadmin --authentication-type password'.format(resource_group, vm)).get_output_in_json()
|
||||
vm_id = vm_json['id']
|
||||
|
||||
# test alert commands
|
||||
rule1 = 'rule1'
|
||||
rule2 = 'rule2'
|
||||
rule3 = 'rule3'
|
||||
webhook1 = 'https://alert.contoso.com?apiKey=value'
|
||||
webhook2 = 'https://contoso.com/alerts'
|
||||
self.cmd('monitor alert create -g {} -n {} --target {} --condition "Percentage CPU > 90 avg 5m"'
|
||||
.format(resource_group, rule1, vm_id),
|
||||
checks=[
|
||||
JMESPathCheck('actions[0].customEmails', []),
|
||||
JMESPathCheck('actions[0].sendToServiceOwners', False),
|
||||
JMESPathCheck('alertRuleResourceName', rule1),
|
||||
JMESPathCheck('condition.dataSource.metricName', 'Percentage CPU'),
|
||||
JMESPathCheck('condition.dataSource.resourceUri', vm_id),
|
||||
JMESPathCheck('condition.threshold', 90.0),
|
||||
JMESPathCheck('condition.timeAggregation', 'Average'),
|
||||
JMESPathCheck('condition.windowSize', '0:05:00')
|
||||
])
|
||||
self.cmd('monitor alert create -g {} -n {} --target {} --target-namespace Microsoft.Compute '
|
||||
'--target-type virtualMachines --disabled --condition "Percentage CPU >= 60 avg 1h" '
|
||||
'--description "Test Rule 2" -a email test1@contoso.com test2@contoso.com test3@contoso.com'
|
||||
.format(resource_group, rule2, vm),
|
||||
checks=[
|
||||
JMESPathCheck('length(actions[0].customEmails)', 3),
|
||||
JMESPathCheck('actions[0].sendToServiceOwners', False),
|
||||
JMESPathCheck('alertRuleResourceName', rule2),
|
||||
JMESPathCheck('condition.dataSource.metricName', 'Percentage CPU'),
|
||||
JMESPathCheck('condition.dataSource.resourceUri', vm_id),
|
||||
JMESPathCheck('condition.threshold', 60.0),
|
||||
JMESPathCheck('condition.timeAggregation', 'Average'),
|
||||
JMESPathCheck('condition.windowSize', '1:00:00'),
|
||||
JMESPathCheck('isEnabled', False),
|
||||
JMESPathCheck('description', 'Test Rule 2')
|
||||
])
|
||||
self.cmd('monitor alert create -g {} -n {} --target {} --condition "Percentage CPU >= 99 avg 5m" '
|
||||
'--action webhook {} --action webhook {} apiKey=value'
|
||||
.format(resource_group, rule3, vm_id, webhook1, webhook2),
|
||||
checks=[
|
||||
JMESPathCheck('alertRuleResourceName', rule3),
|
||||
JMESPathCheck('condition.dataSource.metricName', 'Percentage CPU'),
|
||||
JMESPathCheck('condition.dataSource.resourceUri', vm_id),
|
||||
JMESPathCheck('condition.operator', 'GreaterThanOrEqual'),
|
||||
JMESPathCheck('condition.threshold', 99.0),
|
||||
JMESPathCheck('condition.timeAggregation', 'Average'),
|
||||
JMESPathCheck('condition.windowSize', '0:05:00'),
|
||||
JMESPathCheck('isEnabled', True),
|
||||
JMESPathCheck('description', 'Percentage CPU >= 99 avg 5m')
|
||||
])
|
||||
self.cmd('monitor alert show -g {} -n {}'.format(resource_group, rule1), checks=[
|
||||
JMESPathCheck('alertRuleResourceName', rule1)
|
||||
])
|
||||
|
||||
self.cmd('monitor alert delete -g {} -n {}'.format(resource_group, rule2))
|
||||
self.cmd('monitor alert delete -g {} -n {}'.format(resource_group, rule3))
|
||||
self.cmd('monitor alert list -g {}'.format(resource_group), checks=[JMESPathCheck('length(@)', 1)])
|
||||
|
||||
def _check_emails(actions, emails_to_verify, email_service_owners=None):
|
||||
emails = next((x for x in actions if x['odatatype'].endswith('RuleEmailAction')), None)
|
||||
custom_emails = emails['customEmails']
|
||||
if emails_to_verify is not None:
|
||||
self.assertEqual(str(emails_to_verify.sort()), str(custom_emails.sort()))
|
||||
if email_service_owners is not None:
|
||||
self.assertEqual(emails['sendToServiceOwners'], email_service_owners)
|
||||
|
||||
def _check_webhooks(actions, uris_to_check):
|
||||
webhooks = [x['serviceUri'] for x in actions if x['odatatype'].endswith('RuleWebhookAction')]
|
||||
if uris_to_check is not None:
|
||||
self.assertEqual(webhooks.sort(), uris_to_check.sort())
|
||||
|
||||
# test updates
|
||||
result = self.cmd('monitor alert update -g {} -n {} -a email test1@contoso.com -a webhook {} --operator ">=" '
|
||||
'--threshold 85'.format(resource_group, rule1, webhook1),
|
||||
checks=[
|
||||
JMESPathCheck('condition.operator', 'GreaterThanOrEqual'),
|
||||
JMESPathCheck('condition.threshold', 85.0),
|
||||
]).get_output_in_json()
|
||||
_check_emails(result['actions'], ['test1@contoso.com'], None)
|
||||
_check_webhooks(result['actions'], [webhook1])
|
||||
|
||||
result = self.cmd('monitor alert update -g {} -n {} -r email test1@contoso.com -a email test2@contoso.com '
|
||||
'-a email test3@contoso.com'.format(resource_group, rule1)).get_output_in_json()
|
||||
_check_emails(result['actions'], ['test1@contoso.com', 'test2@contoso.com', 'test3@contoso.com'], None)
|
||||
|
||||
result = self.cmd('monitor alert update -g {} -n {} --email-service-owners'
|
||||
.format(resource_group, rule1)).get_output_in_json()
|
||||
_check_emails(result['actions'], None, True)
|
||||
|
||||
self.cmd('monitor alert update -g {} -n {} --email-service-owners False --remove-action webhook {} '
|
||||
'--add-action webhook {}'.format(resource_group, rule1, webhook1, webhook2))
|
||||
_check_webhooks(result['actions'], [webhook2])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import unittest
|
||||
unittest.main()
|
|
@ -0,0 +1,16 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# 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, ResourceGroupPreparer, StorageAccountPreparer
|
||||
|
||||
|
||||
class TestMonitorMetrics(ScenarioTest):
|
||||
@ResourceGroupPreparer(location='southcentralus')
|
||||
@StorageAccountPreparer()
|
||||
def test_monitor_metrics(self, resource_group, storage_account):
|
||||
resource_id = self.cmd(
|
||||
'az storage account show -n {} -g {} --query id -otsv'.format(storage_account, resource_group)).output
|
||||
|
||||
self.cmd('az monitor metrics list-definitions --resource {}'.format(resource_id))
|
|
@ -0,0 +1,85 @@
|
|||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
import unittest
|
||||
|
||||
try:
|
||||
import unittest.mock as mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
from azure.cli.core.util import CLIError
|
||||
from azure.cli.command_modules.monitor.operations.autoscale_settings import scaffold_autoscale_settings_parameters
|
||||
|
||||
|
||||
class FilterBuilderTests(unittest.TestCase):
|
||||
def test_scaffold_autoscale_settings_parameters(self):
|
||||
template = scaffold_autoscale_settings_parameters(None)
|
||||
self.assertTrue(template)
|
||||
self.assertTrue(isinstance(template, dict))
|
||||
|
||||
|
||||
def _mock_get_subscription_id():
|
||||
return '00000000-0000-0000-0000-000000000000'
|
||||
|
||||
|
||||
class MonitorNameOrIdTest(unittest.TestCase):
|
||||
def _build_namespace(self, name_or_id=None, resource_group=None, provider_namespace=None, parent=None,
|
||||
resource_type=None):
|
||||
from argparse import Namespace
|
||||
ns = Namespace()
|
||||
ns.name_or_id = name_or_id
|
||||
ns.resource_group_name = resource_group
|
||||
ns.namespace = provider_namespace
|
||||
ns.parent = parent
|
||||
ns.resource_type = resource_type
|
||||
return ns
|
||||
|
||||
@mock.patch('azure.cli.core.commands.client_factory.get_subscription_id', _mock_get_subscription_id)
|
||||
def test_monitor_resource_id(self):
|
||||
from azure.cli.command_modules.monitor.validators import get_target_resource_validator
|
||||
validator = get_target_resource_validator('name_or_id', True)
|
||||
|
||||
id = '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-rg/providers/Microsoft.Compute/' \
|
||||
'virtualMachines/vm1'
|
||||
|
||||
# must supply name or ID
|
||||
ns = self._build_namespace()
|
||||
with self.assertRaises(CLIError):
|
||||
validator(ns)
|
||||
|
||||
# must only supply ID or name parameters
|
||||
ns = self._build_namespace(id, 'my-rg', 'blahblah', 'stuff')
|
||||
with self.assertRaises(CLIError):
|
||||
validator(ns)
|
||||
|
||||
# error on invalid ID
|
||||
ns = self._build_namespace('bad-id')
|
||||
with self.assertRaises(CLIError):
|
||||
validator(ns)
|
||||
|
||||
# allow Provider/Type syntax (same as resource commands)
|
||||
ns = self._build_namespace('vm1', 'my-rg', None, None, 'Microsoft.Compute/virtualMachines')
|
||||
validator(ns)
|
||||
self.assertEqual(ns.name_or_id, id)
|
||||
|
||||
# allow Provider and Type separate
|
||||
ns = self._build_namespace('vm1', 'my-rg', 'Microsoft.Compute', None, 'virtualMachines')
|
||||
validator(ns)
|
||||
self.assertEqual(ns.name_or_id, id)
|
||||
|
||||
# verify works with parent
|
||||
id = '/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-rg/providers/Microsoft.Compute/' \
|
||||
'fakeType/type1/anotherFakeType/type2/virtualMachines/vm1'
|
||||
ns = self._build_namespace('vm1', 'my-rg', 'Microsoft.Compute', 'fakeType/type1/anotherFakeType/type2',
|
||||
'virtualMachines')
|
||||
validator(ns)
|
||||
self.assertEqual(ns.name_or_id, id)
|
||||
|
||||
# verify extra parameters are removed
|
||||
self.assertFalse(hasattr(ns, 'resource_name'))
|
||||
self.assertFalse(hasattr(ns, 'namespace'))
|
||||
self.assertFalse(hasattr(ns, 'parent'))
|
||||
self.assertFalse(hasattr(ns, 'resource_type'))
|
|
@ -28,6 +28,13 @@ def _item_to_ordered_dict(item, *properties):
|
|||
return result
|
||||
|
||||
|
||||
def _generic_table_convert(source, row_convert_fn):
|
||||
if not isinstance(source, list):
|
||||
source = [source]
|
||||
|
||||
return [row_convert_fn(each) for each in source]
|
||||
|
||||
|
||||
def action_group_list_table(results):
|
||||
if not isinstance(results, list):
|
||||
results = [results]
|
||||
|
@ -35,10 +42,56 @@ def action_group_list_table(results):
|
|||
output_results = []
|
||||
for result in results:
|
||||
data = _item_to_ordered_dict(result, 'name', 'resourceGroup', 'groupShortName', 'enabled', 'location',
|
||||
('emailReceivers', 'email'),
|
||||
('smsReceivers', 'sms'),
|
||||
('emailReceivers', 'email'), ('smsReceivers', 'sms'),
|
||||
('webhookReceivers', 'webhook'))
|
||||
|
||||
output_results.append(data)
|
||||
|
||||
return output_results
|
||||
|
||||
|
||||
def metrics_definitions_table(results):
|
||||
def row_convert(item):
|
||||
from collections import OrderedDict
|
||||
result = OrderedDict()
|
||||
result['Display Name'] = item['name']['localizedValue']
|
||||
result['Metric Name'] = item['name']['value']
|
||||
result['Unit'] = item['unit']
|
||||
result['Type'] = item['primaryAggregationType']
|
||||
result['Dimension Required'] = 'True' if item['isDimensionRequired'] else 'False'
|
||||
result['Dimensions'] = ', '.join(d['value'] for d in item.get('dimensions', []) or [])
|
||||
|
||||
return result
|
||||
|
||||
return _generic_table_convert(results, row_convert)
|
||||
|
||||
|
||||
def metrics_table(results):
|
||||
from collections import OrderedDict
|
||||
|
||||
def from_time(time_string):
|
||||
from datetime import datetime
|
||||
try:
|
||||
return datetime.strptime(time_string, '%Y-%m-%dT%H:%M:%S+00:00').strftime('%Y-%m-%d %H:%M:%S')
|
||||
except ValueError:
|
||||
return time_string
|
||||
|
||||
retval = []
|
||||
for value_group in results['value']:
|
||||
name = value_group['name']['localizedValue']
|
||||
for series in value_group['timeseries']:
|
||||
metadata = dict((m['name']['localizedValue'], m['value']) for m in series['metadatavalues'])
|
||||
|
||||
for data in series['data']:
|
||||
row = OrderedDict()
|
||||
row['Timestamp'] = from_time(data['timeStamp'])
|
||||
row['Name'] = name
|
||||
for metadata_name, metadata_value in metadata.items():
|
||||
row[metadata_name] = metadata_value
|
||||
|
||||
for field in data:
|
||||
if field == 'timeStamp':
|
||||
continue
|
||||
row[field] = data[field]
|
||||
retval.append(row)
|
||||
return retval
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# ISO format with explicit indication of timezone
|
||||
DATE_TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
|
||||
|
||||
|
||||
def get_resource_group_location(name):
|
||||
from azure.cli.core.commands.client_factory import get_mgmt_service_client
|
||||
|
@ -10,3 +15,32 @@ def get_resource_group_location(name):
|
|||
|
||||
# pylint: disable=no-member
|
||||
return get_mgmt_service_client(ResourceType.MGMT_RESOURCE_RESOURCES).resource_groups.get(name).location
|
||||
|
||||
|
||||
def get_operator_map():
|
||||
from azure.mgmt.monitor.models import ConditionOperator
|
||||
return {'>': ConditionOperator.greater_than.value, '>=': ConditionOperator.greater_than_or_equal.value,
|
||||
'<': ConditionOperator.less_than, '<=': ConditionOperator.less_than_or_equal}
|
||||
|
||||
|
||||
def get_aggregation_map():
|
||||
from azure.mgmt.monitor.models import TimeAggregationOperator
|
||||
return {'avg': TimeAggregationOperator.average.value, 'min': TimeAggregationOperator.minimum.value,
|
||||
'max': TimeAggregationOperator.maximum.value, 'total': TimeAggregationOperator.total.value,
|
||||
'last': TimeAggregationOperator.last.value}
|
||||
|
||||
|
||||
def validate_time_range_and_add_defaults(start_time, end_time, formatter='startTime eq {} and endTime eq {}'):
|
||||
try:
|
||||
end_time = datetime.strptime(end_time, DATE_TIME_FORMAT) if end_time else datetime.utcnow()
|
||||
except ValueError:
|
||||
raise ValueError("Input '{}' is not valid datetime. Valid example: 2000-12-31T12:59:59Z".format(end_time))
|
||||
|
||||
try:
|
||||
start_time = datetime.strptime(start_time, DATE_TIME_FORMAT) if start_time else end_time - timedelta(hours=1)
|
||||
if start_time >= end_time:
|
||||
raise ValueError("Start time cannot be later than end time.")
|
||||
except ValueError:
|
||||
raise ValueError("Input '{}' is not valid datetime. Valid example: 2000-12-31T12:59:59Z".format(start_time))
|
||||
|
||||
return formatter.format(start_time.strftime('%Y-%m-%dT%H:%M:%SZ'), end_time.strftime('%Y-%m-%dT%H:%M:%SZ'))
|
||||
|
|
|
@ -7,7 +7,7 @@ from azure.cli.core.commands.arm import is_valid_resource_id, resource_id, parse
|
|||
from knack.util import CLIError
|
||||
|
||||
|
||||
def get_target_resource_validator(dest, required):
|
||||
def get_target_resource_validator(dest, required, preserve_resource_group_parameter=False):
|
||||
def _validator(namespace):
|
||||
name_or_id = getattr(namespace, dest)
|
||||
rg = namespace.resource_group_name
|
||||
|
@ -39,6 +39,8 @@ def get_target_resource_validator(dest, required):
|
|||
del namespace.namespace
|
||||
del namespace.parent
|
||||
del namespace.resource_type
|
||||
if not preserve_resource_group_parameter:
|
||||
del namespace.resource_group_name
|
||||
return _validator
|
||||
|
||||
|
||||
|
@ -129,3 +131,42 @@ def process_action_group_detail_for_creation(namespace):
|
|||
}
|
||||
|
||||
ns['action_group'] = ActionGroupResource(**action_group_resource_properties)
|
||||
|
||||
|
||||
def process_metric_timespan(namespace):
|
||||
from .util import validate_time_range_and_add_defaults
|
||||
|
||||
ns = vars(namespace)
|
||||
start_time = ns.pop('start_time', None)
|
||||
end_time = ns.pop('end_time', None)
|
||||
ns['timespan'] = validate_time_range_and_add_defaults(start_time, end_time, formatter='{}/{}')
|
||||
|
||||
|
||||
def process_metric_aggregation(namespace):
|
||||
ns = vars(namespace)
|
||||
aggregation = ns.pop('aggregation', None)
|
||||
if aggregation:
|
||||
ns['aggregation'] = ','.join(aggregation)
|
||||
|
||||
|
||||
def process_metric_result_type(namespace):
|
||||
from azure.mgmt.monitor.models.monitor_management_client_enums import ResultType
|
||||
|
||||
ns = vars(namespace)
|
||||
metadata_only = ns.pop('metadata', False)
|
||||
if metadata_only:
|
||||
ns['result_type'] = ResultType.metadata
|
||||
|
||||
|
||||
def process_metric_dimension(namespace):
|
||||
ns = vars(namespace)
|
||||
|
||||
dimensions = ns.pop('dimension', None)
|
||||
if not dimensions:
|
||||
return
|
||||
|
||||
param_filter = ns.pop('filter', None)
|
||||
if param_filter:
|
||||
raise CLIError('usage: --dimension and --filter parameters are mutually exclusive.')
|
||||
|
||||
ns['filter'] = ' and '.join("{} eq '*'".format(d) for d in dimensions)
|
||||
|
|
|
@ -12,7 +12,7 @@ except ImportError:
|
|||
logger.warn("Wheel is not available, disabling bdist_wheel hook")
|
||||
cmdclass = {}
|
||||
|
||||
VERSION = "0.0.12"
|
||||
VERSION = "0.0.13"
|
||||
CLASSIFIERS = [
|
||||
'Development Status :: 4 - Beta',
|
||||
'Intended Audience :: Developers',
|
||||
|
@ -29,8 +29,7 @@ CLASSIFIERS = [
|
|||
|
||||
DEPENDENCIES = [
|
||||
'azure-cli-core',
|
||||
'azure-monitor==0.3.0',
|
||||
'azure-mgmt-monitor==0.3.0',
|
||||
'azure-mgmt-monitor==0.4.0',
|
||||
'azure-mgmt-resource==1.2.1'
|
||||
]
|
||||
|
||||
|
@ -53,9 +52,10 @@ setup(
|
|||
'azure',
|
||||
'azure.cli',
|
||||
'azure.cli.command_modules',
|
||||
'azure.cli.command_modules.monitor'
|
||||
'azure.cli.command_modules.monitor',
|
||||
'azure.cli.command_modules.monitor.operations'
|
||||
],
|
||||
package_data={'azure.cli.command_modules.monitor': ['autoscale-parameters-template.json']},
|
||||
package_data={'azure.cli.command_modules.monitor.operations': ['autoscale-parameters-template.json']},
|
||||
install_requires=DEPENDENCIES,
|
||||
cmdclass=cmdclass
|
||||
)
|
||||
|
|
Загрузка…
Ссылка в новой задаче