Skip to content

Commit 53492ee

Browse files
#1026 unit tests and fixtures for ReservedCapacityGroup
1 parent 1046cfe commit 53492ee

File tree

11 files changed

+431
-12
lines changed

11 files changed

+431
-12
lines changed

SoftLayer/CLI/virt/capacity/create-options.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,3 @@ def get_price(item):
4343
if price.get('locationGroupId') == '':
4444
the_price = "%0.4f" % float(price['hourlyRecurringFee'])
4545
return the_price
46-
47-
def get_router_ids():
48-
pass

SoftLayer/CLI/virt/capacity/detail.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
def cli(env, identifier, columns):
5050
"""Reserved Capacity Group details. Will show which guests are assigned to a reservation."""
5151
manager = CapacityManager(env.client)
52-
mask = "mask[instances[billingItem[category], guest]]"
52+
mask = """mask[instances[id,createDate,guestId,billingItem[id, recurringFee, category[name]],
53+
guest[modifyDate,id, primaryBackendIpAddress, primaryIpAddress,domain, hostname]]]"""
5354
result = manager.get_object(identifier, mask)
5455
try:
5556
flavor = result['instances'][0]['billingItem']['description']

SoftLayer/fixtures/SoftLayer_Account.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,3 +575,37 @@
575575
'username': 'sl1234-abob',
576576
'virtualGuestCount': 99}
577577
]
578+
579+
getReservedCapacityGroups = [
580+
{'accountId': 1234,
581+
'backendRouterId': 1411193,
582+
'createDate': '2018-09-24T16:33:09-06:00',
583+
'id': 3103,
584+
'modifyDate': '',
585+
'name': 'test-capacity',
586+
'availableInstanceCount': 1,
587+
'instanceCount': 2,
588+
'occupiedInstanceCount': 1,
589+
'backendRouter':
590+
{'accountId': 1,
591+
'bareMetalInstanceFlag': 0,
592+
'domain': 'softlayer.com',
593+
'fullyQualifiedDomainName': 'bcr02a.dal13.softlayer.com',
594+
'hardwareStatusId': 5,
595+
'hostname': 'bcr02a.dal13',
596+
'id': 1411193,
597+
'notes': '',
598+
'provisionDate': '',
599+
'serviceProviderId': 1,
600+
'serviceProviderResourceId': '',
601+
'primaryIpAddress': '10.0.144.28',
602+
'datacenter': {'id': 1854895, 'longName': 'Dallas 13', 'name': 'dal13', 'statusId': 2},
603+
'hardwareFunction': {'code': 'ROUTER', 'description': 'Router', 'id': 1},
604+
'topLevelLocation': {'id': 1854895, 'longName': 'Dallas 13', 'name': 'dal13', 'statusId': 2}
605+
},
606+
'instances': [
607+
{'id': 3501, 'billingItem': {'description': 'B1.1x2 (1 Year Term)', 'hourlyRecurringFee': '.032'}},
608+
{'id': 3519, 'billingItem': {'description': 'B1.1x2 (1 Year Term)', 'hourlyRecurringFee': '.032'}}
609+
]
610+
}
611+
]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
getAllObjects = [
2+
{
3+
'backendRouterId': 117917,
4+
'backendRouterName': 'bcr01a.ams01',
5+
'datacenterId': 265592,
6+
'datacenterLongName': 'Amsterdam 1',
7+
'datacenterName': 'ams01',
8+
'frontendRouterId': 117960,
9+
'frontendRouterName': 'fcr01a.ams01',
10+
'name': 'ams01.pod01'
11+
},
12+
{
13+
'backendRouterId': 1115295,
14+
'backendRouterName': 'bcr01a.wdc07',
15+
'datacenterId': 2017603,
16+
'datacenterLongName': 'Washington 7',
17+
'datacenterName': 'wdc07',
18+
'frontendRouterId': 1114993,
19+
'frontendRouterName': 'fcr01a.wdc07',
20+
'name': 'wdc07.pod01'
21+
}
22+
]

