diff --git a/SoftLayer/managers/ordering.py b/SoftLayer/managers/ordering.py index d99d9dcbb..874213e7f 100644 --- a/SoftLayer/managers/ordering.py +++ b/SoftLayer/managers/ordering.py @@ -27,7 +27,8 @@ def get_packages_of_type(self, package_types, mask): type keynames we are interested in. :param string mask: Mask to specify the properties we want to retrieve """ - package_service = self.get_package_service() + + package_service = self.client['Product_Package'] _filter = { 'type': { 'keyName': { @@ -44,12 +45,6 @@ def get_packages_of_type(self, package_types, mask): packages = self.filter_outlet_packages(packages) return packages - def get_package_service(self): - """ Get the service to query product packages - :return SoftLayer.API.Service - """ - return self.client['Product_Package'] - @staticmethod def filter_outlet_packages(packages): """ Remove packages designated as OUTLET @@ -60,6 +55,7 @@ def filter_outlet_packages(packages): :param packages: Dictionary of packages. Name and description keys must be present in each of them. """ + non_outlet_packages = [] for package in packages: @@ -78,6 +74,7 @@ def get_only_active_packages(packages): :param packages Dictionary of packages, isActive key must be present """ + active_packages = [] for package in packages: @@ -110,6 +107,7 @@ def get_package_id_by_type(self, package_type): we are interested in :raises ValueError when no package of the given type is found """ + mask = "mask[id, name, description, isActive, type[keyName]]" package = self.get_package_by_type(package_type, mask) if package: @@ -119,55 +117,65 @@ def get_package_id_by_type(self, package_type): def get_quotes(self): """ Retrieve a list of quotes + :return a list of SoftLayer_Billing_Order_Quote """ + quotes = self.client['Account'].getActiveQuotes() return quotes def get_quote_details(self, quote_id): """ Retrieve quote details + :param quote_id ID number of target quote """ + quote = self.client['Billing_Order_Quote'].getObject(id=quote_id) return quote def get_order_container(self, quote_id): """ Generate an order container from a quote object + :param quote_id ID number of target quote """ + quote = self.client['Billing_Order_Quote'] container = quote.getRecalculatedOrderContainer(id=quote_id) return container['orderContainers'][0] - def generate_order_template(self, quote_id=None, hostnames=None, - domain=None, quantity=None): + def generate_order_template(self, quote_id, extra, quantity=1): """ Generate a complete order template + :param int quote_id: ID of target quote - :param list hostnames: List of hostnames as strings - :param string domain: Domain name to be used for all servers - :param int quantity: Quantity to override default + :param list extra: List of dictionaries that have extra details about + the order such as hostname or domain names for + virtual servers or hardware nodes + :param int quantity: Number of ~things~ to order """ + container = self.get_order_container(quote_id) - if quantity is not None: - container['quantity'] = quantity + container['quantity'] = quantity + + # NOTE(kmcdonald): This will only work with virtualGuests and hardware. + # There has to be a better way, since this is based on + # an existing quote that supposedly knows about this + # detail if container['packageId'] == 46: product_type = 'virtualGuests' else: product_type = 'hardware' - if len(hostnames) != container['quantity']: - raise ValueError("You must specify a hostname for each " - "server in the quote") + if len(extra) != quantity: + raise ValueError("You must specify extra for each server in the " + "quote") container[product_type] = [] - for hostname in hostnames: - container[product_type].append( - {'hostname': hostname, 'domain': domain} - ) + for extra_details in extra: + container[product_type].append(extra_details) container['presetId'] = None return container - def verify_quote(self, **kwargs): + def verify_quote(self, quote_id, extra, quantity=1): """ Verifies that a quote order is valid without actually ordering the resources @@ -177,17 +185,20 @@ def verify_quote(self, **kwargs): :param string domain: domain of the new servers :param int quantity: Quantity to override default """ - container = self.generate_order_template(**kwargs) + + container = self.generate_order_template(quote_id, extra, + quantity=quantity) return self.client['Product_Order'].verifyOrder(container) - def order_quote(self, **kwargs): - """ - Places an order using a quote + def order_quote(self, quote_id, extra, quantity=1): + """ Places an order using a quote :param int quote_id: ID for the target quote :param list hostnames: hostnames of the servers :param string domain: domain of the new server :param int quantity: Quantity to override default """ - container = self.generate_order_template(**kwargs) + + container = self.generate_order_template(quote_id, extra, + quantity=quantity) return self.client['Product_Order'].placeOrder(container) diff --git a/SoftLayer/managers/vs.py b/SoftLayer/managers/vs.py index d8538fc5b..f558d7501 100644 --- a/SoftLayer/managers/vs.py +++ b/SoftLayer/managers/vs.py @@ -642,7 +642,7 @@ def _get_package_items(self): mask = "mask[description,capacity,prices[id,categories[name,id]]]" package_type = "VIRTUAL_SERVER_INSTANCE" package_id = self.ordering_manager.get_package_id_by_type(package_type) - package_service = self.ordering_manager.get_package_service() + package_service = self.client['Product_Package'] return package_service.getItems(id=package_id, mask=mask) diff --git a/SoftLayer/tests/managers/ordering_tests.py b/SoftLayer/tests/managers/ordering_tests.py index 66ffcda86..025e31af3 100644 --- a/SoftLayer/tests/managers/ordering_tests.py +++ b/SoftLayer/tests/managers/ordering_tests.py @@ -1,6 +1,6 @@ """ SoftLayer.tests.managers.ordering_tests - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :license: MIT, see LICENSE for more details. """ @@ -83,19 +83,41 @@ def test_get_quotes(self): def test_get_quote_details(self): quote = self.ordering.get_quote_details(1234) - quote_fixture = self.ordering.client['Billing_Order_Quote'].getObject( - id=1234) + quote_service = self.ordering.client['Billing_Order_Quote'] + quote_fixture = quote_service.getObject(id=1234) self.assertEqual(quote, quote_fixture) def test_verify_quote(self): - result = self.ordering.verify_quote( - quote_id=1234, - domain='example.com', - hostnames=['test1'], - quantity=1) + order_service = self.ordering.client['Product_Order'] + result = self.ordering.verify_quote(1234, + [{'hostname': 'test1', + 'domain': 'example.com'}], + quantity=1) - self.assertEqual(result, self.ordering.client['Product_Order']. - verifyOrder()) + self.assertEqual(result, order_service.verifyOrder()) + self.assertTrue(order_service.verifyOrder.called) def test_order_quote(self): - return True + order_service = self.ordering.client['Product_Order'] + result = self.ordering.verify_quote(1234, + [{'hostname': 'test1', + 'domain': 'example.com'}], + quantity=1) + + self.assertEqual(result, order_service.placeOrder()) + self.assertTrue(order_service.placeOrder.called) + + def test_generate_order_template(self): + result = self.ordering.generate_order_template( + 1234, [{'hostname': 'test1', 'domain': 'example.com'}], quantity=1) + self.assertEqual(result, {'presetId': None, + 'hardware': [{'domain': 'example.com', + 'hostname': 'test1'}], + 'useHourlyPricing': '', + 'packageId': 50, + 'prices': [{'id': 1921}], + 'quantity': 1}) + + def test_generate_order_template_extra_quantity(self): + with self.assertRaises(ValueError): + self.ordering.generate_order_template(1234, [], quantity=1)