Skip to content

Commit e478f1d

Browse files
Merge pull request #1087 from allmightyspiff/676
#676 - ipv6 support for creating virtual guests
2 parents 08ca596 + 0b94a90 commit e478f1d

19 files changed

Lines changed: 1176 additions & 905 deletions

SoftLayer/CLI/metadata.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
\b
3737
Examples :
3838
%s
39-
""" % ('*'+'\n*'.join(META_CHOICES),
40-
'slcli metadata '+'\nslcli metadata '.join(META_CHOICES))
39+
""" % ('*' + '\n*'.join(META_CHOICES),
40+
'slcli metadata ' + '\nslcli metadata '.join(META_CHOICES))
4141

4242

4343
@click.command(help=HELP,

SoftLayer/CLI/virt/capacity/create_guest.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@
3636
def cli(env, **args):
3737
"""Allows for creating a virtual guest in a reserved capacity."""
3838
create_args = _parse_create_args(env.client, args)
39-
if args.get('ipv6'):
40-
create_args['ipv6'] = True
39+
4140
create_args['primary_disk'] = args.get('primary_disk')
4241
manager = CapacityManager(env.client)
4342
capacity_id = args.get('capacity_id')

SoftLayer/CLI/virt/create.py

Lines changed: 100 additions & 188 deletions
Large diffs are not rendered by default.

SoftLayer/CLI/virt/upgrade.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,30 @@
1616
completed. However for Network, no reboot is required.""")
1717
@click.argument('identifier')
1818
@click.option('--cpu', type=click.INT, help="Number of CPU cores")
19-
@click.option('--private',
20-
is_flag=True,
19+
@click.option('--private', is_flag=True,
2120
help="CPU core will be on a dedicated host server.")
2221
@click.option('--memory', type=virt.MEM_TYPE, help="Memory in megabytes")
2322
@click.option('--network', type=click.INT, help="Network port speed in Mbps")
24-
@click.option('--flavor', type=click.STRING, help="Flavor keyName\n"
25-
"Do not use --memory, --cpu or --private, if you are using flavors")
23+
@click.option('--flavor', type=click.STRING,
24+
help="Flavor keyName\nDo not use --memory, --cpu or --private, if you are using flavors")
2625
@environment.pass_env
2726
def cli(env, identifier, cpu, private, memory, network, flavor):
2827
"""Upgrade a virtual server."""
2928

3029
vsi = SoftLayer.VSManager(env.client)
3130

3231
if not any([cpu, memory, network, flavor]):
33-
raise exceptions.ArgumentError(
34-
"Must provide [--cpu], [--memory], [--network], or [--flavor] to upgrade")
32+
raise exceptions.ArgumentError("Must provide [--cpu], [--memory], [--network], or [--flavor] to upgrade")
3533

3634
if private and not cpu:
37-
raise exceptions.ArgumentError(
38-
"Must specify [--cpu] when using [--private]")
35+
raise exceptions.ArgumentError("Must specify [--cpu] when using [--private]")
3936

4037
vs_id = helpers.resolve_id(vsi.resolve_ids, identifier, 'VS')
41-
if not (env.skip_confirmations or formatting.confirm(
42-
"This action will incur charges on your account. "
43-
"Continue?")):
38+
if not (env.skip_confirmations or formatting.confirm("This action will incur charges on your account. Continue?")):
4439
raise exceptions.CLIAbort('Aborted')
4540

4641
if memory:
4742
memory = int(memory / 1024)
4843

49-
if not vsi.upgrade(vs_id,
50-
cpus=cpu,
51-
memory=memory,
52-
nic_speed=network,
53-
public=not private,
54-
preset=flavor):
44+
if not vsi.upgrade(vs_id, cpus=cpu, memory=memory, nic_speed=network, public=not private, preset=flavor):
5545
raise exceptions.CLIAbort('VS Upgrade Failed')

SoftLayer/fixtures/SoftLayer_Product_Order.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,29 @@
1313
'setupFee': '1',
1414
'item': {'id': 1, 'description': 'this is a thing'},
1515
}]}
16-
placeOrder = verifyOrder
16+
placeOrder = {
17+
'orderId': 1234,
18+
'orderDate': '2013-08-01 15:23:45',
19+
'orderDetails': {
20+
'prices': [{
21+
'id': 1,
22+
'laborFee': '2',
23+
'oneTimeFee': '2',
24+
'oneTimeFeeTax': '.1',
25+
'quantity': 1,
26+
'recurringFee': '2',
27+
'recurringFeeTax': '.1',
28+
'hourlyRecurringFee': '2',
29+
'setupFee': '1',
30+
'item': {'id': 1, 'description': 'this is a thing'},
31+
}],
32+
'virtualGuests': [{
33+
'id': 1234567,
34+
'globalIdentifier': '1a2b3c-1701',
35+
'fullyQualifiedDomainName': 'test.guest.com'
36+
}]
37+
}
38+
}
1739

1840
# Reserved Capacity Stuff
1941

@@ -75,7 +97,9 @@
7597
'id': 1,
7698
'description': 'B1.1x2 (1 Year ''Term)',
7799
'keyName': 'B1_1X2_1_YEAR_TERM',
78-
}
100+
},
101+
'hourlyRecurringFee': 1.0,
102+
'recurringFee': 2.0
79103
}
80104
]
81105
}

SoftLayer/fixtures/SoftLayer_Virtual_Guest.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,16 @@
533533
setUserMetadata = ['meta']
534534
reloadOperatingSystem = 'OK'
535535
setTags = True
536-
createArchiveTransaction = {}
536+
createArchiveTransaction = {
537+
'createDate': '2018-12-10T17:29:18-06:00',
538+
'elapsedSeconds': 0,
539+
'guestId': 12345678,
540+
'hardwareId': None,
541+
'id': 12345,
542+
'modifyDate': '2018-12-10T17:29:18-06:00',
543+
'statusChangeDate': '2018-12-10T17:29:18-06:00'
544+
}
545+
537546
executeRescueLayer = True
538547

539548
getUpgradeItemPrices = [

SoftLayer/managers/vs.py

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818

1919
LOGGER = logging.getLogger(__name__)
2020

21-
22-
# pylint: disable=no-self-use
21+
# pylint: disable=no-self-use,too-many-lines
2322

2423

2524
class VSManager(utils.IdentifierMixin, object):
@@ -664,12 +663,10 @@ def change_port_speed(self, instance_id, public, speed):
664663
A port speed of 0 will disable the interface.
665664
"""
666665
if public:
667-
return self.client.call('Virtual_Guest',
668-
'setPublicNetworkInterfaceSpeed',
666+
return self.client.call('Virtual_Guest', 'setPublicNetworkInterfaceSpeed',
669667
speed, id=instance_id)
670668
else:
671-
return self.client.call('Virtual_Guest',
672-
'setPrivateNetworkInterfaceSpeed',
669+
return self.client.call('Virtual_Guest', 'setPrivateNetworkInterfaceSpeed',
673670
speed, id=instance_id)
674671

675672
def _get_ids_from_hostname(self, hostname):
@@ -784,10 +781,7 @@ def capture(self, instance_id, name, additional_disks=False, notes=None):
784781
continue
785782

786783
# We never want swap devices
787-
type_name = utils.lookup(block_device,
788-
'diskImage',
789-
'type',
790-
'keyName')
784+
type_name = utils.lookup(block_device, 'diskImage', 'type', 'keyName')
791785
if type_name == 'SWAP':
792786
continue
793787

@@ -804,8 +798,7 @@ def capture(self, instance_id, name, additional_disks=False, notes=None):
804798
return self.guest.createArchiveTransaction(
805799
name, disks_to_capture, notes, id=instance_id)
806800

807-
def upgrade(self, instance_id, cpus=None, memory=None,
808-
nic_speed=None, public=True, preset=None):
801+
def upgrade(self, instance_id, cpus=None, memory=None, nic_speed=None, public=True, preset=None):
809802
"""Upgrades a VS instance.
810803
811804
Example::
@@ -832,17 +825,16 @@ def upgrade(self, instance_id, cpus=None, memory=None,
832825
data = {'nic_speed': nic_speed}
833826

834827
if cpus is not None and preset is not None:
835-
raise exceptions.SoftLayerError("Do not use cpu, private and memory if you are using flavors")
828+
raise ValueError("Do not use cpu, private and memory if you are using flavors")
836829
data['cpus'] = cpus
837830

838831
if memory is not None and preset is not None:
839-
raise exceptions.SoftLayerError("Do not use memory, private or cpu if you are using flavors")
832+
raise ValueError("Do not use memory, private or cpu if you are using flavors")
840833
data['memory'] = memory
841834

842835
maintenance_window = datetime.datetime.now(utils.UTC())
843836
order = {
844-
'complexType': 'SoftLayer_Container_Product_Order_Virtual_Guest_'
845-
'Upgrade',
837+
'complexType': 'SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade',
846838
'properties': [{
847839
'name': 'MAINTENANCE_WINDOW',
848840
'value': maintenance_window.strftime("%Y-%m-%d %H:%M:%S%z")
@@ -874,6 +866,59 @@ def upgrade(self, instance_id, cpus=None, memory=None,
874866
return True
875867
return False
876868

869+
def order_guest(self, guest_object, test=False):
870+
"""Uses Product_Order::placeOrder to create a virtual guest.
871+
872+
Useful when creating a virtual guest with options not supported by Virtual_Guest::createObject
873+
specifically ipv6 support.
874+
875+
:param dictionary guest_object: See SoftLayer.CLI.virt.create._parse_create_args
876+
877+
Example::
878+
new_vsi = {
879+
'domain': u'test01.labs.sftlyr.ws',
880+
'hostname': u'minion05',
881+
'datacenter': u'hkg02',
882+
'flavor': 'BL1_1X2X100'
883+
'dedicated': False,
884+
'private': False,
885+
'os_code' : u'UBUNTU_LATEST',
886+
'hourly': True,
887+
'ssh_keys': [1234],
888+
'disks': ('100','25'),
889+
'local_disk': True,
890+
'tags': 'test, pleaseCancel',
891+
'public_security_groups': [12, 15],
892+
'ipv6': True
893+
}
894+
895+
vsi = mgr.order_guest(new_vsi)
896+
# vsi will have the newly created vsi receipt.
897+
# vsi['orderDetails']['virtualGuests'] will be an array of created Guests
898+
print vsi
899+
"""
900+
tags = guest_object.pop('tags', None)
901+
template = self.verify_create_instance(**guest_object)
902+
903+
if guest_object.get('ipv6'):
904+
ipv6_price = self.ordering_manager.get_price_id_list('PUBLIC_CLOUD_SERVER', ['1_IPV6_ADDRESS'])
905+
template['prices'].append({'id': ipv6_price[0]})
906+
907+
# Notice this is `userdata` from the cli, but we send it in as `userData`
908+
if guest_object.get('userdata'):
909+
# SL_Virtual_Guest::generateOrderTemplate() doesn't respect userData, so we need to add it ourself
910+
template['virtualGuests'][0]['userData'] = [{"value": guest_object.get('userdata')}]
911+
912+
if test:
913+
result = self.client.call('Product_Order', 'verifyOrder', template)
914+
else:
915+
result = self.client.call('Product_Order', 'placeOrder', template)
916+
if tags is not None:
917+
virtual_guests = utils.lookup(result, 'orderDetails', 'virtualGuests')
918+
for guest in virtual_guests:
919+
self.set_tags(tags, guest_id=guest['id'])
920+
return result
921+
877922
def _get_package_items(self):
878923
"""Following Method gets all the item ids related to VS.
879924

SoftLayer/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ def query_filter_date(start, end):
121121
return {
122122
'operation': 'betweenDate',
123123
'options': [
124-
{'name': 'startDate', 'value': [startdate+' 0:0:0']},
125-
{'name': 'endDate', 'value': [enddate+' 0:0:0']}
124+
{'name': 'startDate', 'value': [startdate + ' 0:0:0']},
125+
{'name': 'endDate', 'value': [enddate + ' 0:0:0']}
126126
]
127127
}
128128

tests/CLI/modules/subnet_tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,5 @@ def test_detail(self):
3737
json.loads(result.output))
3838

3939
def test_list(self):
40-
result = self.run_command(['subnet', 'list'])
40+
result = self.run_command(['subnet', 'list'])
4141
self.assert_no_fail(result)

tests/CLI/modules/vs/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)