SoftLayer/fixtures/SoftLayer_Product_Order.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
'item': {'id': 1, 'description': 'this is a thing'},
1515
}]}
1616
placeOrder = verifyOrder
17+

SoftLayer/fixtures/SoftLayer_Product_Package.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,3 +1542,83 @@
15421542
]
15431543

15441544
getAccountRestrictedActivePresets = []
1545+
1546+
RESERVED_CAPACITY = [{"id": 1059}]
1547+
getItems_RESERVED_CAPACITY = [
1548+
{
1549+
'id': 12273,
1550+
'keyName': 'B1_1X2_1_YEAR_TERM',
1551+
'itemCategory': {
1552+
'categoryCode': 'reserved_capacity',
1553+
'id': 2060,
1554+
'name': 'Reserved Capacity',
1555+
'quantityLimit': 20,
1556+
'sortOrder': ''
1557+
},
1558+
'prices': [
1559+
{
1560+
'currentPriceFlag': '',
1561+
'hourlyRecurringFee': '.032',
1562+
'id': 217561,
1563+
'itemId': 12273,
1564+
'laborFee': '0',
1565+
'locationGroupId': '',
1566+
'onSaleFlag': '',
1567+
'oneTimeFee': '0',
1568+
'quantity': '',
1569+
'setupFee': '0',
1570+
'sort': 0,
1571+
'tierMinimumThreshold': '',
1572+
'categories': [
1573+
{
1574+
'categoryCode': 'reserved_capacity',
1575+
'id': 2060,
1576+
'name': 'Reserved Capacity',
1577+
'quantityLimit': 20,
1578+
'sortOrder': ''
1579+
}
1580+
]
1581+
}
1582+
]
1583+
}
1584+
]
1585+
1586+
getItems_1_IPV6_ADDRESS = [
1587+
{
1588+
'id': 4097,
1589+
'keyName': '1_IPV6_ADDRESS',
1590+
'itemCategory': {
1591+
'categoryCode': 'pri_ipv6_addresses',
1592+
'id': 325,
1593+
'name': 'Primary IPv6 Addresses',
1594+
'quantityLimit': 0,
1595+
'sortOrder': 34
1596+
},
1597+
'prices': [
1598+
{
1599+
'currentPriceFlag': '',
1600+
'hourlyRecurringFee': '0',
1601+
'id': 17129,
1602+
'itemId': 4097,
1603+
'laborFee': '0',
1604+
'locationGroupId': '',
1605+
'onSaleFlag': '',
1606+
'oneTimeFee': '0',
1607+
'quantity': '',
1608+
'recurringFee': '0',
1609+
'setupFee': '0',
1610+
'sort': 0,
1611+
'tierMinimumThreshold': '',
1612+
'categories': [
1613+
{
1614+
'categoryCode': 'pri_ipv6_addresses',
1615+
'id': 325,
1616+
'name': 'Primary IPv6 Addresses',
1617+
'quantityLimit': 0,
1618+
'sortOrder': 34
1619+
}
1620+
]
1621+
}
1622+
]
1623+
}
1624+
]

