diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c408f0ec..17b9b49df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## [5.6.3] - 2018-11-07 + +- Changes: https://github.com/softlayer/softlayer-python/compare/v5.6.0...v5.6.3 + ++ #1065 Updated urllib3 and requests libraries due to CVE-2018-18074 ++ #1070 Fixed an ordering bug ++ Updated release process and fab-file + ## [5.6.0] - 2018-10-16 - Changes: https://github.com/softlayer/softlayer-python/compare/v5.5.3...v5.6.0 diff --git a/SoftLayer/CLI/securitygroup/rule.py b/SoftLayer/CLI/securitygroup/rule.py index 4f624308c..815262313 100644 --- a/SoftLayer/CLI/securitygroup/rule.py +++ b/SoftLayer/CLI/securitygroup/rule.py @@ -15,7 +15,9 @@ 'ethertype', 'portRangeMin', 'portRangeMax', - 'protocol'] + 'protocol', + 'createDate', + 'modifyDate'] @click.command() @@ -49,7 +51,9 @@ def rule_list(env, securitygroup_id, sortby): rule.get('ethertype') or formatting.blank(), port_min, port_max, - rule.get('protocol') or formatting.blank() + rule.get('protocol') or formatting.blank(), + rule.get('createDate') or formatting.blank(), + rule.get('modifyDate') or formatting.blank() ]) env.fout(table) diff --git a/SoftLayer/CLI/virt/create_options.py b/SoftLayer/CLI/virt/create_options.py index 7bacd8bf0..b50fde3d2 100644 --- a/SoftLayer/CLI/virt/create_options.py +++ b/SoftLayer/CLI/virt/create_options.py @@ -1,5 +1,6 @@ """Virtual server order options.""" # :license: MIT, see LICENSE for more details. +# pylint: disable=too-many-statements import os import os.path diff --git a/SoftLayer/CLI/vpn/ipsec/translation/add.py b/SoftLayer/CLI/vpn/ipsec/translation/add.py index a0b7a35e6..952f7fd6c 100644 --- a/SoftLayer/CLI/vpn/ipsec/translation/add.py +++ b/SoftLayer/CLI/vpn/ipsec/translation/add.py @@ -11,12 +11,10 @@ @click.command() @click.argument('context_id', type=int) -# todo: Update to utilize custom IP address type @click.option('-s', '--static-ip', required=True, help='Static IP address value') -# todo: Update to utilize custom IP address type @click.option('-r', '--remote-ip', required=True, diff --git a/SoftLayer/CLI/vpn/ipsec/translation/update.py b/SoftLayer/CLI/vpn/ipsec/translation/update.py index b78585db0..4f0709001 100644 --- a/SoftLayer/CLI/vpn/ipsec/translation/update.py +++ b/SoftLayer/CLI/vpn/ipsec/translation/update.py @@ -15,12 +15,10 @@ required=True, type=int, help='Translation identifier to update') -# todo: Update to utilize custom IP address type @click.option('-s', '--static-ip', default=None, help='Static IP address value') -# todo: Update to utilize custom IP address type @click.option('-r', '--remote-ip', default=None, diff --git a/SoftLayer/CLI/vpn/ipsec/update.py b/SoftLayer/CLI/vpn/ipsec/update.py index 4056f3b8f..738a1d9f9 100644 --- a/SoftLayer/CLI/vpn/ipsec/update.py +++ b/SoftLayer/CLI/vpn/ipsec/update.py @@ -13,7 +13,6 @@ @click.option('--friendly-name', default=None, help='Friendly name value') -# todo: Update to utilize custom IP address type @click.option('--remote-peer', default=None, help='Remote peer IP address value') diff --git a/SoftLayer/consts.py b/SoftLayer/consts.py index 29e3f58d2..ee5f29ab0 100644 --- a/SoftLayer/consts.py +++ b/SoftLayer/consts.py @@ -5,7 +5,7 @@ :license: MIT, see LICENSE for more details. """ -VERSION = 'v5.6.0' +VERSION = 'v5.6.3' API_PUBLIC_ENDPOINT = 'https://api.softlayer.com/xmlrpc/v3.1/' API_PRIVATE_ENDPOINT = 'https://api.service.softlayer.com/xmlrpc/v3.1/' API_PUBLIC_ENDPOINT_REST = 'https://api.softlayer.com/rest/v3.1/' diff --git a/SoftLayer/managers/hardware.py b/SoftLayer/managers/hardware.py index 6980f4397..9f97a1d3d 100644 --- a/SoftLayer/managers/hardware.py +++ b/SoftLayer/managers/hardware.py @@ -92,7 +92,7 @@ def cancel_hardware(self, hardware_id, reason='unneeded', comment='', immediate= billing_id = hw_billing['billingItem']['id'] if immediate and not hw_billing['hourlyBillingFlag']: - LOGGER.warning("Immediate cancelation of montly servers is not guaranteed. " + + LOGGER.warning("Immediate cancelation of montly servers is not guaranteed." "Please check the cancelation ticket for updates.") result = self.client.call('Billing_Item', 'cancelItem', diff --git a/SoftLayer/managers/ipsec.py b/SoftLayer/managers/ipsec.py index 130623c48..29317516e 100644 --- a/SoftLayer/managers/ipsec.py +++ b/SoftLayer/managers/ipsec.py @@ -227,10 +227,6 @@ def update_translation(self, context_id, translation_id, static_ip=None, translation.pop('customerIpAddressId', None) if notes is not None: translation['notes'] = notes - # todo: Update this signature to return the updated translation - # once internal and customer IP addresses can be fetched - # and set on the translation object, i.e. that which is - # currently being handled in get_translations self.context.editAddressTranslation(translation, id=context_id) return True diff --git a/SoftLayer/managers/network.py b/SoftLayer/managers/network.py index b568e8896..4223143ae 100644 --- a/SoftLayer/managers/network.py +++ b/SoftLayer/managers/network.py @@ -372,7 +372,7 @@ def get_securitygroup(self, group_id, **kwargs): 'description,' '''rules[id, remoteIp, remoteGroupId, direction, ethertype, portRangeMin, - portRangeMax, protocol],''' + portRangeMax, protocol, createDate, modifyDate],''' '''networkComponentBindings[ networkComponent[ id, diff --git a/SoftLayer/managers/ordering.py b/SoftLayer/managers/ordering.py index 18a606b05..c0eca1dc4 100644 --- a/SoftLayer/managers/ordering.py +++ b/SoftLayer/managers/ordering.py @@ -378,8 +378,10 @@ def get_item_price_id(core, prices): if not price['locationGroupId']: capacity_min = int(price.get('capacityRestrictionMinimum', -1)) capacity_max = int(price.get('capacityRestrictionMaximum', -1)) - if capacity_min == -1: + # return first match if no restirction, or no core to check + if capacity_min == -1 or core is None: price_id = price['id'] + # this check is mostly to work nicely with preset configs elif capacity_min <= int(core) <= capacity_max: price_id = price['id'] return price_id diff --git a/SoftLayer/managers/vs.py b/SoftLayer/managers/vs.py index 03595d8d5..dbbaa98c4 100644 --- a/SoftLayer/managers/vs.py +++ b/SoftLayer/managers/vs.py @@ -503,15 +503,16 @@ def verify_create_instance(self, **kwargs): 'domain': u'test01.labs.sftlyr.ws', 'hostname': u'minion05', 'datacenter': u'hkg02', + 'flavor': 'BL1_1X2X100' 'dedicated': False, 'private': False, - 'cpus': 1, 'os_code' : u'UBUNTU_LATEST', 'hourly': True, 'ssh_keys': [1234], 'disks': ('100','25'), 'local_disk': True, - 'memory': 1024 + 'tags': 'test, pleaseCancel', + 'public_security_groups': [12, 15] } vsi = mgr.verify_create_instance(**new_vsi) @@ -536,15 +537,14 @@ def create_instance(self, **kwargs): 'domain': u'test01.labs.sftlyr.ws', 'hostname': u'minion05', 'datacenter': u'hkg02', + 'flavor': 'BL1_1X2X100' 'dedicated': False, 'private': False, - 'cpus': 1, 'os_code' : u'UBUNTU_LATEST', 'hourly': True, 'ssh_keys': [1234], 'disks': ('100','25'), 'local_disk': True, - 'memory': 1024, 'tags': 'test, pleaseCancel', 'public_security_groups': [12, 15] } @@ -607,17 +607,16 @@ def create_instances(self, config_list): # Define the instance we want to create. new_vsi = { 'domain': u'test01.labs.sftlyr.ws', - 'hostname': u'multi-test', + 'hostname': u'minion05', 'datacenter': u'hkg02', + 'flavor': 'BL1_1X2X100' 'dedicated': False, 'private': False, - 'cpus': 1, 'os_code' : u'UBUNTU_LATEST', 'hourly': True, - 'ssh_keys': [87634], + 'ssh_keys': [1234], 'disks': ('100','25'), 'local_disk': True, - 'memory': 1024, 'tags': 'test, pleaseCancel', 'public_security_groups': [12, 15] } diff --git a/fabfile.py b/fabfile.py index c864c537e..cd6a968f5 100644 --- a/fabfile.py +++ b/fabfile.py @@ -12,8 +12,8 @@ def make_html(): def upload(): "Upload distribution to PyPi" - local('python setup.py sdist upload') - local('python setup.py bdist_wheel upload') + local('python setup.py sdist bdist_wheel') + local('twine upload dist/*') def clean(): diff --git a/setup.py b/setup.py index c860c85be..e99860a97 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ setup( name='SoftLayer', - version='5.6.1', + version='5.6.3', description=DESCRIPTION, long_description=LONG_DESCRIPTION, author='SoftLayer Technologies, Inc.', diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 224313b06..f5ec61df5 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: slcli # check to see if it's available -version: '5.6.0+git' # check versioning +version: '5.6.3+git' # check versioning summary: Python based SoftLayer API Tool. # 79 char long summary description: | A command-line interface is also included and can be used to manage various SoftLayer products and services. diff --git a/tests/CLI/modules/securitygroup_tests.py b/tests/CLI/modules/securitygroup_tests.py index 65c496b63..9b7e4c6a7 100644 --- a/tests/CLI/modules/securitygroup_tests.py +++ b/tests/CLI/modules/securitygroup_tests.py @@ -118,7 +118,9 @@ def test_securitygroup_rule_list(self): 'remoteGroupId': None, 'protocol': None, 'portRangeMin': None, - 'portRangeMax': None}], + 'portRangeMax': None, + 'createDate': None, + 'modifyDate': None}], json.loads(result.output)) def test_securitygroup_rule_add(self): diff --git a/tests/managers/ordering_tests.py b/tests/managers/ordering_tests.py index 4b2c431cb..b5d2aaa48 100644 --- a/tests/managers/ordering_tests.py +++ b/tests/managers/ordering_tests.py @@ -569,3 +569,31 @@ def test_get_item_price_id_with_capacity_restriction(self): price_id = self.ordering.get_item_price_id("8", price1) self.assertEqual(1234, price_id) + + def test_issues1067(self): + # https://github.com/softlayer/softlayer-python/issues/1067 + item_mock = self.set_mock('SoftLayer_Product_Package', 'getItems') + item_mock_return = [ + { + 'id': 10453, + 'itemCategory': {'categoryCode': 'server'}, + 'keyName': 'INTEL_INTEL_XEON_4110_2_10', + 'prices': [ + { + 'capacityRestrictionMaximum': '2', + 'capacityRestrictionMinimum': '2', + 'capacityRestrictionType': 'PROCESSOR', + 'categories': [{'categoryCode': 'os'}], + 'id': 201161, + 'locationGroupId': None, + 'recurringFee': '250', + 'setupFee': '0' + } + ] + } + ] + item_mock.return_value = item_mock_return + item_keynames = ['INTEL_INTEL_XEON_4110_2_10'] + package = 'DUAL_INTEL_XEON_PROCESSOR_SCALABLE_FAMILY_4_DRIVES' + result = self.ordering.get_price_id_list(package, item_keynames, None) + self.assertIn(201161, result) diff --git a/tox.ini b/tox.ini index ae456665f..e5c7c2f66 100644 --- a/tox.ini +++ b/tox.ini @@ -36,6 +36,10 @@ commands = -d locally-disabled \ -d no-else-return \ -d len-as-condition \ + -d useless-object-inheritance \ + -d consider-using-in \ + -d consider-using-dict-comprehension \ + -d useless-import-alias \ --max-args=25 \ --max-branches=20 \ --max-statements=65 \