Current section

Files

Jump to
nextroll_erlcloud src erlcloud_directconnect.erl
Raw

src/erlcloud_directconnect.erl

-module(erlcloud_directconnect).
%%% Library initialization.
-export([
new/2, new/4, configure/2
]).
%% DirectConnect API
-export([
describe_connections/0, describe_connections/1, describe_connections/2,
describe_connections_on_interconnect/1, describe_connections_on_interconnect/2,
describe_interconnects/0, describe_interconnects/1, describe_interconnects/2,
describe_locations/0, describe_locations/1,
describe_virtual_gateways/0, describe_virtual_gateways/1,
describe_virtual_interfaces/0, describe_virtual_interfaces/1, describe_virtual_interfaces/2
]).
-define(API_VERSION, "2012-10-25").
-define(SERVICE_NAME, "directconnect").
-define(API_PREFIX, "OvertureService.").
-include("erlcloud.hrl").
-include("erlcloud_aws.hrl").
%%%------------------------------------------------------------------------------
%%% Shared types
%%%------------------------------------------------------------------------------
-type connection() :: proplist().
-type interconnect() :: proplist().
-type location() :: proplist().
-type virtual_gateway() :: proplist().
-type virtual_interface() :: proplist().
-export_type([
connection/0,
interconnect/0,
location/0,
virtual_gateway/0,
virtual_interface/0
]).
%%%------------------------------------------------------------------------------
%%% Library initialization
%%%------------------------------------------------------------------------------
-spec configure(string(), string()) -> ok.
configure(AccessKeyID, SecretAccessKey) ->
put(aws_config, new(AccessKeyID, SecretAccessKey)),
ok.
-spec new(string(), string()) -> aws_config().
new(AccessKeyID, SecretAccessKey) ->
#aws_config{
access_key_id = AccessKeyID,
secret_access_key = SecretAccessKey
}.
-spec new(string(), string(), string(), non_neg_integer()) -> aws_config().
new(AccessKeyID, SecretAccessKey, Host, Port) ->
#aws_config{
access_key_id = AccessKeyID,
secret_access_key = SecretAccessKey,
directconnect_host = Host,
directconnect_port = Port
}.
%%%==============================================================================
%%% API Functions
%%%==============================================================================
%%%------------------------------------------------------------------------------
%%% DescribeConnections
%%%------------------------------------------------------------------------------
%%------------------------------------------------------------------------------
%% @doc
%% DirectConnect API:
%% http://docs.aws.amazon.com/directconnect/latest/APIReference/API_DescribeConnections.html
%%
%% ===Example===
%%
%% Get all connections:
%%
%% {ok, Connections} = erlcloud_directconnect:describe_connections().
%%
%% Get specific connection:
%%
%% {ok, [Connection]} =
%% erlcloud_directconnect:describe_connections("dxcon-fg5678gh").
%%
%%------------------------------------------------------------------------------
-spec describe_connections() ->
{ok, [connection()]} | {error, term()}.
describe_connections() ->
describe_connections(default_config()).
-spec describe_connections(aws_config() | string() | none) ->
{ok, [connection()]} | {error, term()}.
describe_connections(Config) when is_record(Config, aws_config) ->
describe_connections(none, Config);
describe_connections(ConnectionId) ->
describe_connections(ConnectionId, default_config()).
-spec describe_connections(string() | none, aws_config()) ->
{ok, [connection()]} | {error, term()}.
describe_connections(ConnectionId, Config) ->
Params = [{<<"connectionId">>, ConnectionId}],
case dc_query("DescribeConnections", Params, Config) of
{ok, Response} ->
Connections = proplists:get_value(<<"connections">>, Response),
{ok, [ extract_connection(C) || C <- Connections ]};
{error, Reason} ->
{error, Reason}
end.
%%%------------------------------------------------------------------------------
%%% DescribeConnectionsOnInterconnect
%%%------------------------------------------------------------------------------
%%------------------------------------------------------------------------------
%% @doc
%% DirectConnect API:
%% http://docs.aws.amazon.com/directconnect/latest/APIReference/API_DescribeConnectionsOnInterconnect.html
%%
%% ===Example===
%%
%% Get all connections for specific interconnect:
%%
%% {ok, Connections} =
%% erlcloud_directconnect:describe_connections_on_interconnect("dxcon-abc123").
%%
%%------------------------------------------------------------------------------
-spec describe_connections_on_interconnect(string()) ->
{ok, [connection()]} | {error, term()}.
describe_connections_on_interconnect(InterconnectId) ->
describe_connections_on_interconnect(InterconnectId, default_config()).
-spec describe_connections_on_interconnect(string(), aws_config()) ->
{ok, [connection()]} | {error, term()}.
describe_connections_on_interconnect(InterconnectId, Config) ->
Params = [{<<"interconnectId">>, InterconnectId}],
case dc_query("DescribeConnectionsOnInterconnect", Params, Config) of
{ok, Response} ->
Connections = proplists:get_value(<<"connections">>, Response),
{ok, [ extract_connection(C) || C <- Connections ]};
{error, Reason} ->
{error, Reason}
end.
%%%------------------------------------------------------------------------------
%%% DescribeInterconnects
%%%------------------------------------------------------------------------------
%%------------------------------------------------------------------------------
%% @doc
%% DirectConnect API:
%% http://docs.aws.amazon.com/directconnect/latest/APIReference/API_DescribeInterconnects.html
%%
%% ===Example===
%%
%% Get all interconnects:
%%
%% {ok, InterConnects} = erlcloud_directconnect:describe_interconnects().
%%
%% Get specific interconnect:
%%
%% {ok, [InterConnect]} =
%% erlcloud_directconnect:describe_interconnects("dxcon-abc123").
%%
%%------------------------------------------------------------------------------
-spec describe_interconnects() ->
{ok, [interconnect()]} | {error, term()}.
describe_interconnects() ->
describe_interconnects(default_config()).
-spec describe_interconnects(aws_config() | string() | none) ->
{ok, [interconnect()]} | {error, term()}.
describe_interconnects(Config) when is_record(Config, aws_config) ->
describe_interconnects(none, Config);
describe_interconnects(InterconnectId) ->
describe_interconnects(InterconnectId, default_config()).
-spec describe_interconnects(string() | none, aws_config()) ->
{ok, [interconnect()]} | {error, term()}.
describe_interconnects(InterconnectId, Config) ->
Params = [{<<"interconnectId">>, InterconnectId}],
case dc_query("DescribeInterconnects", Params, Config) of
{ok, Response} ->
Interconnects = proplists:get_value(<<"interconnects">>, Response),
{ok, [ extract_interconnect(I) || I <- Interconnects ]};
{error, Reason} ->
{error, Reason}
end.
%%%------------------------------------------------------------------------------
%%% DescribeLocations
%%%------------------------------------------------------------------------------
%%------------------------------------------------------------------------------
%% @doc
%% DirectConnect API:
%% http://docs.aws.amazon.com/directconnect/latest/APIReference/API_DescribeLocations.html
%%
%% ===Example===
%%
%% Get all locations:
%%
%% {ok, Locations} = erlcloud_directconnect:describe_locations().
%%
%%------------------------------------------------------------------------------
-spec describe_locations() -> {ok, [location()]} | {error, term()}.
describe_locations() ->
describe_locations(default_config()).
-spec describe_locations(aws_config()) -> {ok, [location()]} | {error, term()}.
describe_locations(Config) ->
case dc_query("DescribeLocations", [], Config) of
{ok, Response} ->
Locations = proplists:get_value(<<"locations">>, Response),
{ok, [ extract_location(L) || L <- Locations ]};
{error, Reason} ->
{error, Reason}
end.
%%%------------------------------------------------------------------------------
%%% DescribeVirtualGateways
%%%------------------------------------------------------------------------------
%%------------------------------------------------------------------------------
%% @doc
%% DirectConnect API:
%% http://docs.aws.amazon.com/directconnect/latest/APIReference/API_DescribeVirtualGateways.html
%%
%% ===Example===
%%
%% Get all virtual gateways:
%%
%% {ok, VirtualGateways} = erlcloud_directconnect:describe_virtual_gateways().
%%
%%------------------------------------------------------------------------------
-spec describe_virtual_gateways() ->
{ok, [virtual_gateway()]} | {error, term()}.
describe_virtual_gateways() ->
describe_virtual_gateways(default_config()).
-spec describe_virtual_gateways(aws_config()) ->
{ok, [virtual_gateway()]} | {error, term()}.
describe_virtual_gateways(Config) ->
case dc_query("DescribeVirtualGateways", [], Config) of
{ok, Response} ->
VGateways = proplists:get_value(<<"virtualGateways">>, Response),
{ok, [ extract_virtual_gateways(V) || V <- VGateways ]};
{error, Reason} ->
{error, Reason}
end.
%%%------------------------------------------------------------------------------
%%% DescribeVirtualInterfaces
%%%------------------------------------------------------------------------------
%%------------------------------------------------------------------------------
%% @doc
%% DirectConnect API:
%% http://docs.aws.amazon.com/directconnect/latest/APIReference/API_DescribeVirtualInterfaces.html
%%
%% ===Example===
%%
%% Get all virtual interfaces:
%%
%% {ok, VirtualInterfaces} = erlcloud_directconnect:describe_virtual_interfaces().
%%
%%
%% Get virtual intefafaces for specific connection:
%%
%% {ok, VirtualInterfaces} =
%% erlcloud_directconnect:describe_virtual_interfaces("dxcon-fg5678gh").
%%
%%
%% Get specific virtual interface by id:
%%
%% {ok, [VirtualInterface]} =
%% erlcloud_directconnect:describe_virtual_interfaces(none, "dxvif-123dfg56").
%%
%%------------------------------------------------------------------------------
-spec describe_virtual_interfaces() ->
{ok, [virtual_interface()]} | {error, term()}.
describe_virtual_interfaces() ->
describe_virtual_interfaces(default_config()).
-spec describe_virtual_interfaces(aws_config() | string() | none) ->
{ok, [virtual_interface()]} | {error, term()}.
describe_virtual_interfaces(Config) when is_record(Config, aws_config) ->
describe_virtual_interfaces(none, Config);
describe_virtual_interfaces(ConnectionId) ->
describe_virtual_interfaces(ConnectionId, default_config()).
-spec describe_virtual_interfaces(
string() | none, aws_config() | string() | none) ->
{ok, [virtual_interface()]} | {error, term()}.
describe_virtual_interfaces(ConnectionId, Config)
when is_record(Config, aws_config) ->
describe_virtual_interfaces(ConnectionId, none, Config);
describe_virtual_interfaces(ConnectionId, VirtualInterfaceId) ->
describe_virtual_interfaces(ConnectionId, VirtualInterfaceId,
default_config()).
-spec describe_virtual_interfaces(
string() | none, string() | none, aws_config()) ->
{ok, [virtual_interface()]} | {error, term()}.
describe_virtual_interfaces(ConnectionId, VirtualInterfaceId, Config) ->
Params = [{<<"connectionId">>, ConnectionId},
{<<"virtualInterfaceId">>, VirtualInterfaceId}],
case dc_query("DescribeVirtualInterfaces", Params, Config) of
{ok, Response} ->
VIs = proplists:get_value(<<"virtualInterfaces">>, Response),
{ok, [ extract_virtual_interface(VI) || VI <- VIs ]};
{error, Reason} ->
{error, Reason}
end.
%%%------------------------------------------------------------------------------
%%% Internal functions
%%%------------------------------------------------------------------------------
extract_connection(J) ->
erlcloud_json:decode(
[
{bandwidth, <<"bandwidth">>, optional_string},
{connection_id, <<"connectionId">>, optional_string},
{connection_name, <<"connectionName">>, optional_string},
{connection_state, <<"connectionState">>, optional_string},
{location, <<"location">>, optional_string},
{owner_account, <<"ownerAccount">>, optional_string},
{partner_name, <<"partnerName">>, optional_string},
{region, <<"region">>, optional_string},
{vlan, <<"vlan">>, optional_integer}
], J).
extract_interconnect(J) ->
erlcloud_json:decode(
[
{bandwidth, <<"bandwidth">>, optional_string},
{interconnect_id, <<"interconnectId">>, optional_string},
{interconnect_name, <<"interconnectName">>, optional_string},
{interconnect_state, <<"interconnectState">>, optional_string},
{location, <<"location">>, optional_string},
{region, <<"region">>, optional_string}
], J).
extract_location(J) ->
erlcloud_json:decode(
[
{location_code, <<"locationCode">>, optional_string},
{location_name, <<"locationName">>, optional_string}
], J).
extract_virtual_gateways(J) ->
erlcloud_json:decode(
[
{virtual_gateway_id, <<"virtualGatewayId">>, optional_string},
{virtual_gateway_state, <<"virtualGatewayState">>, optional_string}
], J).
extract_virtual_interface(J) ->
erlcloud_json:decode(
[
{amazon_address, <<"amazonAddress">>, optional_string},
{asn, <<"asn">>, optional_integer},
{auth_key, <<"authKey">>, optional_string},
{connection_id, <<"connectionId">>, optional_string},
{customer_address, <<"customerAddress">>, optional_string},
{customer_router_config, <<"customerRouterConfig">>, optional_string},
{location, <<"location">>, optional_string},
{owner_account, <<"ownerAccount">>, optional_string},
{route_filter_prefixes, <<"routeFilterPrefixes">>,
{optional_map, fun extract_route_filter_prefixes/1}},
{virtual_gateway_id, <<"virtualGatewayId">>, optional_string},
{virtual_interface_id, <<"virtualInterfaceId">>, optional_string},
{virtual_interface_name, <<"virtualInterfaceName">>, optional_string},
{virtual_interface_state, <<"virtualInterfaceState">>, optional_string},
{virtual_interface_type, <<"virtualInterfaceType">>, optional_string},
{vlan, <<"vlan">>, optional_integer}
], J).
extract_route_filter_prefixes(J) ->
erlcloud_json:decode(
[
{cidr, <<"cidr">>, optional_string}
], J).
prepare_query_params({_K, none}) ->
false;
prepare_query_params({K, V}) when is_integer(V) ->
{true, {K, V}};
prepare_query_params({K, V}) when is_list(V) ->
{true, {K, list_to_binary(V)}}.
default_config() ->
erlcloud_aws:default_config().
dc_query(Operation, Params, Config) ->
Body = case lists:filtermap(fun prepare_query_params/1, Params) of
[] ->
<<"{}">>;
PrepParams ->
jsx:encode(PrepParams)
end,
Headers = headers(Config, lists:flatten(?API_PREFIX, Operation), Body,
?SERVICE_NAME),
case erlcloud_aws:http_headers_body(
erlcloud_httpc:request(
url(Config), post,
[{<<"content-type">>, <<"application/x-amz-json-1.1">>} | Headers],
Body, 1000, Config)) of
{ok, {_RespHeader, RespBody}} ->
{ok, jsx:decode(RespBody, [{return_maps, false}])};
{error, Reason} ->
{error, Reason}
end.
-type headers() :: [{string(), string()}].
-spec headers(aws_config(), string(), binary(), string()) -> headers().
headers(Config, Operation, Body, Service) ->
Headers = [
{"host", Config#aws_config.directconnect_host},
{"x-amz-target", Operation}
],
Region =
erlcloud_aws:aws_region_from_host(Config#aws_config.directconnect_host),
erlcloud_aws:sign_v4_headers(Config, Headers, Body, Region, Service).
url(#aws_config{directconnect_scheme = Scheme, directconnect_host = Host} = Config) ->
lists:flatten([Scheme, Host, port_spec(Config)]).
port_spec(#aws_config{directconnect_port=80}) ->
"";
port_spec(#aws_config{directconnect_port=Port}) ->
[":", erlang:integer_to_list(Port)].