SoftLayer/fixtures/SoftLayer_Virtual_Guest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,3 +617,6 @@
617617
}
618618
},
619619
]
620+
621+
622+
# RESERVED_ORDER_TEMPLATE = {'imageTemplateId': '', 'location': '1854895', 'packageId': 835, 'presetId': 215, 'quantity': 1, 'sourceVirtualGuestId': '', 'useHourlyPricing': True, 'complexType': 'SoftLayer_Container_Product_Order_Virtual_Guest', 'prices': [{'hourlyRecurringFee': '0', 'id': 211451, 'recurringFee': '0', 'item': {'description': 'Ubuntu Linux 18.04 LTS Bionic Beaver Minimal Install (64 bit) '}}, {'hourlyRecurringFee': '0', 'id': 2202, 'recurringFee': '0', 'item': {'description': '25 GB (SAN)'}}, {'hourlyRecurringFee': '0', 'id': 905, 'recurringFee': '0', 'item': {'description': 'Reboot / Remote Console'}}, {'hourlyRecurringFee': '0', 'id': 273, 'recurringFee': '0', 'item': {'description': '100 Mbps Public & Private Network Uplinks'}}, {'hourlyRecurringFee': '0', 'id': 1800, 'item': {'description': '0 GB Bandwidth Allotment'}}, {'hourlyRecurringFee': '0', 'id': 21, 'recurringFee': '0', 'item': {'description': '1 IP Address'}}, {'hourlyRecurringFee': '0', 'id': 55, 'recurringFee': '0', 'item': {'description': 'Host Ping'}}, {'hourlyRecurringFee': '0', 'id': 57, 'recurringFee': '0', 'item': {'description': 'Email and Ticket'}}, {'hourlyRecurringFee': '0', 'id': 58, 'recurringFee': '0', 'item': {'description': 'Automated Notification'}}, {'hourlyRecurringFee': '0', 'id': 420, 'recurringFee': '0', 'item': {'description': 'Unlimited SSL VPN Users & 1 PPTP VPN User per account'}}, {'hourlyRecurringFee': '0', 'id': 418, 'recurringFee': '0', 'item': {'description': 'Nessus Vulnerability Assessment & Reporting'}}, {'id': 17129}], 'sshKeys': [{'sshKeyIds': [87634]}], 'virtualGuests': [{'domain': 'cgallo.com', 'hostname': 'A1538172419'}], 'reservedCapacityId': 3103}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
getObject = {
2+
'accountId': 1234,
3+
'backendRouterId': 1411193,
4+
'backendRouter': {
5+
'fullyQualifiedDomainName': 'bcr02a.dal13.softlayer.com',
6+
'hostname': 'bcr02a.dal13',
7+
'id': 1411193,
8+
'datacenter': {
9+
'id': 1854895,
10+
'longName': 'Dallas 13',
11+
'name': 'dal13',
12+
13+
}
14+
},
15+
'createDate': '2018-09-24T16:33:09-06:00',
16+
'id': 3103,
17+
'modifyDate': '',
18+
'name': 'test-capacity',
19+
'instances': [
20+
{
21+
'createDate': '2018-09-24T16:33:09-06:00',
22+
'guestId': 62159257,
23+
'id': 3501,
24+
'billingItem': {
25+
'id': 348319479,
26+
'recurringFee': '3.04',
27+
'category': { 'name': 'Reserved Capacity' },
28+
'item': {
29+
'keyName': 'B1_1X2_1_YEAR_TERM'
30+
}
31+
},
32+
'guest': {
33+
'domain': 'cgallo.com',
34+
'hostname': 'test-reserved-instance',
35+
'id': 62159257,
36+
'modifyDate': '2018-09-27T16:49:26-06:00',
37+
'primaryBackendIpAddress': '10.73.150.179',
38+
'primaryIpAddress': '169.62.147.165'
39+
}
40+
},
41+
{
42+
'createDate': '2018-09-24T16:33:10-06:00',
43+
'guestId': 62159275,
44+
'id': 3519,
45+
'billingItem': {
46+
'id': 348319443,
47+
'recurringFee': '3.04',
48+
'category': {
49+
'name': 'Reserved Capacity'
50+
},
51+
'item': {
52+
'keyName': 'B1_1X2_1_YEAR_TERM'
53+
}
54+
}
55+
}
56+
]
57+
}

SoftLayer/managers/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
from SoftLayer.managers.ticket import TicketManager
2828
from SoftLayer.managers.user import UserManager
2929
from SoftLayer.managers.vs import VSManager
30+
from SoftLayer.managers.vs_capacity import CapacityManager
3031

3132

