diff --git a/otcextensions/osclient/auto_scaling/v1/activity.py b/otcextensions/osclient/auto_scaling/v1/activity.py index ea6d014db..bf44dc171 100644 --- a/otcextensions/osclient/auto_scaling/v1/activity.py +++ b/otcextensions/osclient/auto_scaling/v1/activity.py @@ -31,18 +31,19 @@ class ListAutoScalingActivityLogs(command.Lister): def get_parser(self, prog_name): parser = super(ListAutoScalingActivityLogs, self).get_parser(prog_name) parser.add_argument( - 'group', + '--group', metavar='', + required=True, help=_('AS Group ID or name') ) parser.add_argument( - '--start_time', + '--start-time', metavar='', help=_('Specifies the start time for querying scaling ' 'action logs. Format: `YYYY-MM-DDThh:mm:ssZ`') ) parser.add_argument( - '--end_time', + '--end-time', metavar='', help=_('Specifies the end time for querying scaling ' 'action logs. Format: `YYYY-MM-DDThh:mm:ssZ`') diff --git a/otcextensions/osclient/auto_scaling/v1/config.py b/otcextensions/osclient/auto_scaling/v1/config.py index d29bf03c3..f839cf89e 100644 --- a/otcextensions/osclient/auto_scaling/v1/config.py +++ b/otcextensions/osclient/auto_scaling/v1/config.py @@ -152,13 +152,13 @@ def get_parser(self, prog_name): help=_('Flavor ID or Name for the ECS instance') ) group1.add_argument( - '--image_id', + '--image-id', metavar='', help=_('Image ID for the ECS instance to be created') ) group = parser.add_mutually_exclusive_group() group.add_argument( - '--instance_id', + '--instance-id', metavar='', help=_('AS Configuration name\n' 'Is mutually exclusive with ECS group') @@ -187,14 +187,14 @@ def get_parser(self, prog_name): help=_('Key name for the new ECS instance') ) parser.add_argument( - '--public_ip_bandwith', + '--public-ip-bandwith', metavar='', type=int, help=_('Defines EIP Bandwith (Mbit/s) to be attached ' 'to the new ECS instance') ) parser.add_argument( - '--user_data', + '--user-data', metavar='', help=_('Path to the cloud-init user_data file') ) diff --git a/otcextensions/osclient/auto_scaling/v1/group.py b/otcextensions/osclient/auto_scaling/v1/group.py index cded083a7..0fac7b320 100644 --- a/otcextensions/osclient/auto_scaling/v1/group.py +++ b/otcextensions/osclient/auto_scaling/v1/group.py @@ -62,6 +62,11 @@ class ListAutoScalingGroup(command.Lister): def get_parser(self, prog_name): parser = super(ListAutoScalingGroup, self).get_parser(prog_name) + parser.add_argument( + '--name', + metavar='', + help=_('Name or ID of the AS group') + ) parser.add_argument( '--limit', dest='limit', @@ -78,13 +83,40 @@ def get_parser(self, prog_name): 'specified marker. When used with --limit, set this to ' 'the last ID displayed in the previous run') ) + parser.add_argument( + '--scaling-configuration-id', + metavar='', + help=_('ID of the AS configuration') + ) + parser.add_argument( + '--status', + metavar='', + help=_('Shows AS groups with specific status:\n' + ': AS group is working\n' + ': AS group is paused\n' + ': AS group has malfunctions\n' + ': AS group is being deleted') + ) return parser def take_action(self, parsed_args): client = self.app.client_manager.auto_scaling - data = client.groups() + args = {} + if parsed_args.limit: + args['limit'] = parsed_args.limit + if parsed_args.marker: + args['marker'] = parsed_args.marker + if parsed_args.name: + args['name'] = parsed_args.name + if parsed_args.scaling_configuration_id: + args['scaling_configuration_id'] = \ + parsed_args.scaling_configuration_id + if parsed_args.status: + args['status'] = parsed_args.status + + data = client.groups(**args) return ( self.columns, @@ -137,36 +169,36 @@ def get_parser(self, prog_name): help=_('Name of the new configuration group') ) parser.add_argument( - '--desire_instance_number', + '--desire-instance-number', metavar='', type=int, help=_('Desired number of instances') ) parser.add_argument( - '--min_instance_number', + '--min-instance-number', metavar='', type=int, help=_('Minimal number of instances') ) parser.add_argument( - '--max_instance_number', + '--max-instance-number', metavar='', type=int, help=_('Maximal number of instances') ) parser.add_argument( - '--cool_down_time', + '--cool-down-time', metavar='', type=int, help=_('Specifies cooling duration in seconds') ) parser.add_argument( - '--lb_listener_id', + '--lb-listener-id', metavar='', help=_('Specifies ELB Listener ID') ) parser.add_argument( - '--lbaas_listener', + '--lbaas-listener', metavar='', action='append', help=_('Specifies ULB Listener Information in format: ' @@ -174,47 +206,47 @@ def get_parser(self, prog_name): '(Repeat multiple times, up to 3 times)') ) parser.add_argument( - '--availability_zone', + '--availability-zone', metavar='', action='append', help=_('Specifies the availability zones information ' '(Repeat multiple times)') ) parser.add_argument( - '--subnet', - metavar='', + '--network-id', + metavar='', action='append', required=True, help=_('Network ID of the subnet' '(Repeat multiple times, up to 5 times)') ) parser.add_argument( - '--security_group', + '--security-group', metavar='', action='append', - required=True, + # required=True, help=_('Security Group ID' '(Repeat multiple times)') ) parser.add_argument( - '--router', - metavar='', + '--router-id', + metavar='', required=True, help=_('Router (VPC) ID') ) parser.add_argument( - '--audit_method', + '--audit-method', metavar='', help=_('Specifies the audit method [`NOVA_AUDIT`, `ELB_AUDIT`]') ) parser.add_argument( - '--audit_time', + '--audit-time', metavar='', type=int, help=_('Specifies the audit time in minutes') ) parser.add_argument( - '--terminate_policy', + '--terminate-policy', metavar='', help=_('Specifies the termination policy' ' [`OLD_CONFIG_OLD_INSTANCE` (default), ' @@ -230,7 +262,7 @@ def get_parser(self, prog_name): '(Repeat multiple times)') ) parser.add_argument( - '--delete_public_ip', + '--delete-public-ip', default=False, action='store_true', help=_('Specifies whether to delete EIP when deleting the ECS') @@ -241,17 +273,18 @@ def take_action(self, parsed_args): args = {} args['name'] = parsed_args.name - args['vpc_id'] = parsed_args.router + args['router_id'] = parsed_args.router_id - subnets = [] - for subnet in parsed_args.subnet: - subnets.append({'id': subnet}) - args['networks'] = subnets + networks = [] + for network in parsed_args.network_id: + networks.append({'id': network}) + args['networks'] = networks - sgs = [] - for sg in parsed_args.security_group: - sgs.append({'id': sg}) - args['security_groups'] = sgs + if parsed_args.security_group: + sgs = [] + for sg in parsed_args.security_group: + sgs.append({'id': sg}) + args['security_groups'] = sgs if parsed_args.desire_instance_number: args['desire_instance_number'] = parsed_args.desire_instance_number @@ -337,36 +370,36 @@ def get_parser(self, prog_name): help=_('AS Group name or ID') ) parser.add_argument( - '--desire_instance_number', + '--desire-instance-number', metavar='', type=int, help=_('Desired number of instances') ) parser.add_argument( - '--min_instance_number', + '--min-instance-number', metavar='', type=int, help=_('Minimal number of instances') ) parser.add_argument( - '--max_instance_number', + '--max-instance-number', metavar='', type=int, help=_('Maximal number of instances') ) parser.add_argument( - '--cool_down_time', + '--cool-down-time', metavar='', type=int, help=_('Specifies cooling duration in seconds') ) parser.add_argument( - '--lb_listener_id', + '--lb-listener-id', metavar='', help=_('Specifies ELB Listener ID') ) parser.add_argument( - '--lbaas_listener', + '--lbaas-listener', metavar='', action='append', help=_('Specifies ULB Listener Information in format: ' @@ -374,47 +407,46 @@ def get_parser(self, prog_name): '(Repeat multiple times, up to 3 times)') ) parser.add_argument( - '--availability_zone', + '--availability-zone', metavar='', action='append', help=_('Specifies the availability zones information ' '(Repeat multiple times)') ) parser.add_argument( - '--subnetwork', - metavar='', + '--network-id', + metavar='', + default=[], action='append', - required=True, help=_('Network ID of the subnet' '(Repeat multiple times, up to 5 times)') ) parser.add_argument( - '--security_group', + '--security-group', metavar='', + default=[], action='append', - required=True, help=_('Security Group ID' '(Repeat multiple times)') ) parser.add_argument( - '--network_id', - metavar='', - required=True, - help=_('Network (VPC) ID') + '--router-id', + metavar='', + help=_('Router (VPC) ID') ) parser.add_argument( - '--audit_method', + '--audit-method', metavar='', help=_('Specifies the audit method [`NOVA_AUDIT`, `ELB_AUDIT`]') ) parser.add_argument( - '--audit_time', + '--audit-time', metavar='', type=int, help=_('Specifies the audit time in minutes') ) parser.add_argument( - '--terminate_policy', + '--terminate-policy', metavar='', help=_('Specifies the termination policy' ' [`OLD_CONFIG_OLD_INSTANCE` (default), ' @@ -430,7 +462,7 @@ def get_parser(self, prog_name): '(Repeat multiple times)') ) parser.add_argument( - '--delete_public_ip', + '--delete-public-ip', default=False, action='store_true', help=_('Specifies whether to delete EIP when deleting the ECS') @@ -440,17 +472,20 @@ def get_parser(self, prog_name): def take_action(self, parsed_args): args = {} - args['vpc_id'] = parsed_args.network_id + if parsed_args.router_id: + args['router_id'] = parsed_args.router_id - subnets = [] - for subnet in parsed_args.subnetwork: - subnets.append({'id': subnet}) - args['networks'] = subnets + networks = [] + for network in parsed_args.network_id: + networks.append({'id': network}) + if networks: + args['networks'] = networks sgs = [] for sg in parsed_args.security_group: sgs.append({'id': sg}) - args['security_groups'] = sgs + if sgs: + args['security_groups'] = sgs if parsed_args.desire_instance_number: args['desire_instance_number'] = parsed_args.desire_instance_number @@ -495,7 +530,8 @@ def take_action(self, parsed_args): args['notifications'] = lst client = self.app.client_manager.auto_scaling - group = client.update_group(group=parsed_args.group, **args) + group = client.find_group(parsed_args.group, ignore_missing=False) + group = client.update_group(group, **args) display_columns, columns = _get_columns(group) data = utils.get_item_properties(group, columns, formatters={}) diff --git a/otcextensions/osclient/auto_scaling/v1/instance.py b/otcextensions/osclient/auto_scaling/v1/instance.py index 061c09b78..03f55608d 100644 --- a/otcextensions/osclient/auto_scaling/v1/instance.py +++ b/otcextensions/osclient/auto_scaling/v1/instance.py @@ -31,18 +31,19 @@ class ListAutoScalingInstance(command.Lister): def get_parser(self, prog_name): parser = super(ListAutoScalingInstance, self).get_parser(prog_name) parser.add_argument( - 'group', + '--group', metavar='', + required=True, help=_('AS Group ID or Name for the instances query') ) parser.add_argument( - '--life_cycle_state', + '--life-cycle-state', metavar='', help=_('Life cycle state of the instances to query\n' 'Could be in [`INSERVICE`, `PENDING`, `REMOVING`]') ) parser.add_argument( - '--health_status', + '--health-status', metavar='', help=_('Health status of the instances to query\n' 'Could be in [`INITIALIZING`, `NORMAL`, `ERROR`]') @@ -91,7 +92,7 @@ def get_parser(self, prog_name): help=_('AS Instance ID to be deleted') ) parser.add_argument( - '--delete_instance', + '--delete-instance', action='store_true', default=False, help=_('Specifies, whether instance should be completely deleted') @@ -117,8 +118,9 @@ def get_parser(self, prog_name): parser = super(BatchActionAutoScalingInstance, self).\ get_parser(prog_name) parser.add_argument( - 'group', + '--group', metavar='', + required=True, help=_('AS Group ID or Name') ) parser.add_argument( @@ -134,7 +136,7 @@ def get_parser(self, prog_name): help=_('AS Instance ID to be deleted') ) parser.add_argument( - '--delete_instance', + '--delete-instance', action='store_true', default=False, help=_('Specifies, whether instance should be completely deleted' diff --git a/otcextensions/osclient/auto_scaling/v1/policy.py b/otcextensions/osclient/auto_scaling/v1/policy.py index e17755052..f0baacbea 100644 --- a/otcextensions/osclient/auto_scaling/v1/policy.py +++ b/otcextensions/osclient/auto_scaling/v1/policy.py @@ -104,18 +104,26 @@ def get_parser(self, prog_name): parser.add_argument( 'policy', metavar='', - help=_('ID of the configuration policy') + help=_('ID of the configuration policy\n' + 'For Policy Name search --group param is needed') + ) + parser.add_argument( + '--group', + metavar='', + help=_('ScalingGroup ID or Name if Name searched is used') ) return parser def take_action(self, parsed_args): client = self.app.client_manager.auto_scaling - obj = client.get_policy(parsed_args.policy) - - # display_columns, columns = _get_columns(obj) - # data = utils.get_item_properties( - # obj, columns, formatters={'instance_config': _format_instance}) + if parsed_args.group: + group = client.find_group(parsed_args.group, ignore_missing=False) + obj = client.find_policy(parsed_args.policy, + group=group, + ignore_missing=False) + else: + obj = client.get_policy(parsed_args.policy) fmt = set_attributes_for_print_detail(obj) # display_columns, columns = _get_columns(obj) @@ -159,30 +167,30 @@ def get_parser(self, prog_name): help=_('AS Policy type [`ALARM`, `SCHEDULED`, `RECURRENCE`]') ) parser.add_argument( - '--cool_down_time', + '--cool-down-time', metavar='', type=int, help=_('Specifies the cooling time in seconds for the policy') ) parser.add_argument( - '--alarm_id', + '--alarm-id', metavar='', help=_('Specifies the alarm_id for the policy') ) parser.add_argument( - '--action_operation', + '--action-operation', metavar='', help=_('Specifies the policy operation ' 'Can be [`ADD`, `REMOVE`, `SET`]') ) parser.add_argument( - '--action_instance_number', + '--action-instance-number', metavar='', type=int, help=_('Specifies number of instances to be operated') ) parser.add_argument( - '--launch_time', + '--launch-time', metavar='', help=_('Specifies the time when the scaling action is triggered. ' 'The time format must comply with UTC.\n' @@ -190,7 +198,7 @@ def get_parser(self, prog_name): '* when type=`RECURRENCE`, then `hh:mm`\n') ) parser.add_argument( - '--recurrence_type', + '--recurrence-type', metavar='', help=_( 'Specifies the periodic triggering type\n' @@ -199,7 +207,7 @@ def get_parser(self, prog_name): ) ) parser.add_argument( - '--recurrence_value', + '--recurrence-value', metavar='', help=_( 'Specifies the frequency, at which actions are triggered\n' @@ -210,13 +218,13 @@ def get_parser(self, prog_name): ) ) parser.add_argument( - '--start_time', + '--start-time', metavar='', help=_('Specifies the start time in of the action in the ' '`YYYY-MM-DDThh:mmZ` format') ) parser.add_argument( - '--end_time', + '--end-time', metavar='', help=_('Specifies the end time in of the action in the ' '`YYYY-MM-DDThh:mmZ` format\n' @@ -315,7 +323,7 @@ def get_parser(self, prog_name): parser.add_argument( 'policy', metavar='', - help=_('AS Policy name or ID') + help=_('AS Policy ID') ) parser.add_argument( '--group', @@ -326,35 +334,33 @@ def get_parser(self, prog_name): parser.add_argument( '--type', metavar='', - required=True, - # choices=['ALARM', 'SCHEDULED', 'RECURRENCE'], help=_('AS Policy type [`ALARM`, `SCHEDULED`, `RECURRENCE`]') ) parser.add_argument( - '--cool_down_time', + '--cool-down-time', metavar='', type=int, help=_('Specifies the cooling time in seconds for the policy') ) parser.add_argument( - '--alarm_id', + '--alarm-id', metavar='', help=_('Specifies the alarm_id for the policy') ) parser.add_argument( - '--action_operation', + '--action-operation', metavar='', help=_('Specifies the policy operation ' 'Can be [`ADD`, `REMOVE`, `SET`]') ) parser.add_argument( - '--action_instance_number', + '--action-instance-number', metavar='', type=int, help=_('Specifies number of instances to be operated') ) parser.add_argument( - '--launch_time', + '--launch-time', metavar='', help=_('Specifies the time when the scaling action is triggered. ' 'The time format must comply with UTC.\n' @@ -362,7 +368,7 @@ def get_parser(self, prog_name): '* when type=`RECURRENCE`, then `hh:mm`\n') ) parser.add_argument( - '--recurrence_type', + '--recurrence-type', metavar='', help=_( 'Specifies the periodic triggering type\n' @@ -371,7 +377,7 @@ def get_parser(self, prog_name): ) ) parser.add_argument( - '--recurrence_value', + '--recurrence-value', metavar='', help=_( 'Specifies the frequency, at which actions are triggered\n' @@ -382,13 +388,13 @@ def get_parser(self, prog_name): ) ) parser.add_argument( - '--start_time', + '--start-time', metavar='', help=_('Specifies the start time in of the action in the ' '`YYYY-MM-DDThh:mmZ` format') ) parser.add_argument( - '--end_time', + '--end-time', metavar='', help=_('Specifies the end time in of the action in the ' '`YYYY-MM-DDThh:mmZ` format\n' @@ -401,13 +407,14 @@ def take_action(self, parsed_args): policy_attrs = {} # policy_attrs['name'] = parsed_args.name policy_attrs['scaling_group_id'] = parsed_args.group - policy_type = parsed_args.type.upper() - if policy_type not in self.POLICY_TYPES: - msg = (_('Unsupported policy type. Should be one of %s') - % self.POLICY_TYPES) - raise argparse.ArgumentTypeError(msg) - else: - policy_attrs['type'] = policy_type + if parsed_args.type: + policy_type = parsed_args.type.upper() + if policy_type not in self.POLICY_TYPES: + msg = (_('Unsupported policy type. Should be one of %s') + % self.POLICY_TYPES) + raise argparse.ArgumentTypeError(msg) + else: + policy_attrs['type'] = policy_type if parsed_args.alarm_id: policy_attrs['alarm_id'] = parsed_args.alarm_id if parsed_args.cool_down_time: @@ -437,8 +444,9 @@ def take_action(self, parsed_args): client = self.app.client_manager.auto_scaling + policy = client.get_policy(parsed_args.policy) policy = client.update_policy( - policy=parsed_args.policy, **policy_attrs) + policy, **policy_attrs) fmt = set_attributes_for_print_detail(policy) # display_columns, columns = _get_columns(obj) @@ -475,7 +483,7 @@ def get_parser(self, prog_name): parser.add_argument( 'policy', metavar='', - help=_('AS Policy ID or name') + help=_('AS Policy ID') ) return parser @@ -494,7 +502,7 @@ def get_parser(self, prog_name): parser.add_argument( 'policy', metavar='', - help=_('AS Policy ID or name') + help=_('AS Policy ID') ) return parser diff --git a/otcextensions/sdk/auto_scaling/v1/_base.py b/otcextensions/sdk/auto_scaling/v1/_base.py index c63026088..3538af915 100644 --- a/otcextensions/sdk/auto_scaling/v1/_base.py +++ b/otcextensions/sdk/auto_scaling/v1/_base.py @@ -60,3 +60,15 @@ def _action(self, session, body): url, # endpoint_override=endpoint_override, json=body) + + def commit(self, session, prepend_key=False, has_body=True, + retry_on_conflict=None, base_path=None): + return \ + super(Resource, self).commit(session, prepend_key=prepend_key, + has_body=has_body, + retry_on_conflict=retry_on_conflict, + base_path=base_path) + + def create(self, session, prepend_key=False, base_path=None, **params): + return super(Resource, self).create(session, prepend_key=prepend_key, + base_path=base_path, **params) diff --git a/otcextensions/sdk/auto_scaling/v1/_proxy.py b/otcextensions/sdk/auto_scaling/v1/_proxy.py index 7c020739c..1600db592 100644 --- a/otcextensions/sdk/auto_scaling/v1/_proxy.py +++ b/otcextensions/sdk/auto_scaling/v1/_proxy.py @@ -307,10 +307,11 @@ def delete_policy(self, policy, ignore_missing=True): return self._delete(_policy.Policy, policy, ignore_missing=ignore_missing) - def find_policy(self, name_or_id, ignore_missing=True): + def find_policy(self, name_or_id, group, ignore_missing=True): """Find a single policy :param name_or_id: The name or ID of a policy + :param group: ID of a group :param bool ignore_missing: When set to ``False`` :class:`~openstack.exceptions.ResourceNotFound` will be raised when the policy does not exist. @@ -319,8 +320,10 @@ def find_policy(self, name_or_id, ignore_missing=True): :returns: ``None`` """ + group = self._get_resource(_group.Group, group) return self._find(_policy.Policy, name_or_id, - ignore_missing=ignore_missing) + ignore_missing=ignore_missing, + group_id=group.id) def execute_policy(self, policy): """execute policy diff --git a/otcextensions/sdk/auto_scaling/v1/config.py b/otcextensions/sdk/auto_scaling/v1/config.py index ff551016a..f14f7ae7f 100644 --- a/otcextensions/sdk/auto_scaling/v1/config.py +++ b/otcextensions/sdk/auto_scaling/v1/config.py @@ -54,7 +54,7 @@ class InstanceConfig(resource.Resource): class Config(_base.Resource): - # resource_key = 'scaling_configuration' + resource_key = 'scaling_configuration' resources_key = 'scaling_configurations' base_path = '/scaling_configuration' # query_marker_key = 'start_number' diff --git a/otcextensions/sdk/auto_scaling/v1/group.py b/otcextensions/sdk/auto_scaling/v1/group.py index 7175be6a8..7f135ec3d 100644 --- a/otcextensions/sdk/auto_scaling/v1/group.py +++ b/otcextensions/sdk/auto_scaling/v1/group.py @@ -26,14 +26,14 @@ class Group(_base.Resource): allow_list = True allow_fetch = True allow_delete = True - allow_update = True + allow_commit = True _query_mapping = resource.QueryParameters( - 'scaling_configuration_id', 'scaling_group_name', 'limit', - scaling_group_name='scaling_group_name', - # status='scaling_group_status', - marker=query_marker_key, - limit='limit' + 'id', 'name', 'limit', 'marker', + 'scaling_configuration_id', + name='scaling_group_name', + status='scaling_group_status', + marker=query_marker_key ) #: Properties @@ -49,9 +49,9 @@ class Group(_base.Resource): #: AutoScaling group detail detail = resource.Body('detail') #: VPC id - (Router Id) - network_id = resource.Body('vpc_id') + router_id = resource.Body('vpc_id') #: network id list - (Subnet) - subnetworks = resource.Body('networks', type=list) + networks = resource.Body('networks', type=list) #: security group id list security_groups = resource.Body('security_groups', type=list) #: Auto Scaling Config ID reference, used for creating instance diff --git a/otcextensions/sdk/auto_scaling/v1/policy.py b/otcextensions/sdk/auto_scaling/v1/policy.py index 81d81b64c..f98b6ae31 100644 --- a/otcextensions/sdk/auto_scaling/v1/policy.py +++ b/otcextensions/sdk/auto_scaling/v1/policy.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. from openstack import resource +from openstack import exceptions from otcextensions.sdk.auto_scaling.v1 import _base @@ -41,8 +42,19 @@ class Action(resource.Resource): #: Scaling trigger action type #: valid values include: ``ADD``, ``REMOVE``, ``SET`` operation = resource.Body('operation') - #: The instance number action for - instance_number = resource.Body('instance_number') + #: Number of instances which will be operated by the action + #: Values from 0 to 200 are possible. + #: Note: Use either instance_number or instance_percentage + #: If nothing of instance_number or instance_percentage is set, the + #: default value is 1. + instance_number = resource.Body('instance_number', type=int) + #: Percentage of instances which are currently there to be operated + #: by the action + #: Values from 0 to 20000 are possible. + #: Note: Use either instance_number or instance_percentage + #: If nothing of instance_number or instance_percentage is set, the default + #: value is 1. + instance_percentage = resource.Body('instance_percentage', type=int) class Policy(_base.Resource): @@ -75,14 +87,14 @@ class Policy(_base.Resource): #: valid values include: ``ALARM``, ``SCHEDULED``, ``RECURRENCE`` type = resource.Body('scaling_policy_type') #: AutoScaling group reference the policy apply to - scaling_group_id = resource.URI('scaling_group_id') + scaling_group_id = resource.Body('scaling_group_id') alarm_id = resource.Body('alarm_id') scheduled_policy = resource.Body('scheduled_policy', type=ScheduledPolicy) scaling_policy_action = resource.Body('scaling_policy_action', type=Action) - cool_down_time = resource.Body('cool_down_time') + cool_down_time = resource.Body('cool_down_time', type=int) create_time = resource.Body('create_time') #: valid values include: ``INSERVICE``, ``PAUSED`` status = resource.Body('policy_status') @@ -101,3 +113,58 @@ def resume(self, session): """resume policy""" body = {"action": "resume"} self._action(session, body) + + @classmethod + def find(cls, session, name_or_id, ignore_missing=True, **params): + """Find a resource by its name or id. + + :param session: The session to use for making this request. + :type session: :class:`~keystoneauth1.adapter.Adapter` + :param name_or_id: This resource's identifier, if needed by + the request. The default is ``None``. + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be + raised when the resource does not exist. + When set to ``True``, None will be returned when + attempting to find a nonexistent resource. + :param dict params: Any additional parameters to be passed into + underlying methods, such as to + :meth:`~openstack.resource.Resource.existing` + in order to pass on URI parameters. + + :return: The :class:`Resource` object matching the given name or id + or None if nothing matches. + :raises: :class:`openstack.exceptions.DuplicateResource` if more + than one resource is found for this request. + :raises: :class:`openstack.exceptions.ResourceNotFound` if nothing + is found and ignore_missing is ``False``. + """ + session = cls._get_session(session) + # Try to short-circuit by looking directly for a matching ID. + group_id = params.pop('group_id', None) + try: + match = cls.existing( + id=name_or_id, + connection=session._get_connection(), + **params) + return match.fetch(session, **params) + except exceptions.NotFoundException: + pass + + # if ('name' in cls._query_mapping._mapping.keys() + # and 'name' not in params): + params['name'] = name_or_id + + base_path = '/scaling_policy/{id}/list'.format(id=group_id) + data = cls.list(session, + base_path=base_path, + **params) + + result = cls._get_one_match(name_or_id, data) + if result is not None: + return result + + if ignore_missing: + return None + raise exceptions.ResourceNotFound( + "No %s found for %s" % (cls.__name__, name_or_id)) diff --git a/otcextensions/tests/unit/osclient/auto_scaling/v1/fakes.py b/otcextensions/tests/unit/osclient/auto_scaling/v1/fakes.py index 5b12dd175..8a8dc006e 100644 --- a/otcextensions/tests/unit/osclient/auto_scaling/v1/fakes.py +++ b/otcextensions/tests/unit/osclient/auto_scaling/v1/fakes.py @@ -52,7 +52,7 @@ def generate(cls): 'id': 'id-' + uuid.uuid4().hex, 'status': 'SOME STATUS', 'detail': 'detail-' + uuid.uuid4().hex, - 'network_id': 'id-vpc-' + uuid.uuid4().hex, + 'router_id': 'id-vpc-' + uuid.uuid4().hex, } obj = group.Group.existing(**object_info) return obj diff --git a/otcextensions/tests/unit/osclient/auto_scaling/v1/test_activity.py b/otcextensions/tests/unit/osclient/auto_scaling/v1/test_activity.py index 30da58ba4..63132fc85 100644 --- a/otcextensions/tests/unit/osclient/auto_scaling/v1/test_activity.py +++ b/otcextensions/tests/unit/osclient/auto_scaling/v1/test_activity.py @@ -58,10 +58,10 @@ def setUp(self): def test_list_default(self): arglist = [ - '--start_time', '2200-01-01T00:00:00Z', - '--end_time', '2200-01-02T00:00:00Z', + '--start-time', '2200-01-01T00:00:00Z', + '--end-time', '2200-01-02T00:00:00Z', '--limit', '14', - 'group1' + '--group', 'group1' ] verifylist = [ diff --git a/otcextensions/tests/unit/osclient/auto_scaling/v1/test_config.py b/otcextensions/tests/unit/osclient/auto_scaling/v1/test_config.py index f19a953a6..295e900ff 100644 --- a/otcextensions/tests/unit/osclient/auto_scaling/v1/test_config.py +++ b/otcextensions/tests/unit/osclient/auto_scaling/v1/test_config.py @@ -172,7 +172,7 @@ def test_create_ok(self): arglist = [ 'config_name', '--flavor', 'some_flavor', - '--image_id', 'some_image', + '--image-id', 'some_image', '--disk', 'SYS,SSD,10', '--disk', 'DATA,SSD,5', ] diff --git a/otcextensions/tests/unit/osclient/auto_scaling/v1/test_group.py b/otcextensions/tests/unit/osclient/auto_scaling/v1/test_group.py index 6c98e5011..95e3472fb 100644 --- a/otcextensions/tests/unit/osclient/auto_scaling/v1/test_group.py +++ b/otcextensions/tests/unit/osclient/auto_scaling/v1/test_group.py @@ -50,10 +50,19 @@ def setUp(self): def test_list_default(self): arglist = [ + '--name', 'grp', + '--status', 'PAUSED', + '--scaling-configuration-id', '2', + '--limit', '12' ] verifylist = [ + ('name', 'grp'), + ('status', 'PAUSED'), + ('scaling_configuration_id', '2'), + ('limit', 12) ] + # Verify cm is triggereg with default parameters parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -65,7 +74,11 @@ def test_list_default(self): # Trigger the action columns, data = self.cmd.take_action(parsed_args) - self.client.groups.assert_called_once_with() + self.client.groups.assert_called_once_with( + name='grp', + status='PAUSED', + scaling_configuration_id='2', + limit=12) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) @@ -73,7 +86,7 @@ def test_list_default(self): class TestShowAutoScalingGroup(TestAutoScalingGroup): - columns = ('create_time', 'detail', 'id', 'name', 'network_id', 'status') + columns = ('create_time', 'detail', 'id', 'name', 'router_id', 'status') _group = fakes.FakeGroup.create_one() @@ -82,7 +95,7 @@ class TestShowAutoScalingGroup(TestAutoScalingGroup): _group.detail, _group.id, _group.name, - _group.network_id, + _group.router_id, _group.status, ) @@ -119,7 +132,7 @@ def test_show_default(self): class TestCreateAutoScalingGroup(TestAutoScalingGroup): - columns = ('create_time', 'detail', 'id', 'name', 'network_id', 'status') + columns = ('create_time', 'detail', 'id', 'name', 'router_id', 'status') _group = fakes.FakeGroup.create_one() @@ -128,7 +141,7 @@ class TestCreateAutoScalingGroup(TestAutoScalingGroup): _group.detail, _group.id, _group.name, - _group.network_id, + _group.router_id, _group.status, ) @@ -141,23 +154,23 @@ def setUp(self): def test_create(self): arglist = [ - '--desire_instance_number', '10', - '--min_instance_number', '1', - '--max_instance_number', '15', - '--cool_down_time', '1', - '--availability_zone', 'eu-1', - '--availability_zone', 'eu-2', - '--subnet', 'sub1', - '--subnet', 'sub2', - '--router', 'vpc-1', - '--security_group', 'sg1', - '--security_group', 'sg2', - '--lb_listener_id', 'lb1', - '--lbaas_listener', 'lbas1:14', - '--lbaas_listener', 'lbas2:15:10', - '--audit_method', 'some_method', - '--audit_time', '15', - '--terminate_policy', 'pol', + '--desire-instance-number', '10', + '--min-instance-number', '1', + '--max-instance-number', '15', + '--cool-down-time', '1', + '--availability-zone', 'eu-1', + '--availability-zone', 'eu-2', + '--network-id', 'sub1', + '--network-id', 'sub2', + '--router-id', 'vpc-1', + '--security-group', 'sg1', + '--security-group', 'sg2', + '--lb-listener-id', 'lb1', + '--lbaas-listener', 'lbas1:14', + '--lbaas-listener', 'lbas2:15:10', + '--audit-method', 'some_method', + '--audit-time', '15', + '--terminate-policy', 'pol', '--notification', 'EMAIL', '--notification', 'SMS', @@ -169,9 +182,9 @@ def test_create(self): ('max_instance_number', 15), ('cool_down_time', 1), ('availability_zone', ['eu-1', 'eu-2']), - ('subnet', ['sub1', 'sub2']), + ('network_id', ['sub1', 'sub2']), ('security_group', ['sg1', 'sg2']), - ('router', 'vpc-1'), + ('router_id', 'vpc-1'), ('lb_listener_id', 'lb1'), ('lbaas_listener', ['lbas1:14', 'lbas2:15:10']), ('audit_method', 'some_method'), @@ -208,7 +221,7 @@ def test_create(self): networks=[{'id': 'sub1'}, {'id': 'sub2'}], notifications=['EMAIL', 'SMS'], security_groups=[{'id': 'sg1'}, {'id': 'sg2'}], - vpc_id='vpc-1' + router_id='vpc-1' ) self.assertEqual(self.columns, columns) @@ -245,7 +258,7 @@ def test_sdelete(self): class TestUpdateAutoScalingGroup(TestAutoScalingGroup): - columns = ('create_time', 'detail', 'id', 'name', 'network_id', 'status') + columns = ('create_time', 'detail', 'id', 'name', 'router_id', 'status') _group = fakes.FakeGroup.create_one() @@ -254,7 +267,7 @@ class TestUpdateAutoScalingGroup(TestAutoScalingGroup): _group.detail, _group.id, _group.name, - _group.network_id, + _group.router_id, _group.status, ) @@ -267,23 +280,23 @@ def setUp(self): def test_create(self): arglist = [ - '--desire_instance_number', '10', - '--min_instance_number', '1', - '--max_instance_number', '15', - '--cool_down_time', '1', - '--availability_zone', 'eu-1', - '--availability_zone', 'eu-2', - '--subnetwork', 'sub1', - '--subnetwork', 'sub2', - '--network_id', 'vpc-1', - '--security_group', 'sg1', - '--security_group', 'sg2', - '--lb_listener_id', 'lb1', - '--lbaas_listener', 'lbas1:14', - '--lbaas_listener', 'lbas2:15:10', - '--audit_method', 'some_method', - '--audit_time', '15', - '--terminate_policy', 'pol', + '--desire-instance-number', '10', + '--min-instance-number', '1', + '--max-instance-number', '15', + '--cool-down-time', '1', + '--availability-zone', 'eu-1', + '--availability-zone', 'eu-2', + '--network-id', 'sub1', + '--network-id', 'sub2', + '--router-id', 'vpc-1', + '--security-group', 'sg1', + '--security-group', 'sg2', + '--lb-listener-id', 'lb1', + '--lbaas-listener', 'lbas1:14', + '--lbaas-listener', 'lbas2:15:10', + '--audit-method', 'some_method', + '--audit-time', '15', + '--terminate-policy', 'pol', '--notification', 'EMAIL', '--notification', 'SMS', @@ -295,9 +308,9 @@ def test_create(self): ('max_instance_number', 15), ('cool_down_time', 1), ('availability_zone', ['eu-1', 'eu-2']), - ('subnetwork', ['sub1', 'sub2']), + ('network_id', ['sub1', 'sub2']), ('security_group', ['sg1', 'sg2']), - ('network_id', 'vpc-1'), + ('router_id', 'vpc-1'), ('lb_listener_id', 'lb1'), ('lbaas_listener', ['lbas1:14', 'lbas2:15:10']), ('audit_method', 'some_method'), @@ -314,10 +327,15 @@ def test_create(self): self._group ] + self.client.find_group.side_effect = [ + self._group + ] + # Trigger the action columns, data = self.cmd.take_action(parsed_args) self.client.update_group.assert_called_with( + self._group, available_zones=['eu-1', 'eu-2'], cool_down_time=1, desire_instance_number=10, @@ -330,11 +348,10 @@ def test_create(self): {'id': 'lbas2', 'protocol_port': '15', 'weight': '10'}], max_instance_number=15, min_instance_number=1, - group='test_name', networks=[{'id': 'sub1'}, {'id': 'sub2'}], notifications=['EMAIL', 'SMS'], security_groups=[{'id': 'sg1'}, {'id': 'sg2'}], - vpc_id='vpc-1' + router_id='vpc-1' ) self.assertEqual(self.columns, columns) diff --git a/otcextensions/tests/unit/osclient/auto_scaling/v1/test_instance.py b/otcextensions/tests/unit/osclient/auto_scaling/v1/test_instance.py index 0fd9b4dc0..9b94ea5d0 100644 --- a/otcextensions/tests/unit/osclient/auto_scaling/v1/test_instance.py +++ b/otcextensions/tests/unit/osclient/auto_scaling/v1/test_instance.py @@ -57,9 +57,9 @@ def setUp(self): def test_list(self): arglist = [ - 'grp', - '--life_cycle_state', 'lc', - '--health_status', 'hs', + '--group', 'grp', + '--life-cycle-state', 'lc', + '--health-status', 'hs', '--limit', '12' ] @@ -111,7 +111,7 @@ def setUp(self): def test_remove(self): arglist = [ 'Instance1', - '--delete_instance' + '--delete-instance' ] verifylist = [ ('instance', 'Instance1'), @@ -140,10 +140,10 @@ def setUp(self): def test_wrong_action(self): arglist = [ - 'grp1', + '--group', 'grp1', 'ADD1', 'Instance1', - '--delete_instance', + '--delete-instance', ] verifylist = [ ('instance', ['Instance1']), @@ -159,7 +159,7 @@ def test_wrong_action(self): def test_add(self): arglist = [ - 'grp1', + '--group', 'grp1', 'ADD', 'Instance1', ] @@ -185,11 +185,11 @@ def test_add(self): def test_remove(self): arglist = [ - 'grp1', + '--group', 'grp1', 'REMOVE', 'Instance1', 'Instance2', - '--delete_instance', + '--delete-instance', ] verifylist = [ ('instance', ['Instance1', 'Instance2']), @@ -214,7 +214,7 @@ def test_remove(self): def test_protect(self): arglist = [ - 'grp1', + '--group', 'grp1', 'protect', 'Instance1', 'Instance2', @@ -241,7 +241,7 @@ def test_protect(self): def test_unprotect(self): arglist = [ - 'grp1', + '--group', 'grp1', 'unProtect', 'Instance1', 'Instance2', diff --git a/otcextensions/tests/unit/osclient/auto_scaling/v1/test_policy.py b/otcextensions/tests/unit/osclient/auto_scaling/v1/test_policy.py index 8e0a668b5..feab2f710 100644 --- a/otcextensions/tests/unit/osclient/auto_scaling/v1/test_policy.py +++ b/otcextensions/tests/unit/osclient/auto_scaling/v1/test_policy.py @@ -171,15 +171,15 @@ def test_create(self): arglist = [ '--group', 'group1', '--type', 'ALARM', - '--cool_down_time', '1', - '--alarm_id', 'alarm1', - '--action_operation', 'ADD', - '--action_instance_number', '7', - '--launch_time', 'launch_time1', - '--recurrence_type', 'recurrence_type1', - '--recurrence_value', 'recurrence_value1', - '--start_time', 'st1', - '--end_time', 'et1', + '--cool-down-time', '1', + '--alarm-id', 'alarm1', + '--action-operation', 'ADD', + '--action-instance-number', '7', + '--launch-time', 'launch_time1', + '--recurrence-type', 'recurrence_type1', + '--recurrence-value', 'recurrence_value1', + '--start-time', 'st1', + '--end-time', 'et1', 'test_name' ] @@ -292,15 +292,15 @@ def test_create(self): arglist = [ '--group', 'group1', '--type', 'ALARM', - '--cool_down_time', '1', - '--alarm_id', 'alarm1', - '--action_operation', 'ADD', - '--action_instance_number', '7', - '--launch_time', 'launch_time1', - '--recurrence_type', 'recurrence_type1', - '--recurrence_value', 'recurrence_value1', - '--start_time', 'st1', - '--end_time', 'et1', + '--cool-down-time', '1', + '--alarm-id', 'alarm1', + '--action-operation', 'ADD', + '--action-instance-number', '7', + '--launch-time', 'launch_time1', + '--recurrence-type', 'recurrence_type1', + '--recurrence-value', 'recurrence_value1', + '--start-time', 'st1', + '--end-time', 'et1', 'policy1' ] @@ -326,13 +326,17 @@ def test_create(self): self._obj ] + self.client.get_policy.side_effect = [ + self._obj + ] + # Trigger the action columns, data = self.cmd.take_action(parsed_args) self.client.update_policy.assert_called_with( + self._obj, alarm_id='alarm1', cool_down_time=1, - policy='policy1', scaling_group_id='group1', scaling_policy_action={'operation': 'ADD', 'instance_number': 7}, scheduled_policy={ diff --git a/otcextensions/tests/unit/sdk/auto_scaling/v1/test_group.py b/otcextensions/tests/unit/sdk/auto_scaling/v1/test_group.py index e825cc740..72cb7610d 100644 --- a/otcextensions/tests/unit/sdk/auto_scaling/v1/test_group.py +++ b/otcextensions/tests/unit/sdk/auto_scaling/v1/test_group.py @@ -73,7 +73,7 @@ def test_basic(self): self.assertTrue(sot.allow_list) self.assertTrue(sot.allow_create) self.assertTrue(sot.allow_get) - self.assertTrue(sot.allow_update) + self.assertTrue(sot.allow_commit) self.assertTrue(sot.allow_delete) def test_make_it(self): diff --git a/otcextensions/tests/unit/sdk/auto_scaling/v1/test_policy.py b/otcextensions/tests/unit/sdk/auto_scaling/v1/test_policy.py index 3e0b220bc..b0a9fcc86 100644 --- a/otcextensions/tests/unit/sdk/auto_scaling/v1/test_policy.py +++ b/otcextensions/tests/unit/sdk/auto_scaling/v1/test_policy.py @@ -137,7 +137,6 @@ def test_create(self): call_args = self.sess.post.call_args_list[0] expected_json = copy.deepcopy(EXAMPLE) - expected_json.pop('scaling_group_id') self.assertEqual('/scaling_policy', call_args[0][0]) self.assertDictEqual(expected_json, call_args[1]['json']) @@ -184,7 +183,6 @@ def test_update(self): expected_json = copy.deepcopy(EXAMPLE) expected_json.pop('scaling_policy_id') - expected_json.pop('scaling_group_id') self.assertEqual( 'scaling_policy/%s' % EXAMPLE['scaling_policy_id'], diff --git a/otcextensions/tests/unit/sdk/auto_scaling/v1/test_proxy.py b/otcextensions/tests/unit/sdk/auto_scaling/v1/test_proxy.py index 248d8212e..467f6227a 100644 --- a/otcextensions/tests/unit/sdk/auto_scaling/v1/test_proxy.py +++ b/otcextensions/tests/unit/sdk/auto_scaling/v1/test_proxy.py @@ -184,10 +184,14 @@ def test_find(self): self._verify2( 'openstack.proxy.Proxy._find', self.proxy.find_policy, - method_args=['pol'], + method_args=['pol', 'group'], + method_kwargs={}, expected_args=[_policy.Policy, 'pol'], expected_kwargs={ - 'ignore_missing': True}) + 'ignore_missing': True, + 'group_id': 'group' + } + ) def test_update(self): self._verify2( diff --git a/setup.cfg b/setup.cfg index 65555cce7..02db5bd22 100644 --- a/setup.cfg +++ b/setup.cfg @@ -121,6 +121,7 @@ openstack.auto_scaling.v1 = as_policy_execute = otcextensions.osclient.auto_scaling.v1.policy:ExecuteAutoScalingPolicy as_policy_enable = otcextensions.osclient.auto_scaling.v1.policy:EnableAutoScalingPolicy as_policy_disable = otcextensions.osclient.auto_scaling.v1.policy:DisableAutoScalingPolicy + as_policy_delete = otcextensions.osclient.auto_scaling.v1.policy:DeleteAutoScalingPolicy as_instance_list = otcextensions.osclient.auto_scaling.v1.instance:ListAutoScalingInstance as_instance_remove = otcextensions.osclient.auto_scaling.v1.instance:RemoveAutoScalingInstance as_instance_batch = otcextensions.osclient.auto_scaling.v1.instance:BatchActionAutoScalingInstance