diff --git a/SoftLayer/CLI/routes.py b/SoftLayer/CLI/routes.py index c2d517e2d..c1dcc4b7d 100644 --- a/SoftLayer/CLI/routes.py +++ b/SoftLayer/CLI/routes.py @@ -217,19 +217,6 @@ ('image:share', 'SoftLayer.CLI.image.share:cli'), ('image:share-deny', 'SoftLayer.CLI.image.share_deny:cli'), - ('ipsec', 'SoftLayer.CLI.vpn.ipsec'), - ('ipsec:configure', 'SoftLayer.CLI.vpn.ipsec.configure:cli'), - ('ipsec:detail', 'SoftLayer.CLI.vpn.ipsec.detail:cli'), - ('ipsec:list', 'SoftLayer.CLI.vpn.ipsec.list:cli'), - ('ipsec:subnet-add', 'SoftLayer.CLI.vpn.ipsec.subnet.add:cli'), - ('ipsec:subnet-remove', 'SoftLayer.CLI.vpn.ipsec.subnet.remove:cli'), - ('ipsec:translation-add', 'SoftLayer.CLI.vpn.ipsec.translation.add:cli'), - ('ipsec:translation-remove', 'SoftLayer.CLI.vpn.ipsec.translation.remove:cli'), - ('ipsec:translation-update', 'SoftLayer.CLI.vpn.ipsec.translation.update:cli'), - ('ipsec:update', 'SoftLayer.CLI.vpn.ipsec.update:cli'), - ('ipsec:order', 'SoftLayer.CLI.vpn.ipsec.order:cli'), - ('ipsec:cancel', 'SoftLayer.CLI.vpn.ipsec.cancel:cli'), - ('loadbal', 'SoftLayer.CLI.loadbal'), ('loadbal:detail', 'SoftLayer.CLI.loadbal.detail:cli'), ('loadbal:list', 'SoftLayer.CLI.loadbal.list:cli'), diff --git a/SoftLayer/CLI/vpn/__init__.py b/SoftLayer/CLI/vpn/__init__.py deleted file mode 100644 index a61d51191..000000000 --- a/SoftLayer/CLI/vpn/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Virtual Private Networks""" diff --git a/SoftLayer/CLI/vpn/ipsec/__init__.py b/SoftLayer/CLI/vpn/ipsec/__init__.py deleted file mode 100644 index 72e48782c..000000000 --- a/SoftLayer/CLI/vpn/ipsec/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""IPSEC VPN""" diff --git a/SoftLayer/CLI/vpn/ipsec/cancel.py b/SoftLayer/CLI/vpn/ipsec/cancel.py deleted file mode 100644 index 05688a106..000000000 --- a/SoftLayer/CLI/vpn/ipsec/cancel.py +++ /dev/null @@ -1,39 +0,0 @@ -"""Cancel an IPSec service.""" -# :license: MIT, see LICENSE for more details. - -import click - -import SoftLayer -from SoftLayer.CLI import environment -from SoftLayer.CLI import exceptions -from SoftLayer.CLI import formatting - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.argument('identifier') -@click.option('--immediate', - is_flag=True, - default=False, - help="Cancels the service immediately (instead of on the billing anniversary)") -@click.option('--reason', - help="An optional cancellation reason. See cancel-reasons for a list of available options") -@click.option('--force', default=False, is_flag=True, help="Force cancel ipsec vpn without confirmation") -@environment.pass_env -def cli(env, identifier, immediate, reason, force): - """Cancel a IPSEC VPN tunnel context.""" - - manager = SoftLayer.IPSECManager(env.client) - context = manager.get_tunnel_context(identifier, mask='billingItem') - - if 'billingItem' not in context: - raise SoftLayer.SoftLayerError("Cannot locate billing. May already be cancelled.") - - if not force: - if not (env.skip_confirmations or - formatting.confirm("This will cancel the Ipsec Vpn and cannot be undone. Continue?")): - raise exceptions.CLIAbort('Aborted') - - result = manager.cancel_item(context['billingItem']['id'], immediate, reason) - - if result: - env.fout(f"Ipsec {identifier} was cancelled.") diff --git a/SoftLayer/CLI/vpn/ipsec/configure.py b/SoftLayer/CLI/vpn/ipsec/configure.py deleted file mode 100644 index 7fe0ea456..000000000 --- a/SoftLayer/CLI/vpn/ipsec/configure.py +++ /dev/null @@ -1,29 +0,0 @@ -"""Request network configuration of an IPSEC tunnel context.""" -# :license: MIT, see LICENSE for more details. - -import click - -import SoftLayer -from SoftLayer.CLI import environment -from SoftLayer.CLI.exceptions import CLIHalt - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.argument('context_id', type=int) -@environment.pass_env -def cli(env, context_id): - """Request configuration of a tunnel context. - - This action will update the advancedConfigurationFlag on the context - instance and further modifications against the context will be prevented - until all changes can be propgated to network devices. - """ - manager = SoftLayer.IPSECManager(env.client) - # ensure context can be retrieved by given id - manager.get_tunnel_context(context_id) - - succeeded = manager.apply_configuration(context_id) - if succeeded: - click.echo(f'Configuration request received for context #{context_id}') - else: - raise CLIHalt(f'Failed to enqueue configuration request for context #{context_id}') diff --git a/SoftLayer/CLI/vpn/ipsec/detail.py b/SoftLayer/CLI/vpn/ipsec/detail.py deleted file mode 100644 index 64c06eefb..000000000 --- a/SoftLayer/CLI/vpn/ipsec/detail.py +++ /dev/null @@ -1,176 +0,0 @@ -"""List IPSEC VPN Tunnel Context Details.""" -# :license: MIT, see LICENSE for more details. - -import click - -import SoftLayer -from SoftLayer.CLI import environment -from SoftLayer.CLI import formatting - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.argument('context_id', type=int) -@click.option('-i', - '--include', - default=[], - multiple=True, - type=click.Choice(['at', 'is', 'rs', 'sr', 'ss']), - help='Include additional resources') -@environment.pass_env -def cli(env, context_id, include): - """List IPSEC VPN tunnel context details. - - Additional resources can be joined using multiple instances of the - include option, for which the following choices are available. - - \b - at: address translations - is: internal subnets - rs: remote subnets - sr: statically routed subnets - ss: service subnets - """ - mask = _get_tunnel_context_mask(('at' in include), - ('is' in include), - ('rs' in include), - ('sr' in include), - ('ss' in include)) - manager = SoftLayer.IPSECManager(env.client) - context = manager.get_tunnel_context(context_id, mask=mask) - - env.fout(_get_context_table(context)) - - for relation in include: - if relation == 'at': - env.fout(_get_address_translations_table(context.get('addressTranslations', []))) - elif relation == 'is': - env.fout(_get_subnets_table(context.get('internalSubnets', []), title="Internal Subnets")) - elif relation == 'rs': - env.fout(_get_subnets_table(context.get('customerSubnets', []), title="Remote Subnets")) - elif relation == 'sr': - env.fout(_get_subnets_table(context.get('staticRouteSubnets', []), title="Static Subnets")) - elif relation == 'ss': - env.fout(_get_subnets_table(context.get('serviceSubnets', []), title="Service Subnets")) - - -def _get_address_translations_table(address_translations): - """Yields a formatted table to print address translations. - - :param List[dict] address_translations: List of address translations. - :return Table: Formatted for address translation output. - """ - table = formatting.Table(['id', - 'static IP address', - 'static IP address id', - 'remote IP address', - 'remote IP address id', - 'note'], title="Address Translations") - for address_translation in address_translations: - table.add_row([address_translation.get('id', ''), - address_translation.get('internalIpAddressRecord', {}).get('ipAddress', ''), - address_translation.get('internalIpAddressId', ''), - address_translation.get('customerIpAddressRecord', {}).get('ipAddress', ''), - address_translation.get('customerIpAddressId', ''), - address_translation.get('notes', '')]) - return table - - -def _get_subnets_table(subnets, title): - """Yields a formatted table to print subnet details. - - :param List[dict] subnets: List of subnets. - :return Table: Formatted for subnet output. - """ - table = formatting.Table(['id', 'network identifier', 'cidr', 'note'], title=title) - for subnet in subnets: - table.add_row([subnet.get('id', ''), - subnet.get('networkIdentifier', ''), - subnet.get('cidr', ''), - subnet.get('note', '')]) - return table - - -def _get_tunnel_context_mask(address_translations=False, - internal_subnets=False, - remote_subnets=False, - static_subnets=False, - service_subnets=False): - """Yields a mask object for a tunnel context. - - All exposed properties on the tunnel context service are included in - the constructed mask. Additional joins may be requested. - - :param bool address_translations: Whether to join the context's address - translation entries. - :param bool internal_subnets: Whether to join the context's internal - subnet associations. - :param bool remote_subnets: Whether to join the context's remote subnet - associations. - :param bool static_subnets: Whether to join the context's statically - routed subnet associations. - :param bool service_subnets: Whether to join the SoftLayer service - network subnets. - :return string: Encoding for the requested mask object. - """ - entries = ['id', - 'accountId', - 'advancedConfigurationFlag', - 'createDate', - 'customerPeerIpAddress', - 'modifyDate', - 'name', - 'friendlyName', - 'internalPeerIpAddress', - 'phaseOneAuthentication', - 'phaseOneDiffieHellmanGroup', - 'phaseOneEncryption', - 'phaseOneKeylife', - 'phaseTwoAuthentication', - 'phaseTwoDiffieHellmanGroup', - 'phaseTwoEncryption', - 'phaseTwoKeylife', - 'phaseTwoPerfectForwardSecrecy', - 'presharedKey'] - if address_translations: - entries.append('addressTranslations[internalIpAddressRecord[ipAddress],' - 'customerIpAddressRecord[ipAddress]]') - if internal_subnets: - entries.append('internalSubnets') - if remote_subnets: - entries.append('customerSubnets') - if static_subnets: - entries.append('staticRouteSubnets') - if service_subnets: - entries.append('serviceSubnets') - return f"[mask[{','.join(entries)}]]" - - -def _get_context_table(context): - """Yields a formatted table to print context details. - - :param dict context: The tunnel context - :return Table: Formatted for tunnel context output - """ - table = formatting.KeyValueTable(['name', 'value'], title='Context Details') - table.align['name'] = 'r' - table.align['value'] = 'l' - - table.add_row(['id', context.get('id', '')]) - table.add_row(['name', context.get('name', '')]) - table.add_row(['friendly name', context.get('friendlyName', '')]) - table.add_row(['internal peer IP address', context.get('internalPeerIpAddress', '')]) - table.add_row(['remote peer IP address', context.get('customerPeerIpAddress', '')]) - table.add_row(['advanced configuration flag', context.get('advancedConfigurationFlag', '')]) - table.add_row(['preshared key', context.get('presharedKey', '')]) - table.add_row(['phase 1 authentication', context.get('phaseOneAuthentication', '')]) - table.add_row(['phase 1 diffie hellman group', context.get('phaseOneDiffieHellmanGroup', '')]) - table.add_row(['phase 1 encryption', context.get('phaseOneEncryption', '')]) - table.add_row(['phase 1 key life', context.get('phaseOneKeylife', '')]) - table.add_row(['phase 2 authentication', context.get('phaseTwoAuthentication', '')]) - table.add_row(['phase 2 diffie hellman group', context.get('phaseTwoDiffieHellmanGroup', '')]) - table.add_row(['phase 2 encryption', context.get('phaseTwoEncryption', '')]) - table.add_row(['phase 2 key life', context.get('phaseTwoKeylife', '')]) - table.add_row(['phase 2 perfect forward secrecy', context.get('phaseTwoPerfectForwardSecrecy', '')]) - table.add_row(['created', context.get('createDate')]) - table.add_row(['modified', context.get('modifyDate')]) - return table diff --git a/SoftLayer/CLI/vpn/ipsec/list.py b/SoftLayer/CLI/vpn/ipsec/list.py deleted file mode 100644 index 652bd8330..000000000 --- a/SoftLayer/CLI/vpn/ipsec/list.py +++ /dev/null @@ -1,35 +0,0 @@ -"""List IPSec VPN Tunnel Contexts.""" -# :license: MIT, see LICENSE for more details. - -import click - -import SoftLayer -from SoftLayer.CLI import environment -from SoftLayer.CLI import formatting - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.option('--sortby', help='Column to sort by', - default='created') -@environment.pass_env -def cli(env, sortby): - """List IPSec VPN tunnel contexts""" - manager = SoftLayer.IPSECManager(env.client) - contexts = manager.get_tunnel_contexts() - - table = formatting.Table(['id', - 'name', - 'friendly name', - 'internal peer IP address', - 'remote peer IP address', - 'created']) - table.sortby = sortby - - for context in contexts: - table.add_row([context.get('id', ''), - context.get('name', ''), - context.get('friendlyName', ''), - context.get('internalPeerIpAddress', ''), - context.get('customerPeerIpAddress', ''), - context.get('createDate', '')]) - env.fout(table) diff --git a/SoftLayer/CLI/vpn/ipsec/order.py b/SoftLayer/CLI/vpn/ipsec/order.py deleted file mode 100644 index 2ca6413ef..000000000 --- a/SoftLayer/CLI/vpn/ipsec/order.py +++ /dev/null @@ -1,34 +0,0 @@ -"""Order a IPSec VPN tunnel.""" -# :licenses: MIT, see LICENSE for more details. - -import click - -import SoftLayer - -from SoftLayer.CLI import environment -from SoftLayer.CLI import exceptions -from SoftLayer.CLI import formatting - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.option('--datacenter', '-d', required=True, prompt=True, help="Datacenter shortname") -@environment.pass_env -def cli(env, datacenter): - """Order/create a IPSec VPN tunnel instance.""" - - ipsec_manager = SoftLayer.IPSECManager(env.client) - - if not (env.skip_confirmations or formatting.confirm( - "This action will incur charges on your account. Continue?")): - raise exceptions.CLIAbort('Aborting ipsec order.') - - result = ipsec_manager.order(datacenter, ['IPSEC_STANDARD']) - - table = formatting.KeyValueTable(['Name', 'Value']) - table.align['name'] = 'r' - table.align['value'] = 'l' - table.add_row(['Id', result['orderId']]) - table.add_row(['Created', result['orderDate']]) - table.add_row(['Name', result['placedOrder']['items'][0]['description']]) - - env.fout(table) diff --git a/SoftLayer/CLI/vpn/ipsec/subnet/__init__.py b/SoftLayer/CLI/vpn/ipsec/subnet/__init__.py deleted file mode 100644 index 5ec029c51..000000000 --- a/SoftLayer/CLI/vpn/ipsec/subnet/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""IPSEC VPN Subnets""" diff --git a/SoftLayer/CLI/vpn/ipsec/subnet/add.py b/SoftLayer/CLI/vpn/ipsec/subnet/add.py deleted file mode 100644 index c9e1f56ab..000000000 --- a/SoftLayer/CLI/vpn/ipsec/subnet/add.py +++ /dev/null @@ -1,76 +0,0 @@ -"""Add a subnet to an IPSEC tunnel context.""" -# :license: MIT, see LICENSE for more details. - -import click - -import SoftLayer -from SoftLayer.CLI.custom_types import NetworkParamType -from SoftLayer.CLI import environment -from SoftLayer.CLI.exceptions import ArgumentError -from SoftLayer.CLI.exceptions import CLIHalt - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.argument('context_id', type=int) -@click.option('-s', - '--subnet-id', - default=None, - type=int, - help='Subnet identifier to add') -@click.option('-t', - '--subnet-type', - '--type', - required=True, - type=click.Choice(['internal', 'remote', 'service']), - help='Subnet type to add') -@click.option('-n', - '--network-identifier', - '--network', - default=None, - type=NetworkParamType(), - help='Subnet network identifier to create') -@environment.pass_env -def cli(env, context_id, subnet_id, subnet_type, network_identifier): - """Add a subnet to an IPSEC tunnel context. - - A subnet id may be specified to link to the existing tunnel context. - - Otherwise, a network identifier in CIDR notation should be specified, - indicating that a subnet resource should first be created before associating - it with the tunnel context. Note that this is only supported for remote - subnets, which are also deleted upon failure to attach to a context. - - A separate configuration request should be made to realize changes on - network devices. - """ - create_remote = False - if subnet_id is None: - if network_identifier is None: - raise ArgumentError('Either a network identifier or subnet id ' - 'must be provided.') - if subnet_type != 'remote': - raise ArgumentError(f'Unable to create {subnet_type} subnets') - create_remote = True - - manager = SoftLayer.IPSECManager(env.client) - context = manager.get_tunnel_context(context_id) - - if create_remote: - subnet = manager.create_remote_subnet(context['accountId'], - identifier=network_identifier[0], - cidr=network_identifier[1]) - subnet_id = subnet['id'] - env.out(f'Created subnet {network_identifier[0]}/{network_identifier[1]} #{subnet_id}') - - succeeded = False - if subnet_type == 'internal': - succeeded = manager.add_internal_subnet(context_id, subnet_id) - elif subnet_type == 'remote': - succeeded = manager.add_remote_subnet(context_id, subnet_id) - elif subnet_type == 'service': - succeeded = manager.add_service_subnet(context_id, subnet_id) - - if succeeded: - env.out(f'Added {subnet_type} subnet #{subnet_id}') - else: - raise CLIHalt(f'Failed to add {subnet_type} subnet #{subnet_id}') diff --git a/SoftLayer/CLI/vpn/ipsec/subnet/remove.py b/SoftLayer/CLI/vpn/ipsec/subnet/remove.py deleted file mode 100644 index 96ae253ba..000000000 --- a/SoftLayer/CLI/vpn/ipsec/subnet/remove.py +++ /dev/null @@ -1,50 +0,0 @@ -"""Remove a subnet from an IPSEC tunnel context.""" -# :license: MIT, see LICENSE for more details. - -import click - -import SoftLayer -from SoftLayer.CLI import environment -from SoftLayer.CLI.exceptions import CLIHalt - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.argument('context_id', type=int) -@click.option('-s', - '--subnet-id', - required=True, - type=int, - help='Subnet identifier to remove') -@click.option('-t', - '--subnet-type', - '--type', - required=True, - type=click.Choice(['internal', 'remote', 'service']), - help='Subnet type to add') -@environment.pass_env -def cli(env, context_id, subnet_id, subnet_type): - """Remove a subnet from an IPSEC tunnel context. - - The subnet id to remove must be specified. - - Remote subnets are deleted upon removal from a tunnel context. - - A separate configuration request should be made to realize changes on - network devices. - """ - manager = SoftLayer.IPSECManager(env.client) - # ensure context can be retrieved by given id - manager.get_tunnel_context(context_id) - - succeeded = False - if subnet_type == 'internal': - succeeded = manager.remove_internal_subnet(context_id, subnet_id) - elif subnet_type == 'remote': - succeeded = manager.remove_remote_subnet(context_id, subnet_id) - elif subnet_type == 'service': - succeeded = manager.remove_service_subnet(context_id, subnet_id) - - if succeeded: - env.out(f'Removed {subnet_type} subnet #{subnet_id}') - else: - raise CLIHalt(f'Failed to remove {subnet_type} subnet #{subnet_id}') diff --git a/SoftLayer/CLI/vpn/ipsec/translation/__init__.py b/SoftLayer/CLI/vpn/ipsec/translation/__init__.py deleted file mode 100644 index 18be25229..000000000 --- a/SoftLayer/CLI/vpn/ipsec/translation/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""IPSEC VPN Address Translations""" diff --git a/SoftLayer/CLI/vpn/ipsec/translation/add.py b/SoftLayer/CLI/vpn/ipsec/translation/add.py deleted file mode 100644 index 196a6c429..000000000 --- a/SoftLayer/CLI/vpn/ipsec/translation/add.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Add an address translation to an IPSEC tunnel context.""" -# :license: MIT, see LICENSE for more details. - -import click - -import SoftLayer -from SoftLayer.CLI import environment -# from SoftLayer.CLI.exceptions import ArgumentError -# from SoftLayer.CLI.exceptions import CLIHalt - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.argument('context_id', type=int) -@click.option('-s', - '--static-ip', - required=True, - help='Static IP address value') -@click.option('-r', - '--remote-ip', - required=True, - help='Remote IP address value') -@click.option('-n', - '--note', - default=None, - help='Note value') -@environment.pass_env -def cli(env, context_id, static_ip, remote_ip, note): - """Add an address translation to an IPSEC tunnel context. - - A separate configuration request should be made to realize changes on - network devices. - """ - manager = SoftLayer.IPSECManager(env.client) - # ensure context can be retrieved by given id - manager.get_tunnel_context(context_id) - - translation = manager.create_translation(context_id, - static_ip=static_ip, - remote_ip=remote_ip, - notes=note) - env.out(f"Created translation from {static_ip} to {remote_ip} #{translation['id']}") diff --git a/SoftLayer/CLI/vpn/ipsec/translation/remove.py b/SoftLayer/CLI/vpn/ipsec/translation/remove.py deleted file mode 100644 index e9ab43fdb..000000000 --- a/SoftLayer/CLI/vpn/ipsec/translation/remove.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Remove a translation entry from an IPSEC tunnel context.""" -# :license: MIT, see LICENSE for more details. - -import click - -import SoftLayer -from SoftLayer.CLI import environment -from SoftLayer.CLI.exceptions import CLIHalt - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.argument('context_id', type=int) -@click.option('-t', - '--translation-id', - required=True, - type=int, - help='Translation identifier to remove') -@environment.pass_env -def cli(env, context_id, translation_id): - """Remove a translation entry from an IPSEC tunnel context. - - A separate configuration request should be made to realize changes on - network devices. - """ - manager = SoftLayer.IPSECManager(env.client) - # ensure translation can be retrieved by given id - manager.get_translation(context_id, translation_id) - - succeeded = manager.remove_translation(context_id, translation_id) - if succeeded: - env.out(f'Removed translation #{translation_id}') - else: - raise CLIHalt(f'Failed to remove translation #{translation_id}') diff --git a/SoftLayer/CLI/vpn/ipsec/translation/update.py b/SoftLayer/CLI/vpn/ipsec/translation/update.py deleted file mode 100644 index bc2b1563d..000000000 --- a/SoftLayer/CLI/vpn/ipsec/translation/update.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Update an address translation for an IPSEC tunnel context.""" -# :license: MIT, see LICENSE for more details. - -import click - -import SoftLayer -from SoftLayer.CLI import environment -from SoftLayer.CLI.exceptions import CLIHalt - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.argument('context_id', type=int) -@click.option('-t', - '--translation-id', - required=True, - type=int, - help='Translation identifier to update') -@click.option('-s', - '--static-ip', - default=None, - help='Static IP address value') -@click.option('-r', - '--remote-ip', - default=None, - help='Remote IP address value') -@click.option('-n', - '--note', - default=None, - help='Note value') -@environment.pass_env -def cli(env, context_id, translation_id, static_ip, remote_ip, note): - """Update an address translation for an IPSEC tunnel context. - - A separate configuration request should be made to realize changes on - network devices. - """ - manager = SoftLayer.IPSECManager(env.client) - succeeded = manager.update_translation(context_id, - translation_id, - static_ip=static_ip, - remote_ip=remote_ip, - notes=note) - if succeeded: - env.out(f'Updated translation #{translation_id}') - else: - raise CLIHalt(f'Failed to update translation #{translation_id}') diff --git a/SoftLayer/CLI/vpn/ipsec/update.py b/SoftLayer/CLI/vpn/ipsec/update.py deleted file mode 100644 index 8a1e6f7a9..000000000 --- a/SoftLayer/CLI/vpn/ipsec/update.py +++ /dev/null @@ -1,101 +0,0 @@ -"""Updates an IPSEC tunnel context.""" -# :license: MIT, see LICENSE for more details. - -import click - -import SoftLayer -from SoftLayer.CLI import environment -from SoftLayer.CLI.exceptions import CLIHalt - - -@click.command(cls=SoftLayer.CLI.command.SLCommand, ) -@click.argument('context_id', type=int) -@click.option('--friendly-name', - default=None, - help='Friendly name value') -@click.option('--remote-peer', - default=None, - help='Remote peer IP address value') -@click.option('--preshared-key', - default=None, - help='Preshared key value') -@click.option('--phase1-auth', - '--p1-auth', - default=None, - type=click.Choice(['MD5', 'SHA1', 'SHA256']), - help='Phase 1 authentication value') -@click.option('--phase1-crypto', - '--p1-crypto', - default=None, - type=click.Choice(['DES', '3DES', 'AES128', 'AES192', 'AES256']), - help='Phase 1 encryption value') -@click.option('--phase1-dh', - '--p1-dh', - default=None, - type=click.Choice(['0', '1', '2', '5']), - help='Phase 1 diffie hellman group value') -@click.option('--phase1-key-ttl', - '--p1-key-ttl', - default=None, - type=click.IntRange(120, 172800), - help='Phase 1 key life value') -@click.option('--phase2-auth', - '--p2-auth', - default=None, - type=click.Choice(['MD5', 'SHA1', 'SHA256']), - help='Phase 2 authentication value') -@click.option('--phase2-crypto', - '--p2-crypto', - default=None, - type=click.Choice(['DES', '3DES', 'AES128', 'AES192', 'AES256']), - help='Phase 2 encryption value') -@click.option('--phase2-dh', - '--p2-dh', - default=None, - type=click.Choice(['0', '1', '2', '5']), - help='Phase 2 diffie hellman group value') -@click.option('--phase2-forward-secrecy', - '--p2-forward-secrecy', - default=None, - type=click.IntRange(0, 1), - help='Phase 2 perfect forward secrecy value') -@click.option('--phase2-key-ttl', - '--p2-key-ttl', - default=None, - type=click.IntRange(120, 172800), - help='Phase 2 key life value') -@environment.pass_env -def cli(env, context_id, friendly_name, remote_peer, preshared_key, - phase1_auth, phase1_crypto, phase1_dh, phase1_key_ttl, phase2_auth, - phase2_crypto, phase2_dh, phase2_forward_secrecy, phase2_key_ttl): - """Update tunnel context properties. - - Updates are made atomically, so either all are accepted or none are. - - Key life values must be in the range 120-172800. - - Phase 2 perfect forward secrecy must be in the range 0-1. - - A separate configuration request should be made to realize changes on - network devices. - """ - manager = SoftLayer.IPSECManager(env.client) - succeeded = manager.update_tunnel_context( - context_id, - friendly_name=friendly_name, - remote_peer=remote_peer, - preshared_key=preshared_key, - phase1_auth=phase1_auth, - phase1_crypto=phase1_crypto, - phase1_dh=phase1_dh, - phase1_key_ttl=phase1_key_ttl, - phase2_auth=phase2_auth, - phase2_crypto=phase2_crypto, - phase2_dh=phase2_dh, - phase2_forward_secrecy=phase2_forward_secrecy, - phase2_key_ttl=phase2_key_ttl - ) - if succeeded: - env.out(f'Updated context #{context_id}') - else: - raise CLIHalt(f'Failed to update context #{context_id}') diff --git a/SoftLayer/consts.py b/SoftLayer/consts.py index 2a1d23eaf..25c00902f 100644 --- a/SoftLayer/consts.py +++ b/SoftLayer/consts.py @@ -5,7 +5,7 @@ :license: MIT, see LICENSE for more details. """ -VERSION = 'v6.2.6' +VERSION = 'v6.2.7' API_PUBLIC_ENDPOINT = 'https://api.softlayer.com/xmlrpc/v3.1/' API_PRIVATE_ENDPOINT = 'https://api.service.softlayer.com/xmlrpc/v3.1/' API_PUBLIC_ENDPOINT_REST = 'https://api.softlayer.com/rest/v3.1/' diff --git a/SoftLayer/managers/__init__.py b/SoftLayer/managers/__init__.py index 8a6c8c095..08f7a5a73 100644 --- a/SoftLayer/managers/__init__.py +++ b/SoftLayer/managers/__init__.py @@ -17,7 +17,6 @@ from SoftLayer.managers.firewall import FirewallManager from SoftLayer.managers.hardware import HardwareManager from SoftLayer.managers.image import ImageManager -from SoftLayer.managers.ipsec import IPSECManager from SoftLayer.managers.license import LicensesManager from SoftLayer.managers.load_balancer import LoadBalancerManager from SoftLayer.managers.metadata import MetadataManager @@ -46,7 +45,6 @@ 'FirewallManager', 'HardwareManager', 'ImageManager', - 'IPSECManager', 'LicensesManager', 'LoadBalancerManager', 'MetadataManager', diff --git a/SoftLayer/managers/ipsec.py b/SoftLayer/managers/ipsec.py deleted file mode 100644 index 0212d7732..000000000 --- a/SoftLayer/managers/ipsec.py +++ /dev/null @@ -1,317 +0,0 @@ -""" - SoftLayer.ipsec - ~~~~~~~~~~~~~~~~~~ - IPSec VPN Manager - - :license: MIT, see LICENSE for more details. -""" - -from SoftLayer.exceptions import SoftLayerAPIError -from SoftLayer.managers import ordering -from SoftLayer import utils - - -class IPSECManager(utils.IdentifierMixin, object): - """Manage SoftLayer IPSEC VPN tunnel contexts. - - This provides helpers to manage IPSEC contexts, private and remote subnets, - and NAT translations. - - :param SoftLayer.API.BaseClient client: the client instance - :param SoftLayer.API.BaseClient account: account service client - :param SoftLayer.API.BaseClient context: tunnel context client - :param SoftLayer.API.BaseClient customer_subnet: remote subnet client - """ - - def __init__(self, client): - self.client = client - self.account = client['Account'] - self.context = client['Network_Tunnel_Module_Context'] - self.remote_subnet = client['Network_Customer_Subnet'] - - def add_internal_subnet(self, context_id, subnet_id): - """Add an internal subnet to a tunnel context. - - :param int context_id: The id-value representing the context instance. - :param int subnet_id: The id-value representing the internal subnet. - :return bool: True if internal subnet addition was successful. - """ - return self.context.addPrivateSubnetToNetworkTunnel(subnet_id, - id=context_id) - - def add_remote_subnet(self, context_id, subnet_id): - """Adds a remote subnet to a tunnel context. - - :param int context_id: The id-value representing the context instance. - :param int subnet_id: The id-value representing the remote subnet. - :return bool: True if remote subnet addition was successful. - """ - return self.context.addCustomerSubnetToNetworkTunnel(subnet_id, - id=context_id) - - def add_service_subnet(self, context_id, subnet_id): - """Adds a service subnet to a tunnel context. - - :param int context_id: The id-value representing the context instance. - :param int subnet_id: The id-value representing the service subnet. - :return bool: True if service subnet addition was successful. - """ - return self.context.addServiceSubnetToNetworkTunnel(subnet_id, - id=context_id) - - def apply_configuration(self, context_id): - """Requests network configuration for a tunnel context. - - :param int context_id: The id-value representing the context instance. - :return bool: True if the configuration request was successfully queued. - """ - return self.context.applyConfigurationsToDevice(id=context_id) - - def create_remote_subnet(self, account_id, identifier, cidr): - """Creates a remote subnet on the given account. - - :param string account_id: The account identifier. - :param string identifier: The network identifier of the remote subnet. - :param string cidr: The CIDR value of the remote subnet. - :return dict: Mapping of properties for the new remote subnet. - """ - return self.remote_subnet.createObject({ - 'accountId': account_id, - 'cidr': cidr, - 'networkIdentifier': identifier - }) - - def create_translation(self, context_id, static_ip, remote_ip, notes): - """Creates an address translation on a tunnel context/ - - :param int context_id: The id-value representing the context instance. - :param string static_ip: The IP address value representing the - internal side of the translation entry, - :param string remote_ip: The IP address value representing the remote - side of the translation entry, - :param string notes: The notes to supply with the translation entry, - :return dict: Mapping of properties for the new translation entry. - """ - return self.context.createAddressTranslation({ - 'customerIpAddress': remote_ip, - 'internalIpAddress': static_ip, - 'notes': notes - }, id=context_id) - - def delete_remote_subnet(self, subnet_id): - """Deletes a remote subnet from the current account. - - :param string subnet_id: The id-value representing the remote subnet. - :return bool: True if subnet deletion was successful. - """ - return self.remote_subnet.deleteObject(id=subnet_id) - - def get_tunnel_context(self, context_id, **kwargs): - """Retrieves the network tunnel context instance. - - :param int context_id: The id-value representing the context instance. - :return dict: Mapping of properties for the tunnel context. - :raise SoftLayerAPIError: If a context cannot be found. - """ - _filter = utils.NestedDict(kwargs.get('filter') or {}) - _filter['networkTunnelContexts']['id'] = utils.query_filter(context_id) - - kwargs['filter'] = _filter.to_dict() - contexts = self.account.getNetworkTunnelContexts(**kwargs) - if len(contexts) == 0: - raise SoftLayerAPIError('SoftLayer_Exception_ObjectNotFound', - f'Unable to find object with id of \'{context_id}\'') - return contexts[0] - - def get_translation(self, context_id, translation_id): - """Retrieves a translation entry for the given id values. - - :param int context_id: The id-value representing the context instance. - :param int translation_id: The id-value representing the translation - instance. - :return dict: Mapping of properties for the translation entry. - :raise SoftLayerAPIError: If a translation cannot be found. - """ - translation = next((x for x in self.get_translations(context_id) - if x['id'] == translation_id), None) - if translation is None: - raise SoftLayerAPIError('SoftLayer_Exception_ObjectNotFound', - f'Unable to find object with id of \'{translation_id}\'') - return translation - - def get_translations(self, context_id): - """Retrieves all translation entries for a tunnel context. - - :param int context_id: The id-value representing the context instance. - :return list(dict): Translations associated with the given context - """ - _mask = ('[mask[addressTranslations[customerIpAddressRecord,' - 'internalIpAddressRecord]]]') - context = self.get_tunnel_context(context_id, mask=_mask) - # Pull the internal and remote IP addresses into the translation - for translation in context.get('addressTranslations', []): - remote_ip = translation.get('customerIpAddressRecord', {}) - internal_ip = translation.get('internalIpAddressRecord', {}) - translation['customerIpAddress'] = remote_ip.get('ipAddress', '') - translation['internalIpAddress'] = internal_ip.get('ipAddress', '') - translation.pop('customerIpAddressRecord', None) - translation.pop('internalIpAddressRecord', None) - return context['addressTranslations'] - - def get_tunnel_contexts(self, **kwargs): - """Retrieves network tunnel module context instances. - - :return list(dict): Contexts associated with the current account. - """ - return self.account.getNetworkTunnelContexts(**kwargs) - - def remove_internal_subnet(self, context_id, subnet_id): - """Remove an internal subnet from a tunnel context. - - :param int context_id: The id-value representing the context instance. - :param int subnet_id: The id-value representing the internal subnet. - :return bool: True if internal subnet removal was successful. - """ - return self.context.removePrivateSubnetFromNetworkTunnel(subnet_id, - id=context_id) - - def remove_remote_subnet(self, context_id, subnet_id): - """Removes a remote subnet from a tunnel context. - - :param int context_id: The id-value representing the context instance. - :param int subnet_id: The id-value representing the remote subnet. - :return bool: True if remote subnet removal was successful. - """ - return self.context.removeCustomerSubnetFromNetworkTunnel(subnet_id, - id=context_id) - - def remove_service_subnet(self, context_id, subnet_id): - """Removes a service subnet from a tunnel context. - - :param int context_id: The id-value representing the context instance. - :param int subnet_id: The id-value representing the service subnet. - :return bool: True if service subnet removal was successful. - """ - return self.context.removeServiceSubnetFromNetworkTunnel(subnet_id, - id=context_id) - - def remove_translation(self, context_id, translation_id): - """Removes a translation entry from a tunnel context. - - :param int context_id: The id-value representing the context instance. - :param int translation_id: The id-value representing the translation. - :return bool: True if translation entry removal was successful. - """ - return self.context.deleteAddressTranslation(translation_id, - id=context_id) - - def update_translation(self, context_id, translation_id, static_ip=None, - remote_ip=None, notes=None): - """Updates an address translation entry using the given values. - - :param int context_id: The id-value representing the context instance. - :param dict template: A key-value mapping of translation properties. - :param string static_ip: The static IP address value to update. - :param string remote_ip: The remote IP address value to update. - :param string notes: The notes value to update. - :return bool: True if the update was successful. - """ - translation = self.get_translation(context_id, translation_id) - - if static_ip is not None: - translation['internalIpAddress'] = static_ip - translation.pop('internalIpAddressId', None) - if remote_ip is not None: - translation['customerIpAddress'] = remote_ip - translation.pop('customerIpAddressId', None) - if notes is not None: - translation['notes'] = notes - self.context.editAddressTranslation(translation, id=context_id) - return True - - def update_tunnel_context(self, context_id, friendly_name=None, - remote_peer=None, preshared_key=None, - phase1_auth=None, phase1_crypto=None, - phase1_dh=None, phase1_key_ttl=None, - phase2_auth=None, phase2_crypto=None, - phase2_dh=None, phase2_forward_secrecy=None, - phase2_key_ttl=None): - """Updates a tunnel context using the given values. - - :param string context_id: The id-value representing the context. - :param string friendly_name: The friendly name value to update. - :param string remote_peer: The remote peer IP address value to update. - :param string preshared_key: The preshared key value to update. - :param string phase1_auth: The phase 1 authentication value to update. - :param string phase1_crypto: The phase 1 encryption value to update. - :param string phase1_dh: The phase 1 diffie hellman group value - to update. - :param string phase1_key_ttl: The phase 1 key life value to update. - :param string phase2_auth: The phase 2 authentication value to update. - :param string phase2_crypto: The phase 2 encryption value to update. - :param string phase2_df: The phase 2 diffie hellman group value - to update. - :param string phase2_forward_secriecy: The phase 2 perfect forward - secrecy value to update. - :param string phase2_key_ttl: The phase 2 key life value to update. - :return bool: True if the update was successful. - """ - context = self.get_tunnel_context(context_id) - - if friendly_name is not None: - context['friendlyName'] = friendly_name - if remote_peer is not None: - context['customerPeerIpAddress'] = remote_peer - if preshared_key is not None: - context['presharedKey'] = preshared_key - if phase1_auth is not None: - context['phaseOneAuthentication'] = phase1_auth - if phase1_crypto is not None: - context['phaseOneEncryption'] = phase1_crypto - if phase1_dh is not None: - context['phaseOneDiffieHellmanGroup'] = phase1_dh - if phase1_key_ttl is not None: - context['phaseOneKeylife'] = phase1_key_ttl - if phase2_auth is not None: - context['phaseTwoAuthentication'] = phase2_auth - if phase2_crypto is not None: - context['phaseTwoEncryption'] = phase2_crypto - if phase2_dh is not None: - context['phaseTwoDiffieHellmanGroup'] = phase2_dh - if phase2_forward_secrecy is not None: - context['phaseTwoPerfectForwardSecrecy'] = phase2_forward_secrecy - if phase2_key_ttl is not None: - context['phaseTwoKeylife'] = phase2_key_ttl - return self.context.editObject(context, id=context_id) - - def order(self, datacenter, item_package): - """Create a ipsec. - - :param string datacenter: the datacenter shortname - :param string[] item_package: items array - """ - complex_type = 'SoftLayer_Container_Product_Order_Network_Tunnel_Ipsec' - ordering_manager = ordering.OrderingManager(self.client) - return ordering_manager.place_order(package_keyname='ADDITIONAL_PRODUCTS', - location=datacenter, - item_keynames=item_package, - complex_type=complex_type, - hourly=False) - - def cancel_item(self, identifier, immediate, reason): - """Cancels the specified billing item Ipsec. - - Example:: - - # Cancels ipsec id 1234 - result = mgr.cancel_item(billing_item_id=1234) - - :param int billing_id: The ID of the billing item to be cancelled. - :param string reason: The reason code for the cancellation. This should come from - :func:`get_cancellation_reasons`. - :param bool immediate: If set to True, will automatically update the cancelation ticket to request - the resource be reclaimed asap. This request still has to be reviewed by a human - :returns: True on success or an exception - """ - return self.client.call('SoftLayer_Billing_Item', 'cancelItem', - True, immediate, reason, id=identifier) diff --git a/setup.py b/setup.py index 6cb0bec25..6f3b5e34b 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ setup( name='SoftLayer', - version='v6.2.6', + version='v6.2.7', description=DESCRIPTION, long_description=LONG_DESCRIPTION, long_description_content_type='text/x-rst', diff --git a/tests/CLI/modules/ipsec_tests.py b/tests/CLI/modules/ipsec_tests.py deleted file mode 100644 index eb473101d..000000000 --- a/tests/CLI/modules/ipsec_tests.py +++ /dev/null @@ -1,559 +0,0 @@ -""" - SoftLayer.tests.CLI.modules.ipsec_tests - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :license: MIT, see LICENSE for more details. -""" - -import json - -from SoftLayer.CLI.exceptions import ArgumentError -from SoftLayer.CLI.exceptions import CLIHalt -from SoftLayer.fixtures import SoftLayer_Product_Order -from SoftLayer.fixtures import SoftLayer_Product_Package -from SoftLayer import testing -from SoftLayer import utils - - -class IPSECTests(testing.TestCase): - - def test_ipsec_configure(self): - mock_account = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - mock_account.return_value = [{'id': 445}] - - mock_tunnel = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'applyConfigurationsToDevice') - mock_tunnel.return_value = True - - result = self.run_command(['ipsec', 'configure', '445']) - self.assert_no_fail(result) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'applyConfigurationsToDevice', - identifier=445) - self.assertEqual('Configuration request received for context #445\n', - result.output) - - def test_ipsec_configure_fails(self): - mock_account = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - mock_account.return_value = [{'id': 445}] - - mock_tunnel = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'applyConfigurationsToDevice') - mock_tunnel.return_value = False - - result = self.run_command(['ipsec', 'configure', '445']) - self.assertIsInstance(result.exception, CLIHalt) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'applyConfigurationsToDevice', - identifier=445) - self.assertEqual(('Failed to enqueue configuration request for ' - 'context #445\n'), - result.output) - - def test_ipsec_detail(self): - _mask = ('[mask[id,accountId,advancedConfigurationFlag,createDate,' - 'customerPeerIpAddress,modifyDate,name,friendlyName,' - 'internalPeerIpAddress,phaseOneAuthentication,' - 'phaseOneDiffieHellmanGroup,phaseOneEncryption,' - 'phaseOneKeylife,phaseTwoAuthentication,' - 'phaseTwoDiffieHellmanGroup,phaseTwoEncryption,' - 'phaseTwoKeylife,phaseTwoPerfectForwardSecrecy,presharedKey,' - 'addressTranslations[internalIpAddressRecord[ipAddress],' - 'customerIpAddressRecord[ipAddress]],internalSubnets,' - 'customerSubnets,staticRouteSubnets,serviceSubnets]]') - mock = self.set_mock('SoftLayer_Account', 'getNetworkTunnelContexts') - mock.return_value = [{ - 'id': 445, - 'name': 'der tunnel', - 'friendlyName': 'the tunnel', - 'internalPeerIpAddress': '10.0.0.1', - 'customerPeerIpAddress': '50.0.0.1', - 'advancedConfigurationFlag': 0, - 'presharedKey': 'secret', - 'phaseOneAuthentication': 'MD5', - 'phaseOneDiffieHellmanGroup': 1, - 'phaseOneEncryption': 'DES', - 'phaseOneKeylife': 600, - 'phaseTwoAuthentication': 'MD5', - 'phaseTwoDiffieHellmanGroup': 1, - 'phaseTwoEncryption': 'DES', - 'phaseTwoKeylife': 600, - 'phaseTwoPerfectForwardSecrecy': 0, - 'createDate': '2017-05-17T12:00:00-06:00', - 'modifyDate': '2017-05-17T12:01:00-06:00', - 'addressTranslations': [{ - 'id': 872341, - 'internalIpAddressId': 982341, - 'internalIpAddressRecord': {'ipAddress': '10.0.0.1'}, - 'customerIpAddressId': 872422, - 'customerIpAddressRecord': {'ipAddress': '50.0.0.1'}, - 'notes': 'surprise!' - }], - 'internalSubnets': [{ - 'id': 324113, - 'networkIdentifier': '10.20.0.0', - 'cidr': 29, - 'note': 'Private Network' - }], - 'customerSubnets': [{ - 'id': 873411, - 'networkIdentifier': '50.0.0.0', - 'cidr': 26, - 'note': 'Offsite Network' - }], - 'serviceSubnets': [{ - 'id': 565312, - 'networkIdentifier': '100.10.0.0', - 'cidr': 26, - 'note': 'Service Network' - }], - 'staticRouteSubnets': [{ - 'id': 998232, - 'networkIdentifier': '50.50.0.0', - 'cidr': 29, - 'note': 'Static Network' - }] - }] - result = self.run_command(['ipsec', 'detail', '445', '-iat', '-iis', '-irs', '-isr', '-iss']) - - split_output = [] - # Converts Rich JSON output to actual JSON data. JSON UTIL - for table in utils.decode_stacked(result.output): - split_output.append(table) - - self.assertEqual(6, len(split_output)) - self.assert_no_fail(result) - self.assert_called_with('SoftLayer_Account', 'getNetworkTunnelContexts', mask=_mask) - self.assertEqual({'id': 445, - 'name': 'der tunnel', - 'friendly name': 'the tunnel', - 'internal peer IP address': '10.0.0.1', - 'remote peer IP address': '50.0.0.1', - 'advanced configuration flag': 0, - 'preshared key': 'secret', - 'phase 1 authentication': 'MD5', - 'phase 1 diffie hellman group': 1, - 'phase 1 encryption': 'DES', - 'phase 1 key life': 600, - 'phase 2 authentication': 'MD5', - 'phase 2 diffie hellman group': 1, - 'phase 2 encryption': 'DES', - 'phase 2 key life': 600, - 'phase 2 perfect forward secrecy': 0, - 'created': '2017-05-17T12:00:00-06:00', - 'modified': '2017-05-17T12:01:00-06:00'}, - split_output[0]) - self.assertEqual([{'id': 872341, - 'remote IP address': '50.0.0.1', - 'remote IP address id': 872422, - 'static IP address': '10.0.0.1', - 'static IP address id': 982341, - 'note': 'surprise!'}], - split_output[1]) - self.assertEqual([{'id': 324113, - 'network identifier': '10.20.0.0', - 'cidr': 29, - 'note': 'Private Network'}], - split_output[2]) - self.assertEqual([{'id': 873411, - 'network identifier': '50.0.0.0', - 'cidr': 26, - 'note': 'Offsite Network'}], - split_output[3]) - self.assertEqual([{'id': 998232, - 'network identifier': '50.50.0.0', - 'cidr': 29, - 'note': 'Static Network'}], - split_output[4]) - self.assertEqual([{'id': 565312, - 'network identifier': '100.10.0.0', - 'cidr': 26, - 'note': 'Service Network'}], - split_output[5]) - - def test_ipsec_list(self): - mock = self.set_mock('SoftLayer_Account', 'getNetworkTunnelContexts') - mock.return_value = [{'id': 445, - 'name': 'der tunnel', - 'friendlyName': 'the tunnel', - 'internalPeerIpAddress': '10.0.0.1', - 'customerPeerIpAddress': '50.0.0.1', - 'advancedConfigurationFlag': 0, - 'presharedKey': 'secret', - 'phaseOneAuthentication': 'MD5', - 'phaseOneDiffieHellmanGroup': 1, - 'phaseOneEncryption': 'DES', - 'phaseOneKeylife': 600, - 'phaseTwoAuthentication': 'MD5', - 'phaseTwoDiffieHellmanGroup': 1, - 'phaseTwoEncryption': 'DES', - 'phaseTwoKeylife': 600, - 'phaseTwoPerfectForwardSecrecy': 0, - 'createDate': '2017-05-17T12:00:00-06:00', - 'modifyDate': '2017-05-17T12:01:00-06:00'}] - result = self.run_command(['ipsec', 'list']) - - self.assert_no_fail(result) - self.assertEqual([{ - 'id': 445, - 'name': 'der tunnel', - 'friendly name': 'the tunnel', - 'internal peer IP address': '10.0.0.1', - 'remote peer IP address': '50.0.0.1', - 'created': '2017-05-17T12:00:00-06:00' - }], json.loads(result.output)) - - def test_ipsec_update(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445, - 'name': 'der tunnel', - 'friendlyName': 'the tunnel', - 'internalPeerIpAddress': '10.0.0.1', - 'customerPeerIpAddress': '50.0.0.1', - 'advancedConfigurationFlag': 0, - 'presharedKey': 'secret', - 'phaseOneAuthentication': 'MD5', - 'phaseOneDiffieHellmanGroup': 1, - 'phaseOneEncryption': 'DES', - 'phaseOneKeylife': 600, - 'phaseTwoAuthentication': 'MD5', - 'phaseTwoDiffieHellmanGroup': 1, - 'phaseTwoEncryption': 'DES', - 'phaseTwoKeylife': 600, - 'phaseTwoPerfectForwardSecrecy': 0}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'editObject') - tunnel_mock.return_value = True - - result = self.run_command(['ipsec', 'update', '445', - '--friendly-name=ipsec tunnel', - '--remote-peer=50.0.0.2', - '--preshared-key=enigma', - '--p1-auth=SHA256', '--p1-crypto=AES256', - '--p1-dh=5', '--p1-key-ttl=120', - '--p2-auth=SHA1', '--p2-crypto=AES192', - '--p2-dh=2', '--p2-forward-secrecy=1', - '--p2-key-ttl=240']) - self.assert_no_fail(result) - self.assertEqual(result.output, 'Updated context #445\n') - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'editObject', - identifier=445, - args=({'id': 445, - 'name': 'der tunnel', - 'friendlyName': 'ipsec tunnel', - 'internalPeerIpAddress': '10.0.0.1', - 'customerPeerIpAddress': '50.0.0.2', - 'advancedConfigurationFlag': 0, - 'presharedKey': 'enigma', - 'phaseOneAuthentication': 'SHA256', - 'phaseOneDiffieHellmanGroup': '5', - 'phaseOneEncryption': 'AES256', - 'phaseOneKeylife': 120, - 'phaseTwoAuthentication': 'SHA1', - 'phaseTwoDiffieHellmanGroup': '2', - 'phaseTwoEncryption': 'AES192', - 'phaseTwoKeylife': 240, - 'phaseTwoPerfectForwardSecrecy': 1},)) - - def test_ipsec_update_fails(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'editObject') - tunnel_mock.return_value = False - - result = self.run_command(['ipsec', 'update', '445']) - self.assertIsInstance(result.exception, CLIHalt) - self.assertEqual('Failed to update context #445\n', result.output) - - def test_ipsec_subnet_add_internal(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'addPrivateSubnetToNetworkTunnel') - tunnel_mock.return_value = True - - result = self.run_command(['ipsec', 'subnet-add', '445', '-tinternal', - '-s234716']) - self.assert_no_fail(result) - self.assertEqual(result.output, 'Added internal subnet #234716\n') - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'addPrivateSubnetToNetworkTunnel', - identifier=445, - args=(234716,)) - - def test_ipsec_subnet_add_remote(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445, 'accountId': 999000}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'addCustomerSubnetToNetworkTunnel') - tunnel_mock.return_value = True - - subnet_mock = self.set_mock('SoftLayer_Network_Customer_Subnet', - 'createObject') - subnet_mock.return_value = {'id': 234716} - - result = self.run_command(['ipsec', 'subnet-add', '445', '-tremote', - '-n50.0.0.0/26']) - self.assert_no_fail(result) - self.assertEqual(result.output, - ('Created subnet 50.0.0.0/26 #234716\n' - 'Added remote subnet #234716\n')) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'addCustomerSubnetToNetworkTunnel', - identifier=445, - args=(234716,)) - self.assert_called_with('SoftLayer_Network_Customer_Subnet', - 'createObject', - args=({'networkIdentifier': '50.0.0.0', - 'cidr': 26, - 'accountId': 999000},)) - - def test_ipsec_subnet_add_service(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'addServiceSubnetToNetworkTunnel') - tunnel_mock.return_value = True - - result = self.run_command(['ipsec', 'subnet-add', '445', '-tservice', - '-s234716']) - self.assert_no_fail(result) - self.assertEqual(result.output, 'Added service subnet #234716\n') - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'addServiceSubnetToNetworkTunnel', - identifier=445, - args=(234716,)) - - def test_ipsec_subnet_add_without_id_or_network(self): - result = self.run_command(['ipsec', 'subnet-add', '445', '-tinternal']) - self.assertIsInstance(result.exception, ArgumentError) - - def test_ipsec_subnet_add_internal_with_network(self): - result = self.run_command(['ipsec', 'subnet-add', '445', '-tinternal', - '-n50.0.0.0/26']) - self.assertIsInstance(result.exception, ArgumentError) - - def test_ipsec_subnet_add_fails(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'addPrivateSubnetToNetworkTunnel') - tunnel_mock.return_value = False - - result = self.run_command(['ipsec', 'subnet-add', '445', '-tinternal', - '-s234716']) - self.assertIsInstance(result.exception, CLIHalt) - self.assertEqual(result.output, - 'Failed to add internal subnet #234716\n') - - def test_ipsec_subnet_remove_internal(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'removePrivateSubnetFromNetworkTunnel') - tunnel_mock.return_value = True - - result = self.run_command(['ipsec', 'subnet-remove', '445', - '-tinternal', '-s234716']) - self.assert_no_fail(result) - self.assertEqual(result.output, 'Removed internal subnet #234716\n') - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'removePrivateSubnetFromNetworkTunnel', - identifier=445, - args=(234716,)) - - def test_ipsec_subnet_remove_remote(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'removeCustomerSubnetFromNetworkTunnel') - tunnel_mock.return_value = True - - result = self.run_command(['ipsec', 'subnet-remove', '445', - '-tremote', '-s234716']) - self.assert_no_fail(result) - self.assertEqual(result.output, 'Removed remote subnet #234716\n') - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'removeCustomerSubnetFromNetworkTunnel', - identifier=445, - args=(234716,)) - - def test_ipsec_subnet_remove_service(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'removeServiceSubnetFromNetworkTunnel') - tunnel_mock.return_value = True - - result = self.run_command(['ipsec', 'subnet-remove', '445', - '-tservice', '-s234716']) - self.assert_no_fail(result) - self.assertEqual(result.output, 'Removed service subnet #234716\n') - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'removeServiceSubnetFromNetworkTunnel', - identifier=445, - args=(234716,)) - - def test_ipsec_subnet_remove_fails(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'removePrivateSubnetFromNetworkTunnel') - tunnel_mock.return_value = False - - result = self.run_command(['ipsec', 'subnet-remove', '445', - '-tinternal', '-s234716']) - self.assertIsInstance(result.exception, CLIHalt) - self.assertEqual(result.output, - 'Failed to remove internal subnet #234716\n') - - def test_ipsec_translation_add(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'createAddressTranslation') - tunnel_mock.return_value = {'id': 872843} - - result = self.run_command(['ipsec', 'translation-add', '445', - '-s10.50.0.0', '-r50.50.0.0', '-nlost']) - self.assert_no_fail(result) - self.assertEqual(result.output, - ('Created translation from 10.50.0.0 to 50.50.0.0 ' - '#872843\n')) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'createAddressTranslation', - identifier=445, - args=({'customerIpAddress': '50.50.0.0', - 'internalIpAddress': '10.50.0.0', - 'notes': 'lost'},)) - - def test_ipsec_translation_remove(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445, - 'addressTranslations': [{'id': 872843}]}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'deleteAddressTranslation') - tunnel_mock.return_value = True - - result = self.run_command(['ipsec', 'translation-remove', '445', - '-t872843']) - self.assert_no_fail(result) - self.assertEqual(result.output, 'Removed translation #872843\n') - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'deleteAddressTranslation', - identifier=445, - args=(872843,)) - - def test_ipsec_translation_remove_fails(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445, - 'addressTranslations': [{'id': 872843}]}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'deleteAddressTranslation') - tunnel_mock.return_value = False - - result = self.run_command(['ipsec', 'translation-remove', '445', - '-t872843']) - self.assertIsInstance(result.exception, CLIHalt) - self.assertEqual(result.output, - 'Failed to remove translation #872843\n') - - def test_ipsec_translation_update(self): - account_mock = self.set_mock('SoftLayer_Account', - 'getNetworkTunnelContexts') - account_mock.return_value = [{'id': 445, - 'addressTranslations': [{'id': 872843}]}] - - tunnel_mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'editAddressTranslation') - tunnel_mock.return_value = {'id': 872843} - - result = self.run_command(['ipsec', 'translation-update', '445', - '-t872843', '-s10.50.0.1', '-r50.50.0.1', - '-nlost']) - self.assert_no_fail(result) - self.assertEqual(result.output, 'Updated translation #872843\n') - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'editAddressTranslation', - identifier=445, - args=({'id': 872843, - 'internalIpAddress': '10.50.0.1', - 'customerIpAddress': '50.50.0.1', - 'notes': 'lost'},)) - - def test_ipsec_order(self): - _mock = self.set_mock('SoftLayer_Product_Package', 'getItems') - _mock.return_value = SoftLayer_Product_Package.getItems_IPSEC - - order_mock = self.set_mock('SoftLayer_Product_Order', 'placeOrder') - order_mock.return_value = SoftLayer_Product_Order.ipsec_placeOrder - result = self.run_command(['ipsec', 'order', '-d', 'dal13']) - self.assert_no_fail(result) - - def test_ipsec_cancel(self): - mock = self.set_mock('SoftLayer_Account', 'getNetworkTunnelContexts') - mock.return_value = [{ - "createDate": "2013-11-05T16:03:53-06:00", - "id": 445, - "internalPeerIpAddress": "184.172.127.9", - "modifyDate": "2022-07-19T09:34:53-06:00", - "name": "ipsec003", - "phaseOneAuthentication": "MD5", - "phaseOneDiffieHellmanGroup": 2, - "phaseOneEncryption": "3DES", - "phaseOneKeylife": 14400, - "phaseTwoAuthentication": "MD5", - "phaseTwoDiffieHellmanGroup": 2, - "phaseTwoEncryption": "3DES", - "phaseTwoKeylife": 3600, - "phaseTwoPerfectForwardSecrecy": 1, - "billingItem": { - "allowCancellationFlag": 1, - "categoryCode": "network_tunnel", - "createDate": "2022-07-19T09:34:52-06:00", - "cycleStartDate": "2022-08-03T23:07:43-06:00", - "description": "IPSEC - Standard", - "id": 977194617, - "lastBillDate": "2022-08-03T23:07:43-06:00", - "modifyDate": "2022-08-03T23:07:43-06:00", - "nextBillDate": "2022-09-03T23:00:00-06:00", - "oneTimeFee": "0", - "orderItemId": 932515967, - "recurringMonths": 1, - "serviceProviderId": 1, - }}] - - mock = self.set_mock('SoftLayer_Billing_Item', 'cancelItem') - mock.return_value = True - result = self.run_command(['ipsec', 'cancel', '445', '--immediate', '--reason', 'test']) - self.assert_no_fail(result) diff --git a/tests/managers/ipsec_tests.py b/tests/managers/ipsec_tests.py deleted file mode 100644 index b47ad8677..000000000 --- a/tests/managers/ipsec_tests.py +++ /dev/null @@ -1,327 +0,0 @@ -""" - SoftLayer.tests.managers.ipsec_tests - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :license: MIT, see LICENSE for more details. -""" -from unittest.mock import MagicMock as MagicMock - -import SoftLayer -from SoftLayer.exceptions import SoftLayerAPIError -from SoftLayer.fixtures import SoftLayer_Product_Order -from SoftLayer.fixtures import SoftLayer_Product_Package - -from SoftLayer import testing - - -class IPSECTests(testing.TestCase): - - def set_up(self): - self.ipsec = SoftLayer.IPSECManager(self.client) - - def test_add_internal_subnet(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'addPrivateSubnetToNetworkTunnel') - mock.return_value = True - self.assertEqual(self.ipsec.add_internal_subnet(445, 565787), True) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'addPrivateSubnetToNetworkTunnel', - args=(565787,), - identifier=445) - - def test_add_remote_subnet(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'addCustomerSubnetToNetworkTunnel') - mock.return_value = True - self.assertEqual(self.ipsec.add_remote_subnet(445, 565787), True) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'addCustomerSubnetToNetworkTunnel', - args=(565787,), - identifier=445) - - def test_add_service_subnet(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'addServiceSubnetToNetworkTunnel') - mock.return_value = True - self.assertEqual(self.ipsec.add_service_subnet(445, 565787), True) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'addServiceSubnetToNetworkTunnel', - args=(565787,), - identifier=445) - - def test_apply_configuration(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'applyConfigurationsToDevice') - mock.return_value = True - self.assertEqual(self.ipsec.apply_configuration(445), True) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'applyConfigurationsToDevice', - args=(), - identifier=445) - - def test_create_remote_subnet(self): - mock = self.set_mock('SoftLayer_Network_Customer_Subnet', - 'createObject') - mock.return_value = {'id': 565787, - 'networkIdentifier': '50.0.0.0', - 'cidr': 29, - 'accountId': 999000} - result = self.ipsec.create_remote_subnet(999000, '50.0.0.0', 29) - self.assertEqual(result, mock.return_value) - self.assert_called_with('SoftLayer_Network_Customer_Subnet', - 'createObject', - args=({'networkIdentifier': '50.0.0.0', - 'cidr': 29, - 'accountId': 999000},)) - - def test_create_translation(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'createAddressTranslation') - mock.return_value = {'id': 787989, - 'customerIpAddress': '50.0.0.0', - 'customerIpAddressId': 672634, - 'internalIpAddress': '10.0.0.0', - 'internalIpAddressId': 871231, - 'notes': 'first translation'} - result = self.ipsec.create_translation(445, - '10.0.0.0', - '50.0.0.0', - 'first translation') - self.assertEqual(result, mock.return_value) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'createAddressTranslation', - args=({'customerIpAddress': '50.0.0.0', - 'internalIpAddress': '10.0.0.0', - 'notes': 'first translation'},), - identifier=445) - - def test_delete_remote_subnet(self): - mock = self.set_mock('SoftLayer_Network_Customer_Subnet', - 'deleteObject') - mock.return_value = True - self.assertEqual(self.ipsec.delete_remote_subnet(565787), True) - self.assert_called_with('SoftLayer_Network_Customer_Subnet', - 'deleteObject', - identifier=565787) - - def test_get_tunnel_context(self): - _filter = {'networkTunnelContexts': {'id': {'operation': 445}}} - _mask = '[mask[id]]' - - mock = self.set_mock('SoftLayer_Account', 'getNetworkTunnelContexts') - mock.return_value = [{'id': 445}] - result = self.ipsec.get_tunnel_context(445, mask=_mask) - self.assertEqual(result, mock.return_value[0]) - self.assert_called_with('SoftLayer_Account', - 'getNetworkTunnelContexts', - filter=_filter, - mask=_mask) - - def test_get_tunnel_context_raises_error(self): - mock = self.set_mock('SoftLayer_Account', 'getNetworkTunnelContexts') - mock.return_value = [] - self.assertRaises(SoftLayerAPIError, - self.ipsec.get_tunnel_context, - 445) - - def test_get_translation(self): - mock = self.set_mock('SoftLayer_Account', 'getNetworkTunnelContexts') - mock.return_value = [{'id': 445, 'addressTranslations': - [{'id': 234123}, {'id': 872341}]}] - self.assertEqual(self.ipsec.get_translation(445, 872341), - {'id': 872341, - 'customerIpAddress': '', - 'internalIpAddress': ''}) - self.assert_called_with('SoftLayer_Account', - 'getNetworkTunnelContexts') - - def test_get_translation_raises_error(self): - mock = self.set_mock('SoftLayer_Account', 'getNetworkTunnelContexts') - mock.return_value = [{'id': 445, 'addressTranslations': - [{'id': 234123}]}] - self.assertRaises(SoftLayerAPIError, - self.ipsec.get_translation, - 445, - 872341) - - def test_get_translations(self): - _mask = ('[mask[addressTranslations[customerIpAddressRecord,' - 'internalIpAddressRecord]]]') - _filter = {'networkTunnelContexts': {'id': {'operation': 445}}} - mock = self.set_mock('SoftLayer_Account', 'getNetworkTunnelContexts') - mock.return_value = [{'id': 445, - 'addressTranslations': [{ - 'id': 234123, - 'customerIpAddressRecord': - {'ipAddress': '50.0.0.0'}, - 'customerIpAddressId': 234112, - 'internalIpAddressRecord': - {'ipAddress': '10.0.0.0'}, - 'internalIpAddressId': 234442 - }]}] - self.assertEqual(self.ipsec.get_translations(445), - [{'id': 234123, - 'customerIpAddress': '50.0.0.0', - 'customerIpAddressId': 234112, - 'internalIpAddress': '10.0.0.0', - 'internalIpAddressId': 234442}]) - self.assert_called_with('SoftLayer_Account', - 'getNetworkTunnelContexts', - filter=_filter, - mask=_mask) - - def test_get_tunnel_contexts(self): - _mask = '[mask[addressTranslations]]' - mock = self.set_mock('SoftLayer_Account', 'getNetworkTunnelContexts') - mock.return_value = [{'id': 445}, {'id': 446}] - self.assertEqual(self.ipsec.get_tunnel_contexts(mask=_mask), - mock.return_value) - self.assert_called_with('SoftLayer_Account', - 'getNetworkTunnelContexts', - mask=_mask) - - def test_remove_internal_subnet(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'removePrivateSubnetFromNetworkTunnel') - mock.return_value = True - self.assertEqual(self.ipsec.remove_internal_subnet(445, 565787), True) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'removePrivateSubnetFromNetworkTunnel', - args=(565787,), - identifier=445) - - def test_remove_remote_subnet(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'removeCustomerSubnetFromNetworkTunnel') - mock.return_value = True - self.assertEqual(self.ipsec.remove_remote_subnet(445, 565787), True) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'removeCustomerSubnetFromNetworkTunnel', - args=(565787,), - identifier=445) - - def test_remove_service_subnet(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'removeServiceSubnetFromNetworkTunnel') - mock.return_value = True - self.assertEqual(self.ipsec.remove_service_subnet(445, 565787), True) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'removeServiceSubnetFromNetworkTunnel', - args=(565787,), - identifier=445) - - def test_remove_translation(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'deleteAddressTranslation') - mock.return_value = True - self.assertEqual(self.ipsec.remove_translation(445, 787547), True) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'deleteAddressTranslation', - args=(787547,), - identifier=445) - - def test_update_translation(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'editAddressTranslation') - mock.return_value = True - translation = {'id': 234123, - 'customerIpAddress': '50.0.0.0', - 'customerIpAddressId': 234112, - 'internalIpAddress': '10.0.0.0', - 'internalIpAddressId': 234442} - self.ipsec.get_translation = MagicMock(return_value=translation) - - result = self.ipsec.update_translation(445, - 234123, - static_ip='10.0.0.2', - remote_ip='50.0.0.2', - notes='do not touch') - self.assertEqual(result, True) - self.ipsec.get_translation.assert_called_with(445, 234123) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'editAddressTranslation', - args=({'id': 234123, - 'customerIpAddress': '50.0.0.2', - 'internalIpAddress': '10.0.0.2', - 'notes': 'do not touch'},), - identifier=445) - - def test_update_tunnel_context(self): - mock = self.set_mock('SoftLayer_Network_Tunnel_Module_Context', - 'editObject') - mock.return_value = True - context = {'id': 445, - 'name': 'der tunnel', - 'friendlyName': 'the tunnel', - 'internalPeerIpAddress': '10.0.0.1', - 'customerPeerIpAddress': '50.0.0.1', - 'advancedConfigurationFlag': 0, - 'presharedKey': 'secret', - 'phaseOneAuthentication': 'MD5', - 'phaseOneDiffieHellmanGroup': 1, - 'phaseOneEncryption': 'DES', - 'phaseOneKeylife': 600, - 'phaseTwoAuthentication': 'MD5', - 'phaseTwoDiffieHellmanGroup': 1, - 'phaseTwoEncryption': 'DES', - 'phaseTwoKeylife': 600, - 'phaseTwoPerfectForwardSecrecy': 0} - self.ipsec.get_tunnel_context = MagicMock(return_value=context) - - result = self.ipsec.update_tunnel_context(445, - friendly_name='ipsec tunnel', - remote_peer='50.0.0.2', - preshared_key='enigma', - phase1_auth='SHA256', - phase1_dh=5, - phase1_crypto='AES256', - phase1_key_ttl=120, - phase2_auth='SHA128', - phase2_dh=2, - phase2_crypto='AES192', - phase2_key_ttl=240, - phase2_forward_secrecy=1) - self.assertEqual(result, True) - self.ipsec.get_tunnel_context.assert_called_with(445) - self.assert_called_with('SoftLayer_Network_Tunnel_Module_Context', - 'editObject', - args=({'id': 445, - 'name': 'der tunnel', - 'friendlyName': 'ipsec tunnel', - 'internalPeerIpAddress': '10.0.0.1', - 'customerPeerIpAddress': '50.0.0.2', - 'advancedConfigurationFlag': 0, - 'presharedKey': 'enigma', - 'phaseOneAuthentication': 'SHA256', - 'phaseOneDiffieHellmanGroup': 5, - 'phaseOneEncryption': 'AES256', - 'phaseOneKeylife': 120, - 'phaseTwoAuthentication': 'SHA128', - 'phaseTwoDiffieHellmanGroup': 2, - 'phaseTwoEncryption': 'AES192', - 'phaseTwoKeylife': 240, - 'phaseTwoPerfectForwardSecrecy': 1},), - identifier=445) - - def test_order(self): - _mock = self.set_mock('SoftLayer_Product_Package', 'getItems') - _mock.return_value = SoftLayer_Product_Package.getItems_IPSEC - - _mock = self.set_mock('SoftLayer_Product_Order', 'placeOrder') - _mock.return_value = SoftLayer_Product_Order.ipsec_placeOrder - result = self.ipsec.order('dal13', ['IPSEC_STANDARD']) - order = { - 'orderDate': '2022-07-14T16:09:08-06:00', - 'orderId': 123456, 'placedOrder': {'items': [ - {'categoryCode': 'network_tunnel', - 'description': 'IPSEC - Standard', - 'id': 931479898, - 'itemId': 1092, - 'itemPriceId': '2048'}]}} - self.assertEqual(result, order) - - def test_cancel_item(self): - _mock = self.set_mock('SoftLayer_Billing_Item', 'cancelItem') - _mock.return_value = True - result = self.ipsec.cancel_item(443, True, 'test') - self.assertEqual(result, True)