Current section
Files
Jump to
Current section
Files
lib/compute_engine/impl.ex
defmodule GCloudex.ComputeEngine.Impl do
@moduledoc """
"""
defmacro __using__(:compute_engine) do
quote do
use GCloudex.ComputeEngine.Request
@project_id GCloudex.get_project_id
@instance_ep "https://www.googleapis.com/compute/v1/projects/#{@project_id}/zones"
@no_zone_ep "https://www.googleapis.com/compute/v1/projects/#{@project_id}"
###################
### Autoscalers ###
###################
@doc """
Retrieves a list of autoscalers contained within the specified 'zone' and
according to the 'query_params' if provided.
"""
@spec list_autoscalers(zone :: binary, query_params :: map) :: HTTPResponse.t
def list_autoscalers(zone, query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/zones/#{zone}/autoscalers", [], "", query
end
@doc """
Returns the specified 'autoscaler' resource if it exists in the given 'zone'.
"""
@spec get_autoscaler(zone :: binary, autoscaler :: binary, fields :: binary) :: HTTPResponse.t
def get_autoscaler(zone, autoscaler, fields \\ "") do
query = fields_binary_to_map fields
request :get, @no_zone_ep <> "/zones/#{zone}/autoscalers/#{autoscaler}", [], "", query
end
@doc """
Creates an autoscaler in the given 'zone' using the data provided in
'autoscaler_resource'.
For the properties and structure of the 'autoscaler_resource' check
https://cloud.google.com/compute/docs/reference/latest/autoscalers#resource
"""
@spec insert_autoscaler(zone :: binary, autoscaler_resource :: Map.t, fields :: binary) :: HTTPResponse.t | no_return
def insert_autoscaler(zone, autoscaler_resource, fields \\ "") do
query = fields_binary_to_map fields
body = autoscaler_resource |> Poison.encode!
request(
:post,
@no_zone_ep <> "/zones/#{zone}/autoscalers",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Updates 'autoscaler_name' in the specified 'zone' using the data included in
the 'autoscaler_resource'. This function supports patch semantics.
"""
@spec patch_autoscaler(zone :: binary, autoscaler_name :: binary, autoscaler_resource :: Map.t, fields :: binary) :: HTTPResponse.t
def patch_autoscaler(zone, autoscaler_name, autoscaler_resource, fields \\ "") do
query =
if fields == "" do
%{"autoscaler" => autoscaler_name} |> URI.encode_query
else
%{"autoscaler" => autoscaler_name, "fields" => fields} |> URI.encode_query
end
body = autoscaler_resource |> Poison.encode!
request(
:patch,
@no_zone_ep <> "/zones/#{zone}/autoscalers",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Updates an autoscaler in the specified 'zone' using the data included in
the 'autoscaler_resource'. The 'autoscaler_name' may be provided but it's
optional.
"""
@spec update_autoscaler(zone :: binary, autoscaler_name :: binary, autoscaler_resource :: Map.t, fields :: binary) :: HTTPResponse.t
def update_autoscaler(zone, autoscaler_name \\ "", autoscaler_resource, fields \\ "") do
body = autoscaler_resource |> Poison.encode!
query =
case {autoscaler_name == "", fields == ""} do
{true, true} ->
""
{true, false} ->
%{"fields" => fields} |> URI.encode_query
{false, true} ->
%{"autoscaler" => autoscaler_name} |> URI.encode_query
{false, false} ->
%{"autoscaler" => autoscaler_name, "fields" => fields} |> URI.encode_query
end
request(
:put,
@no_zone_ep <> "/zones/#{zone}/autoscalers",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Deletes the specified 'autoscaler' if it exists in the given 'zone'.
"""
@spec delete_autoscaler(zone :: binary, autoscaler :: binary, fields :: binary) :: HTTPResponse.t
def delete_autoscaler(zone, autoscaler, fields \\ "") do
query = fields_binary_to_map fields
request(:delete, @no_zone_ep <> "/zones/#{zone}/autoscalers/#{autoscaler}", [], "", query)
end
@doc """
Retrieves an aggregated list of autoscalers according to the given
'query_params' if provided.
"""
@spec aggregated_list_of_autoscalers(query_params :: Map.t) :: HTTPResponse.t
def aggregated_list_of_autoscalers(query_params \\ %{}) do
query = query_params |> URI.encode_query
request(:get, @no_zone_ep <> "/aggregated/autoscalers", [], "", query)
end
#################
### DiskTypes ###
#################
@doc """
Retrieves a list of disk types available to the specified 'zone' according
to the given 'query_params' if provided.
"""
@spec list_disk_types(zone :: binary, query_params :: Map.t) :: HTTPResponse.t
def list_disk_types(zone, query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/zones/#{zone}/diskTypes", [], "", query
end
@doc """
Returns the specified 'disk_type' if it exists in the given 'zone'.
"""
@spec get_disk_type(zone :: binary, disk_type :: binary, fields :: binary) :: HTTPResponse.t
def get_disk_type(zone, disk_type, fields \\ "") do
query = fields_binary_to_map fields
request(
:get,
@no_zone_ep <> "/zones/#{zone}/diskTypes/#{disk_type}",
[],
"",
query)
end
@doc """
Retrieves an aggregated list of Disk Types according to the
'query_params' if provided.
"""
@spec aggregated_list_of_disk_types(query_params :: Map.t) :: HTTPResponse.t
def aggregated_list_of_disk_types(query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/aggregated/diskTypes", [], "", query
end
#############
### Disks ###
#############
@doc """
Retrieves a list of persistent disks contained within the specified 'zone' and
according to the given 'query_params' if provided.
"""
@spec list_disks(zone :: binary, query_params :: Map.t) :: HTTPResponse.t
def list_disks(zone, query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/zones/#{zone}/disks", [], "", query
end
@doc """
Returns a specified persistent 'disk' if it exists in the given 'zone'. The
HTTP reply contains a Disk Resource in the body.
"""
@spec get_disk(zone :: binary, disk :: binary, fields :: binary) :: HTTPResponse.t
def get_disk(zone, disk, fields \\ "") do
query = fields_binary_to_map fields
request :get, @no_zone_ep <> "/zones/#{zone}/disks/#{disk}", [], "", query
end
@doc """
Creates a persistent disk in the specified 'zone' using the data in the
'disk_resource'. You can create a disk with a 'source_image' or a
sourceSnapshot (provided in the 'disk_resource'), or create an empty 500 GB
data disk by omitting all properties. You can also create a disk that is
larger than the default size by specifying the sizeGb property in the
'disk_resource'.
"""
@spec insert_disk(zone :: binary, disk_resource :: map, source_image :: binary, fields :: binary) :: HTTPResponse.t
def insert_disk(zone, disk_resource, source_image \\ "", fields \\ "") do
if not Map.has_key?(disk_resource, "name") do
raise ArgumentError, message: "The Disk Resource must contain at least the 'name' key."
end
query =
case {source_image != "", fields != ""} do
{true, true} ->
fields_binary_to_map(fields) <> "&sourceImage=#{source_image}"
{true, false} ->
%{"sourceImage" => source_image} |> URI.encode_query
{false, true} ->
fields_binary_to_map fields
{false, false} ->
%{} |> URI.encode_query
end
body = disk_resource |> Poison.encode!
request(
:post,
@no_zone_ep <> "/zones/#{zone}/disks",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Deletes the specified persistent 'disk' if it exists in the given 'zone'.
"""
@spec delete_disk(zone :: binary, disk :: binary, fields :: binary) :: HTTPResponse.t
def delete_disk(zone, disk, fields \\ "") do
query = fields_binary_to_map fields
request :delete, @no_zone_ep <> "/zones/#{zone}/disks/#{disk}", [], "", query
end
@doc """
Resizes the specified persistent 'disk' if it exists in the given 'zone' to
the provided 'size_gb'.
"""
@spec resize_disk(zone :: binary, disk :: binary, size_gb :: pos_integer, fields :: binary) :: HTTPResponse.t
def resize_disk(zone, disk, size_gb, fields \\ "") when size_gb > 0 do
query = fields_binary_to_map fields
body = %{"sizeGb" => size_gb} |> Poison.encode!
request(
:post,
@no_zone_ep <> "/zones/#{zone}/disks/#{disk}/resize",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Retrieves an aggregated list of persistent disks according to the given
'query_params' if they're provided.
"""
@spec aggregated_list_of_disks(query_params :: Map.t) :: HTTPResponse.t
def aggregated_list_of_disks(query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/aggregated/disks", [], "", query
end
@doc """
Creates a snapshot of a specified persistent 'disk' if it exists in the
given 'zone' and according to the given 'resource'. The 'request' map must
contain the keys "name" and "description" and "name" must obey the
refex '(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)'.
"""
@spec create_snapshot(zone :: binary, disk :: binary, request :: Map.t, fields :: binary) :: HTTPResponse.t
def create_snapshot(zone, disk, request, fields \\ "") when request != %{} do
query = fields_binary_to_map fields
body = request |> Poison.encode!
request(
:post,
@no_zone_ep <> "/zones/#{zone}/disks/#{disk}/createSnapshot",
[{"Content-Type", "application/json"}],
body,
query)
end
#################
### Firewalls ###
#################
@doc """
Retrieves the list of firewall rules according to the 'query_params' if
provided.
"""
@spec list_firewalls(query_params :: Map.t) :: HTTPResponse.t
def list_firewalls(query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/global/firewalls", [], "", query
end
@doc """
Returns the specified 'firewall'.
"""
@spec get_firewall(firewall :: binary, fields :: binary) :: HTTPResponse.t
def get_firewall(firewall, fields \\ "") do
query = fields_binary_to_map fields
request :get, @no_zone_ep <> "/global/firewalls/#{firewall}", [], "", query
end
@doc """
Creates a new firewall using the data included in 'firewall_resource'. For
information about the structure and properties of Firewall Resources check
https://cloud.google.com/compute/docs/reference/latest/firewalls#resource
"""
@spec insert_firewall(firewall_resource :: Map.t, fields :: binary) :: HTTPResponse.t
def insert_firewall(firewall_resource, fields \\ "") when is_map(firewall_resource) do
query = fields_binary_to_map fields
body = firewall_resource |> Poison.encode!
request(
:post,
@no_zone_ep <> "/global/firewalls",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Updates the specified 'firewall' rule with the data included in the
'firewall_resource'. This function supports patch semantics.
"""
@spec patch_firewall(firewall :: binary, firewall_resource :: Map.t, fields :: binary) :: HTTPResponse.t
def patch_firewall(firewall, firewall_resource, fields \\ "") when is_map(firewall_resource) do
query = fields_binary_to_map fields
body = firewall_resource |> Poison.encode!
request(
:patch,
@no_zone_ep <> "/global/firewalls/#{firewall}",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Updates the specified 'firewall' rule with the data included in the
'firewall_resource'.
"""
@spec update_firewall(firewall :: binary, firewall_resource :: map, fields :: binary) :: HTTPResponse.t
def update_firewall(firewall, firewall_resource, fields \\ "") when is_map(firewall_resource) do
query = fields_binary_to_map fields
body = firewall_resource |> Poison.encode!
request(
:put,
@no_zone_ep <> "/global/firewalls/#{firewall}",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Deletes the specified 'firewall'.
"""
@spec delete_firewall(firewall :: binary, fields :: binary) :: HTTPResponse.t
def delete_firewall(firewall, fields \\ "") do
query = fields_binary_to_map fields
request(
:delete,
@no_zone_ep <> "/global/firewalls/#{firewall}",
[],
"",
query)
end
##############
### Images ###
##############
@doc """
Retrieves the list of private images available (project scoped only).
"""
@spec list_images(query_params :: Map.t) :: HTTPResponse.t
def list_images(query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/global/images", [], "", query
end
@doc """
Returns the specified 'image'.
"""
@spec get_image(image :: binary, fields :: binary) :: HTTPResponse.t
def get_image(image, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(:get, @no_zone_ep <> "/global/images/#{image}", [], "", query)
end
@doc """
Creates an image with the provided 'image_resource'.
"""
@spec insert_image_with_resource(image_resource :: Map.t, fields :: binary) :: HTTPResponse.t
def insert_image_with_resource(image_resource, fields \\ "") when is_map(image_resource) do
body = image_resource |> Poison.encode!
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@no_zone_ep <> "/global/images",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Creates an image with the given 'name' and 'source_url'. This function uses
the minimal amount of parameters needed to build the image. For a more
detailed image creation use insert_image_with_resource/2 where more complex
Image Resources can be passed.
"""
@spec insert_image(name :: binary, source_url :: binary, fields :: binary) :: HTTPResponse.t
def insert_image(name, source_url, fields \\ "") do
body = %{"name" => name, "rawDisk" => %{"source" => source_url}} |> Poison.encode!
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@no_zone_ep <> "/global/images",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Deletes the specified 'image'.
"""
@spec delete_image(image :: binary, fields :: binary) :: HTTPResponse.t
def delete_image(image, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(:delete, @no_zone_ep <> "/global/images/#{image}", [], "", query)
end
@doc """
Sets the deprecation status of an 'image' using the data provided in the
'request_params'.
"""
@spec deprecate_image(image :: binary, request_params :: Map.t, fields :: binary) :: HTTPResponse.t
def deprecate_image(image, request_params, fields \\ "") do
body = request_params |> Poison.encode!
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@no_zone_ep <> "/global/images/#{image}/deprecate",
[{"Content-Type", "application/json"}],
body,
query)
end
######################
### InstanceGroups ###
######################
@doc """
Retrieves the list of instance groups that are located in the
specified 'zone'.
"""
@spec list_instance_groups(zone :: binary, query_params :: Map.t) :: HTTPResponse.t
def list_instance_groups(zone, query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/zones/#{zone}/instanceGroups", [], "", query
end
@doc """
Lists the instances in the specified 'instance_group' if it exists in the
given 'zone'. A filter for the state of the instances can be passed
through 'instance_state'.
"""
@spec list_instances_in_group(zone :: binary, instance_group :: binary, instance_state :: binary, query_params :: Map.t) :: HTTPResponse.t
def list_instances_in_group(zone, instance_group, instance_state \\ "", query_params \\ %{}) do
query = query_params |> URI.encode_query
body = %{"instanceState" => instance_state} |> Poison.encode!
request(
:post,
@no_zone_ep <> "/zones/#{zone}/instanceGroups/#{instance_group}/listInstances",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Returns the specified 'instance_group' if it exists in the given 'zone'.
"""
@spec get_instance_group(zone :: binary, instance_group :: binary, fields :: binary) :: HTTPResponse.t
def get_instance_group(zone, instance_group, fields \\ "") do
query = fields_binary_to_map fields
request(:get, @no_zone_ep <> "/zones/#{zone}/instanceGroups/#{instance_group}", [], "", query)
end
@doc """
Creates an Instance Group in the specified 'zone' using the data provided
in 'instance_group_resource'. For the structure and properties required in
the Instance Group Resources check
https://cloud.google.com/compute/docs/reference/latest/instanceGroups#resource
"""
@spec insert_instance_group(zone :: binary, instance_group_resource :: map, fields :: binary) :: HTTPResponse.t
def insert_instance_group(zone, instance_group_resource, fields \\ "") when is_map(instance_group_resource) do
query = fields_binary_to_map fields
body = instance_group_resource |> Poison.encode!
request(
:post,
@no_zone_ep <> "/zones/#{zone}/instanceGroups",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Deletes the specified 'instance_group' if it exists in the given 'zone'.
"""
@spec delete_instance_group(zone :: binary, instance_group :: binary, fields :: binary) :: HTTPResponse.t
def delete_instance_group(zone, instance_group, fields \\ "") do
query = fields_binary_to_map fields
request(
:delete,
@no_zone_ep <> "/zones/#{zone}/instanceGroups/#{instance_group}",
[],
"",
query)
end
@doc """
Retrieves the list of Instance Groups and sorts them by zone.
"""
@spec aggregated_list_of_instance_groups(query_params :: Map.t) :: HTTPResponse.t
def aggregated_list_of_instance_groups(query_params \\ %{}) do
query = query_params |> URI.encode_query
request(:get, @no_zone_ep <> "/aggregated/instanceGroups", [], "", query)
end
@doc """
Adds a list of 'instances' to the specified 'instance_group' if it exists in
the given 'zone'.
"""
@spec add_instances_to_group(zone :: binary, instance_group :: binary, instances :: [binary], fields :: binary) :: HTTPResponse.t
def add_instances_to_group(zone, instance_group, instances, fields \\ "") do
query = fields_binary_to_map fields
body = %{"instances" => build_list_of_instances(instances, [])}
|> Poison.encode!
request(
:post,
@no_zone_ep <> "/zones/#{zone}/instanceGroups/#{instance_group}/addInstances",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Removes the 'instances' from the provided 'instance_group' if it exists in
the given 'zone'.
"""
@spec remove_instances_from_group(zone :: binary, insance_group :: binary, instances :: [binary], fields :: binary) :: HTTPResponse.t
def remove_instances_from_group(zone, instance_group, instances, fields \\ "") do
query = fields_binary_to_map fields
body = %{"instances" => build_list_of_instances(instances, [])}
|> Poison.encode!
request(
:post,
@no_zone_ep <> "/zones/#{zone}/instanceGroups/#{instance_group}/removeInstances",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Sets the named 'ports' for the specified 'instance_group' if it exists in the
given 'zone'. The 'ports' must be passed as a list of tuples with the format
{<name>, <port>}.
"""
@spec set_named_ports_for_group(zone :: binary, instance_group :: binary, ports :: [{name :: binary, port :: binary}], fingerprint :: binary, fields :: binary) :: HTTPResponse.t
def set_named_ports_for_group(zone, instance_group, ports, fingerprint \\ "", fields \\ "") do
query = fields_binary_to_map fields
body = %{"namedPorts" => build_list_of_ports(ports, [])}
body =
if fingerprint != "" do
body |> Map.put_new("fingerprint", fingerprint) |> Poison.encode!
else
body |> Poison.encode!
end
request(
:post,
@no_zone_ep <> "/zones/#{zone}/instanceGroups/#{instance_group}/setNamedPorts",
[{"Content-Type", "application/json"}],
body,
query)
end
defp build_list_of_instances([head | []], state), do: state ++ [%{"instance" => head}]
defp build_list_of_instances([head | tail], state) do
build_list_of_instances tail, state ++ [%{"instance" => head}]
end
defp build_list_of_ports([_head = {name, port} | []], state), do: state ++ [%{"name" => name, "port" => port}]
defp build_list_of_ports([_head = {name, port} | tail], state) do
build_list_of_ports tail, state ++ [%{"name" => name, "port" => port}]
end
#################
### Instances ###
#################
@doc """
Lists all instances in the given 'zone' obeying the given 'query_params' if
present.
"""
@spec list_instances(zone :: binary, query_params :: Map.t) :: HTTPResponse.t
def list_instances(zone, query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @instance_ep <> "/#{zone}/instances", [], "", query
end
@doc """
Returns the data about the 'instance' in the given 'zone' if it exists.
"""
@spec get_instance(zone :: binary, instance :: binary, fields :: binary) :: HTTPResponse.t
def get_instance(zone, instance, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:get,
@instance_ep <> "/#{zone}/instances/#{instance}",
[],
"",
query)
end
@doc """
Creates a new Virtual Machine instance on Google Compute Engine in the given
'zone' and with properties defined in 'instance_resource'. Example of the
minimal Instance Resource the API will accept:
%{
"disks" =>
[
%{
"autoDelete" => true, "boot" => true,
"initializeParams" =>
%{
"sourceImage" =>
"projects/debian-cloud/global/images/debian-8-jessie-v20160119"
},
"type" => "PERSISTENT"
}
],
"machineType" => "zones/europe-west1-d/machineTypes/f1-micro",
"name" => "example-instance",
"networkInterfaces" =>
[
%{
"accessConfigs" =>
[
%{
"name" => "External NAT",
"type" => "ONE_TO_ONE_NAT"
}
],
"network" => "global/networks/default"
}
]
}
For the 'instance_resource' check the documentation at:
https://cloud.google.com/compute/docs/reference/latest/instances#resource
"""
@spec insert_instance(zone :: binary, instance_resource :: Map.t, fields :: binary) :: HTTPResponse.t
def insert_instance(zone, instance_resource, fields \\ "") do
body = instance_resource |> Poison.encode!
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Deletes the given 'instance' if it exists in the given 'zone'.
"""
@spec delete_instance(zone :: binary, instance :: binary, fields :: binary) :: HTTPResponse.t
def delete_instance(zone, instance, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:delete,
@instance_ep <> "/#{zone}/instances/#{instance}",
[],
"",
query)
end
@doc """
Starts a stopped 'instance' if it exists in the given 'zone'.
"""
@spec start_instance(zone :: binary, instance :: binary, fields :: binary) :: HTTPResponse.t
def start_instance(zone, instance, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/start",
[{"Content-Type", "application/json"}],
"",
query)
end
@doc """
Stops a running 'instance' if it exists in the given 'zone'.
"""
@spec stop_instance(zone :: binary, instance :: binary, fields :: binary) :: HTTPResponse.t
def stop_instance(zone, instance, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/stop",
[{"Content-Type", "application/json"}],
"",
query)
end
@doc """
Performs a hard reset on the 'instance' if it exists in the given 'zone'.
"""
@spec reset_instance(zone :: binary, instance :: binary, fields :: binary) :: HTTPResponse.t
def reset_instance(zone, instance, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/reset",
[{"Content-Type", "application/json"}],
"",
query)
end
@doc """
Adds an access config to the 'instance' if it exists in the given 'zone'. The
kind and type will automatically be added with the default (and only possible)
values.
"""
@spec add_access_config(zone :: binary, instance :: binary, network_interface :: binary, name :: binary, nat_ip :: binary, fields :: binary) :: HTTPResponse.t
def add_access_config(zone, instance, network_interface, name, nat_ip \\ "", fields \\ "") do
body =
%{
"kind" => "compute#accessConfig",
"type" => "ONE_TO_ONE_NAT",
"name" => name
}
body =
if nat_ip != "" do
body |> Map.put_new("natIP", nat_ip)
else
body
end
query =
if fields == "" do
%{"networkInterface" => network_interface} |> URI.encode_query
else
%{"networkInterface" => network_interface, "fields" => fields}
|> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/addAccessConfig",
[{"Content-Type", "application/json"}],
body |> Poison.encode!,
query)
end
@doc """
Deletes te 'access_config' from the 'instance' 'network_interface' if the
'instance' exists in the given 'zone'.
"""
@spec delete_access_config(zone :: binary, instance :: binary, access_config :: binary, network_interface :: binary, fields :: binary) :: HTTPResponse.t
def delete_access_config(zone, instance, access_config, network_interface, fields \\ "") do
query =
if fields == "" do
%{"accessConfig" => access_config, "networkInterface" => network_interface}
|> URI.encode_query
else
%{
"accessConfig" => access_config,
"networkInterface" => network_interface,
"fields" => fields
}
|> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/deleteAccessConfig",
[{"Content-Type", "application/json"}],
"",
query)
end
@doc """
Retrieves aggregated list of instances according to the specified
'query_params' if present.
"""
@spec aggregated_list_of_instances(query_params :: Map.t) :: HTTPResponse.t
def aggregated_list_of_instances(query_params \\ %{}) do
query = query_params |> URI.encode_query
request(
:get,
@no_zone_ep <> "/aggregated/instances",
[],
"",
query)
end
@doc """
Attaches the 'disk_resource' to the 'instance' if it exists in the given
'zone'.
Disk Resource structure:
{
"kind": "compute#attachedDisk",
"index": integer,
"type": string,
"mode": string,
"source": string,
"deviceName": string,
"boot": boolean,
"initializeParams": {
"diskName": string,
"sourceImage": string,
"diskSizeGb": long,
"diskType": string
},
"autoDelete": boolean,
"licenses": [
string
],
"interface": string
}
"""
@spec attach_disk(zone :: binary, instance :: binary, disk_resource :: map, fields :: binary) :: HTTPResponse.t
def attach_disk(zone, instance, disk_resource, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/attachDisk",
[{"Content-Type", "application/json"}],
disk_resource |> Poison.encode!,
query)
end
@doc """
Detaches the disk with 'device_name' from the 'instance' if it exists in the
given 'zone'.
"""
@spec detach_disk(zone :: binary, instance :: binary, device_name :: binary, fields :: binary) :: HTTPResponse.t
def detach_disk(zone, instance, device_name, fields \\ "") do
query =
if fields == "" do
%{"deviceName" => device_name} |> URI.encode_query
else
%{"deviceName" => device_name, "fields" => fields} |> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/detachDisk",
[{"Content-Type", "application/json"}],
"",
query)
end
@doc """
Sets the 'auto_delete' flag for the disk with 'device_name' attached to
'instance' if it exists in the given 'zone'.
"""
@spec set_disk_auto_delete(zone :: binary, instance :: binary, auto_delete :: boolean, device_name :: binary, fields :: binary) :: HTTPResponse.t
def set_disk_auto_delete(zone, instance, auto_delete, device_name, fields \\ "") do
query =
if fields == "" do
%{"deviceName" => device_name, "autoDelete" => auto_delete}
|> URI.encode_query
else
%{
"deviceName" => device_name,
"autoDelete" => auto_delete,
"fields" => fields
}
|> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/setDiskAutoDelete",
[{"Content-Type", "application/json"}],
"",
query)
end
@doc """
Returns the specified 'instance' serial 'port' output if the 'instance'
exists in the given 'zone'. The 'port' accepted values are from 1 to 4,
inclusive.
"""
@spec get_serial_port_output(zone :: binary, instance :: binary, port :: 1..4, fields :: binary) :: HTTPResponse.t
def get_serial_port_output(zone, instance, port \\ 1, fields \\ "") do
port =
if port == 1 do
port
else
port
end
query =
if fields == "" do
%{"port" => port} |> URI.encode_query
else
%{"port" => port, "fields" => fields} |> URI.encode_query
end
request(
:get,
@instance_ep <> "/#{zone}/instances/#{instance}/serialPort",
[],
"",
query)
end
@doc """
Changes the Machine Type for a stopped 'instance' to the specified
'machine_type' if the 'instance' exists in the given 'zone'.
"""
@spec set_machine_type(zone :: binary, instance :: binary, machine_type :: binary, fields :: binary) :: HTTPResponse.t
def set_machine_type(zone, instance, machine_type, fields \\ "") do
body = %{"machineType" => machine_type} |> Poison.encode!
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/setMachineType",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Sets metadata for the specified 'instance' to the data specified in
'fingerprint' and 'items'. The 'instance' must exist in the given 'zone'.
The 'items' should be passed as a list of maps:
[
%{
"key" => "some key value",
"value" => "some value"
},
%{
"key" => "some other key value",
"value" => "some other value"
}
]
"""
@spec set_metadata(zone :: binary, instance :: binary, fingerprint :: binary, items :: list(map), fields :: binary) :: HTTPResponse.t
def set_metadata(zone, instance, fingerprint, items, fields \\ "") do
body = %{"kind" => "compute#metadata"}
|> Map.put_new("fingerprint", fingerprint)
|> Map.put_new("items", items)
|> Poison.encode!
query =
if fields == "" do
fields
else
%{"fields" => fields}
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/setMetadata",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Sets an 'instance' scheduling options if it exists in the given 'zone'. The
'preemptible' option cannot be changed after instance creation.
"""
@spec set_scheduling(zone :: binary, instance :: binary, {on_host_maintenance :: binary, automatic_restart :: boolean, preemptible :: boolean}, fields :: binary) :: HTTPResponse.t
def set_scheduling(zone, instance, {on_host_maintenance, automatic_restart, preemptible}, fields \\ "") do
body = %{
"onHostMaintenance" => on_host_maintenance,
"automaticRestart" => automatic_restart,
"preemptible" => preemptible
}
|> Poison.encode!
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/setScheduling",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Sets tags for the specified 'instance' to the given 'fingerprint' and 'items'.
The 'instance' must exist in the given 'zone'.
"""
@spec set_tags(zone :: binary, instance :: binary, fingerprint :: binary, items :: list(binary), fields :: binary) :: HTTPResponse.t
def set_tags(zone, instance, fingerprint, items, fields \\ "") do
body = %{"fingerprint" => fingerprint, "items" => items} |> Poison.encode!
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:post,
@instance_ep <> "/#{zone}/instances/#{instance}/setTags",
[{"Content-Type", "application/json"}],
body,
query)
end
################
### Licenses ###
################
@doc """
Returns the specified 'license' resource.
"""
@spec get_license(binary, binary) :: HTTPResponse.t
def get_license(license, fields \\ "") do
query = fields_binary_to_map fields
request :get, @no_zone_ep <> "/global/licenses/#{license}", [], "", query
end
#####################
### Machine Types ###
#####################
@doc """
Retrieves a list of machine types available in the specified 'zone' and
that fit in the given 'query_params' if present.
"""
@spec list_machine_types(zone :: binary, query_params :: Map.t) :: HTTPResponse.t
def list_machine_types(zone, query_params \\ %{}) do
query = query_params |> URI.encode_query
request(:get, @instance_ep <> "/#{zone}/machineTypes", [], "", query)
end
@doc """
Returns the specified 'machine_type' in the given 'zone'.
"""
@spec get_machine_type(zone :: binary, machine_type :: binary, fields :: binary) :: HTTPResponse.t
def get_machine_type(zone, machine_type, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request(
:get,
@instance_ep <> "/#{zone}/machineTypes/#{machine_type}",
[],
"",
query)
end
@doc """
Returns an aggragated list of machine types following the specified
'query_params' if present.
"""
@spec aggregated_list_of_machine_types(query_params :: Map.t) :: HTTPResponse.t
def aggregated_list_of_machine_types(query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/aggregated/machineTypes", [], "", query
end
################
### Networks ###
################
@doc """
Retrieves the list of networks available according to the given
'query_params' if provided.
"""
@spec list_networks(query_params :: Map.t) :: HTTPResponse.t
def list_networks(query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/global/networks", [], "", query
end
@doc """
Returns the speciefied 'network'.
"""
@spec get_network(network :: binary, fields :: binary) :: HTTPResponse.t
def get_network(network, fields \\ "") do
query = fields_binary_to_map fields
request :get, @no_zone_ep <> "/global/networks/#{network}", [], "", query
end
@doc """
Creates a network using the data specified in 'network_resource'. To read
about the structure and properties of the Network Resource check
https://cloud.google.com/compute/docs/reference/latest/networks#resource.
"""
@spec insert_network(network_resource :: Map.t, fields :: binary) :: HTTPResponse.t | no_return
def insert_network(network_resource, fields \\ "") when is_map(network_resource) do
query = fields_binary_to_map fields
body = network_resource |> Poison.encode!
request(
:post,
@no_zone_ep <> "/global/networks",
[{"Content-Type", "application/json"}],
body,
query)
end
@doc """
Deletes the specified 'network'.
"""
@spec delete_network(network :: binary, fields :: binary) :: HTTPResponse.t
def delete_network(network, fields \\ "") do
query = fields_binary_to_map fields
request(
:delete,
@no_zone_ep <> "/global/networks/#{network}",
[],
"",
query)
end
###############
### Regions ###
###############
@doc """
Retrieves a list of region resources according to the given 'query_params'.
"""
@spec list_regions(query_params :: Map.t) :: HTTPResponse.t
def list_regions(query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/regions", [], "", query
end
@doc """
Returns the specified 'region' resource.
"""
@spec get_region(region :: binary, fields :: binary) :: HTTPResponse.t
def get_region(region, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request :get, @no_zone_ep <> "/regions/#{region}", [], "", query
end
#############
### Zones ###
#############
@doc """
Retrieves the list of Zone resources available according to the given
'query_params'.
"""
@spec list_zones(query_params :: Map.t) :: HTTPResponse.t
def list_zones(query_params \\ %{}) do
query = query_params |> URI.encode_query
request :get, @no_zone_ep <> "/zones", [], "", query
end
@doc """
Returns the specified 'zone' resource.
"""
@spec get_zone(zone :: binary, fields :: binary) :: HTTPResponse.t
def get_zone(zone, fields \\ "") do
query =
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
request :get, @no_zone_ep <> "/zones/#{zone}", [], "", query
end
###############
### Helpers ###
###############
defp fields_binary_to_map(fields) do
if fields == "" do
fields
else
%{"fields" => fields} |> URI.encode_query
end
end
end
end
end