Skip to content

Commit 4dc59ad

Browse files
Merge pull request #1729 from caberos/issue1725
New command: ipsec cancel
2 parents 48a600d + cfaeba9 commit 4dc59ad

File tree

6 files changed

+98
-1
lines changed

6 files changed

+98
-1
lines changed

SoftLayer/CLI/routes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@
213213
('ipsec:translation-update', 'SoftLayer.CLI.vpn.ipsec.translation.update:cli'),
214214
('ipsec:update', 'SoftLayer.CLI.vpn.ipsec.update:cli'),
215215
('ipsec:order', 'SoftLayer.CLI.vpn.ipsec.order:cli'),
216+
('ipsec:cancel', 'SoftLayer.CLI.vpn.ipsec.cancel:cli'),
216217

217218
('loadbal', 'SoftLayer.CLI.loadbal'),
218219
('loadbal:detail', 'SoftLayer.CLI.loadbal.detail:cli'),

SoftLayer/CLI/vpn/ipsec/cancel.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Cancel an IPSec service."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
6+
import SoftLayer
7+
from SoftLayer.CLI import environment
8+
9+
10+
@click.command(cls=SoftLayer.CLI.command.SLCommand, )
11+
@click.argument('identifier')
12+
@click.option('--immediate',
13+
is_flag=True,
14+
default=False,
15+
help="Cancels the service immediately (instead of on the billing anniversary)")
16+
@click.option('--reason',
17+
help="An optional cancellation reason. See cancel-reasons for a list of available options")
18+
@environment.pass_env
19+
def cli(env, identifier, immediate, reason):
20+
"""Cancel a IPSEC VPN tunnel context."""
21+
22+
manager = SoftLayer.IPSECManager(env.client)
23+
context = manager.get_tunnel_context(identifier, mask='billingItem')
24+
25+
if 'billingItem' not in context:
26+
raise SoftLayer.SoftLayerError("Cannot locate billing. May already be cancelled.")
27+
28+
result = manager.cancel_item(context['billingItem']['id'], immediate, reason)
29+
30+
if result:
31+
env.fout("Ipsec {} was cancelled.".format(identifier))

SoftLayer/managers/ipsec.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,21 @@ def order(self, datacenter, item_package):
299299
item_keynames=item_package,
300300
complex_type=complex_type,
301301
hourly=False)
302+
303+
def cancel_item(self, identifier, immediate, reason):
304+
"""Cancels the specified billing item Ipsec.
305+
306+
Example::
307+
308+
# Cancels ipsec id 1234
309+
result = mgr.cancel_item(billing_item_id=1234)
310+
311+
:param int billing_id: The ID of the billing item to be cancelled.
312+
:param string reason: The reason code for the cancellation. This should come from
313+
:func:`get_cancellation_reasons`.
314+
:param bool immediate: If set to True, will automatically update the cancelation ticket to request
315+
the resource be reclaimed asap. This request still has to be reviewed by a human
316+
:returns: True on success or an exception
317+
"""
318+
return self.client.call('SoftLayer_Billing_Item', 'cancelItem',
319+
True, immediate, reason, id=identifier)

docs/cli/ipsec.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,4 +275,8 @@ The following is an example of updating an existing address translation entry.
275275

276276
.. click:: SoftLayer.CLI.vpn.ipsec.order:cli
277277
:prog: ipsec order
278+
:show-nested:
279+
280+
.. click:: SoftLayer.CLI.vpn.ipsec.cancel:cli
281+
:prog: ipsec cancel
278282
:show-nested:

tests/CLI/modules/ipsec_tests.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import json
99

10-
1110
from SoftLayer.CLI.exceptions import ArgumentError
1211
from SoftLayer.CLI.exceptions import CLIHalt
1312
from SoftLayer.fixtures import SoftLayer_Product_Order
@@ -520,3 +519,41 @@ def test_ipsec_order(self):
520519
order_mock.return_value = SoftLayer_Product_Order.ipsec_placeOrder
521520
result = self.run_command(['ipsec', 'order', '-d', 'dal13'])
522521
self.assert_no_fail(result)
522+
523+
def test_ipsec_cancel(self):
524+
mock = self.set_mock('SoftLayer_Account', 'getNetworkTunnelContexts')
525+
mock.return_value = [{
526+
"createDate": "2013-11-05T16:03:53-06:00",
527+
"id": 445,
528+
"internalPeerIpAddress": "184.172.127.9",
529+
"modifyDate": "2022-07-19T09:34:53-06:00",
530+
"name": "ipsec003",
531+
"phaseOneAuthentication": "MD5",
532+
"phaseOneDiffieHellmanGroup": 2,
533+
"phaseOneEncryption": "3DES",
534+
"phaseOneKeylife": 14400,
535+
"phaseTwoAuthentication": "MD5",
536+
"phaseTwoDiffieHellmanGroup": 2,
537+
"phaseTwoEncryption": "3DES",
538+
"phaseTwoKeylife": 3600,
539+
"phaseTwoPerfectForwardSecrecy": 1,
540+
"billingItem": {
541+
"allowCancellationFlag": 1,
542+
"categoryCode": "network_tunnel",
543+
"createDate": "2022-07-19T09:34:52-06:00",
544+
"cycleStartDate": "2022-08-03T23:07:43-06:00",
545+
"description": "IPSEC - Standard",
546+
"id": 977194617,
547+
"lastBillDate": "2022-08-03T23:07:43-06:00",
548+
"modifyDate": "2022-08-03T23:07:43-06:00",
549+
"nextBillDate": "2022-09-03T23:00:00-06:00",
550+
"oneTimeFee": "0",
551+
"orderItemId": 932515967,
552+
"recurringMonths": 1,
553+
"serviceProviderId": 1,
554+
}}]
555+
556+
mock = self.set_mock('SoftLayer_Billing_Item', 'cancelItem')
557+
mock.return_value = True
558+
result = self.run_command(['ipsec', 'cancel', '445', '--immediate', '--reason', 'test'])
559+
self.assert_no_fail(result)

tests/managers/ipsec_tests.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,9 @@ def test_order(self):
319319
'itemId': 1092,
320320
'itemPriceId': '2048'}]}}
321321
self.assertEqual(result, order)
322+
323+
def test_cancel_item(self):
324+
_mock = self.set_mock('SoftLayer_Billing_Item', 'cancelItem')
325+
_mock.return_value = True
326+
result = self.ipsec.cancel_item(443, True, 'test')
327+
self.assertEqual(result, True)

0 commit comments

Comments
 (0)