3233
__all__ = [
3334
'BlockStorageManager',
35+
'CapacityManager',
3436
'CDNManager',
3537
'DedicatedHostManager',
3638
'DNSManager',

SoftLayer/managers/vs_capacity.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,34 +53,49 @@ def get_object(self, identifier, mask=None):
5353

5454
def get_create_options(self):
5555
mask = "mask[attributes,prices[pricingLocationGroup]]"
56-
# mask = "mask[id, description, capacity, units]"
5756
results = self.ordering_manager.list_items(self.capacity_package, mask=mask)
5857
return results
5958

60-
def get_available_routers(self):
61-
"""Pulls down all backendRouterIds that are available"""
59+
def get_available_routers(self, dc=None):
60+
"""Pulls down all backendRouterIds that are available
61+
62+
:param string dc: A specific location to get routers for, like 'dal13'.
63+
:returns list: A list of locations where RESERVED_CAPACITY can be ordered.
64+
"""
6265
mask = "mask[locations]"
6366
# Step 1, get the package id
6467
package = self.ordering_manager.get_package_by_key(self.capacity_package, mask="id")
6568

6669
# Step 2, get the regions this package is orderable in
67-
regions = self.client.call('Product_Package', 'getRegions', id=package['id'], mask=mask)
68-
_filter = {'datacenterName': {'operation': ''}}
70+
regions = self.client.call('Product_Package', 'getRegions', id=package['id'], mask=mask, iter=True)
71+
_filter = None
6972
routers = {}
73+
if dc is not None:
74+
_filter = {'datacenterName': {'operation': dc}}
7075

7176
# Step 3, for each location in each region, get the pod details, which contains the router id
77+
pods = self.client.call('Network_Pod', 'getAllObjects', filter=_filter, iter=True)
7278
for region in regions:
7379
routers[region['keyname']] = []
7480
for location in region['locations']:
7581
location['location']['pods'] = list()
76-
_filter['datacenterName']['operation'] = location['location']['name']
77-
location['location']['pods'] = self.client.call('Network_Pod', 'getAllObjects', filter=_filter)
82+
for pod in pods:
83+
if pod['datacenterName'] == location['location']['name']:
84+
location['location']['pods'].append(pod)
7885

7986
# Step 4, return the data.
8087
return regions
8188

8289
def create(self, name, datacenter, backend_router_id, capacity, quantity, test=False):
83-
"""Orders a Virtual_ReservedCapacityGroup"""
90+
"""Orders a Virtual_ReservedCapacityGroup
91+
92+
:params string name: Name for the new reserved capacity
93+
:params string datacenter: like 'dal13'
94+
:params int backend_router_id: This selects the pod. See create_options for a list
95+
:params string capacity: Capacity KeyName, see create_options for a list
96+
:params int quantity: Number of guest this capacity can support
97+
:params bool test: If True, don't actually order, just test.
98+
"""
8499
args = (self.capacity_package, datacenter, [capacity])
85100
extras = {"backendRouterId": backend_router_id, "name": name}
86101
kwargs = {
@@ -96,6 +111,18 @@ def create(self, name, datacenter, backend_router_id, capacity, quantity, test=F
96111
return receipt
97112

98113
def create_guest(self, capacity_id, test, guest_object):
114+
"""Turns an empty Reserve Capacity into a real Virtual Guest
115+
116+
:params int capacity_id: ID of the RESERVED_CAPACITY_GROUP to create this guest into
117+
:params bool test: True will use verifyOrder, False will use placeOrder
118+
:params dictionary guest_object: Below is the minimum info you need to send in
119+
guest_object = {
120+
'domain': 'test.com',
121+
'hostname': 'A1538172419',
122+
'os_code': 'UBUNTU_LATEST_64',
123+
'primary_disk': '25',
124+
}
125+
"""
99126
vs_manager = VSManager(self.client)
100127
mask = "mask[instances[id, billingItem[id, item[id,keyName]]], backendRouter[id, datacenter[name]]]"
101128
capacity = self.get_object(capacity_id)

0 commit comments

Comments
 (0)