New Module to manage AWS direct connect link aggregation groups (#27250)
* Add module_utils/aws/direct_connect.py for frequently used functions * new AWS Direct Connect link aggregation group module with tests and placebo recordings * remove extra argument * Remove use of undefined var * Fix param name for extra exception codes for AWSRetry to use. * Fix undefined var and line length and metadata version number * Fix copyright headers
This commit is contained in:
parent
fe21dd272d
commit
a48e0b5101
26 changed files with 1622 additions and 0 deletions
86
lib/ansible/module_utils/aws/direct_connect.py
Normal file
86
lib/ansible/module_utils/aws/direct_connect.py
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
# This code is part of Ansible, but is an independent component.
|
||||||
|
# This particular file snippet, and this file snippet only, is BSD licensed.
|
||||||
|
# Modules you write using this snippet, which is embedded dynamically by Ansible
|
||||||
|
# still belong to the author of the module, and may assign their own license
|
||||||
|
# to the complete work.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2017 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
# are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
"""
|
||||||
|
This module adds shared support for Direct Connect modules.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import traceback
|
||||||
|
try:
|
||||||
|
import botocore
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
from ansible.module_utils.ec2 import camel_dict_to_snake_dict
|
||||||
|
|
||||||
|
|
||||||
|
class DirectConnectError(Exception):
|
||||||
|
def __init__(self, msg, last_traceback=None, response={}):
|
||||||
|
self.msg = msg
|
||||||
|
self.last_traceback = last_traceback
|
||||||
|
self.response = camel_dict_to_snake_dict(response)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_connection(client, connection_id):
|
||||||
|
try:
|
||||||
|
client.delete_connection(connectionId=connection_id)
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
raise DirectConnectError(msg="Failed to delete DirectConnection {0}.".format(connection_id),
|
||||||
|
last_traceback=traceback.format_exc(),
|
||||||
|
response=e.response)
|
||||||
|
|
||||||
|
|
||||||
|
def associate_connection_and_lag(client, connection_id, lag_id):
|
||||||
|
try:
|
||||||
|
client.associate_connection_with_lag(connectionId=connection_id,
|
||||||
|
lagId=lag_id)
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
raise DirectConnectError(msg="Failed to associate Direct Connect connection {0}"
|
||||||
|
" with link aggregation group {1}.".format(connection_id, lag_id),
|
||||||
|
last_traceback=traceback.format_exc(),
|
||||||
|
response=e.response)
|
||||||
|
|
||||||
|
|
||||||
|
def disassociate_connection_and_lag(client, connection_id, lag_id):
|
||||||
|
try:
|
||||||
|
client.disassociate_connection_from_lag(connectionId=connection_id,
|
||||||
|
lagId=lag_id)
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
raise DirectConnectError(msg="Failed to disassociate Direct Connect connection {0}"
|
||||||
|
" from link aggregation group {1}.".format(connection_id, lag_id),
|
||||||
|
last_traceback=traceback.format_exc(),
|
||||||
|
response=e.response)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_virtual_interface(client, virtual_interface):
|
||||||
|
try:
|
||||||
|
client.delete_virtual_interface(virtualInterfaceId=virtual_interface)
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
raise DirectConnectError(msg="Could not delete virtual interface {0}".format(virtual_interface),
|
||||||
|
last_traceback=traceback.format_exc(),
|
||||||
|
response=e.response)
|
|
@ -0,0 +1,453 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# Copyright (c) 2017 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||||
|
'status': ['preview'],
|
||||||
|
'supported_by': 'community'}
|
||||||
|
|
||||||
|
|
||||||
|
DOCUMENTATION = """
|
||||||
|
---
|
||||||
|
module: aws_direct_connect_link_aggregation_group
|
||||||
|
short_description: Manage Direct Connect LAG bundles.
|
||||||
|
description:
|
||||||
|
- Create, delete, or modify a Direct Connect link aggregation group.
|
||||||
|
version_added: "2.4"
|
||||||
|
author: "Sloane Hertel (@s-hertel)"
|
||||||
|
requirements:
|
||||||
|
- boto3
|
||||||
|
- botocore
|
||||||
|
options:
|
||||||
|
state:
|
||||||
|
description:
|
||||||
|
- The state of the Direct Connect link aggregation group.
|
||||||
|
choices:
|
||||||
|
- present
|
||||||
|
- absent
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- The name of the Direct Connect link aggregation group.
|
||||||
|
link_aggregation_group_id:
|
||||||
|
description:
|
||||||
|
- The ID of the Direct Connect link aggregation group.
|
||||||
|
num_connections:
|
||||||
|
description:
|
||||||
|
- The number of connections with which to intialize the link aggregation group.
|
||||||
|
min_links:
|
||||||
|
description:
|
||||||
|
- The minimum number of physical connections that must be operational for the LAG itself to be operational.
|
||||||
|
location:
|
||||||
|
description:
|
||||||
|
- The location of the link aggregation group.
|
||||||
|
bandwidth:
|
||||||
|
description:
|
||||||
|
- The bandwidth of the link aggregation group.
|
||||||
|
force_delete:
|
||||||
|
description:
|
||||||
|
- This allows the minimum number of links to be set to 0, any hosted connections disassociated,
|
||||||
|
and any virtual interfaces associated to the LAG deleted.
|
||||||
|
connection_id:
|
||||||
|
description:
|
||||||
|
- A connection ID to link with the link aggregation group upon creation.
|
||||||
|
delete_with_disassociation:
|
||||||
|
description:
|
||||||
|
- To be used with I(state=absent) to delete connections after disassociating them with the LAG.
|
||||||
|
wait:
|
||||||
|
description:
|
||||||
|
- Whether or not to wait for the operation to complete. May be useful when waiting for virtual interfaces
|
||||||
|
to be deleted. May modify the time of waiting with C(wait_timeout).
|
||||||
|
type: bool
|
||||||
|
wait_timeout:
|
||||||
|
description:
|
||||||
|
- The duration in seconds to wait if I(wait) is True.
|
||||||
|
default: 120
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXAMPLES = """
|
||||||
|
|
||||||
|
# create a Direct Connect connection
|
||||||
|
- aws_direct_connect_link_aggregation_group:
|
||||||
|
state: present
|
||||||
|
location: EqDC2
|
||||||
|
lag_id: dxlag-xxxxxxxx
|
||||||
|
bandwidth: 1Gbps
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
RETURN = """
|
||||||
|
changed:
|
||||||
|
type: str
|
||||||
|
description: Whether or not the LAG has changed.
|
||||||
|
returned: always
|
||||||
|
aws_device:
|
||||||
|
type: str
|
||||||
|
description: The AWS Direct Connection endpoint that hosts the LAG.
|
||||||
|
sample: "EqSe2-1bwfvazist2k0"
|
||||||
|
returned: when I(state=present)
|
||||||
|
connections:
|
||||||
|
type: list
|
||||||
|
description: A list of connections bundled by this LAG.
|
||||||
|
sample:
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"aws_device": "EqSe2-1bwfvazist2k0",
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connection_id": "dxcon-fgzjah5a",
|
||||||
|
"connection_name": "Requested Connection 1 for Lag dxlag-fgtoh97h",
|
||||||
|
"connection_state": "down",
|
||||||
|
"lag_id": "dxlag-fgnsp4rq",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"owner_account": "448830907657",
|
||||||
|
"region": "us-west-2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
returned: when I(state=present)
|
||||||
|
connections_bandwidth:
|
||||||
|
type: str
|
||||||
|
description: The individual bandwidth of the physical connections bundled by the LAG.
|
||||||
|
sample: "1Gbps"
|
||||||
|
returned: when I(state=present)
|
||||||
|
lag_id:
|
||||||
|
type: str
|
||||||
|
description: Unique identifier for the link aggregation group.
|
||||||
|
sample: "dxlag-fgnsp4rq"
|
||||||
|
returned: when I(state=present)
|
||||||
|
lag_name:
|
||||||
|
type: str
|
||||||
|
description: User-provided name for the link aggregation group.
|
||||||
|
returned: when I(state=present)
|
||||||
|
lag_state:
|
||||||
|
type: str
|
||||||
|
description: State of the LAG.
|
||||||
|
sample: "pending"
|
||||||
|
returned: when I(state=present)
|
||||||
|
location:
|
||||||
|
type: str
|
||||||
|
description: Where the connection is located.
|
||||||
|
sample: "EqSe2"
|
||||||
|
returned: when I(state=present)
|
||||||
|
minimum_links:
|
||||||
|
type: int
|
||||||
|
description: The minimum number of physical connections that must be operational for the LAG itself to be operational.
|
||||||
|
returned: when I(state=present)
|
||||||
|
number_of_connections:
|
||||||
|
type: int
|
||||||
|
description: The number of physical connections bundled by the LAG.
|
||||||
|
returned: when I(state=present)
|
||||||
|
owner_account:
|
||||||
|
type: str
|
||||||
|
description: Owner account ID of the LAG.
|
||||||
|
returned: when I(state=present)
|
||||||
|
region:
|
||||||
|
type: str
|
||||||
|
description: The region in which the LAG exists.
|
||||||
|
returned: when I(state=present)
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ansible.module_utils.ec2 import (camel_dict_to_snake_dict, ec2_argument_spec, HAS_BOTO3,
|
||||||
|
get_aws_connection_info, boto3_conn, AWSRetry)
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.aws.direct_connect import (delete_connection,
|
||||||
|
delete_virtual_interface,
|
||||||
|
disassociate_connection_and_lag)
|
||||||
|
import traceback
|
||||||
|
import time
|
||||||
|
|
||||||
|
try:
|
||||||
|
import botocore
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
# handled by imported HAS_BOTO3
|
||||||
|
|
||||||
|
|
||||||
|
class DirectConnectError(Exception):
|
||||||
|
def __init__(self, msg, last_traceback, response):
|
||||||
|
self.msg = msg
|
||||||
|
self.last_traceback = last_traceback
|
||||||
|
self.response = response
|
||||||
|
|
||||||
|
|
||||||
|
def lag_status(client, lag_id):
|
||||||
|
return lag_exists(client, lag_id=lag_id, lag_name=None, verify=False)
|
||||||
|
|
||||||
|
|
||||||
|
def lag_exists(client, lag_id=None, lag_name=None, verify=True):
|
||||||
|
""" If verify=True, returns the LAG ID or None
|
||||||
|
If verify=False, returns the LAG's data (or an empty dict)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if lag_id:
|
||||||
|
response = client.describe_lags(lagId=lag_id)
|
||||||
|
else:
|
||||||
|
response = client.describe_lags()
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
if lag_id and verify:
|
||||||
|
return False
|
||||||
|
elif lag_id:
|
||||||
|
return {}
|
||||||
|
else:
|
||||||
|
failed_op = "Failed to describe DirectConnect link aggregation groups."
|
||||||
|
raise DirectConnectError(msg=failed_op,
|
||||||
|
last_traceback=traceback.format_exc(),
|
||||||
|
response=e.response)
|
||||||
|
|
||||||
|
match = [] # List of LAG IDs that are exact matches
|
||||||
|
lag = [] # List of LAG data that are exact matches
|
||||||
|
|
||||||
|
# look for matching connections
|
||||||
|
if len(response.get('lags', [])) == 1 and lag_id:
|
||||||
|
if response['lags'][0]['lagState'] != 'deleted':
|
||||||
|
match.append(response['lags'][0]['lagId'])
|
||||||
|
lag.append(response['lags'][0])
|
||||||
|
else:
|
||||||
|
for each in response.get('lags', []):
|
||||||
|
if each['lagState'] != 'deleted':
|
||||||
|
if not lag_id:
|
||||||
|
if lag_name == each['lagName']:
|
||||||
|
match.append(each['lagId'])
|
||||||
|
else:
|
||||||
|
match.append(each['lagId'])
|
||||||
|
|
||||||
|
# verifying if the connections exists; if true, return connection identifier, otherwise return False
|
||||||
|
if verify and len(match) == 1:
|
||||||
|
return match[0]
|
||||||
|
elif verify:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# not verifying if the connection exists; just return current connection info
|
||||||
|
else:
|
||||||
|
if len(lag) == 1:
|
||||||
|
return lag[0]
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def create_lag(client, num_connections, location, bandwidth, name, connection_id):
|
||||||
|
if not name:
|
||||||
|
raise DirectConnectError(msg="Failed to create a Direct Connect link aggregation group: name required.")
|
||||||
|
|
||||||
|
parameters = dict(numberOfConnections=num_connections,
|
||||||
|
location=location,
|
||||||
|
connectionsBandwidth=bandwidth,
|
||||||
|
lagName=name)
|
||||||
|
if connection_id:
|
||||||
|
parameters.update(connectionId=connection_id)
|
||||||
|
try:
|
||||||
|
lag = client.create_lag(**parameters)
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
raise DirectConnectError(msg="Failed to create DirectConnect link aggregation group {0}".format(name),
|
||||||
|
last_traceback=traceback.format_exc(),
|
||||||
|
response=e.response)
|
||||||
|
|
||||||
|
return lag['lagId']
|
||||||
|
|
||||||
|
|
||||||
|
def delete_lag(client, lag_id):
|
||||||
|
try:
|
||||||
|
client.delete_lag(lagId=lag_id)
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
raise DirectConnectError(msg="Failed to delete Direct Connect link aggregation group {0}.".format(lag_id),
|
||||||
|
last_traceback=traceback.format_exc(),
|
||||||
|
response=e.response)
|
||||||
|
|
||||||
|
|
||||||
|
@AWSRetry.backoff(tries=5, delay=2, backoff=2.0, catch_extra_error_codes=['DirectConnectClientException'])
|
||||||
|
def _update_lag(client, lag_id, lag_name, min_links):
|
||||||
|
params = {}
|
||||||
|
if min_links:
|
||||||
|
params.update(minimumLinks=min_links)
|
||||||
|
if lag_name:
|
||||||
|
params.update(lagName=lag_name)
|
||||||
|
|
||||||
|
client.update_lag(lagId=lag_id, **params)
|
||||||
|
|
||||||
|
|
||||||
|
def update_lag(client, lag_id, lag_name, min_links, num_connections, wait, wait_timeout):
|
||||||
|
start = time.time()
|
||||||
|
|
||||||
|
if min_links and min_links > num_connections:
|
||||||
|
raise DirectConnectError(msg="The number of connections {0} must be greater than the minimum number of links "
|
||||||
|
"{1} to update the LAG {2}".format(num_connections, min_links, lag_id),
|
||||||
|
last_traceback=None,
|
||||||
|
response=None)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
_update_lag(client, lag_id, lag_name, min_links)
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
if wait and time.time() - start <= wait_timeout:
|
||||||
|
continue
|
||||||
|
msg = "Failed to update Direct Connect link aggregation group {0}.".format(lag_id)
|
||||||
|
if "MinimumLinks cannot be set higher than the number of connections" in e.response['Error']['Message']:
|
||||||
|
msg += "Unable to set the min number of links to {0} while the LAG connections are being requested".format(min_links)
|
||||||
|
raise DirectConnectError(msg=msg,
|
||||||
|
last_traceback=traceback.format_exc(),
|
||||||
|
response=e.response)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def lag_changed(current_status, name, min_links):
|
||||||
|
""" Determines if a modifiable link aggregation group attribute has been modified. """
|
||||||
|
return (name and name != current_status['lagName']) or (min_links and min_links != current_status['minimumLinks'])
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_present(client, num_connections, lag_id, lag_name, location, bandwidth, connection_id, min_links, wait, wait_timeout):
|
||||||
|
exists = lag_exists(client, lag_id, lag_name)
|
||||||
|
if not exists and lag_id:
|
||||||
|
raise DirectConnectError(msg="The Direct Connect link aggregation group {0} does not exist.".format(lag_id), last_traceback=None, response="")
|
||||||
|
|
||||||
|
# the connection is found; get the latest state and see if it needs to be updated
|
||||||
|
if exists:
|
||||||
|
lag_id = exists
|
||||||
|
latest_state = lag_status(client, lag_id)
|
||||||
|
if lag_changed(latest_state, lag_name, min_links):
|
||||||
|
update_lag(client, lag_id, lag_name, min_links, num_connections, wait, wait_timeout)
|
||||||
|
return True, lag_id
|
||||||
|
return False, lag_id
|
||||||
|
|
||||||
|
# no connection found; create a new one
|
||||||
|
else:
|
||||||
|
lag_id = create_lag(client, num_connections, location, bandwidth, lag_name, connection_id)
|
||||||
|
update_lag(client, lag_id, lag_name, min_links, num_connections, wait, wait_timeout)
|
||||||
|
return True, lag_id
|
||||||
|
|
||||||
|
|
||||||
|
def describe_virtual_interfaces(client, lag_id):
|
||||||
|
try:
|
||||||
|
response = client.describe_virtual_interfaces(connectionId=lag_id)
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
raise DirectConnectError(msg="Failed to describe any virtual interfaces associated with LAG: {0}".format(lag_id),
|
||||||
|
last_traceback=traceback.format_exc(),
|
||||||
|
response=e.response)
|
||||||
|
return response.get('virtualInterfaces', [])
|
||||||
|
|
||||||
|
|
||||||
|
def get_connections_and_virtual_interfaces(client, lag_id):
|
||||||
|
virtual_interfaces = describe_virtual_interfaces(client, lag_id)
|
||||||
|
connections = lag_status(client, lag_id=lag_id).get('connections', [])
|
||||||
|
return virtual_interfaces, connections
|
||||||
|
|
||||||
|
|
||||||
|
def disassociate_vis(client, lag_id, virtual_interfaces):
|
||||||
|
for vi in virtual_interfaces:
|
||||||
|
delete_virtual_interface(client, vi['virtualInterfaceId'])
|
||||||
|
try:
|
||||||
|
response = client.delete_virtual_interface(virtualInterfaceId=vi['virtualInterfaceId'])
|
||||||
|
except botocore.exceptions.ClientError as e:
|
||||||
|
raise DirectConnectError(msg="Could not delete virtual interface {0} to delete link aggregation group {1}.".format(vi, lag_id),
|
||||||
|
last_traceback=traceback.format_exc(),
|
||||||
|
response=e.response)
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_absent(client, lag_id, lag_name, force_delete, delete_with_disassociation, wait, wait_timeout):
|
||||||
|
lag_id = lag_exists(client, lag_id, lag_name)
|
||||||
|
if not lag_id:
|
||||||
|
return False
|
||||||
|
|
||||||
|
latest_status = lag_status(client, lag_id)
|
||||||
|
|
||||||
|
# determinine the associated connections and virtual interfaces to disassociate
|
||||||
|
virtual_interfaces, connections = get_connections_and_virtual_interfaces(client, lag_id)
|
||||||
|
|
||||||
|
# If min_links is not 0, there are associated connections, or if there are virtual interfaces, ask for force_delete
|
||||||
|
if any((latest_status['minimumLinks'], virtual_interfaces, connections)) and not force_delete:
|
||||||
|
raise DirectConnectError(msg="There are a minimum number of links, hosted connections, or associated virtual interfaces for LAG {0}. "
|
||||||
|
"To force deletion of the LAG use delete_force: True (if the LAG has virtual interfaces they will be deleted). "
|
||||||
|
"Optionally, to ensure hosted connections are deleted after disassocation use delete_with_disassocation: True "
|
||||||
|
"and wait: True (as Virtual Interfaces may take a few moments to delete)".format(lag_id),
|
||||||
|
last_traceback=None,
|
||||||
|
response=None)
|
||||||
|
|
||||||
|
# update min_links to be 0 so we can remove the LAG
|
||||||
|
update_lag(client, lag_id, None, 0, len(connections), wait, wait_timeout)
|
||||||
|
|
||||||
|
# if virtual_interfaces and not delete_vi_with_disassociation: Raise failure; can't delete while vi attached
|
||||||
|
for connection in connections:
|
||||||
|
disassociate_connection_and_lag(client, connection['connectionId'], lag_id)
|
||||||
|
if delete_with_disassociation:
|
||||||
|
delete_connection(client, connection['connectionId'])
|
||||||
|
|
||||||
|
for vi in virtual_interfaces:
|
||||||
|
delete_virtual_interface(client, vi['virtualInterfaceId'])
|
||||||
|
|
||||||
|
start_time = time.time()
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
delete_lag(client, lag_id)
|
||||||
|
except DirectConnectError as e:
|
||||||
|
if ('until its Virtual Interfaces are deleted' in e.response) and (time.time() - start_time < wait_timeout) and wait:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
argument_spec = ec2_argument_spec()
|
||||||
|
argument_spec.update(dict(
|
||||||
|
state=dict(required=True, choices=['present', 'absent']),
|
||||||
|
name=dict(),
|
||||||
|
link_aggregation_group_id=dict(),
|
||||||
|
num_connections=dict(type='int'),
|
||||||
|
min_links=dict(type='int'),
|
||||||
|
location=dict(),
|
||||||
|
bandwidth=dict(),
|
||||||
|
connection_id=dict(),
|
||||||
|
delete_with_disassociation=dict(type='bool', default=False),
|
||||||
|
force_delete=dict(type='bool', default=False),
|
||||||
|
wait=dict(type='bool', default=False),
|
||||||
|
wait_timeout=dict(type='int', default=120),
|
||||||
|
))
|
||||||
|
|
||||||
|
module = AnsibleModule(argument_spec=argument_spec,
|
||||||
|
required_one_of=[('link_aggregation_group_id', 'name')],
|
||||||
|
required_if=[('state', 'present', ('location', 'bandwidth'))])
|
||||||
|
|
||||||
|
if not HAS_BOTO3:
|
||||||
|
module.fail_json(msg='boto3 required for this module')
|
||||||
|
|
||||||
|
region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module, boto3=True)
|
||||||
|
if not region:
|
||||||
|
module.fail_json(msg="Either region or AWS_REGION or EC2_REGION environment variable or boto config aws_region or ec2_region must be set.")
|
||||||
|
|
||||||
|
connection = boto3_conn(module, conn_type='client',
|
||||||
|
resource='directconnect', region=region,
|
||||||
|
endpoint=ec2_url, **aws_connect_kwargs)
|
||||||
|
|
||||||
|
state = module.params.get('state')
|
||||||
|
try:
|
||||||
|
if state == 'present':
|
||||||
|
changed, lag_id = ensure_present(connection,
|
||||||
|
num_connections=module.params.get("num_connections"),
|
||||||
|
lag_id=module.params.get("link_aggregation_group_id"),
|
||||||
|
lag_name=module.params.get("name"),
|
||||||
|
location=module.params.get("location"),
|
||||||
|
bandwidth=module.params.get("bandwidth"),
|
||||||
|
connection_id=module.params.get("connection_id"),
|
||||||
|
min_links=module.params.get("min_links"),
|
||||||
|
wait=module.params.get("wait"),
|
||||||
|
wait_timeout=module.params.get("wait_timeout"))
|
||||||
|
response = lag_status(connection, lag_id)
|
||||||
|
elif state == "absent":
|
||||||
|
changed = ensure_absent(connection,
|
||||||
|
lag_id=module.params.get("link_aggregation_group_id"),
|
||||||
|
lag_name=module.params.get("name"),
|
||||||
|
force_delete=module.params.get("force_delete"),
|
||||||
|
delete_with_disassociation=module.params.get("delete_with_disassociation"),
|
||||||
|
wait=module.params.get('wait'),
|
||||||
|
wait_timeout=module.params.get('wait_timeout'))
|
||||||
|
response = {}
|
||||||
|
except DirectConnectError as e:
|
||||||
|
if e.response:
|
||||||
|
module.fail_json(msg=e.msg, exception=e.last_traceback, **e.response)
|
||||||
|
elif e.last_traceback:
|
||||||
|
module.fail_json(msg=e.msg, exception=e.last_traceback)
|
||||||
|
else:
|
||||||
|
module.fail_json(msg=e.msg)
|
||||||
|
|
||||||
|
module.exit_json(changed=changed, **camel_dict_to_snake_dict(response))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bf2372eb-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "216",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:39:02 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bf2372eb-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
},
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "deleted",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lagState": "deleted",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bf437e0e-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "266",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:39:02 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bf437e0e-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
},
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [],
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"numberOfConnections": 0,
|
||||||
|
"lagName": "ansible_lag_1"
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bd224baf-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:59 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bd224baf-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bda84490-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:59 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bda84490-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "be79c564-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:39:01 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "be79c564-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"virtualInterfaces": [],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "be66d9a3-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "24",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:39:00 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "be66d9a3-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bf0c687a-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "218",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:39:01 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bf0c687a-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
},
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lagState": "pending",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bef64869-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "509",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:39:01 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bef64869-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
},
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1"
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bc1aedd9-70a7-11e7-a2a8-21d8bda1f5ec",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:57 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bc1aedd9-70a7-11e7-a2a8-21d8bda1f5ec"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bc4902ba-70a7-11e7-a2a8-21d8bda1f5ec",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:57 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bc4902ba-70a7-11e7-a2a8-21d8bda1f5ec"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bc7ff13c-70a7-11e7-a2a8-21d8bda1f5ec",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:57 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bc7ff13c-70a7-11e7-a2a8-21d8bda1f5ec"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"virtualInterfaces": [],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bc6dc8cb-70a7-11e7-a2a8-21d8bda1f5ec",
|
||||||
|
"content-length": "24",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:57 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bc6dc8cb-70a7-11e7-a2a8-21d8bda1f5ec"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"Error": {
|
||||||
|
"Code": "DirectConnectClientException",
|
||||||
|
"Message": "Could not find Lag with ID dxlag-XXXXXXXX"
|
||||||
|
},
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 400,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"connection": "close",
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "bb67ca78-70a7-11e7-a2a8-21d8bda1f5ec",
|
||||||
|
"content-length": "95",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:56 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "bb67ca78-70a7-11e7-a2a8-21d8bda1f5ec"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 400
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "b8662323-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:50 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "b8662323-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "b91b4255-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:52 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "b91b4255-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "b5e4a858-70a7-11e7-a69f-95e467ba41d7",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:46 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "b5e4a858-70a7-11e7-a69f-95e467ba41d7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-9uinh2jjnuu9",
|
||||||
|
"connections": [],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 0,
|
||||||
|
"lagName": "sherteltestlag",
|
||||||
|
"lagId": "dxlag-fgr4lfqt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-2bii1jufy4y7p",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgytkicv",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgytkicv",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-fgsxammv"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_2",
|
||||||
|
"lagId": "dxlag-fgytkicv"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [],
|
||||||
|
"lagState": "deleted",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 0,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgee5gk5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-2bii1jufy4y7p",
|
||||||
|
"connections": [],
|
||||||
|
"lagState": "deleted",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 0,
|
||||||
|
"lagName": "ansible_lag_2_update",
|
||||||
|
"lagId": "dxlag-fg0hj0n3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [],
|
||||||
|
"lagState": "deleted",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 0,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-ffg1zmo4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-2oqu43nde4cs1",
|
||||||
|
"connections": [],
|
||||||
|
"lagState": "deleted",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 0,
|
||||||
|
"lagName": "ansible_lag_2_update",
|
||||||
|
"lagId": "dxlag-ffzm4jk8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [],
|
||||||
|
"lagState": "deleted",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 0,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-ffuid1ql"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-2oqu43nde4cs1",
|
||||||
|
"connections": [],
|
||||||
|
"lagState": "deleted",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 0,
|
||||||
|
"lagName": "ansible_lag_2_update",
|
||||||
|
"lagId": "dxlag-ffpq2qa7"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "b6a0a55a-70a7-11e7-a69f-95e467ba41d7",
|
||||||
|
"content-length": "2920",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:49 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "b6a0a55a-70a7-11e7-a69f-95e467ba41d7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-1bwfvazist2k0",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgkk4dja",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgkk4dja",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-ffx41o23"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_1",
|
||||||
|
"lagId": "dxlag-fgkk4dja"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "b4aa057e-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:44 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "b4aa057e-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"Error": {
|
||||||
|
"Code": "DirectConnectClientException",
|
||||||
|
"Message": "Could not find Lag with ID dxlag-XXXXXXXX"
|
||||||
|
},
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 400,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"connection": "close",
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "b7f55ff2-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "95",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:50 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "b7f55ff2-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 400
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"Error": {
|
||||||
|
"Code": "DirectConnectClientException",
|
||||||
|
"Message": "Lag ID doesntexist has an invalid format."
|
||||||
|
},
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 400,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"connection": "close",
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "b3c76dc0-70a7-11e7-a2a8-21d8bda1f5ec",
|
||||||
|
"content-length": "95",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:42 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "b3c76dc0-70a7-11e7-a2a8-21d8bda1f5ec"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 400
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-2bii1jufy4y7p",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgytkicv",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgytkicv",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-fgsxammv"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_2",
|
||||||
|
"lagId": "dxlag-fgytkicv"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "b9cc69e9-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "520",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:53 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "b9cc69e9-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lags": [
|
||||||
|
{
|
||||||
|
"awsDevice": "EqSe2-2bii1jufy4y7p",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgytkicv",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgytkicv",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-fgsxammv"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lagState": "pending",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"location": "EqSe2",
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_2_update",
|
||||||
|
"lagId": "dxlag-fgytkicv"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "ba91197b-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "527",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:54 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "ba91197b-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"lagState": "pending",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"RetryAttempts": 0,
|
||||||
|
"HTTPStatusCode": 200,
|
||||||
|
"HTTPHeaders": {
|
||||||
|
"content-type": "application/x-amz-json-1.1",
|
||||||
|
"x-amzn-requestid": "ba76658a-70a7-11e7-83ab-ef16f9ac5159",
|
||||||
|
"content-length": "516",
|
||||||
|
"date": "Mon, 24 Jul 2017 19:38:54 GMT"
|
||||||
|
},
|
||||||
|
"RequestId": "ba76658a-70a7-11e7-83ab-ef16f9ac5159"
|
||||||
|
},
|
||||||
|
"lagId": "dxlag-fgytkicv",
|
||||||
|
"awsDevice": "EqSe2-2bii1jufy4y7p",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"bandwidth": "1Gbps",
|
||||||
|
"connectionName": "Requested Connection 1 for Lag dxlag-fgytkicv",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"lagId": "dxlag-fgytkicv",
|
||||||
|
"region": "us-west-2",
|
||||||
|
"connectionState": "requested",
|
||||||
|
"connectionId": "dxcon-fgsxammv"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connectionsBandwidth": "1Gbps",
|
||||||
|
"minimumLinks": 0,
|
||||||
|
"ownerAccount": "448830907657",
|
||||||
|
"numberOfConnections": 1,
|
||||||
|
"lagName": "ansible_lag_2_update"
|
||||||
|
},
|
||||||
|
"status_code": 200
|
||||||
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
# (c) 2017 Red Hat Inc.
|
||||||
|
#
|
||||||
|
# This file is part of Ansible
|
||||||
|
#
|
||||||
|
# Ansible is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ansible is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import os
|
||||||
|
import collections
|
||||||
|
from . placebo_fixtures import placeboify, maybe_sleep
|
||||||
|
from ansible.modules.cloud.amazon import aws_direct_connect_link_aggregation_group as lag_module
|
||||||
|
from ansible.module_utils.ec2 import get_aws_connection_info, boto3_conn
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def dependencies():
|
||||||
|
|
||||||
|
# each LAG dict will contain the keys: module, connections, virtual_interfaces
|
||||||
|
Dependencies = collections.namedtuple("Dependencies", ["lag_1", "lag_2"])
|
||||||
|
lag_1 = dict()
|
||||||
|
lag_2 = dict()
|
||||||
|
|
||||||
|
vanilla_params = {"name": "ansible_lag_1",
|
||||||
|
"location": "EqSe2",
|
||||||
|
"num_connections": 1,
|
||||||
|
"min_links": 0,
|
||||||
|
"bandwidth": "1Gbps"}
|
||||||
|
|
||||||
|
for lag in ("ansible_lag_1", "ansible_lag_2"):
|
||||||
|
params = dict(vanilla_params)
|
||||||
|
params["name"] = lag
|
||||||
|
if lag == "ansible_lag_1":
|
||||||
|
lag_1["module"] = FakeModule(**params)
|
||||||
|
else:
|
||||||
|
lag_2["module"] = FakeModule(**params)
|
||||||
|
|
||||||
|
if os.getenv("PLACEBO_RECORD"):
|
||||||
|
region, ec2_url, aws_connect_kwargs = get_aws_connection_info(lag_1["module"], boto3=True)
|
||||||
|
client = boto3_conn(lag_1["module"], conn_type="client", resource="directconnect", region=region, endpoint=ec2_url, **aws_connect_kwargs)
|
||||||
|
# See if link aggregation groups exist
|
||||||
|
for name in ("ansible_lag_1", "ansible_lag_2"):
|
||||||
|
lag_id = lag_module.create_lag(client, num_connections=1, location="EqSe2", bandwidth="1Gbps", name=name, connection_id=None)
|
||||||
|
if name == "ansible_lag_1":
|
||||||
|
lag_1["lag_id"] = lag_id
|
||||||
|
lag_1["name"] = name
|
||||||
|
else:
|
||||||
|
lag_2["lag_id"] = lag_id
|
||||||
|
lag_2["name"] = name
|
||||||
|
yield Dependencies(lag_1=lag_1, lag_2=lag_2)
|
||||||
|
else:
|
||||||
|
lag_1.update(lag_id="dxlag-fgkk4dja", name="ansible_lag_1")
|
||||||
|
lag_2.update(lag_id="dxlag-fgytkicv", name="ansible_lag_2")
|
||||||
|
yield Dependencies(lag_1=lag_1, lag_2=lag_2)
|
||||||
|
|
||||||
|
if os.getenv("PLACEBO_RECORD"):
|
||||||
|
# clean up
|
||||||
|
lag_module.ensure_absent(client, lag_1["lag_id"], lag_1["name"], True, True, True, 120)
|
||||||
|
lag_module.ensure_absent(client, lag_2["lag_id"], lag_2["name"], True, True, True, 120)
|
||||||
|
|
||||||
|
|
||||||
|
class FakeModule(object):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self.params = kwargs
|
||||||
|
|
||||||
|
def fail_json(self, *args, **kwargs):
|
||||||
|
self.exit_args = args
|
||||||
|
self.exit_kwargs = kwargs
|
||||||
|
raise Exception("FAIL")
|
||||||
|
|
||||||
|
def exit_json(self, *args, **kwargs):
|
||||||
|
self.exit_args = args
|
||||||
|
self.exit_kwargs = kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def test_nonexistent_lag_status(placeboify, maybe_sleep):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
exists = lag_module.lag_exists(client=client,
|
||||||
|
lag_id="doesntexist",
|
||||||
|
lag_name="doesntexist",
|
||||||
|
verify=True)
|
||||||
|
assert not exists
|
||||||
|
|
||||||
|
|
||||||
|
def test_lag_status(placeboify, maybe_sleep, dependencies):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
status = lag_module.lag_status(client, lag_id=dependencies.lag_1.get("lag_id"))
|
||||||
|
assert status.get("lagId") == dependencies.lag_1.get("lag_id")
|
||||||
|
assert status.get("lagName") == "ansible_lag_1"
|
||||||
|
|
||||||
|
|
||||||
|
def test_lag_exists(placeboify, maybe_sleep, dependencies):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
exists = lag_module.lag_exists(client=client,
|
||||||
|
lag_id=dependencies.lag_1.get("lag_id"),
|
||||||
|
lag_name=None,
|
||||||
|
verify=True)
|
||||||
|
assert exists
|
||||||
|
|
||||||
|
|
||||||
|
def test_lag_exists_using_name(placeboify, maybe_sleep, dependencies):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
exists = lag_module.lag_exists(client=client,
|
||||||
|
lag_id=None,
|
||||||
|
lag_name=dependencies.lag_1.get("name"),
|
||||||
|
verify=True)
|
||||||
|
assert exists
|
||||||
|
|
||||||
|
|
||||||
|
def test_nonexistent_lag_does_not_exist(placeboify, maybe_sleep):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
exists = lag_module.lag_exists(client=client,
|
||||||
|
lag_id="dxlag-XXXXXXXX",
|
||||||
|
lag_name="doesntexist",
|
||||||
|
verify=True)
|
||||||
|
assert not exists
|
||||||
|
|
||||||
|
|
||||||
|
def test_lag_changed_true(placeboify, maybe_sleep, dependencies):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
status = lag_module.lag_status(client=client, lag_id=dependencies.lag_1.get("lag_id"))
|
||||||
|
assert lag_module.lag_changed(status, "new_name", 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_lag_changed_true_no(placeboify, maybe_sleep, dependencies):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
status = lag_module.lag_status(client=client, lag_id=dependencies.lag_1.get("lag_id"))
|
||||||
|
assert not lag_module.lag_changed(status, "ansible_lag_1", 0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_update_lag(placeboify, maybe_sleep, dependencies):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
status_before = lag_module.lag_status(client=client, lag_id=dependencies.lag_2.get("lag_id"))
|
||||||
|
lag_module.update_lag(client,
|
||||||
|
lag_id=dependencies.lag_2.get("lag_id"),
|
||||||
|
lag_name="ansible_lag_2_update",
|
||||||
|
min_links=0,
|
||||||
|
wait=False,
|
||||||
|
wait_timeout=0,
|
||||||
|
num_connections=1)
|
||||||
|
status_after = lag_module.lag_status(client=client, lag_id=dependencies.lag_2.get("lag_id"))
|
||||||
|
assert status_before != status_after
|
||||||
|
|
||||||
|
# remove the lag name from the statuses and verify it was the only thing changed
|
||||||
|
del status_before['lagName']
|
||||||
|
del status_after['lagName']
|
||||||
|
assert status_before == status_after
|
||||||
|
|
||||||
|
|
||||||
|
def test_delete_nonexistent_lag(placeboify, maybe_sleep):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
changed = lag_module.ensure_absent(client, "dxlag-XXXXXXXX", "doesntexist", True, True, True, 120)
|
||||||
|
assert not changed
|
||||||
|
|
||||||
|
|
||||||
|
def test_delete_lag_with_connections_without_force_delete(placeboify, maybe_sleep, dependencies):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
with pytest.raises(Exception) as error_message:
|
||||||
|
lag_module.ensure_absent(client, dependencies.lag_1.get("lag_id"), "ansible_lag_1", False, True, True, 120)
|
||||||
|
assert "To force deletion of the LAG use delete_force: True" in error_message
|
||||||
|
|
||||||
|
|
||||||
|
def test_delete_lag_with_connections(placeboify, maybe_sleep, dependencies):
|
||||||
|
client = placeboify.client("directconnect")
|
||||||
|
changed = lag_module.ensure_absent(client, dependencies.lag_1.get("lag_id"), "ansible_lag_1", True, True, True, 120)
|
||||||
|
assert changed
|
Loading…
Reference in a new issue