def __call__(self, parser, namespace, values, option_string=None): from azure.mgmt.monitor.models import MetricTrigger if len(values) == 1: # workaround because CMD.exe eats > character... Allows condition to be # specified as a quoted expression values = values[0].split(' ') name_offset = 0 try: metric_name = ' '.join(values[name_offset:-4]) operator = get_autoscale_operator_map()[values[-4]] threshold = int(values[-3]) aggregation = get_autoscale_aggregation_map()[values[-2].lower()] window = period_type(values[-1]) except (IndexError, KeyError): from knack.util import CLIError raise CLIError('usage error: --condition METRIC {==,!=,>,>=,<,<=} ' 'THRESHOLD {avg,min,max,total,count} PERIOD') condition = MetricTrigger( metric_name=metric_name, metric_resource_uri=None, # will be filled in later time_grain=None, # will be filled in later statistic=None, # will be filled in later time_window=window, time_aggregation=aggregation, operator=operator, threshold=threshold) namespace.condition = condition
def validate_autoscale_timegrain(namespace): from azure.mgmt.monitor.models import MetricTrigger from azure.cli.command_modules.monitor.actions import period_type from azure.cli.command_modules.monitor.util import get_autoscale_statistic_map values = namespace.timegrain if len(values) == 1: # workaround because CMD.exe eats > character... Allows condition to be # specified as a quoted expression values = values[0].split(' ') name_offset = 0 try: time_grain = period_type(values[1]) name_offset += 1 except ValueError: time_grain = period_type('1m') try: statistic = get_autoscale_statistic_map()[values[0]] name_offset += 1 except KeyError: statistic = get_autoscale_statistic_map()['avg'] timegrain = MetricTrigger(metric_name=None, metric_resource_uri=None, time_grain=time_grain, statistic=statistic, time_window=None, time_aggregation=None, operator=None, threshold=None) namespace.timegrain = timegrain
def create_rule_instance(params): rule = params.copy() rule['metric_resource_uri'] = rule.get('metric_resource_uri', self.target) rule['time_grain'] = timedelta(minutes=rule.get('time_grain', 0)) rule['time_window'] = timedelta(minutes=rule.get('time_window', 0)) rule['cooldown'] = timedelta(minutes=rule.get('cooldown', 0)) return ScaleRule(metric_trigger=MetricTrigger(**rule), scale_action=ScaleAction(**rule))
def result(self): from azure.mgmt.monitor.models import MetricTrigger, ScaleRuleMetricDimension dim_params = self.parameters.get('dimensions', []) dimensions = [] for dim in dim_params: dimensions.append(ScaleRuleMetricDimension(**dim)) self.parameters['dimensions'] = dimensions self.parameters['metric_resource_uri'] = None # will be filled in later self.parameters['time_grain'] = None # will be filled in later self.parameters['statistic'] = None # will be filled in later return MetricTrigger(**self.parameters)
def create_autoscaling_settings(ExistingVmScaleSetName, VmScaleSetID, resourceGroupName): NewVmScaleSetName = VmScaleSetID.split('/')[-1] existing_asg = monitor_client.autoscale_settings.get( resource_group_name=resourceGroupName, autoscale_setting_name=ExistingVmScaleSetName) rules = [ ScaleRule( metric_trigger=MetricTrigger( metric_name=i.metric_trigger.metric_name, #metric_namespace=i.metric_trigger.additional_properties['metricNamespace'], metric_resource_uri=VmScaleSetID, time_grain=i.metric_trigger.time_grain, statistic=i.metric_trigger.statistic, time_window=i.metric_trigger.time_window, time_aggregation=i.metric_trigger.time_aggregation, operator=i.metric_trigger.operator, threshold=i.metric_trigger.threshold #dimensions = i.metric_trigger.additional_properties['dimensions'] ), scale_action=i.scale_action) for i in existing_asg.profiles[0].rules ] profile = AutoscaleProfile(name=existing_asg.profiles[0].name, capacity=existing_asg.profiles[0].capacity, rules=rules, fixed_date=None, recurrence=None) parameters = AutoscaleSettingResource( location=existing_asg.location, tags=existing_asg.tags, profiles=[profile], notifications=existing_asg.notifications, enabled=True, autoscale_setting_resource_name=NewVmScaleSetName, target_resource_uri=VmScaleSetID) new_asg = monitor_client.autoscale_settings.create_or_update( resource_group_name=resourceGroupName, autoscale_setting_name=NewVmScaleSetName, parameters=parameters)
def shutdown_scaleset_rule(queue_uri: str) -> ScaleRule: return ScaleRule( # Scale in if there are 0 or more messages in the queue (aka: every time) metric_trigger=MetricTrigger( metric_name="ApproximateMessageCount", metric_resource_uri=queue_uri, # Check every 10 minutes time_grain=timedelta(minutes=5), # The average amount of messages there are in the pool queue time_aggregation=TimeAggregationType.AVERAGE, statistic=MetricStatisticType.SUM, # Over the past 10 minutes time_window=timedelta(minutes=5), operator=ComparisonOperationType.GREATER_THAN_OR_EQUAL, threshold=0, divide_per_instance=False, ), scale_action=ScaleAction( direction=ScaleDirection.DECREASE, type=ScaleType.CHANGE_COUNT, value=1, cooldown=timedelta(minutes=5), ), )
def create_auto_scale_profile( queue_uri: str, min: int, max: int, default: int, scale_out_amount: int, scale_out_cooldown: int, scale_in_amount: int, scale_in_cooldown: int, ) -> AutoscaleProfile: return AutoscaleProfile( name=str(uuid.uuid4()), capacity=ScaleCapacity(minimum=min, maximum=max, default=max), # Auto scale tuning guidance: # https://docs.microsoft.com/en-us/azure/architecture/best-practices/auto-scaling rules=[ ScaleRule( metric_trigger=MetricTrigger( metric_name="ApproximateMessageCount", metric_resource_uri=queue_uri, # Check every 15 minutes time_grain=timedelta(minutes=15), # The average amount of messages there are in the pool queue time_aggregation=TimeAggregationType.AVERAGE, statistic=MetricStatisticType.COUNT, # Over the past 15 minutes time_window=timedelta(minutes=15), # When there's more than 1 message in the pool queue operator=ComparisonOperationType.GREATER_THAN_OR_EQUAL, threshold=1, divide_per_instance=False, ), scale_action=ScaleAction( direction=ScaleDirection.INCREASE, type=ScaleType.CHANGE_COUNT, value=scale_out_amount, cooldown=timedelta(minutes=scale_out_cooldown), ), ), # Scale in ScaleRule( # Scale in if no work in the past 20 mins metric_trigger=MetricTrigger( metric_name="ApproximateMessageCount", metric_resource_uri=queue_uri, # Check every 10 minutes time_grain=timedelta(minutes=10), # The average amount of messages there are in the pool queue time_aggregation=TimeAggregationType.AVERAGE, statistic=MetricStatisticType.SUM, # Over the past 10 minutes time_window=timedelta(minutes=10), # When there's no messages in the pool queue operator=ComparisonOperationType.EQUALS, threshold=0, divide_per_instance=False, ), scale_action=ScaleAction( direction=ScaleDirection.DECREASE, type=ScaleType.CHANGE_COUNT, value=scale_in_amount, cooldown=timedelta(minutes=scale_in_cooldown), ), ), ], )