Skip to content

Commit 1046cfe

Browse files
Merge branch 'master' of github.com:softlayer/softlayer-python into 1026
2 parents fcd90dd + 1a58b24 commit 1046cfe

22 files changed

+995
-87
lines changed

SoftLayer/CLI/dns/record_add.py

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,86 @@
55

66
import SoftLayer
77
from SoftLayer.CLI import environment
8+
from SoftLayer.CLI import exceptions
89
from SoftLayer.CLI import helpers
910
# pylint: disable=redefined-builtin
1011

1112

1213
@click.command()
13-
@click.argument('zone')
1414
@click.argument('record')
15-
@click.argument('type')
15+
@click.argument('record_type')
1616
@click.argument('data')
17+
@click.option('--zone',
18+
help="Zone name or identifier that the resource record will be associated with.\n"
19+
"Required for all record types except PTR")
1720
@click.option('--ttl',
18-
type=click.INT,
19-
default=7200,
21+
default=900,
2022
show_default=True,
2123
help='TTL value in seconds, such as 86400')
24+
@click.option('--priority',
25+
default=10,
26+
show_default=True,
27+
help='The priority of the target host. (MX or SRV type only)')
28+
@click.option('--protocol',
29+
type=click.Choice(['tcp', 'udp', 'tls']),
30+
default='tcp',
31+
show_default=True,
32+
help='The protocol of the service, usually either TCP or UDP. (SRV type only)')
33+
@click.option('--port',
34+
type=click.INT,
35+
help='The TCP/UDP/TLS port on which the service is to be found. (SRV type only)')
36+
@click.option('--service',
37+
help='The symbolic name of the desired service. (SRV type only)')
38+
@click.option('--weight',
39+
default=5,
40+
show_default=True,
41+
help='Relative weight for records with same priority. (SRV type only)')
2242
@environment.pass_env
23-
def cli(env, zone, record, type, data, ttl):
24-
"""Add resource record."""
43+
def cli(env, record, record_type, data, zone, ttl, priority, protocol, port, service, weight):
44+
"""Add resource record.
45+
46+
Each resource record contains a RECORD and DATA property, defining a resource's name and it's target data.
47+
Domains contain multiple types of resource records so it can take one of the following values: A, AAAA, CNAME,
48+
MX, SPF, SRV, and PTR.
49+
50+
About reverse records (PTR), the RECORD value must to be the public Ip Address of device you would like to manage
51+
reverse DNS.
52+
53+
slcli dns record-add 10.10.8.21 PTR myhost.com --ttl=900
54+
55+
Examples:
56+
57+
slcli dns record-add myhost.com A 192.168.1.10 --zone=foobar.com --ttl=900
58+
59+
slcli dns record-add myhost.com AAAA 2001:DB8::1 --zone=foobar.com
60+
61+
slcli dns record-add 192.168.1.2 MX 192.168.1.10 --zone=foobar.com --priority=11 --ttl=1800
62+
63+
slcli dns record-add myhost.com TXT "txt-verification=rXOxyZounZs87oacJSKvbUSIQ" --zone=2223334
64+
65+
slcli dns record-add myhost.com SPF "v=spf1 include:_spf.google.com ~all" --zone=2223334
66+
67+
slcli dns record-add myhost.com SRV 192.168.1.10 --zone=2223334 --service=foobar --port=80 --protocol=TCP
68+
69+
"""
2570

2671
manager = SoftLayer.DNSManager(env.client)
27-
zone_id = helpers.resolve_id(manager.resolve_ids, zone, name='zone')
28-
manager.create_record(zone_id, record, type, data, ttl=ttl)
72+
record_type = record_type.upper()
73+
74+
if zone and record_type != 'PTR':
75+
zone_id = helpers.resolve_id(manager.resolve_ids, zone, name='zone')
76+
77+
if record_type == 'MX':
78+
manager.create_record_mx(zone_id, record, data, ttl=ttl, priority=priority)
79+
elif record_type == 'SRV':
80+
manager.create_record_srv(zone_id, record, data, protocol, port, service,
81+
ttl=ttl, priority=priority, weight=weight)
82+
else:
83+
manager.create_record(zone_id, record, record_type, data, ttl=ttl)
84+
85+
elif record_type == 'PTR':
86+
manager.create_record_ptr(record, data, ttl=ttl)
87+
else:
88+
raise exceptions.CLIAbort("%s isn't a valid record type or zone is missing" % record_type)
89+
90+
click.secho("%s record added successfully" % record_type, fg='green')

SoftLayer/CLI/order/package_list.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
from SoftLayer.CLI import formatting
88
from SoftLayer.managers import ordering
99

