From aab9ca0eeba65ce1a40116b6413b7d852c6fab8c Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Wed, 4 Sep 2019 15:22:52 -0500 Subject: [PATCH 01/24] fixed type in readme.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 1f8fb872a..51ea9074a 100644 --- a/README.rst +++ b/README.rst @@ -94,7 +94,7 @@ For the CLI, just use the -vvv option. If you are using the REST endpoint, this If you are using the library directly in python, you can do something like this. -.. code-bock:: python +.. code-block:: python import SoftLayer import logging From ef284ae196d7d18aeadec6995c258d13d4c0b946 Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Wed, 25 Sep 2019 13:51:19 -0500 Subject: [PATCH 02/24] skeleton for autoscale --- SoftLayer/CLI/autoscale/__init__.py | 0 SoftLayer/CLI/autoscale/list.py | 25 +++++++++++++++++++++++++ SoftLayer/CLI/routes.py | 3 +++ SoftLayer/managers/autoscale.py | 19 +++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 SoftLayer/CLI/autoscale/__init__.py create mode 100644 SoftLayer/CLI/autoscale/list.py create mode 100644 SoftLayer/managers/autoscale.py diff --git a/SoftLayer/CLI/autoscale/__init__.py b/SoftLayer/CLI/autoscale/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/SoftLayer/CLI/autoscale/list.py b/SoftLayer/CLI/autoscale/list.py new file mode 100644 index 000000000..031df2cf3 --- /dev/null +++ b/SoftLayer/CLI/autoscale/list.py @@ -0,0 +1,25 @@ +"""List virtual servers.""" +# :license: MIT, see LICENSE for more details. + +import click + +import SoftLayer +from SoftLayer.CLI import columns as column_helper +from SoftLayer.CLI import environment +from SoftLayer.CLI import formatting +from SoftLayer.CLI import helpers +from SoftLayer.managers.autoscale import AutoScaleManager + + +@click.command() +@environment.pass_env +def cli(env): + """List AutoScale Groups.""" + + autoscale = AutoScaleManager(env.client) + groups = autoscale.list() + print(groups) + # table = formatting.Table() + + + # env.fout(table) diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py index fb33ee9e2..a97fb9d4b 100644 --- a/SoftLayer/CLI/routes.py +++ b/SoftLayer/CLI/routes.py @@ -302,6 +302,9 @@ ('report', 'SoftLayer.CLI.report'), ('report:bandwidth', 'SoftLayer.CLI.report.bandwidth:cli'), + + ('autoscale', 'SoftLayer.CLI.autoscale'), + ('autoscale:list', 'SoftLayer.CLI.autoscale.list:cli'), ] ALL_ALIASES = { diff --git a/SoftLayer/managers/autoscale.py b/SoftLayer/managers/autoscale.py new file mode 100644 index 000000000..7e823f98a --- /dev/null +++ b/SoftLayer/managers/autoscale.py @@ -0,0 +1,19 @@ +""" + SoftLayer.autoscale + ~~~~~~~~~~~~ + Autoscale manager + + :license: MIT, see LICENSE for more details. +""" + + + +class AutoScaleManager(object): + + def __init__(self, client): + self.client = client + + + def list(self): + print("LISTING....") + return True \ No newline at end of file From e00e4cff8de50e11bfa9053d50d414e75766c330 Mon Sep 17 00:00:00 2001 From: Christopher Gallo Date: Wed, 25 Sep 2019 16:44:43 -0500 Subject: [PATCH 03/24] autoscale detail and list --- SoftLayer/CLI/autoscale/detail.py | 47 +++++++++++++++++++++++++++++++ SoftLayer/CLI/autoscale/list.py | 18 +++++++++--- SoftLayer/CLI/routes.py | 1 + SoftLayer/managers/autoscale.py | 15 ++++++++-- 4 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 SoftLayer/CLI/autoscale/detail.py diff --git a/SoftLayer/CLI/autoscale/detail.py b/SoftLayer/CLI/autoscale/detail.py new file mode 100644 index 000000000..5fa987154 --- /dev/null +++ b/SoftLayer/CLI/autoscale/detail.py @@ -0,0 +1,47 @@ +"""List Autoscale groups.""" +# :license: MIT, see LICENSE for more details. + +import click + +import SoftLayer +from SoftLayer.CLI import columns as column_helper +from SoftLayer.CLI import environment +from SoftLayer.CLI import formatting +from SoftLayer.CLI import helpers +from SoftLayer.managers.autoscale import AutoScaleManager +from SoftLayer import utils + +from pprint import pprint as pp + +@click.command() +@click.argument('identifier') +@environment.pass_env +def cli(env, identifier): + """List AutoScale Groups.""" + + autoscale = AutoScaleManager(env.client) + group = autoscale.details(identifier) + # print(groups) + # pp(group) + table = formatting.KeyValueTable(["Name", "Value"]) + + table.add_row(['Id', group.get('id')]) + # Ideally we would use regionalGroup->preferredDatacenter, but that generates an error. + table.add_row(['Datacenter', group['regionalGroup']['locations'][0]['longName']]) + table.add_row(['Termination', utils.lookup(group, 'terminationPolicy', 'name')]) + table.add_row(['Minimum Members', group.get('minimumMemberCount')]) + table.add_row(['Maximum Members', group.get('maximumMemberCount')]) + table.add_row(['Current Members', group.get('virtualGuestMemberCount')]) + table.add_row(['Last Action', utils.clean_time(group.get('lastActionDate'))]) + + for network in group.get('networkVlans'): + network_type = utils.lookup(network, 'networkVlan', 'networkSpace') + router = utils.lookup(network, 'networkVlan', 'primaryRouter', 'hostname') + vlan_number = utils.lookup(network, 'networkVlan', 'vlanNumber') + vlan_name = "{}.{}".format(router, vlan_number) + table.add_row([network_type, vlan_name]) + + + + + env.fout(table) diff --git a/SoftLayer/CLI/autoscale/list.py b/SoftLayer/CLI/autoscale/list.py index 031df2cf3..2e427285b 100644 --- a/SoftLayer/CLI/autoscale/list.py +++ b/SoftLayer/CLI/autoscale/list.py @@ -1,4 +1,4 @@ -"""List virtual servers.""" +"""List Autoscale groups.""" # :license: MIT, see LICENSE for more details. import click @@ -9,7 +9,9 @@ from SoftLayer.CLI import formatting from SoftLayer.CLI import helpers from SoftLayer.managers.autoscale import AutoScaleManager +from SoftLayer import utils +from pprint import pprint as pp @click.command() @environment.pass_env @@ -18,8 +20,16 @@ def cli(env): autoscale = AutoScaleManager(env.client) groups = autoscale.list() - print(groups) - # table = formatting.Table() + # print(groups) + # pp(groups) + table = formatting.Table(["Id", "Name", "Status", "Min/Max", "Running"]) + for group in groups: + status = utils.lookup(group, 'status', 'name') + min_max = "{}/{}".format(group.get('minimumMemberCount', '-'), group.get('maximumMemberCount'), '-') + table.add_row([ + group.get('id'), group.get('name'), status, min_max, group.get('virtualGuestMemberCount') + ]) - # env.fout(table) + + env.fout(table) diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py index a97fb9d4b..9b144e396 100644 --- a/SoftLayer/CLI/routes.py +++ b/SoftLayer/CLI/routes.py @@ -305,6 +305,7 @@ ('autoscale', 'SoftLayer.CLI.autoscale'), ('autoscale:list', 'SoftLayer.CLI.autoscale.list:cli'), + ('autoscale:detail', 'SoftLayer.CLI.autoscale.detail:cli'), ] ALL_ALIASES = { diff --git a/SoftLayer/managers/autoscale.py b/SoftLayer/managers/autoscale.py index 7e823f98a..37f244aca 100644 --- a/SoftLayer/managers/autoscale.py +++ b/SoftLayer/managers/autoscale.py @@ -14,6 +14,15 @@ def __init__(self, client): self.client = client - def list(self): - print("LISTING....") - return True \ No newline at end of file + def list(self, mask=None): + if not mask: + mask = "mask[status,virtualGuestMemberCount]" + + return self.client.call('SoftLayer_Account', 'getScaleGroups', mask=mask, iter=True) + + def details(self, identifier, mask=None): + if not mask: + mask = """mask[virtualGuestMembers, terminationPolicy, policies, virtualGuestMemberCount, + networkVlans[networkVlanId,networkVlan[networkSpace,primaryRouter[hostname]]], + loadBalancers, regionalGroup[locations]]""" + return self.client.call('SoftLayer_Scale_Group', 'getObject', id=identifier, mask=mask) \ No newline at end of file From feb8f9aa66687c0df799dfe764f6e9d01bf4c86a Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Thu, 26 Sep 2019 17:55:25 -0500 Subject: [PATCH 04/24] autoscale details mostly done --- SoftLayer/CLI/autoscale/detail.py | 62 ++++++++++++++++++++++++++++++- SoftLayer/managers/autoscale.py | 14 ++++++- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/SoftLayer/CLI/autoscale/detail.py b/SoftLayer/CLI/autoscale/detail.py index 5fa987154..bf11de900 100644 --- a/SoftLayer/CLI/autoscale/detail.py +++ b/SoftLayer/CLI/autoscale/detail.py @@ -23,7 +23,9 @@ def cli(env, identifier): group = autoscale.details(identifier) # print(groups) # pp(group) - table = formatting.KeyValueTable(["Name", "Value"]) + + # Group Config Table + table = formatting.KeyValueTable(["Group", "Value"]) table.add_row(['Id', group.get('id')]) # Ideally we would use regionalGroup->preferredDatacenter, but that generates an error. @@ -32,6 +34,7 @@ def cli(env, identifier): table.add_row(['Minimum Members', group.get('minimumMemberCount')]) table.add_row(['Maximum Members', group.get('maximumMemberCount')]) table.add_row(['Current Members', group.get('virtualGuestMemberCount')]) + table.add_row(['Cooldown', "{} seconds".format(group.get('cooldown'))]) table.add_row(['Last Action', utils.clean_time(group.get('lastActionDate'))]) for network in group.get('networkVlans'): @@ -41,7 +44,62 @@ def cli(env, identifier): vlan_name = "{}.{}".format(router, vlan_number) table.add_row([network_type, vlan_name]) + env.fout(table) + # Template Config Table + config_table = formatting.KeyValueTable(["Template", "Value"]) + template = group.get('virtualGuestMemberTemplate') + + config_table.add_row(['Hostname', template.get('hostname')]) + config_table.add_row(['Domain', template.get('domain')]) + config_table.add_row(['Core', template.get('startCpus')]) + config_table.add_row(['Ram', template.get('maxMemory')]) + network = template.get('networkComponents') + config_table.add_row(['Network', network[0]['maxSpeed']]) + ssh_keys = template.get('sshKeys', []) + ssh_manager = SoftLayer.SshKeyManager(env.client) + for key in ssh_keys: + # Label isn't included when retrieved from the AutoScale group... + ssh_key = ssh_manager.get_key(key.get('id')) + config_table.add_row(['SSH Key {}'.format(ssh_key.get('id')), ssh_key.get('label')]) + disks = template.get('blockDevices') + disk_type = "SAN" + if template.get('localDiskFlag'): + disk_type = "Local" + for disk in disks: + disk_image = disk.get('diskImage') + config_table.add_row(['{} Disk {}'.format(disk_type, disk.get('device')), disk_image.get('capacity')]) + config_table.add_row(['OS', template.get('operatingSystemReferenceCode')]) + config_table.add_row(['Post Install', template.get('postInstallScriptUri') or 'None']) - env.fout(table) + env.fout(config_table) + + + # Policy Config Table + policy_table = formatting.KeyValueTable(["Policy", "Cooldown"]) + policies = group.get('policies') + # pp(policies) + for policy in policies: + policy_table.add_row([policy.get('name'), policy.get('cooldown') or group.get('cooldown')]) + # full_policy = autoscale.get_policy(policy.get('id')) + # pp(full_policy) + + env.fout(policy_table) + + # LB Config Table + # Not sure if this still still a thing? + # lb_table = formatting.KeyValueTable(["Load Balancer", "Value"]) + # loadbal = group.get('loadBalancers') + + # env.fout(lb_table) + + # Active Guests + member_table = formatting.Table(['Id', 'Hostname', 'Created'], title="Active Guests") + guests = group.get('virtualGuestMembers') + for guest in guests: + real_guest = guest.get('virtualGuest') + member_table.add_row([ + guest.get('id'), real_guest.get('hostname'), utils.clean_time(real_guest.get('provisionDate')) + ]) + env.fout(member_table) diff --git a/SoftLayer/managers/autoscale.py b/SoftLayer/managers/autoscale.py index 37f244aca..302e223a1 100644 --- a/SoftLayer/managers/autoscale.py +++ b/SoftLayer/managers/autoscale.py @@ -22,7 +22,17 @@ def list(self, mask=None): def details(self, identifier, mask=None): if not mask: - mask = """mask[virtualGuestMembers, terminationPolicy, policies, virtualGuestMemberCount, + mask = """mask[virtualGuestMembers[id,virtualGuest[hostname,domain,provisionDate]], terminationPolicy, + virtualGuestMemberCount, virtualGuestMemberTemplate[sshKeys], + policies[id,name,createDate,cooldown,actions,triggers,scaleActions], networkVlans[networkVlanId,networkVlan[networkSpace,primaryRouter[hostname]]], loadBalancers, regionalGroup[locations]]""" - return self.client.call('SoftLayer_Scale_Group', 'getObject', id=identifier, mask=mask) \ No newline at end of file + return self.client.call('SoftLayer_Scale_Group', 'getObject', id=identifier, mask=mask) + + def get_policy(self, identifier, mask=None): + if not mask: + mask = """mask[cooldown, createDate, id, name, actions, triggers[type] + + ]""" + + return self.client.call('SoftLayer_Scale_Policy', 'getObject', id=identifier, mask=mask) From ebc80cd56bb406f014e48cbb8bd7b1fb33b419ea Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Fri, 27 Sep 2019 13:40:24 -0500 Subject: [PATCH 05/24] added autoscale scale commands --- SoftLayer/CLI/autoscale/detail.py | 21 ++---------- SoftLayer/CLI/autoscale/list.py | 3 -- SoftLayer/CLI/autoscale/scale.py | 56 +++++++++++++++++++++++++++++++ SoftLayer/CLI/routes.py | 1 + SoftLayer/managers/autoscale.py | 36 ++++++++++++++++++++ 5 files changed, 95 insertions(+), 22 deletions(-) create mode 100644 SoftLayer/CLI/autoscale/scale.py diff --git a/SoftLayer/CLI/autoscale/detail.py b/SoftLayer/CLI/autoscale/detail.py index bf11de900..31c29bed7 100644 --- a/SoftLayer/CLI/autoscale/detail.py +++ b/SoftLayer/CLI/autoscale/detail.py @@ -1,28 +1,23 @@ -"""List Autoscale groups.""" +"""Get details of an Autoscale groups.""" # :license: MIT, see LICENSE for more details. import click import SoftLayer -from SoftLayer.CLI import columns as column_helper from SoftLayer.CLI import environment from SoftLayer.CLI import formatting -from SoftLayer.CLI import helpers from SoftLayer.managers.autoscale import AutoScaleManager from SoftLayer import utils -from pprint import pprint as pp @click.command() @click.argument('identifier') @environment.pass_env def cli(env, identifier): - """List AutoScale Groups.""" + """Get details of an Autoscale groups.""" autoscale = AutoScaleManager(env.client) group = autoscale.details(identifier) - # print(groups) - # pp(group) # Group Config Table table = formatting.KeyValueTable(["Group", "Value"]) @@ -46,7 +41,6 @@ def cli(env, identifier): env.fout(table) - # Template Config Table config_table = formatting.KeyValueTable(["Template", "Value"]) template = group.get('virtualGuestMemberTemplate') @@ -75,25 +69,14 @@ def cli(env, identifier): env.fout(config_table) - # Policy Config Table policy_table = formatting.KeyValueTable(["Policy", "Cooldown"]) policies = group.get('policies') - # pp(policies) for policy in policies: policy_table.add_row([policy.get('name'), policy.get('cooldown') or group.get('cooldown')]) - # full_policy = autoscale.get_policy(policy.get('id')) - # pp(full_policy) env.fout(policy_table) - # LB Config Table - # Not sure if this still still a thing? - # lb_table = formatting.KeyValueTable(["Load Balancer", "Value"]) - # loadbal = group.get('loadBalancers') - - # env.fout(lb_table) - # Active Guests member_table = formatting.Table(['Id', 'Hostname', 'Created'], title="Active Guests") guests = group.get('virtualGuestMembers') diff --git a/SoftLayer/CLI/autoscale/list.py b/SoftLayer/CLI/autoscale/list.py index 2e427285b..043a0892e 100644 --- a/SoftLayer/CLI/autoscale/list.py +++ b/SoftLayer/CLI/autoscale/list.py @@ -4,14 +4,11 @@ import click import SoftLayer -from SoftLayer.CLI import columns as column_helper from SoftLayer.CLI import environment from SoftLayer.CLI import formatting -from SoftLayer.CLI import helpers from SoftLayer.managers.autoscale import AutoScaleManager from SoftLayer import utils -from pprint import pprint as pp @click.command() @environment.pass_env diff --git a/SoftLayer/CLI/autoscale/scale.py b/SoftLayer/CLI/autoscale/scale.py new file mode 100644 index 000000000..f93a5953a --- /dev/null +++ b/SoftLayer/CLI/autoscale/scale.py @@ -0,0 +1,56 @@ +"""Scales an Autoscale group""" +# :license: MIT, see LICENSE for more details. + +import click + +import SoftLayer +from SoftLayer.CLI import environment +from SoftLayer.CLI import formatting +from SoftLayer.managers.autoscale import AutoScaleManager +from SoftLayer import utils + + +@click.command() +@click.argument('identifier') +@click.option('--up/--down', 'scale_up', is_flag=True, default=True, + help="'--up' adds guests, '--down' removes guests.") +@click.option('--by/--to', 'scale_by', is_flag=True, required=True, + help="'--by' will add/remove the specified number of guests." \ + " '--to' will add/remove a number of guests to get the group's guest count to the specified number.") +@click.option('--amount', required=True, type=click.INT, help="Number of guests for the scale action.") +@environment.pass_env +def cli(env, identifier, scale_up, scale_by, amount): + """Scales an Autoscale group. Bypasses a scale group's cooldown period.""" + + autoscale = AutoScaleManager(env.client) + + # Scale By, and go down, need to use negative amount + if not scale_up and scale_by: + amount = amount * -1 + + result = [] + if scale_by: + click.secho("Scaling group {} by {}".format(identifier, amount), fg='green') + result = autoscale.scale(identifier, amount) + else: + click.secho("Scaling group {} to {}".format(identifier, amount), fg='green') + result = autoscale.scale_to(identifier, amount) + + try: + # Check if the first guest has a cancellation date, assume we are removing guests if it is. + cancellationDate = result[0]['virtualGuest']['billingItem']['cancellationDate'] or False + except (IndexError, KeyError, TypeError) as e: + cancellationDate = False + + if cancellationDate: + member_table = formatting.Table(['Id', 'Hostname', 'Created'], title="Cancelled Guests") + else: + member_table = formatting.Table(['Id', 'Hostname', 'Created'], title="Added Guests") + + for guest in result: + real_guest = guest.get('virtualGuest') + member_table.add_row([ + guest.get('id'), real_guest.get('hostname'), utils.clean_time(real_guest.get('createDate')) + ]) + + env.fout(member_table) diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py index 9b144e396..1d7575f5d 100644 --- a/SoftLayer/CLI/routes.py +++ b/SoftLayer/CLI/routes.py @@ -306,6 +306,7 @@ ('autoscale', 'SoftLayer.CLI.autoscale'), ('autoscale:list', 'SoftLayer.CLI.autoscale.list:cli'), ('autoscale:detail', 'SoftLayer.CLI.autoscale.detail:cli'), + ('autoscale:scale', 'SoftLayer.CLI.autoscale.scale:cli'), ] ALL_ALIASES = { diff --git a/SoftLayer/managers/autoscale.py b/SoftLayer/managers/autoscale.py index 302e223a1..fe4d1475c 100644 --- a/SoftLayer/managers/autoscale.py +++ b/SoftLayer/managers/autoscale.py @@ -15,12 +15,23 @@ def __init__(self, client): def list(self, mask=None): + """Calls SoftLayer_Account getScaleGroups()_ + + :param mask: optional SoftLayer_Scale_Group objectMask + .. getScaleGroups(): https://sldn.softlayer.com/reference/services/SoftLayer_Account/getScaleGroups/ + """ if not mask: mask = "mask[status,virtualGuestMemberCount]" return self.client.call('SoftLayer_Account', 'getScaleGroups', mask=mask, iter=True) def details(self, identifier, mask=None): + """Calls SoftLayer_Scale_Group getObject()_ + + :param identifier: SoftLayer_Scale_Group id + :param mask: optional SoftLayer_Scale_Group objectMask + .. _getObject(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getObject/ + """ if not mask: mask = """mask[virtualGuestMembers[id,virtualGuest[hostname,domain,provisionDate]], terminationPolicy, virtualGuestMemberCount, virtualGuestMemberTemplate[sshKeys], @@ -30,9 +41,34 @@ def details(self, identifier, mask=None): return self.client.call('SoftLayer_Scale_Group', 'getObject', id=identifier, mask=mask) def get_policy(self, identifier, mask=None): + """Calls SoftLayer_Scale_Policy getObject()_ + + :param identifier: SoftLayer_Scale_Policy id + :param mask: optional SoftLayer_Scale_Policy objectMask + .. _getObject(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Policy/getObject/ + """ if not mask: mask = """mask[cooldown, createDate, id, name, actions, triggers[type] ]""" return self.client.call('SoftLayer_Scale_Policy', 'getObject', id=identifier, mask=mask) + + def scale(self, identifier, amount): + """Calls SoftLayer_Scale_Group scale()_ + + :param identifier: SoftLayer_Scale_Group Id + :param amount: positive or negative number to scale the group by + + .. _scale(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/scale/ + """ + return self.client.call('SoftLayer_Scale_Group', 'scale', amount, id=identifier) + + def scale_to(self, identifier, amount): + """Calls SoftLayer_Scale_Group scaleTo()_ + + :param identifier: SoftLayer_Scale_Group Id + :param amount: number to scale the group to. + .. _scaleTo(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/scaleTo/ + """ + return self.client.call('SoftLayer_Scale_Group', 'scaleTo', amount, id=identifier) \ No newline at end of file From 645df87fb2b75b572ab03f420226cefb7762cf28 Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Fri, 27 Sep 2019 16:20:33 -0500 Subject: [PATCH 06/24] autoscale logs, tox fixes --- SoftLayer/CLI/autoscale/detail.py | 9 ++++++-- SoftLayer/CLI/autoscale/list.py | 9 +++----- SoftLayer/CLI/autoscale/logs.py | 37 +++++++++++++++++++++++++++++++ SoftLayer/CLI/autoscale/scale.py | 15 ++++++------- SoftLayer/CLI/routes.py | 1 + SoftLayer/managers/autoscale.py | 16 ++++++++++--- 6 files changed, 68 insertions(+), 19 deletions(-) create mode 100644 SoftLayer/CLI/autoscale/logs.py diff --git a/SoftLayer/CLI/autoscale/detail.py b/SoftLayer/CLI/autoscale/detail.py index 31c29bed7..88fec1c18 100644 --- a/SoftLayer/CLI/autoscale/detail.py +++ b/SoftLayer/CLI/autoscale/detail.py @@ -21,6 +21,8 @@ def cli(env, identifier): # Group Config Table table = formatting.KeyValueTable(["Group", "Value"]) + table.align['Group'] = 'l' + table.align['Value'] = 'l' table.add_row(['Id', group.get('id')]) # Ideally we would use regionalGroup->preferredDatacenter, but that generates an error. @@ -31,7 +33,7 @@ def cli(env, identifier): table.add_row(['Current Members', group.get('virtualGuestMemberCount')]) table.add_row(['Cooldown', "{} seconds".format(group.get('cooldown'))]) table.add_row(['Last Action', utils.clean_time(group.get('lastActionDate'))]) - + for network in group.get('networkVlans'): network_type = utils.lookup(network, 'networkVlan', 'networkSpace') router = utils.lookup(network, 'networkVlan', 'primaryRouter', 'hostname') @@ -43,8 +45,11 @@ def cli(env, identifier): # Template Config Table config_table = formatting.KeyValueTable(["Template", "Value"]) + config_table.align['Template'] = 'l' + config_table.align['Value'] = 'l' + template = group.get('virtualGuestMemberTemplate') - + config_table.add_row(['Hostname', template.get('hostname')]) config_table.add_row(['Domain', template.get('domain')]) config_table.add_row(['Core', template.get('startCpus')]) diff --git a/SoftLayer/CLI/autoscale/list.py b/SoftLayer/CLI/autoscale/list.py index 043a0892e..2d360714c 100644 --- a/SoftLayer/CLI/autoscale/list.py +++ b/SoftLayer/CLI/autoscale/list.py @@ -3,7 +3,6 @@ import click -import SoftLayer from SoftLayer.CLI import environment from SoftLayer.CLI import formatting from SoftLayer.managers.autoscale import AutoScaleManager @@ -17,16 +16,14 @@ def cli(env): autoscale = AutoScaleManager(env.client) groups = autoscale.list() - # print(groups) - # pp(groups) - table = formatting.Table(["Id", "Name", "Status", "Min/Max", "Running"]) + table = formatting.Table(["Id", "Name", "Status", "Min/Max", "Running"]) + table.align['Name'] = 'l' for group in groups: status = utils.lookup(group, 'status', 'name') - min_max = "{}/{}".format(group.get('minimumMemberCount', '-'), group.get('maximumMemberCount'), '-') + min_max = "{}/{}".format(group.get('minimumMemberCount'), group.get('maximumMemberCount')) table.add_row([ group.get('id'), group.get('name'), status, min_max, group.get('virtualGuestMemberCount') ]) - env.fout(table) diff --git a/SoftLayer/CLI/autoscale/logs.py b/SoftLayer/CLI/autoscale/logs.py new file mode 100644 index 000000000..6c4c401b3 --- /dev/null +++ b/SoftLayer/CLI/autoscale/logs.py @@ -0,0 +1,37 @@ +"""Retreive logs for an autoscale group""" +# :license: MIT, see LICENSE for more details. + +import click + +from SoftLayer.CLI import environment +from SoftLayer.CLI import formatting +from SoftLayer.managers.autoscale import AutoScaleManager +from SoftLayer import utils + + +@click.command() +@click.argument('identifier') +@click.option('--date-min', '-d', 'date_min', type=click.DateTime(formats=["%Y-%m-%d", "%m/%d/%Y"]), + help='Earliest date to retreive logs for.') +@environment.pass_env +def cli(env, identifier, date_min): + """Retreive logs for an autoscale group""" + + autoscale = AutoScaleManager(env.client) + + mask = "mask[id,createDate,description]" + object_filter = {} + if date_min: + object_filter['logs'] = { + 'createDate': { + 'operation': 'greaterThanDate', + 'options': [{'name': 'date', 'value': [date_min.strftime("%m/%d/%Y")]}] + } + } + + logs = autoscale.get_logs(identifier, mask=mask, object_filter=object_filter) + table = formatting.Table(['Date', 'Entry'], title="Logs") + table.align['Entry'] = 'l' + for log in logs: + table.add_row([utils.clean_time(log.get('createDate')), log.get('description')]) + env.fout(table) diff --git a/SoftLayer/CLI/autoscale/scale.py b/SoftLayer/CLI/autoscale/scale.py index f93a5953a..69fe1305a 100644 --- a/SoftLayer/CLI/autoscale/scale.py +++ b/SoftLayer/CLI/autoscale/scale.py @@ -3,7 +3,6 @@ import click -import SoftLayer from SoftLayer.CLI import environment from SoftLayer.CLI import formatting from SoftLayer.managers.autoscale import AutoScaleManager @@ -15,7 +14,7 @@ @click.option('--up/--down', 'scale_up', is_flag=True, default=True, help="'--up' adds guests, '--down' removes guests.") @click.option('--by/--to', 'scale_by', is_flag=True, required=True, - help="'--by' will add/remove the specified number of guests." \ + help="'--by' will add/remove the specified number of guests." " '--to' will add/remove a number of guests to get the group's guest count to the specified number.") @click.option('--amount', required=True, type=click.INT, help="Number of guests for the scale action.") @environment.pass_env @@ -30,19 +29,19 @@ def cli(env, identifier, scale_up, scale_by, amount): result = [] if scale_by: - click.secho("Scaling group {} by {}".format(identifier, amount), fg='green') + click.secho("Scaling group {} by {}".format(identifier, amount), fg='green') result = autoscale.scale(identifier, amount) else: - click.secho("Scaling group {} to {}".format(identifier, amount), fg='green') + click.secho("Scaling group {} to {}".format(identifier, amount), fg='green') result = autoscale.scale_to(identifier, amount) try: # Check if the first guest has a cancellation date, assume we are removing guests if it is. - cancellationDate = result[0]['virtualGuest']['billingItem']['cancellationDate'] or False - except (IndexError, KeyError, TypeError) as e: - cancellationDate = False + cancel_date = result[0]['virtualGuest']['billingItem']['cancellationDate'] or False + except (IndexError, KeyError, TypeError): + cancel_date = False - if cancellationDate: + if cancel_date: member_table = formatting.Table(['Id', 'Hostname', 'Created'], title="Cancelled Guests") else: member_table = formatting.Table(['Id', 'Hostname', 'Created'], title="Added Guests") diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py index 1d7575f5d..0c47ce90d 100644 --- a/SoftLayer/CLI/routes.py +++ b/SoftLayer/CLI/routes.py @@ -307,6 +307,7 @@ ('autoscale:list', 'SoftLayer.CLI.autoscale.list:cli'), ('autoscale:detail', 'SoftLayer.CLI.autoscale.detail:cli'), ('autoscale:scale', 'SoftLayer.CLI.autoscale.scale:cli'), + ('autoscale:logs', 'SoftLayer.CLI.autoscale.logs:cli'), ] ALL_ALIASES = { diff --git a/SoftLayer/managers/autoscale.py b/SoftLayer/managers/autoscale.py index fe4d1475c..88e8270ca 100644 --- a/SoftLayer/managers/autoscale.py +++ b/SoftLayer/managers/autoscale.py @@ -7,13 +7,12 @@ """ - class AutoScaleManager(object): + """Manager for interacting with Autoscale instances.""" def __init__(self, client): self.client = client - def list(self, mask=None): """Calls SoftLayer_Account getScaleGroups()_ @@ -71,4 +70,15 @@ def scale_to(self, identifier, amount): :param amount: number to scale the group to. .. _scaleTo(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/scaleTo/ """ - return self.client.call('SoftLayer_Scale_Group', 'scaleTo', amount, id=identifier) \ No newline at end of file + return self.client.call('SoftLayer_Scale_Group', 'scaleTo', amount, id=identifier) + + def get_logs(self, identifier, mask=None, object_filter=None): + """Calls SoftLayer_Scale_Group getLogs()_ + + :param identifier: SoftLayer_Scale_Group Id + :param mask: optional SoftLayer_Scale_Group_Log objectMask + :param object_filter: optional SoftLayer_Scale_Group_Log objectFilter + .. getLogs(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getLogs/ + """ + return self.client.call('SoftLayer_Scale_Group', 'getLogs', id=identifier, mask=mask, filter=object_filter, + iter=True) From 53c17e1766d07d78bca11115aaad1bdb3e77618f Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Fri, 27 Sep 2019 16:59:39 -0500 Subject: [PATCH 07/24] #627 autoscale feature documentation --- SoftLayer/managers/autoscale.py | 37 +++++++++++++++++++++------------ docs/api/managers/autoscale.rst | 5 +++++ docs/cli/autoscale.rst | 31 +++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 docs/api/managers/autoscale.rst create mode 100644 docs/cli/autoscale.rst diff --git a/SoftLayer/managers/autoscale.py b/SoftLayer/managers/autoscale.py index 88e8270ca..7f5d3d321 100644 --- a/SoftLayer/managers/autoscale.py +++ b/SoftLayer/managers/autoscale.py @@ -1,6 +1,6 @@ """ SoftLayer.autoscale - ~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~ Autoscale manager :license: MIT, see LICENSE for more details. @@ -14,10 +14,12 @@ def __init__(self, client): self.client = client def list(self, mask=None): - """Calls SoftLayer_Account getScaleGroups()_ + """Calls `SoftLayer_Account::getScaleGroups()`_ :param mask: optional SoftLayer_Scale_Group objectMask - .. getScaleGroups(): https://sldn.softlayer.com/reference/services/SoftLayer_Account/getScaleGroups/ + + .. _SoftLayer_Account::getScaleGroups(): + https://sldn.softlayer.com/reference/services/SoftLayer_Account/getScaleGroups/ """ if not mask: mask = "mask[status,virtualGuestMemberCount]" @@ -25,11 +27,13 @@ def list(self, mask=None): return self.client.call('SoftLayer_Account', 'getScaleGroups', mask=mask, iter=True) def details(self, identifier, mask=None): - """Calls SoftLayer_Scale_Group getObject()_ + """Calls `SoftLayer_Scale_Group::getObject()`_ :param identifier: SoftLayer_Scale_Group id :param mask: optional SoftLayer_Scale_Group objectMask - .. _getObject(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getObject/ + + .. _SoftLayer_Scale_Group::getObject(): + https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getObject/ """ if not mask: mask = """mask[virtualGuestMembers[id,virtualGuest[hostname,domain,provisionDate]], terminationPolicy, @@ -40,11 +44,13 @@ def details(self, identifier, mask=None): return self.client.call('SoftLayer_Scale_Group', 'getObject', id=identifier, mask=mask) def get_policy(self, identifier, mask=None): - """Calls SoftLayer_Scale_Policy getObject()_ + """Calls `SoftLayer_Scale_Policy::getObject()`_ :param identifier: SoftLayer_Scale_Policy id :param mask: optional SoftLayer_Scale_Policy objectMask - .. _getObject(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Policy/getObject/ + + .. _SoftLayer_Scale_Policy::getObject(): + https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Policy/getObject/ """ if not mask: mask = """mask[cooldown, createDate, id, name, actions, triggers[type] @@ -54,31 +60,36 @@ def get_policy(self, identifier, mask=None): return self.client.call('SoftLayer_Scale_Policy', 'getObject', id=identifier, mask=mask) def scale(self, identifier, amount): - """Calls SoftLayer_Scale_Group scale()_ + """Calls `SoftLayer_Scale_Group::scale()`_ :param identifier: SoftLayer_Scale_Group Id :param amount: positive or negative number to scale the group by - .. _scale(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/scale/ + .. _SoftLayer_Scale_Group::scale(): + https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/scale/ """ return self.client.call('SoftLayer_Scale_Group', 'scale', amount, id=identifier) def scale_to(self, identifier, amount): - """Calls SoftLayer_Scale_Group scaleTo()_ + """Calls `SoftLayer_Scale_Group::scaleTo()`_ :param identifier: SoftLayer_Scale_Group Id :param amount: number to scale the group to. - .. _scaleTo(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/scaleTo/ + + .. _SoftLayer_Scale_Group::scaleTo(): + https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/scaleTo/ """ return self.client.call('SoftLayer_Scale_Group', 'scaleTo', amount, id=identifier) def get_logs(self, identifier, mask=None, object_filter=None): - """Calls SoftLayer_Scale_Group getLogs()_ + """Calls `SoftLayer_Scale_Group::getLogs()`_ :param identifier: SoftLayer_Scale_Group Id :param mask: optional SoftLayer_Scale_Group_Log objectMask :param object_filter: optional SoftLayer_Scale_Group_Log objectFilter - .. getLogs(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getLogs/ + + .. _SoftLayer_Scale_Group::getLogs(): + https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getLogs/ """ return self.client.call('SoftLayer_Scale_Group', 'getLogs', id=identifier, mask=mask, filter=object_filter, iter=True) diff --git a/docs/api/managers/autoscale.rst b/docs/api/managers/autoscale.rst new file mode 100644 index 000000000..3a617c244 --- /dev/null +++ b/docs/api/managers/autoscale.rst @@ -0,0 +1,5 @@ +.. _autoscale: + +.. automodule:: SoftLayer.managers.autoscale + :members: + :inherited-members: \ No newline at end of file diff --git a/docs/cli/autoscale.rst b/docs/cli/autoscale.rst new file mode 100644 index 000000000..8d4d83a34 --- /dev/null +++ b/docs/cli/autoscale.rst @@ -0,0 +1,31 @@ +.. _cli_autoscale: + +Autoscale Commands +================== +These commands were added in version `5.8.1 `_ + +For making changes to the triggers or the autoscale group itself, see the `Autoscale Portal`_ + +- `Autoscale Product `_ +- `Autoscale Documentation `_ +- `Autoscale Portal`_ + +.. click:: SoftLayer.CLI.autoscale.list:cli + :prog: autoscale list + :show-nested: + +.. click:: SoftLayer.CLI.autoscale.detail:cli + :prog: autoscale detail + :show-nested: + +.. click:: SoftLayer.CLI.autoscale.scale:cli + :prog: autoscale scale + :show-nested: + +.. click:: SoftLayer.CLI.autoscale.logs:cli + :prog: autoscale logs + :show-nested: + + + +.. _Autoscale Portal: https://cloud.ibm.com/classic/autoscale \ No newline at end of file From eed15b03830bc1496814b7adcfa32ed1eec5264e Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Fri, 27 Sep 2019 17:05:02 -0500 Subject: [PATCH 08/24] tox fixes --- SoftLayer/managers/autoscale.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SoftLayer/managers/autoscale.py b/SoftLayer/managers/autoscale.py index 7f5d3d321..a5aeeca79 100644 --- a/SoftLayer/managers/autoscale.py +++ b/SoftLayer/managers/autoscale.py @@ -18,7 +18,7 @@ def list(self, mask=None): :param mask: optional SoftLayer_Scale_Group objectMask - .. _SoftLayer_Account::getScaleGroups(): + .. _SoftLayer_Account::getScaleGroups(): https://sldn.softlayer.com/reference/services/SoftLayer_Account/getScaleGroups/ """ if not mask: @@ -32,7 +32,7 @@ def details(self, identifier, mask=None): :param identifier: SoftLayer_Scale_Group id :param mask: optional SoftLayer_Scale_Group objectMask - .. _SoftLayer_Scale_Group::getObject(): + .. _SoftLayer_Scale_Group::getObject(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getObject/ """ if not mask: @@ -49,7 +49,7 @@ def get_policy(self, identifier, mask=None): :param identifier: SoftLayer_Scale_Policy id :param mask: optional SoftLayer_Scale_Policy objectMask - .. _SoftLayer_Scale_Policy::getObject(): + .. _SoftLayer_Scale_Policy::getObject(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Policy/getObject/ """ if not mask: @@ -65,7 +65,7 @@ def scale(self, identifier, amount): :param identifier: SoftLayer_Scale_Group Id :param amount: positive or negative number to scale the group by - .. _SoftLayer_Scale_Group::scale(): + .. _SoftLayer_Scale_Group::scale(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/scale/ """ return self.client.call('SoftLayer_Scale_Group', 'scale', amount, id=identifier) @@ -76,7 +76,7 @@ def scale_to(self, identifier, amount): :param identifier: SoftLayer_Scale_Group Id :param amount: number to scale the group to. - .. _SoftLayer_Scale_Group::scaleTo(): + .. _SoftLayer_Scale_Group::scaleTo(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/scaleTo/ """ return self.client.call('SoftLayer_Scale_Group', 'scaleTo', amount, id=identifier) @@ -88,7 +88,7 @@ def get_logs(self, identifier, mask=None, object_filter=None): :param mask: optional SoftLayer_Scale_Group_Log objectMask :param object_filter: optional SoftLayer_Scale_Group_Log objectFilter - .. _SoftLayer_Scale_Group::getLogs(): + .. _SoftLayer_Scale_Group::getLogs(): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getLogs/ """ return self.client.call('SoftLayer_Scale_Group', 'getLogs', id=identifier, mask=mask, filter=object_filter, From 69e11f1f12c61f9bba25d70f37d81693d294dcd7 Mon Sep 17 00:00:00 2001 From: Fernando Ojeda Date: Thu, 3 Oct 2019 10:57:34 -0400 Subject: [PATCH 09/24] Autoscale cli list and managers unit test. --- SoftLayer/fixtures/SoftLayer_Account.py | 88 ++++++ SoftLayer/fixtures/SoftLayer_Scale_Group.py | 290 +++++++++++++++++++ SoftLayer/fixtures/SoftLayer_Scale_Policy.py | 58 ++++ tests/CLI/modules/autoscale_tests.py | 14 + tests/managers/autoscale_tests.py | 95 ++++++ 5 files changed, 545 insertions(+) create mode 100644 SoftLayer/fixtures/SoftLayer_Scale_Group.py create mode 100644 SoftLayer/fixtures/SoftLayer_Scale_Policy.py create mode 100644 tests/CLI/modules/autoscale_tests.py create mode 100644 tests/managers/autoscale_tests.py diff --git a/SoftLayer/fixtures/SoftLayer_Account.py b/SoftLayer/fixtures/SoftLayer_Account.py index a0c865e3d..ac0068c5e 100644 --- a/SoftLayer/fixtures/SoftLayer_Account.py +++ b/SoftLayer/fixtures/SoftLayer_Account.py @@ -769,3 +769,91 @@ } } ] + +getScaleGroups = [ + { + "accountId": 31111, + "cooldown": 1800, + "createDate": "2016-10-25T01:48:34+08:00", + "id": 12222222, + "lastActionDate": "2016-10-25T01:48:34+08:00", + "maximumMemberCount": 5, + "minimumMemberCount": 0, + "name": "tests", + "regionalGroupId": 663, + "virtualGuestMemberTemplate": { + "accountId": 31111, + "domain": "sodg.com", + "hostname": "testing", + "id": None, + "maxCpu": None, + "maxMemory": 32768, + "startCpus": 32, + "blockDevices": [ + { + "device": "0", + "diskImage": { + "capacity": 25, + } + } + ], + "datacenter": { + "name": "sao01", + }, + "hourlyBillingFlag": True, + "operatingSystemReferenceCode": "CENTOS_LATEST", + "privateNetworkOnlyFlag": True + }, + "virtualGuestMemberCount": 0, + "status": { + "id": 1, + "keyName": "ACTIVE", + "name": "Active" + }, + "virtualGuestAssets": [], + "virtualGuestMembers": [] + }, + { + "accountId": 31111, + "cooldown": 1800, + "createDate": "2018-04-24T04:22:00+08:00", + "id": 224533333, + "lastActionDate": "2019-01-19T04:53:18+08:00", + "maximumMemberCount": 10, + "minimumMemberCount": 0, + "modifyDate": "2019-01-19T04:53:21+08:00", + "name": "test-ajcb", + "regionalGroupId": 1025, + "virtualGuestMemberTemplate": { + "accountId": 31111, + "domain": "test.local", + "hostname": "autoscale-ajcb01", + "id": None, + "maxCpu": None, + "maxMemory": 1024, + "postInstallScriptUri": "http://test.com", + "startCpus": 1, + "blockDevices": [ + { + "device": "0", + "diskImage": { + "capacity": 25, + } + } + ], + "datacenter": { + "name": "seo01", + }, + "hourlyBillingFlag": True, + "operatingSystemReferenceCode": "CENTOS_7_64", + }, + "virtualGuestMemberCount": 0, + "status": { + "id": 1, + "keyName": "ACTIVE", + "name": "Active" + }, + "virtualGuestAssets": [], + "virtualGuestMembers": [] + }, +] diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py new file mode 100644 index 000000000..0a30881cf --- /dev/null +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -0,0 +1,290 @@ +getObject = { + "accountId": 31111, + "cooldown": 1800, + "createDate": "2016-10-25T01:48:34+08:00", + "id": 12222222, + "lastActionDate": "2016-10-25T01:48:34+08:00", + "maximumMemberCount": 5, + "minimumMemberCount": 0, + "name": "tests", + "regionalGroupId": 663, + "virtualGuestMemberTemplate": { + "accountId": 31111, + "domain": "sodg.com", + "hostname": "testing", + "id": None, + "maxCpu": None, + "maxMemory": 32768, + "startCpus": 32, + "blockDevices": [ + { + "device": "0", + "diskImage": { + "capacity": 25, + } + } + ], + "datacenter": { + "name": "sao01", + }, + "hourlyBillingFlag": True, + "operatingSystemReferenceCode": "CENTOS_LATEST", + "privateNetworkOnlyFlag": True + }, + "virtualGuestMemberCount": 0, + "status": { + "id": 1, + "keyName": "ACTIVE", + "name": "Active" + }, + "virtualGuestAssets": [], + "virtualGuestMembers": [] +} + +scale = [ + { + "accountId": 31111, + "cooldown": 1800, + "createDate": "2016-10-25T01:48:34+08:00", + "id": 12222222, + "lastActionDate": "2016-10-25T01:48:34+08:00", + "maximumMemberCount": 5, + "minimumMemberCount": 0, + "name": "tests", + "regionalGroupId": 663, + "virtualGuestMemberTemplate": { + "accountId": 31111, + "domain": "sodg.com", + "hostname": "testing", + "id": None, + "maxCpu": None, + "maxMemory": 32768, + "startCpus": 32, + "blockDevices": [ + { + "device": "0", + "diskImage": { + "capacity": 25, + } + } + ], + "datacenter": { + "name": "sao01", + }, + "hourlyBillingFlag": True, + "operatingSystemReferenceCode": "CENTOS_LATEST", + "privateNetworkOnlyFlag": True + }, + "virtualGuestMemberCount": 0, + "status": { + "id": 1, + "keyName": "ACTIVE", + "name": "Active" + }, + "virtualGuestAssets": [], + "virtualGuestMembers": [] + }, + { + "accountId": 31111, + "cooldown": 1800, + "createDate": "2018-04-24T04:22:00+08:00", + "id": 224533333, + "lastActionDate": "2019-01-19T04:53:18+08:00", + "maximumMemberCount": 10, + "minimumMemberCount": 0, + "modifyDate": "2019-01-19T04:53:21+08:00", + "name": "test-ajcb", + "regionalGroupId": 1025, + "virtualGuestMemberTemplate": { + "accountId": 31111, + "domain": "test.local", + "hostname": "autoscale-ajcb01", + "id": None, + "maxCpu": None, + "maxMemory": 1024, + "postInstallScriptUri": "http://test.com", + "startCpus": 1, + "blockDevices": [ + { + "device": "0", + "diskImage": { + "capacity": 25, + } + } + ], + "datacenter": { + "name": "seo01", + }, + "hourlyBillingFlag": True, + "operatingSystemReferenceCode": "CENTOS_7_64", + }, + "virtualGuestMemberCount": 0, + "status": { + "id": 1, + "keyName": "ACTIVE", + "name": "Active" + }, + "virtualGuestAssets": [], + "virtualGuestMembers": [] + }, +] + +scaleTo = [ + { + "accountId": 31111, + "cooldown": 1800, + "createDate": "2016-10-25T01:48:34+08:00", + "id": 12222222, + "lastActionDate": "2016-10-25T01:48:34+08:00", + "maximumMemberCount": 5, + "minimumMemberCount": 0, + "name": "tests", + "regionalGroupId": 663, + "virtualGuestMemberTemplate": { + "accountId": 31111, + "domain": "sodg.com", + "hostname": "testing", + "id": None, + "maxCpu": None, + "maxMemory": 32768, + "startCpus": 32, + "blockDevices": [ + { + "device": "0", + "diskImage": { + "capacity": 25, + } + } + ], + "datacenter": { + "name": "sao01", + }, + "hourlyBillingFlag": True, + "operatingSystemReferenceCode": "CENTOS_LATEST", + "privateNetworkOnlyFlag": True + }, + "virtualGuestMemberCount": 0, + "status": { + "id": 1, + "keyName": "ACTIVE", + "name": "Active" + }, + "virtualGuestAssets": [], + "virtualGuestMembers": [] + }, + { + "accountId": 31111, + "cooldown": 1800, + "createDate": "2018-04-24T04:22:00+08:00", + "id": 224533333, + "lastActionDate": "2019-01-19T04:53:18+08:00", + "maximumMemberCount": 10, + "minimumMemberCount": 0, + "modifyDate": "2019-01-19T04:53:21+08:00", + "name": "test-ajcb", + "regionalGroupId": 1025, + "virtualGuestMemberTemplate": { + "accountId": 31111, + "domain": "test.local", + "hostname": "autoscale-ajcb01", + "id": None, + "maxCpu": None, + "maxMemory": 1024, + "postInstallScriptUri": "http://test.com", + "startCpus": 1, + "blockDevices": [ + { + "device": "0", + "diskImage": { + "capacity": 25, + } + } + ], + "datacenter": { + "name": "seo01", + }, + "hourlyBillingFlag": True, + "operatingSystemReferenceCode": "CENTOS_7_64", + }, + "virtualGuestMemberCount": 0, + "status": { + "id": 1, + "keyName": "ACTIVE", + "name": "Active" + }, + "virtualGuestAssets": [], + "virtualGuestMembers": [] + }, +] + +getLogs = [ + { + "createDate": "2019-10-03T04:26:11+08:00", + "description": "Scaling group to 6 member(s) by adding 3 member(s) as manually requested", + "id": 3821111, + "scaleGroupId": 2252222, + "scaleGroup": { + "accountId": 31111, + "cooldown": 1800, + "createDate": "2018-05-01T03:07:40+08:00", + "id": 2251111, + "lastActionDate": "2019-10-03T04:26:17+08:00", + "maximumMemberCount": 6, + "minimumMemberCount": 2, + "modifyDate": "2019-10-03T04:26:21+08:00", + "name": "ajcb-autoscale11", + "regionalGroupId": 663, + "terminationPolicyId": 2, + "virtualGuestMemberTemplate": { + "accountId": 31111, + "domain": "techsupport.com", + "hostname": "ajcb-autoscale22", + "maxMemory": 1024, + "postInstallScriptUri": "https://pastebin.com/raw/62wrEKuW", + "startCpus": 1, + "blockDevices": [ + { + "device": "0", + "diskImage": { + "capacity": 25, + } + }, + { + "device": "2", + "diskImage": { + "capacity": 10, + } + } + ], + "datacenter": { + "name": "sao01", + }, + "networkComponents": [ + { + "maxSpeed": 100, + } + ], + "operatingSystemReferenceCode": "CENTOS_LATEST", + "sshKeys": [ + { + "id": 49111, + } + ] + }, + "logs": [ + { + "createDate": "2019-09-28T02:31:35+08:00", + "description": "Scaling group to 3 member(s) by removing -1 member(s) as manually requested", + "id": 3821111, + "scaleGroupId": 2251111, + }, + { + "createDate": "2019-09-28T02:26:11+08:00", + "description": "Scaling group to 4 member(s) by adding 2 member(s) as manually requested", + "id": 38211111, + "scaleGroupId": 2251111, + }, + ] + } + }, +] diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Policy.py b/SoftLayer/fixtures/SoftLayer_Scale_Policy.py new file mode 100644 index 000000000..5586fec1f --- /dev/null +++ b/SoftLayer/fixtures/SoftLayer_Scale_Policy.py @@ -0,0 +1,58 @@ +getObject = { + "cooldown": None, + "createDate": "2019-09-27T06:30:14+08:00", + "id": 11111, + "name": "prime-poly", + "scaleGroupId": 2255111, + "scaleGroup": { + "accountId": 31111, + "cooldown": 1800, + "createDate": "2018-05-01T03:07:40+08:00", + "id": 2252222, + "lastActionDate": "2019-09-28T02:31:47+08:00", + "maximumMemberCount": 6, + "minimumMemberCount": 2, + "modifyDate": "2019-09-28T02:31:50+08:00", + "name": "ajcb-autoscale11", + "regionalGroupId": 663, + "terminationPolicyId": 2, + "virtualGuestMemberTemplate": { + "accountId": 31111, + "domain": "techsupport.com", + "hostname": "ajcb-autoscale22", + "id": None, + "maxMemory": 1024, + "postInstallScriptUri": "https://pastebin.com/raw/62wrEKuW", + "startCpus": 1, + "blockDevices": [ + { + "device": "0", + "diskImage": { + "capacity": 25, + } + }, + { + "device": "2", + "diskImage": { + "capacity": 10, + } + } + ], + "datacenter": { + "id": None, + "name": "sao01", + }, + "networkComponents": [ + { + "maxSpeed": 100, + } + ], + "operatingSystemReferenceCode": "CENTOS_LATEST", + "sshKeys": [ + { + "id": 490279, + } + ] + } + } +} diff --git a/tests/CLI/modules/autoscale_tests.py b/tests/CLI/modules/autoscale_tests.py new file mode 100644 index 000000000..33bf4a370 --- /dev/null +++ b/tests/CLI/modules/autoscale_tests.py @@ -0,0 +1,14 @@ +""" + SoftLayer.tests.CLI.modules.autoscale_tests + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Tests for the user cli command +""" +from SoftLayer import testing + + +class AutoScaleTests(testing.TestCase): + + def test_autoscale_list(self): + result = self.run_command(['autoscale', 'list']) + self.assert_no_fail(result) diff --git a/tests/managers/autoscale_tests.py b/tests/managers/autoscale_tests.py new file mode 100644 index 000000000..ba43cb42b --- /dev/null +++ b/tests/managers/autoscale_tests.py @@ -0,0 +1,95 @@ +""" + SoftLayer.tests.managers.autoscale_tests + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + :license: MIT, see LICENSE for more details. +""" + +from SoftLayer import testing +from SoftLayer.managers.autoscale import AutoScaleManager + + +class AutoScaleTests(testing.TestCase): + + def set_up(self): + self.autoscale = AutoScaleManager(self.client) + + def test_autoscale_list(self): + self.autoscale.list() + + self.assert_called_with( + 'SoftLayer_Account', + 'getScaleGroups' + ) + + def test_autoscale_list_with_mask(self): + self.autoscale.list(mask='mask[status,virtualGuestMemberCount]') + + self.assert_called_with( + 'SoftLayer_Account', + 'getScaleGroups' + ) + + def test_autoscale_details(self): + self.autoscale.details(11111) + + self.assert_called_with( + 'SoftLayer_Scale_Group', + 'getObject', + identifier=11111 + ) + + def test_autoscale_details_with_mask(self): + self.autoscale.details(11111, mask='mask[virtualGuestMembers[id,virtualGuest[hostname,domain,provisionDate]], ' + 'terminationPolicy,virtualGuestMemberCount]') + + self.assert_called_with( + 'SoftLayer_Scale_Group', + 'getObject', + identifier=11111 + ) + + def test_autoscale_policy(self): + self.autoscale.get_policy(11111) + + self.assert_called_with( + 'SoftLayer_Scale_Policy', + 'getObject', + identifier=11111 + ) + + def test_autoscale_policy_with_mask(self): + self.autoscale.get_policy(11111, mask='mask[cooldown, createDate, id, name, actions, triggers[type]]') + + self.assert_called_with( + 'SoftLayer_Scale_Policy', + 'getObject', + identifier=11111 + ) + + def test_autoscale_scale(self): + self.autoscale.scale(11111, 3) + + self.assert_called_with( + 'SoftLayer_Scale_Group', + 'scale', + identifier=11111 + ) + + def test_autoscale_scaleTo(self): + self.autoscale.scale_to(11111, 3) + + self.assert_called_with( + 'SoftLayer_Scale_Group', + 'scaleTo', + identifier=11111 + ) + + def test_autoscale_getLogs(self): + self.autoscale.get_logs(11111) + + self.assert_called_with( + 'SoftLayer_Scale_Group', + 'getLogs', + identifier=11111 + ) From 2fcd61beab21ff350a6e675d223b785b387230a4 Mon Sep 17 00:00:00 2001 From: Fernando Ojeda Date: Thu, 3 Oct 2019 11:07:02 -0400 Subject: [PATCH 10/24] Fix analysis tox. --- tests/managers/autoscale_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/managers/autoscale_tests.py b/tests/managers/autoscale_tests.py index ba43cb42b..124a82874 100644 --- a/tests/managers/autoscale_tests.py +++ b/tests/managers/autoscale_tests.py @@ -5,8 +5,8 @@ :license: MIT, see LICENSE for more details. """ -from SoftLayer import testing from SoftLayer.managers.autoscale import AutoScaleManager +from SoftLayer import testing class AutoScaleTests(testing.TestCase): From 3f6f16cd9a1e5637ceefcca03cd9f6c24e35cbd3 Mon Sep 17 00:00:00 2001 From: Fernando Ojeda Date: Thu, 3 Oct 2019 14:35:03 -0400 Subject: [PATCH 11/24] Fix analysis tox. --- SoftLayer/fixtures/SoftLayer_Account.py | 9 ++------- SoftLayer/fixtures/SoftLayer_Scale_Group.py | 14 -------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/SoftLayer/fixtures/SoftLayer_Account.py b/SoftLayer/fixtures/SoftLayer_Account.py index ac0068c5e..ddb2a4354 100644 --- a/SoftLayer/fixtures/SoftLayer_Account.py +++ b/SoftLayer/fixtures/SoftLayer_Account.py @@ -802,7 +802,6 @@ }, "hourlyBillingFlag": True, "operatingSystemReferenceCode": "CENTOS_LATEST", - "privateNetworkOnlyFlag": True }, "virtualGuestMemberCount": 0, "status": { @@ -810,8 +809,6 @@ "keyName": "ACTIVE", "name": "Active" }, - "virtualGuestAssets": [], - "virtualGuestMembers": [] }, { "accountId": 31111, @@ -852,8 +849,6 @@ "id": 1, "keyName": "ACTIVE", "name": "Active" - }, - "virtualGuestAssets": [], - "virtualGuestMembers": [] - }, + } + } ] diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py index 0a30881cf..403bd5203 100644 --- a/SoftLayer/fixtures/SoftLayer_Scale_Group.py +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -47,17 +47,13 @@ "cooldown": 1800, "createDate": "2016-10-25T01:48:34+08:00", "id": 12222222, - "lastActionDate": "2016-10-25T01:48:34+08:00", "maximumMemberCount": 5, "minimumMemberCount": 0, "name": "tests", - "regionalGroupId": 663, "virtualGuestMemberTemplate": { "accountId": 31111, "domain": "sodg.com", "hostname": "testing", - "id": None, - "maxCpu": None, "maxMemory": 32768, "startCpus": 32, "blockDevices": [ @@ -89,12 +85,10 @@ "cooldown": 1800, "createDate": "2018-04-24T04:22:00+08:00", "id": 224533333, - "lastActionDate": "2019-01-19T04:53:18+08:00", "maximumMemberCount": 10, "minimumMemberCount": 0, "modifyDate": "2019-01-19T04:53:21+08:00", "name": "test-ajcb", - "regionalGroupId": 1025, "virtualGuestMemberTemplate": { "accountId": 31111, "domain": "test.local", @@ -148,14 +142,6 @@ "maxCpu": None, "maxMemory": 32768, "startCpus": 32, - "blockDevices": [ - { - "device": "0", - "diskImage": { - "capacity": 25, - } - } - ], "datacenter": { "name": "sao01", }, From d027f82fdc68b4b709c75c82882a3b5c9d5c9d40 Mon Sep 17 00:00:00 2001 From: Daniel Cabero Barrios Date: Thu, 3 Oct 2019 15:54:11 -0400 Subject: [PATCH 12/24] unit test logs and scale --- SoftLayer/fixtures/SoftLayer_Scale_Group.py | 12 ++++++++++++ tests/CLI/modules/autoscale_tests.py | 0 2 files changed, 12 insertions(+) create mode 100644 SoftLayer/fixtures/SoftLayer_Scale_Group.py create mode 100644 tests/CLI/modules/autoscale_tests.py diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py new file mode 100644 index 000000000..a4d885e97 --- /dev/null +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -0,0 +1,12 @@ +getLogs = [ + { + "createDate": "2018-04-23T14:22:52-06:00", + "description": "Scaling group to 3 member(s) by adding 3 member(s) as manually requested", + "id": 123456, + }, { + "createDate": "2018-04-23T14:22:52-06:00", + "description": "Scaling group to 3 member(s) by adding 3 member(s) as manually requested", + "id": 987123456, + } +] + diff --git a/tests/CLI/modules/autoscale_tests.py b/tests/CLI/modules/autoscale_tests.py new file mode 100644 index 000000000..e69de29bb From 292d4fac6d77d54904ae6c5d79fca0894c1f1f27 Mon Sep 17 00:00:00 2001 From: Daniel Cabero Barrios Date: Thu, 3 Oct 2019 15:59:30 -0400 Subject: [PATCH 13/24] unit test logs and scale --- SoftLayer/fixtures/SoftLayer_Scale_Group.py | 53 ++++++++++++++++++--- tests/CLI/modules/autoscale_tests.py | 35 ++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py index a4d885e97..b53e08ff1 100644 --- a/SoftLayer/fixtures/SoftLayer_Scale_Group.py +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -1,12 +1,53 @@ getLogs = [ { - "createDate": "2018-04-23T14:22:52-06:00", - "description": "Scaling group to 3 member(s) by adding 3 member(s) as manually requested", - "id": 123456, + "createDate": "2019-10-02T08:34:21-06:00", + "id": 3145330, + "scaleGroupId": 224541 }, { - "createDate": "2018-04-23T14:22:52-06:00", - "description": "Scaling group to 3 member(s) by adding 3 member(s) as manually requested", - "id": 987123456, + "createDate": "2019-10-02T08:34:21-06:00", + "id": 3145330, + "scaleGroupId": 2245415 + } ] +scale=[] + +scaleTo=[{'createDate': '2019-10-02T15:24:56-06:00', + 'id': 3145162, + 'scaleGroupId': 595465, + 'scaleGroup': {}, + 'virtualGuest': { + 'accountId': 12369852, + 'createDate': '2019 - 10 - 02T15: 24:54 - 06: 00', + 'billingItem': { + "cancellationDate": '2019-10-02T08:34:21-06:00' + }, + 'domain': 'mesos.maceacs.com', + 'fullyQualifiedDomainName': '2 - master - 600e.mesos.maceacs.com', + 'hostname': '2 - master - 600e', + 'id': 852369, + 'maxCpu': 4, + 'maxCpuUnits': 'CORE', + 'maxMemory': 8192, + 'startCpus': 4, + 'statusId': 1001, + 'typeId': 1, + 'uuid': 'acva18321 - bb6b - 4861 - 87f3 - 8a6dbbcf148b', + 'activeTransactions': [{ + 'createDate': '2019 - 10 - 02T15: 24:58 - 06: 00', + 'elapsedSeconds': 2, + 'guestId': 789654123, + 'hardwareId': '', + 'id': 456987, + 'modifyDate': '2019 - 10 - 02T15: 24:58 - 06: 00', + 'statusChangeDate': '2019 - 10 - 02T15: 24:58 - 06: 00', + 'transactionStatus': { + 'averageDuration': '1.48', + 'friendlyName': 'AssignHost', + 'name': 'ASSIGN_HOST'}}], + 'status': { + 'keyName': 'ACTIVE', + 'name': 'Active'} + } + }] diff --git a/tests/CLI/modules/autoscale_tests.py b/tests/CLI/modules/autoscale_tests.py index e69de29bb..faca1fb62 100644 --- a/tests/CLI/modules/autoscale_tests.py +++ b/tests/CLI/modules/autoscale_tests.py @@ -0,0 +1,35 @@ +""" + SoftLayer.tests.CLI.modules.autoscale_tests + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + :license: MIT, see LICENSE for more details. +""" +from SoftLayer import testing + + +class AutoscaleTests(testing.TestCase): + + def test_logs_dates(self): + result = self.run_command(['autoscale', 'logs', '123456', '-d', '2019-02-02']) + print(result) + self.assert_no_fail(result) + + def test_scale_down(self): + result = self.run_command(['autoscale', 'scale', '123456', '--down', '--amount', '2']) + self.assert_no_fail(result) + + def test_scale_up(self): + result = self.run_command(['autoscale', 'scale', '123456', '--up', '--amount', '2']) + self.assert_no_fail(result) + + def test_scale_to(self): + result = self.run_command(['autoscale', 'scale', '789654123', '--down', '--amount', '2']) + self.assert_no_fail(result) + + def test_scale_by_up(self): + result = self.run_command(['autoscale', 'scale', '789654123', '--by', '--down', '--amount', '-1']) + self.assert_no_fail(result) + + def test_scale_ca(self): + result = self.run_command(['autoscale', 'scale', '789654123', '--by', '--down', '--amount', '1']) + self.assert_no_fail(result) From 5cc773755a89105940fb352b7f70a7422e689b0e Mon Sep 17 00:00:00 2001 From: Daniel Cabero Barrios Date: Thu, 3 Oct 2019 16:08:49 -0400 Subject: [PATCH 14/24] fix the tox analysis --- SoftLayer/fixtures/SoftLayer_Scale_Group.py | 69 +++++++++++---------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py index b53e08ff1..9fc9b0483 100644 --- a/SoftLayer/fixtures/SoftLayer_Scale_Group.py +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -11,43 +11,44 @@ } ] -scale=[] +scale = [] -scaleTo=[{'createDate': '2019-10-02T15:24:56-06:00', +scaleTo = [{'createDate': '2019-10-02T15:24:56-06:00', 'id': 3145162, 'scaleGroupId': 595465, 'scaleGroup': {}, 'virtualGuest': { 'accountId': 12369852, - 'createDate': '2019 - 10 - 02T15: 24:54 - 06: 00', - 'billingItem': { - "cancellationDate": '2019-10-02T08:34:21-06:00' - }, - 'domain': 'mesos.maceacs.com', - 'fullyQualifiedDomainName': '2 - master - 600e.mesos.maceacs.com', - 'hostname': '2 - master - 600e', - 'id': 852369, - 'maxCpu': 4, - 'maxCpuUnits': 'CORE', - 'maxMemory': 8192, - 'startCpus': 4, - 'statusId': 1001, - 'typeId': 1, - 'uuid': 'acva18321 - bb6b - 4861 - 87f3 - 8a6dbbcf148b', - 'activeTransactions': [{ - 'createDate': '2019 - 10 - 02T15: 24:58 - 06: 00', - 'elapsedSeconds': 2, - 'guestId': 789654123, - 'hardwareId': '', - 'id': 456987, - 'modifyDate': '2019 - 10 - 02T15: 24:58 - 06: 00', - 'statusChangeDate': '2019 - 10 - 02T15: 24:58 - 06: 00', - 'transactionStatus': { - 'averageDuration': '1.48', - 'friendlyName': 'AssignHost', - 'name': 'ASSIGN_HOST'}}], - 'status': { - 'keyName': 'ACTIVE', - 'name': 'Active'} - } - }] + 'createDate': '2019 - 10 - 02T15: 24:54 - 06: 00', + 'billingItem': { + "cancellationDate": '2019-10-02T08:34:21-06:00' + }, + 'domain': 'mesos.maceacs.com', + 'fullyQualifiedDomainName': '2 - master - 600e.mesos.maceacs.com', + 'hostname': '2 - master - 600e', + 'id': 852369, + 'maxCpu': 4, + 'maxCpuUnits': 'CORE', + 'maxMemory': 8192, + 'startCpus': 4, + 'statusId': 1001, + 'typeId': 1, + 'uuid': 'acva18321 - bb6b - 4861 - 87f3 - 8a6dbbcf148b', + 'activeTransactions': [{ + 'createDate': '2019 - 10 - 02T15: 24:58 - 06: 00', + 'elapsedSeconds': 2, + 'guestId': 789654123, + 'hardwareId': '', + 'id': 456987, + 'modifyDate': '2019 - 10 - 02T15: 24:58 - 06: 00', + 'statusChangeDate': '2019 - 10 - 02T15: 24:58 - 06: 00', + 'transactionStatus': { + 'averageDuration': '1.48', + 'friendlyName': 'AssignHost', + 'name': 'ASSIGN_HOST'}}], + 'status': { + 'keyName': 'ACTIVE', + 'name': 'Active'} + } + } + ] From 50566503803be41b0aa8a618835876fe33bc6a57 Mon Sep 17 00:00:00 2001 From: caberos Date: Fri, 4 Oct 2019 10:39:51 -0400 Subject: [PATCH 15/24] fix any problems with merge --- tests/CLI/modules/autoscale_tests.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/CLI/modules/autoscale_tests.py b/tests/CLI/modules/autoscale_tests.py index 6186cfcb3..843ed4528 100644 --- a/tests/CLI/modules/autoscale_tests.py +++ b/tests/CLI/modules/autoscale_tests.py @@ -1,19 +1,15 @@ """ SoftLayer.tests.CLI.modules.autoscale_tests -<<<<<<< HEAD ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :license: MIT, see LICENSE for more details. -======= ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tests for the user cli command ->>>>>>> 63de0adb45c6c1ccc7135520ebcdaeb38249e9fa """ from SoftLayer import testing -<<<<<<< HEAD class AutoscaleTests(testing.TestCase): def test_logs_dates(self): @@ -39,10 +35,7 @@ def test_scale_by_up(self): def test_scale_ca(self): result = self.run_command(['autoscale', 'scale', '789654123', '--by', '--down', '--amount', '1']) -======= -class AutoScaleTests(testing.TestCase): def test_autoscale_list(self): result = self.run_command(['autoscale', 'list']) ->>>>>>> 63de0adb45c6c1ccc7135520ebcdaeb38249e9fa self.assert_no_fail(result) From 5e61352a7106919efd0bbd57dbdfe610c44d9eda Mon Sep 17 00:00:00 2001 From: ATGE Date: Fri, 4 Oct 2019 11:45:24 -0400 Subject: [PATCH 16/24] adding a default value to dictionaries --- SoftLayer/CLI/autoscale/detail.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/SoftLayer/CLI/autoscale/detail.py b/SoftLayer/CLI/autoscale/detail.py index 88fec1c18..d7484184c 100644 --- a/SoftLayer/CLI/autoscale/detail.py +++ b/SoftLayer/CLI/autoscale/detail.py @@ -34,7 +34,7 @@ def cli(env, identifier): table.add_row(['Cooldown', "{} seconds".format(group.get('cooldown'))]) table.add_row(['Last Action', utils.clean_time(group.get('lastActionDate'))]) - for network in group.get('networkVlans'): + for network in group.get('networkVlans', []): network_type = utils.lookup(network, 'networkVlan', 'networkSpace') router = utils.lookup(network, 'networkVlan', 'primaryRouter', 'hostname') vlan_number = utils.lookup(network, 'networkVlan', 'vlanNumber') @@ -55,17 +55,16 @@ def cli(env, identifier): config_table.add_row(['Core', template.get('startCpus')]) config_table.add_row(['Ram', template.get('maxMemory')]) network = template.get('networkComponents') - config_table.add_row(['Network', network[0]['maxSpeed']]) + config_table.add_row(['Network', network[0]['maxSpeed'] if network else 'Default']) ssh_keys = template.get('sshKeys', []) ssh_manager = SoftLayer.SshKeyManager(env.client) for key in ssh_keys: # Label isn't included when retrieved from the AutoScale group... ssh_key = ssh_manager.get_key(key.get('id')) config_table.add_row(['SSH Key {}'.format(ssh_key.get('id')), ssh_key.get('label')]) - disks = template.get('blockDevices') - disk_type = "SAN" - if template.get('localDiskFlag'): - disk_type = "Local" + disks = template.get('blockDevices', []) + disk_type = "Local" if template.get('localDiskFlag') else "SAN" + for disk in disks: disk_image = disk.get('diskImage') config_table.add_row(['{} Disk {}'.format(disk_type, disk.get('device')), disk_image.get('capacity')]) @@ -76,7 +75,7 @@ def cli(env, identifier): # Policy Config Table policy_table = formatting.KeyValueTable(["Policy", "Cooldown"]) - policies = group.get('policies') + policies = group.get('policies', []) for policy in policies: policy_table.add_row([policy.get('name'), policy.get('cooldown') or group.get('cooldown')]) @@ -84,7 +83,7 @@ def cli(env, identifier): # Active Guests member_table = formatting.Table(['Id', 'Hostname', 'Created'], title="Active Guests") - guests = group.get('virtualGuestMembers') + guests = group.get('virtualGuestMembers', []) for guest in guests: real_guest = guest.get('virtualGuest') member_table.add_row([ From 29ab911aa399085aad81da8a7ea95997a2afb359 Mon Sep 17 00:00:00 2001 From: ATGE Date: Fri, 4 Oct 2019 12:23:55 -0400 Subject: [PATCH 17/24] added autoscale detail test --- SoftLayer/fixtures/SoftLayer_Scale_Group.py | 224 +++++++++++++++++--- tests/CLI/modules/autoscale_tests.py | 6 +- 2 files changed, 195 insertions(+), 35 deletions(-) diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py index 403bd5203..5afda75a7 100644 --- a/SoftLayer/fixtures/SoftLayer_Scale_Group.py +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -1,44 +1,200 @@ getObject = { - "accountId": 31111, - "cooldown": 1800, - "createDate": "2016-10-25T01:48:34+08:00", - "id": 12222222, - "lastActionDate": "2016-10-25T01:48:34+08:00", - "maximumMemberCount": 5, - "minimumMemberCount": 0, - "name": "tests", - "regionalGroupId": 663, - "virtualGuestMemberTemplate": { - "accountId": 31111, - "domain": "sodg.com", - "hostname": "testing", - "id": None, - "maxCpu": None, - "maxMemory": 32768, - "startCpus": 32, - "blockDevices": [ + 'accountId': 31111, + 'balancedTerminationFlag': False, + 'cooldown': 1800, + 'createDate': '2018-04-30T15:07:40-04:00', + 'desiredMemberCount': None, + 'id': 12222222, + 'lastActionDate': '2019-10-02T16:26:17-04:00', + 'loadBalancers': [], + 'maximumMemberCount': 6, + 'minimumMemberCount': 2, + 'modifyDate': '2019-10-03T17:16:47-04:00', + 'name': 'tests', + 'networkVlans': [ + { + 'networkVlan': { + 'accountId': 31111, + 'id': 2222222, + 'modifyDate': '2019-07-16T13:09:47-04:00', + 'networkSpace': 'PRIVATE', + 'primaryRouter': { + 'hostname': 'bcr01a.sao01' + }, + 'primarySubnetId': 1172222, + 'vlanNumber': 1111 + }, + 'networkVlanId': 2281111 + } + ], + 'policies': [ + {'actions': [ { - "device": "0", - "diskImage": { - "capacity": 25, + 'amount': 1, + 'createDate': '2019-09-26T18:30:22-04:00', + 'deleteFlag': None, + 'id': 611111, + 'modifyDate': None, + 'scalePolicy': None, + 'scalePolicyId': 681111, + 'scaleType': 'RELATIVE', + 'typeId': 1 + } + ], + 'cooldown': None, + 'createDate': '2019-09-26T18:30:14-04:00', + 'id': 680000, + 'name': 'prime-poly', + 'scaleActions': [ + { + 'amount': 1, + 'createDate': '2019-09-26T18:30:22-04:00', + 'deleteFlag': None, + 'id': 633333, + 'modifyDate': None, + 'scalePolicy': None, + 'scalePolicyId': 680123, + 'scaleType': 'RELATIVE', + 'typeId': 1 } + ], + 'triggers': [ + { + 'createDate': '2019-09-26T18:30:14-04:00', + 'deleteFlag': None, + 'id': 557111, + 'modifyDate': None, + 'scalePolicy': None, + 'scalePolicyId': 680000, + 'typeId': 3 + } + ] + } + ], + 'regionalGroup': { + 'description': 'sa-bra-south-1', + 'id': 663, + 'locationGroupTypeId': 42, + 'locations': [ + { + 'id': 983497, + 'longName': 'Sao Paulo 1', + 'name': 'sao01', + 'statusId': 2 } ], - "datacenter": { - "name": "sao01", - }, - "hourlyBillingFlag": True, - "operatingSystemReferenceCode": "CENTOS_LATEST", - "privateNetworkOnlyFlag": True + 'name': 'sa-bra-south-1', + 'securityLevelId': None + }, + 'regionalGroupId': 663, + 'status': { + 'id': 1, 'keyName': 'ACTIVE', 'name': 'Active' }, - "virtualGuestMemberCount": 0, - "status": { - "id": 1, - "keyName": "ACTIVE", - "name": "Active" + 'suspendedFlag': False, + 'terminationPolicy': { + 'id': 2, 'keyName': 'NEWEST', 'name': 'Newest' }, - "virtualGuestAssets": [], - "virtualGuestMembers": [] + 'terminationPolicyId': 2, + 'virtualGuestAssets': [], + 'virtualGuestMemberCount': 6, + 'virtualGuestMemberTemplate': { + 'accountId': 31111, + 'blockDevices': [ + { + 'bootableFlag': None, + 'createDate': None, + 'device': '0', + 'diskImage': { + 'capacity': 25, + 'createDate': None, + 'id': None, + 'modifyDate': None, + 'parentId': None, + 'storageRepositoryId': None, + 'typeId': None}, + 'diskImageId': None, + 'guestId': None, + 'hotPlugFlag': None, + 'id': None, + 'modifyDate': None, + 'statusId': None + }, + { + 'bootableFlag': None, + 'createDate': None, + 'device': '2', + 'diskImage': { + 'capacity': 10, + 'createDate': None, + 'id': None, + 'modifyDate': None, + 'parentId': None, + 'storageRepositoryId': None, + 'typeId': None}, + 'diskImageId': None, + 'guestId': None, + 'hotPlugFlag': None, + 'id': None, + 'modifyDate': None, + 'statusId': None + } + ], + 'createDate': None, + 'datacenter': { + 'id': None, + 'name': 'sao01', + 'statusId': None + }, + 'dedicatedAccountHostOnlyFlag': None, + 'domain': 'tech-support.com', + 'hostname': 'testing', + 'hourlyBillingFlag': True, + 'id': None, + 'lastPowerStateId': None, + 'lastVerifiedDate': None, + 'localDiskFlag': False, + 'maxCpu': None, + 'maxMemory': 1024, + 'metricPollDate': None, + 'modifyDate': None, + 'networkComponents': [ + { + 'createDate': None, + 'guestId': None, + 'id': None, + 'maxSpeed': 100, + 'modifyDate': None, + 'networkId': None, + 'port': None, + 'speed': None + } + ], + 'operatingSystemReferenceCode': 'CENTOS_LATEST', + 'placementGroupId': None, + 'postInstallScriptUri': 'https://test.com/', + 'privateNetworkOnlyFlag': False, + 'provisionDate': None, + 'sshKeys': [ + { + 'createDate': None, + 'id': 490279, + 'modifyDate': None + } + ], + 'startCpus': 1, + 'statusId': None, + 'typeId': None}, + 'virtualGuestMembers': [ + { + 'id': 3111111, + 'virtualGuest': { + + 'domain': 'tech-support.com', + 'hostname': 'test', + 'provisionDate': '2019-09-27T14:29:53-04:00' + } + } + ] } scale = [ diff --git a/tests/CLI/modules/autoscale_tests.py b/tests/CLI/modules/autoscale_tests.py index 33bf4a370..0c0ae92e0 100644 --- a/tests/CLI/modules/autoscale_tests.py +++ b/tests/CLI/modules/autoscale_tests.py @@ -2,7 +2,7 @@ SoftLayer.tests.CLI.modules.autoscale_tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Tests for the user cli command + Tests for the autoscale cli command """ from SoftLayer import testing @@ -12,3 +12,7 @@ class AutoScaleTests(testing.TestCase): def test_autoscale_list(self): result = self.run_command(['autoscale', 'list']) self.assert_no_fail(result) + + def test_autoscale_detail(self): + result = self.run_command(['autoscale', 'detail', '12222222']) + self.assert_no_fail(result) From 52d3600dd995371b4a3b0c4ba82e8bbe053e5b00 Mon Sep 17 00:00:00 2001 From: ATGE Date: Fri, 4 Oct 2019 12:42:12 -0400 Subject: [PATCH 18/24] fix identation --- SoftLayer/fixtures/SoftLayer_Scale_Group.py | 27 +++++++++++---------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py index 5afda75a7..b2361784a 100644 --- a/SoftLayer/fixtures/SoftLayer_Scale_Group.py +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -28,19 +28,20 @@ } ], 'policies': [ - {'actions': [ - { - 'amount': 1, - 'createDate': '2019-09-26T18:30:22-04:00', - 'deleteFlag': None, - 'id': 611111, - 'modifyDate': None, - 'scalePolicy': None, - 'scalePolicyId': 681111, - 'scaleType': 'RELATIVE', - 'typeId': 1 - } - ], + { + 'actions': [ + { + 'amount': 1, + 'createDate': '2019-09-26T18:30:22-04:00', + 'deleteFlag': None, + 'id': 611111, + 'modifyDate': None, + 'scalePolicy': None, + 'scalePolicyId': 681111, + 'scaleType': 'RELATIVE', + 'typeId': 1 + } + ], 'cooldown': None, 'createDate': '2019-09-26T18:30:14-04:00', 'id': 680000, From 3e853199e7b7af63d79259c80318b28f98836238 Mon Sep 17 00:00:00 2001 From: caberos Date: Fri, 4 Oct 2019 15:22:15 -0400 Subject: [PATCH 19/24] Update SoftLayer_Scale_Group.py --- SoftLayer/fixtures/SoftLayer_Scale_Group.py | 22 ++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py index 403bd5203..afaaf118b 100644 --- a/SoftLayer/fixtures/SoftLayer_Scale_Group.py +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -50,6 +50,12 @@ "maximumMemberCount": 5, "minimumMemberCount": 0, "name": "tests", + "virtualGuest": { + "accountId": 31111, + "createDate": "2019-10-02T15:24:54-06:00", + "billingItem": { + "cancellationDate": "2019-10-02T08:34:21-06:00"} + }, "virtualGuestMemberTemplate": { "accountId": 31111, "domain": "sodg.com", @@ -89,6 +95,12 @@ "minimumMemberCount": 0, "modifyDate": "2019-01-19T04:53:21+08:00", "name": "test-ajcb", + "virtualGuest": { + "accountId": 31111, + "createDate": "2019-10-02T15:24:54-06:00", + "billingItem": { + "cancellationDate": "2019-10-02T08:34:21-06:00"} + }, "virtualGuestMemberTemplate": { "accountId": 31111, "domain": "test.local", @@ -120,7 +132,7 @@ }, "virtualGuestAssets": [], "virtualGuestMembers": [] - }, + } ] scaleTo = [ @@ -134,6 +146,8 @@ "minimumMemberCount": 0, "name": "tests", "regionalGroupId": 663, + "virtualGuest": { + }, "virtualGuestMemberTemplate": { "accountId": 31111, "domain": "sodg.com", @@ -169,6 +183,12 @@ "modifyDate": "2019-01-19T04:53:21+08:00", "name": "test-ajcb", "regionalGroupId": 1025, + "virtualGuest": { + "accountId": 31111, + "createDate": "2019-10-02T15:24:54-06:00", + "billingItem": { + "cancellationDate": "2019-10-02T08:34:21-06:00"} + }, "virtualGuestMemberTemplate": { "accountId": 31111, "domain": "test.local", From 3dcf3f6a8a25675bbb8417b68755ec3275669c3d Mon Sep 17 00:00:00 2001 From: caberos Date: Fri, 4 Oct 2019 15:57:32 -0400 Subject: [PATCH 20/24] fix analysis tool --- tests/CLI/modules/autoscale_tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/CLI/modules/autoscale_tests.py b/tests/CLI/modules/autoscale_tests.py index 843ed4528..b3d7293c9 100644 --- a/tests/CLI/modules/autoscale_tests.py +++ b/tests/CLI/modules/autoscale_tests.py @@ -33,8 +33,9 @@ def test_scale_by_up(self): result = self.run_command(['autoscale', 'scale', '789654123', '--by', '--down', '--amount', '-1']) self.assert_no_fail(result) - def test_scale_ca(self): + def test_scale_cancel(self): result = self.run_command(['autoscale', 'scale', '789654123', '--by', '--down', '--amount', '1']) + self.assert_no_fail(result) def test_autoscale_list(self): result = self.run_command(['autoscale', 'list']) From 58b27c6bf5400a717acd00b7866964ef11f36e59 Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Fri, 4 Oct 2019 17:35:43 -0500 Subject: [PATCH 21/24] #627 added autoscale tag, to allow users to tag all guests in a group at once --- SoftLayer/CLI/autoscale/detail.py | 2 +- SoftLayer/CLI/autoscale/edit.py | 27 ++++++++++++++++ SoftLayer/CLI/autoscale/tag.py | 34 +++++++++++++++++++++ SoftLayer/CLI/routes.py | 2 ++ SoftLayer/fixtures/SoftLayer_Scale_Group.py | 2 ++ SoftLayer/managers/autoscale.py | 12 +++++++- docs/cli/autoscale.rst | 7 +++++ tests/CLI/modules/autoscale_tests.py | 8 +++++ tests/managers/autoscale_tests.py | 21 +++++++++++++ 9 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 SoftLayer/CLI/autoscale/edit.py create mode 100644 SoftLayer/CLI/autoscale/tag.py diff --git a/SoftLayer/CLI/autoscale/detail.py b/SoftLayer/CLI/autoscale/detail.py index d7484184c..337be43a6 100644 --- a/SoftLayer/CLI/autoscale/detail.py +++ b/SoftLayer/CLI/autoscale/detail.py @@ -87,6 +87,6 @@ def cli(env, identifier): for guest in guests: real_guest = guest.get('virtualGuest') member_table.add_row([ - guest.get('id'), real_guest.get('hostname'), utils.clean_time(real_guest.get('provisionDate')) + real_guest.get('id'), real_guest.get('hostname'), utils.clean_time(real_guest.get('provisionDate')) ]) env.fout(member_table) diff --git a/SoftLayer/CLI/autoscale/edit.py b/SoftLayer/CLI/autoscale/edit.py new file mode 100644 index 000000000..644316e72 --- /dev/null +++ b/SoftLayer/CLI/autoscale/edit.py @@ -0,0 +1,27 @@ +"""Edits an Autoscale group.""" +# :license: MIT, see LICENSE for more details. + +import click + +from SoftLayer.CLI import environment +from SoftLayer.managers.autoscale import AutoScaleManager + + +@click.command() +@click.argument('identifier') +# Suspend / Unsuspend +# Name +# Min/Max +# template->userData +# 'hostname', 'domain', 'startCpus', 'maxMemory', 'localDiskFlag' +# 'blockDeviceTemplateGroup.globalIdentifier +# blockDevices.diskImage.capacity +# sshKeys.id +# postInstallScriptUri +@environment.pass_env +def cli(env, identifier): + """Edits an Autoscale group.""" + + autoscale = AutoScaleManager(env.client) + groups = autoscale.details(identifier) + click.echo(groups) diff --git a/SoftLayer/CLI/autoscale/tag.py b/SoftLayer/CLI/autoscale/tag.py new file mode 100644 index 000000000..e1fe1745b --- /dev/null +++ b/SoftLayer/CLI/autoscale/tag.py @@ -0,0 +1,34 @@ +"""Tags all guests in an autoscale group.""" +# :license: MIT, see LICENSE for more details. + +import click + +from SoftLayer.CLI import environment +from SoftLayer.managers.autoscale import AutoScaleManager +from SoftLayer.managers.vs import VSManager + + +@click.command() +@click.argument('identifier') +@click.option('--tags', '-g', help="Tags to set for each guest in this group. Existing tags are overwritten. " + "An empty string will remove all tags") +@environment.pass_env +def cli(env, identifier, tags): + """Tags all guests in an autoscale group. + + --tags "Use, quotes, if you, want whitespace" + + --tags Otherwise,Just,commas + """ + + autoscale = AutoScaleManager(env.client) + vsmanager = VSManager(env.client) + mask = "mask[id,virtualGuestId,virtualGuest[tagReferences,id,hostname]]" + guests = autoscale.get_virtual_guests(identifier, mask=mask) + click.echo("New Tags: {}".format(tags)) + for guest in guests: + real_guest = guest.get('virtualGuest') + click.echo("Setting tags for {}".format(real_guest.get('hostname'))) + vsmanager.set_tags(tags, real_guest.get('id'),) + click.echo("Done") + # pp(guests) diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py index 0c47ce90d..5c37541df 100644 --- a/SoftLayer/CLI/routes.py +++ b/SoftLayer/CLI/routes.py @@ -308,6 +308,8 @@ ('autoscale:detail', 'SoftLayer.CLI.autoscale.detail:cli'), ('autoscale:scale', 'SoftLayer.CLI.autoscale.scale:cli'), ('autoscale:logs', 'SoftLayer.CLI.autoscale.logs:cli'), + ('autoscale:tag', 'SoftLayer.CLI.autoscale.tag:cli'), + ('autoscale:edit', 'SoftLayer.CLI.autoscale.edit:cli') ] ALL_ALIASES = { diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py index 7e9325ff2..f9da7ff68 100644 --- a/SoftLayer/fixtures/SoftLayer_Scale_Group.py +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -198,6 +198,8 @@ ] } +getVirtualGuestMembers = getObject['virtualGuestMembers'] + scale = [ { "accountId": 31111, diff --git a/SoftLayer/managers/autoscale.py b/SoftLayer/managers/autoscale.py index a5aeeca79..5298b05c6 100644 --- a/SoftLayer/managers/autoscale.py +++ b/SoftLayer/managers/autoscale.py @@ -36,7 +36,7 @@ def details(self, identifier, mask=None): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getObject/ """ if not mask: - mask = """mask[virtualGuestMembers[id,virtualGuest[hostname,domain,provisionDate]], terminationPolicy, + mask = """mask[virtualGuestMembers[id,virtualGuest[id,hostname,domain,provisionDate]], terminationPolicy, virtualGuestMemberCount, virtualGuestMemberTemplate[sshKeys], policies[id,name,createDate,cooldown,actions,triggers,scaleActions], networkVlans[networkVlanId,networkVlan[networkSpace,primaryRouter[hostname]]], @@ -93,3 +93,13 @@ def get_logs(self, identifier, mask=None, object_filter=None): """ return self.client.call('SoftLayer_Scale_Group', 'getLogs', id=identifier, mask=mask, filter=object_filter, iter=True) + + def get_virtual_guests(self, identifier, mask=None): + """Calls `SoftLayer_Scale_Group::getVirtualGuestMembers()`_ + + :param identifier: SoftLayer_Scale_Group Id + :param mask: optional SoftLayer_Scale_Member objectMask + .. _SoftLayer_Scale_Group::getVirtualGuestMembers(): + https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getVirtualGuestMembers/ + """ + return self.client.call('SoftLayer_Scale_Group', 'getVirtualGuestMembers', id=identifier, mask=mask, iter=True) diff --git a/docs/cli/autoscale.rst b/docs/cli/autoscale.rst index 8d4d83a34..a3aa31462 100644 --- a/docs/cli/autoscale.rst +++ b/docs/cli/autoscale.rst @@ -26,6 +26,13 @@ For making changes to the triggers or the autoscale group itself, see the `Autos :prog: autoscale logs :show-nested: +.. click:: SoftLayer.CLI.autoscale.tag:cli + :prog: autoscale tag + :show-nested: + +.. click:: SoftLayer.CLI.autoscale.edit:cli + :prog: autoscale edit + :show-nested: .. _Autoscale Portal: https://cloud.ibm.com/classic/autoscale \ No newline at end of file diff --git a/tests/CLI/modules/autoscale_tests.py b/tests/CLI/modules/autoscale_tests.py index ed55f6999..de686a585 100644 --- a/tests/CLI/modules/autoscale_tests.py +++ b/tests/CLI/modules/autoscale_tests.py @@ -44,3 +44,11 @@ def test_autoscale_list(self): def test_autoscale_detail(self): result = self.run_command(['autoscale', 'detail', '12222222']) self.assert_no_fail(result) + + def test_autoscale_tag(self): + result = self.run_command(['autoscale', 'tag', '12345']) + self.assert_no_fail(result) + + def test_autoscale_edit(self): + result = self.run_command(['autoscale', 'edit', '12345']) + self.assert_no_fail(result) diff --git a/tests/managers/autoscale_tests.py b/tests/managers/autoscale_tests.py index 124a82874..9826778b9 100644 --- a/tests/managers/autoscale_tests.py +++ b/tests/managers/autoscale_tests.py @@ -93,3 +93,24 @@ def test_autoscale_getLogs(self): 'getLogs', identifier=11111 ) + + def test_autoscale_get_virtual_guests(self): + self.autoscale.get_virtual_guests(11111) + + self.assert_called_with( + 'SoftLayer_Scale_Group', + 'getVirtualGuestMembers', + identifier=11111, + mask=None + ) + + def test_autoscale_get_virtual_guests_mask(self): + test_mask = "mask[id]" + self.autoscale.get_virtual_guests(11111, mask=test_mask) + + self.assert_called_with( + 'SoftLayer_Scale_Group', + 'getVirtualGuestMembers', + identifier=11111, + mask=test_mask + ) From 878db94afff463cd3a200c382eb11fafab8588d0 Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Tue, 8 Oct 2019 18:29:56 -0500 Subject: [PATCH 22/24] Edit autoscale groups command --- SoftLayer/CLI/autoscale/edit.py | 56 ++++++++++++++++----- SoftLayer/fixtures/SoftLayer_Scale_Group.py | 2 + SoftLayer/managers/autoscale.py | 13 +++++ tests/CLI/modules/autoscale_tests.py | 34 ++++++++++++- tests/managers/autoscale_tests.py | 9 ++++ 5 files changed, 99 insertions(+), 15 deletions(-) diff --git a/SoftLayer/CLI/autoscale/edit.py b/SoftLayer/CLI/autoscale/edit.py index 644316e72..ef9b610d9 100644 --- a/SoftLayer/CLI/autoscale/edit.py +++ b/SoftLayer/CLI/autoscale/edit.py @@ -9,19 +9,49 @@ @click.command() @click.argument('identifier') -# Suspend / Unsuspend -# Name -# Min/Max -# template->userData -# 'hostname', 'domain', 'startCpus', 'maxMemory', 'localDiskFlag' -# 'blockDeviceTemplateGroup.globalIdentifier -# blockDevices.diskImage.capacity -# sshKeys.id -# postInstallScriptUri -@environment.pass_env -def cli(env, identifier): +@click.option('--name', help="Scale group's name.") +@click.option('--min', 'minimum', type=click.INT, help="Set the minimum number of guests") +@click.option('--max', 'maximum', type=click.INT, help="Set the maximum number of guests") +@click.option('--userdata', help="User defined metadata string") +@click.option('--userfile', '-F', help="Read userdata from a file", + type=click.Path(exists=True, readable=True, resolve_path=True)) +@click.option('--cpu', type=click.INT, help="Number of CPUs for new guests (existing not effected") +@click.option('--memory', type=click.INT, help="RAM in MB or GB for new guests (existing not effected") +@environment.pass_env +def cli(env, identifier, name, minimum, maximum, userdata, userfile, cpu, memory): """Edits an Autoscale group.""" + template = {} autoscale = AutoScaleManager(env.client) - groups = autoscale.details(identifier) - click.echo(groups) + group = autoscale.details(identifier) + + template['name'] = name + template['minimumMemberCount'] = minimum + template['maximumMemberCount'] = maximum + virt_template = {} + if userdata: + virt_template['userData'] = [{"value":userdata}] + elif userfile: + with open(userfile, 'r') as userfile_obj: + virt_template['userData'] = [{"value":userfile_obj.read()}] + virt_template['startCpus'] = cpu + virt_template['maxMemory'] = memory + + # Remove any entries that are `None` as the API will complain about them. + template['virtualGuestMemberTemplate'] = clean_dict(virt_template) + clean_template = clean_dict(template) + + # If there are any values edited in the template, we need to get the OLD template values and replace them. + if template['virtualGuestMemberTemplate']: + # Update old template with new values + for key, value in clean_template['virtualGuestMemberTemplate'].items(): + group['virtualGuestMemberTemplate'][key] = value + clean_template['virtualGuestMemberTemplate'] = group['virtualGuestMemberTemplate'] + + result = autoscale.edit(identifier, clean_template) + click.echo("Done") + + +def clean_dict(dictionary): + """Removes any `None` entires from the dictionary""" + return {k: v for k, v in dictionary.items() if v} diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py index f9da7ff68..a6a666bde 100644 --- a/SoftLayer/fixtures/SoftLayer_Scale_Group.py +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -453,3 +453,5 @@ } }, ] + +editObject = True \ No newline at end of file diff --git a/SoftLayer/managers/autoscale.py b/SoftLayer/managers/autoscale.py index 5298b05c6..842ef2318 100644 --- a/SoftLayer/managers/autoscale.py +++ b/SoftLayer/managers/autoscale.py @@ -103,3 +103,16 @@ def get_virtual_guests(self, identifier, mask=None): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/getVirtualGuestMembers/ """ return self.client.call('SoftLayer_Scale_Group', 'getVirtualGuestMembers', id=identifier, mask=mask, iter=True) + + def edit(self, identifier, template): + """Calls `SoftLayer_Scale_Group::editObject()`_ + + :param identifier: SoftLayer_Scale_Group id + :param template: `SoftLayer_Scale_Group`_ + .. _SoftLayer_Scale_Group::editObject(): + https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/editObject/ + .. _SoftLayer_Scale_Group: https://sldn.softlayer.com/reference/datatypes/SoftLayer_Scale_Group/ + """ + + + return self.client.call('SoftLayer_Scale_Group', 'editObject', template, id=identifier) \ No newline at end of file diff --git a/tests/CLI/modules/autoscale_tests.py b/tests/CLI/modules/autoscale_tests.py index de686a585..bc6887962 100644 --- a/tests/CLI/modules/autoscale_tests.py +++ b/tests/CLI/modules/autoscale_tests.py @@ -7,6 +7,9 @@ Tests for the autoscale cli command """ +import mock +import tempfile +from SoftLayer import fixtures from SoftLayer import testing @@ -49,6 +52,33 @@ def test_autoscale_tag(self): result = self.run_command(['autoscale', 'tag', '12345']) self.assert_no_fail(result) - def test_autoscale_edit(self): - result = self.run_command(['autoscale', 'edit', '12345']) + @mock.patch('SoftLayer.managers.autoscale.AutoScaleManager.edit') + def test_autoscale_edit(self, manager): + result = self.run_command(['autoscale', 'edit', '12345', '--name', 'test']) self.assert_no_fail(result) + manager.assert_called_with('12345', {'name': 'test'}) + + @mock.patch('SoftLayer.managers.autoscale.AutoScaleManager.edit') + def test_autoscale_edit_userdata(self, manager): + group = fixtures.SoftLayer_Scale_Group.getObject + template = { + 'virtualGuestMemberTemplate': group['virtualGuestMemberTemplate'] + } + template['virtualGuestMemberTemplate']['userData'] = [{'value': 'test'}] + + result = self.run_command(['autoscale', 'edit', '12345', '--userdata', 'test']) + self.assert_no_fail(result) + manager.assert_called_with('12345', template) + + @mock.patch('SoftLayer.managers.autoscale.AutoScaleManager.edit') + def test_autoscale_edit_userfile(self, manager): + group = fixtures.SoftLayer_Scale_Group.getObject + template = { + 'virtualGuestMemberTemplate': group['virtualGuestMemberTemplate'] + } + template['virtualGuestMemberTemplate']['userData'] = [{'value': ''}] + + with tempfile.NamedTemporaryFile() as userfile: + result = self.run_command(['autoscale', 'edit', '12345', '--userfile', userfile.name]) + self.assert_no_fail(result) + manager.assert_called_with('12345', template) diff --git a/tests/managers/autoscale_tests.py b/tests/managers/autoscale_tests.py index 9826778b9..266200e40 100644 --- a/tests/managers/autoscale_tests.py +++ b/tests/managers/autoscale_tests.py @@ -114,3 +114,12 @@ def test_autoscale_get_virtual_guests_mask(self): identifier=11111, mask=test_mask ) + + def test_edit_object(self): + template = {'name': 'test'} + self.autoscale.edit(12345, template) + self.assert_called_with( + 'SoftLayer_Scale_Group', + 'editObject', + args=(template,), + identifier=12345) From f1922abed96cb4936dfaa285a18ed5b962ff0a34 Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Tue, 8 Oct 2019 18:37:40 -0500 Subject: [PATCH 23/24] tox fixes --- SoftLayer/CLI/autoscale/edit.py | 6 +++--- SoftLayer/fixtures/SoftLayer_Scale_Group.py | 2 +- SoftLayer/managers/autoscale.py | 4 +--- tests/CLI/modules/autoscale_tests.py | 4 +++- tests/managers/autoscale_tests.py | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/SoftLayer/CLI/autoscale/edit.py b/SoftLayer/CLI/autoscale/edit.py index ef9b610d9..c470aebbf 100644 --- a/SoftLayer/CLI/autoscale/edit.py +++ b/SoftLayer/CLI/autoscale/edit.py @@ -30,10 +30,10 @@ def cli(env, identifier, name, minimum, maximum, userdata, userfile, cpu, memory template['maximumMemberCount'] = maximum virt_template = {} if userdata: - virt_template['userData'] = [{"value":userdata}] + virt_template['userData'] = [{"value": userdata}] elif userfile: with open(userfile, 'r') as userfile_obj: - virt_template['userData'] = [{"value":userfile_obj.read()}] + virt_template['userData'] = [{"value": userfile_obj.read()}] virt_template['startCpus'] = cpu virt_template['maxMemory'] = memory @@ -48,7 +48,7 @@ def cli(env, identifier, name, minimum, maximum, userdata, userfile, cpu, memory group['virtualGuestMemberTemplate'][key] = value clean_template['virtualGuestMemberTemplate'] = group['virtualGuestMemberTemplate'] - result = autoscale.edit(identifier, clean_template) + autoscale.edit(identifier, clean_template) click.echo("Done") diff --git a/SoftLayer/fixtures/SoftLayer_Scale_Group.py b/SoftLayer/fixtures/SoftLayer_Scale_Group.py index a6a666bde..f04d8f56e 100644 --- a/SoftLayer/fixtures/SoftLayer_Scale_Group.py +++ b/SoftLayer/fixtures/SoftLayer_Scale_Group.py @@ -454,4 +454,4 @@ }, ] -editObject = True \ No newline at end of file +editObject = True diff --git a/SoftLayer/managers/autoscale.py b/SoftLayer/managers/autoscale.py index 842ef2318..40d7ebe80 100644 --- a/SoftLayer/managers/autoscale.py +++ b/SoftLayer/managers/autoscale.py @@ -113,6 +113,4 @@ def edit(self, identifier, template): https://sldn.softlayer.com/reference/services/SoftLayer_Scale_Group/editObject/ .. _SoftLayer_Scale_Group: https://sldn.softlayer.com/reference/datatypes/SoftLayer_Scale_Group/ """ - - - return self.client.call('SoftLayer_Scale_Group', 'editObject', template, id=identifier) \ No newline at end of file + return self.client.call('SoftLayer_Scale_Group', 'editObject', template, id=identifier) diff --git a/tests/CLI/modules/autoscale_tests.py b/tests/CLI/modules/autoscale_tests.py index bc6887962..9ea7ebe46 100644 --- a/tests/CLI/modules/autoscale_tests.py +++ b/tests/CLI/modules/autoscale_tests.py @@ -8,10 +8,12 @@ Tests for the autoscale cli command """ import mock -import tempfile + from SoftLayer import fixtures from SoftLayer import testing +import tempfile + class AutoscaleTests(testing.TestCase): diff --git a/tests/managers/autoscale_tests.py b/tests/managers/autoscale_tests.py index 266200e40..6da505409 100644 --- a/tests/managers/autoscale_tests.py +++ b/tests/managers/autoscale_tests.py @@ -116,7 +116,7 @@ def test_autoscale_get_virtual_guests_mask(self): ) def test_edit_object(self): - template = {'name': 'test'} + template = {'name': 'test'} self.autoscale.edit(12345, template) self.assert_called_with( 'SoftLayer_Scale_Group', From daeaff42a1af1212c30f42da26c2553898481fa3 Mon Sep 17 00:00:00 2001 From: allmightyspiff Date: Tue, 8 Oct 2019 18:44:58 -0500 Subject: [PATCH 24/24] removed debug code --- SoftLayer/CLI/autoscale/tag.py | 1 - 1 file changed, 1 deletion(-) diff --git a/SoftLayer/CLI/autoscale/tag.py b/SoftLayer/CLI/autoscale/tag.py index e1fe1745b..58e4101b7 100644 --- a/SoftLayer/CLI/autoscale/tag.py +++ b/SoftLayer/CLI/autoscale/tag.py @@ -31,4 +31,3 @@ def cli(env, identifier, tags): click.echo("Setting tags for {}".format(real_guest.get('hostname'))) vsmanager.set_tags(tags, real_guest.get('id'),) click.echo("Done") - # pp(guests)