Packages

Implementations of some of pluggable modules in the Antikythera Framework, using AWS services.

Current section

Files

Jump to
Raw

lib/ec2.ex

# Copyright(c) 2015-2018 ACCESS CO., LTD. All rights reserved.
use Croma
alias Croma.Result, as: R
defmodule AntikytheraAws.Ec2.ClusterConfiguration do
@behaviour AntikytheraEal.ClusterConfiguration.Behaviour
alias Antikythera.Httpc
require AntikytheraCore.Logger, as: L
@region Application.fetch_env!(:antikythera_aws, :region)
@auto_scaling_group_name Application.fetch_env!(:antikythera_aws, :auto_scaling_group_name)
@availability_zone_metadata_url "http://169.254.169.254/latest/meta-data/placement/availability-zone"
@impl true
defun running_hosts() :: R.t(%{String.t => boolean}) do
run_cli(["autoscaling", "describe-auto-scaling-groups", "--auto-scaling-group-names", @auto_scaling_group_name], fn j1 ->
id_status_map = make_id_status_map(j1)
run_cli(["ec2", "describe-instances", "--instance-ids" | Map.keys(id_status_map)], fn j2 ->
make_id_private_dns_name_map(j2)
|> Map.new(fn {id, dns_name} -> {dns_name, Map.fetch!(id_status_map, id)} end)
|> R.pure()
end)
end)
end
defp run_cli(args, f) do
args_all = ["--region", @region | args]
case System.cmd("aws", args_all, [stderr_to_stdout: true]) do
{json, 0} -> f.(Poison.decode!(json))
{output, _nonzero} ->
L.error("aws-cli with args #{inspect(args_all)} returned nonzero status: #{output}")
{:error, :script_error}
end
end
defp make_id_status_map(decoded) do
decoded
|> Map.fetch!("AutoScalingGroups")
|> hd() # Only 1 auto scaling group name is given to aws-cli describe-auto-scaling-groups command
|> Map.fetch!("Instances")
|> Map.new(fn %{"InstanceId" => id, "LifecycleState" => state} -> {id, state == "InService"} end)
end
defp make_id_private_dns_name_map(decoded) do
decoded
|> Map.fetch!("Reservations")
|> Enum.flat_map(fn %{"Instances" => is} -> is end)
|> Map.new(fn %{"InstanceId" => id, "PrivateDnsName" => name} -> {id, name} end)
end
@impl true
defun zone_of_this_host() :: String.t do
%Httpc.Response{body: body} = Httpc.get!(@availability_zone_metadata_url)
body
end
end