10-
COLUMNS = ['name',
10+
COLUMNS = ['id',
11+
'name',
1112
'keyName',
1213
'type']
1314

@@ -51,6 +52,7 @@ def cli(env, keyword, package_type):
5152

5253
for package in packages:
5354
table.add_row([
55+
package['id'],
5456
package['name'],
5557
package['keyName'],
5658
package['type']['keyName']

SoftLayer/CLI/order/place.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def cli(env, package_keyname, location, preset, verify, billing, complex_type,
4343
can then be converted to be made programmatically by calling
4444
SoftLayer.OrderingManager.place_order() with the same keynames.
4545
46-
Packages for ordering can be retrived from `slcli order package-list`
46+
Packages for ordering can be retrieved from `slcli order package-list`
4747
Presets for ordering can be retrieved from `slcli order preset-list` (not all packages
4848
have presets)
4949

SoftLayer/CLI/order/place_quote.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
"""Place quote"""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import json
5+
6+
import click
7+
8+
from SoftLayer.CLI import environment
9+
from SoftLayer.CLI import formatting
10+
from SoftLayer.managers import ordering
11+
12+
13+
@click.command()
14+
@click.argument('package_keyname')
15+
@click.argument('location')
16+
@click.option('--preset',
17+
help="The order preset (if required by the package)")
18+
@click.option('--name',
19+
help="A custom name to be assigned to the quote (optional)")
20+
@click.option('--send-email',
21+
is_flag=True,
22+
help="The quote will be sent to the email address associated.")
23+
@click.option('--complex-type', help=("The complex type of the order. This typically begins"
24+
" with 'SoftLayer_Container_Product_Order_'."))
25+
@click.option('--extras',
26+
help="JSON string denoting extra data that needs to be sent with the order")
27+
@click.argument('order_items', nargs=-1)
28+
@environment.pass_env
29+
def cli(env, package_keyname, location, preset, name, send_email, complex_type,
30+
extras, order_items):
31+
"""Place a quote.
32+
33+
This CLI command is used for placing a quote of the specified package in
34+
the given location (denoted by a datacenter's long name). Orders made via the CLI
35+
can then be converted to be made programmatically by calling
36+
SoftLayer.OrderingManager.place_quote() with the same keynames.
37+
38+
Packages for ordering can be retrieved from `slcli order package-list`
39+
Presets for ordering can be retrieved from `slcli order preset-list` (not all packages
40+
have presets)
41+
42+
Items can be retrieved from `slcli order item-list`. In order to find required
43+
items for the order, use `slcli order category-list`, and then provide the
44+
--category option for each category code in `slcli order item-list`.
45+
46+
\b
47+
Example:
48+
# Place quote a VSI with 4 CPU, 16 GB RAM, 100 GB SAN disk,
49+
# Ubuntu 16.04, and 1 Gbps public & private uplink in dal13
50+
slcli order place-quote --name "foobar" --send-email CLOUD_SERVER DALLAS13 \\
51+
GUEST_CORES_4 \\
52+
RAM_16_GB \\
53+
REBOOT_REMOTE_CONSOLE \\
54+
1_GBPS_PUBLIC_PRIVATE_NETWORK_UPLINKS \\
55+
BANDWIDTH_0_GB_2 \\
56+
1_IP_ADDRESS \\
57+
GUEST_DISK_100_GB_SAN \\
58+
OS_UBUNTU_16_04_LTS_XENIAL_XERUS_MINIMAL_64_BIT_FOR_VSI \\
59+
MONITORING_HOST_PING \\
60+
NOTIFICATION_EMAIL_AND_TICKET \\
61+
AUTOMATED_NOTIFICATION \\
62+
UNLIMITED_SSL_VPN_USERS_1_PPTP_VPN_USER_PER_ACCOUNT \\
63+
NESSUS_VULNERABILITY_ASSESSMENT_REPORTING \\
64+
--extras '{"virtualGuests": [{"hostname": "test", "domain": "softlayer.com"}]}' \\
65+
--complex-type SoftLayer_Container_Product_Order_Virtual_Guest
66+
67+
"""
68+
manager = ordering.OrderingManager(env.client)
69+
70+
if extras:
71+
extras = json.loads(extras)
72+
73+
args = (package_keyname, location, order_items)
74+
kwargs = {'preset_keyname': preset,
75+
'extras': extras,
76+
'quantity': 1,
77+
'quote_name': name,
78+
'send_email': send_email,
79+
'complex_type': complex_type}
80+
81+
order = manager.place_quote(*args, **kwargs)
82+
83+
table = formatting.KeyValueTable(['name', 'value'])
84+
table.align['name'] = 'r'
85+
table.align['value'] = 'l'
86+
table.add_row(['id', order['quote']['id']])
87+
table.add_row(['name', order['quote']['name']])
88+
table.add_row(['created', order['orderDate']])
89+
table.add_row(['expires', order['quote']['expirationDate']])
90+
table.add_row(['status', order['quote']['status']])
91+
env.fout(table)

SoftLayer/CLI/routes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@
211211
('order:place', 'SoftLayer.CLI.order.place:cli'),
212212
('order:preset-list', 'SoftLayer.CLI.order.preset_list:cli'),
213213
('order:package-locations', 'SoftLayer.CLI.order.package_locations:cli'),
214+
('order:place-quote', 'SoftLayer.CLI.order.place_quote:cli'),
214215

215216
('rwhois', 'SoftLayer.CLI.rwhois'),
216217
('rwhois:edit', 'SoftLayer.CLI.rwhois.edit:cli'),

SoftLayer/CLI/virt/create.py

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -270,33 +270,19 @@ def cli(env, **args):
270270
output = []
271271
if args.get('test'):
272272
result = vsi.verify_create_instance(**data)
273-
total_monthly = 0.0
274-
total_hourly = 0.0
275-
276-
table = formatting.Table(['Item', 'cost'])
277-
table.align['Item'] = 'r'
278-
table.align['cost'] = 'r'
279-
280-
for price in result['prices']:
281-
total_monthly += float(price.get('recurringFee', 0.0))
282-
total_hourly += float(price.get('hourlyRecurringFee', 0.0))
283-
if args.get('billing') == 'hourly':
284-
rate = "%.2f" % float(price['hourlyRecurringFee'])
285-
elif args.get('billing') == 'monthly':
286-
rate = "%.2f" % float(price['recurringFee'])
287-
288-
table.add_row([price['item']['description'], rate])
289-
290-
total = 0
291-
if args.get('billing') == 'hourly':
292-
total = total_hourly
293-
elif args.get('billing') == 'monthly':
294-
total = total_monthly
295-
296-
billing_rate = 'monthly'
297-
if args.get('billing') == 'hourly':
298-
billing_rate = 'hourly'
299-
table.add_row(['Total %s cost' % billing_rate, "%.2f" % total])
273+
274+
if result['presetId']:
275+
ordering_mgr = SoftLayer.OrderingManager(env.client)
276+
item_prices = ordering_mgr.get_item_prices(result['packageId'])
277+
preset_prices = ordering_mgr.get_preset_prices(result['presetId'])
278+
search_keys = ["guest_core", "ram"]
279+
for price in preset_prices['prices']:
280+
if price['item']['itemCategory']['categoryCode'] in search_keys:
281+
item_key_name = price['item']['keyName']
282+
_add_item_prices(item_key_name, item_prices, result)
283+
284+
table = _build_receipt_table(result['prices'], args.get('billing'))
285+
300286
output.append(table)
301287
output.append(formatting.FormattedItem(
302288
None,
@@ -334,6 +320,35 @@ def cli(env, **args):
334320
env.fout(output)
335321

336322

323+
def _add_item_prices(item_key_name, item_prices, result):
324+
"""Add the flavor item prices to the rest o the items prices"""
325+
for item in item_prices:
326+
if item_key_name == item['item']['keyName']:
327+
if 'pricingLocationGroup' in item:
328+
for location in item['pricingLocationGroup']['locations']:
329+
if result['location'] == str(location['id']):
330+
result['prices'].append(item)
331+
332+
333+
def _build_receipt_table(prices, billing="hourly"):
334+
"""Retrieve the total recurring fee of the items prices"""
335+
total = 0.000
336+
table = formatting.Table(['Cost', 'Item'])
337+
table.align['Cost'] = 'r'
338+
table.align['Item'] = 'l'
339+
for price in prices:
340+
rate = 0.000
341+
if billing == "hourly":
342+
rate += float(price.get('hourlyRecurringFee', 0.000))
343+
else:
344+
rate += float(price.get('recurringFee', 0.000))
345+
total += rate
346+
347+
table.add_row(["%.3f" % rate, price['item']['description']])
348+
table.add_row(["%.3f" % total, "Total %s cost" % billing])
349+
return table
350+
351+
337352
def _validate_args(env, args):
338353
"""Raises an ArgumentError if the given arguments are not valid."""
339354

SoftLayer/CLI/virt/upgrade.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,17 @@
2121
help="CPU core will be on a dedicated host server.")
2222
@click.option('--memory', type=virt.MEM_TYPE, help="Memory in megabytes")
2323
@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")
2426
@environment.pass_env
25-
def cli(env, identifier, cpu, private, memory, network):
27+
def cli(env, identifier, cpu, private, memory, network, flavor):
2628
"""Upgrade a virtual server."""
2729

2830
vsi = SoftLayer.VSManager(env.client)
2931

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

3436
if private and not cpu:
3537
raise exceptions.ArgumentError(
@@ -48,5 +50,6 @@ def cli(env, identifier, cpu, private, memory, network):
4850
cpus=cpu,
4951
memory=memory,
5052
nic_speed=network,
51-
public=not private):
53+
public=not private,
54+
preset=flavor):
5255
raise exceptions.CLIAbort('VS Upgrade Failed')

0 commit comments

Comments
 (0)