2015-08-04 09:56:03 +03:00
|
|
|
require "exceptions/conflict_exception"
|
2014-05-08 15:34:26 +04:00
|
|
|
require "providers/base_provider"
|
2015-10-26 12:04:01 +03:00
|
|
|
require "db/mongo/models/provider_accounts/ec2_provider_account"
|
2015-10-26 17:14:48 +03:00
|
|
|
require_relative "ec2_accounts_factory"
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
module Provider
|
|
|
|
|
# Provider for Amazon EC2
|
|
|
|
|
class Ec2 < BaseProvider
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
PROVIDER = "ec2"
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
attr_accessor :availability_zone
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def initialize config
|
|
|
|
|
self.certificate_path = config[:aws_certificate]
|
|
|
|
|
self.ssh_key = config[:aws_ssh_key]
|
2015-08-07 11:36:50 +03:00
|
|
|
options = {
|
2015-12-07 14:14:10 +03:00
|
|
|
:provider => "aws"
|
2014-06-18 15:11:47 +04:00
|
|
|
}
|
2015-12-07 14:14:10 +03:00
|
|
|
if config[:aws_use_iam_profile]
|
|
|
|
|
options[:use_iam_profile] = true
|
|
|
|
|
else
|
|
|
|
|
options[:aws_access_key_id] = config[:aws_access_key_id]
|
|
|
|
|
options[:aws_secret_access_key] = config[:aws_secret_access_key]
|
|
|
|
|
end
|
2015-08-07 12:03:01 +03:00
|
|
|
if config[:aws_proxy] and config[:aws_no_proxy]
|
|
|
|
|
options[:connection_options] = {
|
|
|
|
|
:proxy => config[:aws_proxy],
|
|
|
|
|
:no_proxy => config[:no_proxy]
|
|
|
|
|
}
|
|
|
|
|
end
|
2015-08-07 11:36:50 +03:00
|
|
|
self.connection_options = options
|
2014-06-18 15:11:47 +04:00
|
|
|
self.availability_zone = config[:aws_availability_zone] || "us-east-1a"
|
2014-11-20 15:08:42 +03:00
|
|
|
self.run_list = config[:aws_integration_run_list] || []
|
2014-06-18 15:11:47 +04:00
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def configured?
|
|
|
|
|
o = self.connection_options
|
|
|
|
|
super and !(empty_param?(o[:aws_access_key_id]) or empty_param?(o[:aws_secret_access_key]))
|
|
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def name
|
|
|
|
|
PROVIDER
|
|
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def flavors
|
|
|
|
|
self.compute.flavors.all.map do |f|
|
|
|
|
|
{
|
|
|
|
|
"id" => f.id,
|
|
|
|
|
"cores" => f.cores,
|
|
|
|
|
"disk" => f.disk,
|
|
|
|
|
"name" => f.name,
|
|
|
|
|
"ram" => f.ram
|
|
|
|
|
}
|
2014-05-08 15:34:26 +04:00
|
|
|
end
|
2014-06-18 15:11:47 +04:00
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2015-11-17 12:14:02 +03:00
|
|
|
def groups filters={}
|
2016-01-14 14:17:19 +03:00
|
|
|
g = self.compute.describe_security_groups(filters || {})
|
2014-06-18 15:11:47 +04:00
|
|
|
convert_groups(g.body["securityGroupInfo"])
|
|
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def images filters
|
|
|
|
|
self.compute.describe_images({"image-id" => filters}).body["imagesSet"].map do |i|
|
|
|
|
|
{
|
|
|
|
|
"id" => i["imageId"],
|
|
|
|
|
"name" => i["name"],
|
|
|
|
|
"status" => i["imageState"]
|
|
|
|
|
}
|
2014-05-08 15:34:26 +04:00
|
|
|
end
|
2014-06-18 15:11:47 +04:00
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2015-11-17 12:14:02 +03:00
|
|
|
def networks filters={}
|
|
|
|
|
self.compute.describe_subnets(filters).body["subnetSet"].select{|n| n["state"] == "available"}.map do |n|
|
2014-06-18 15:11:47 +04:00
|
|
|
{
|
|
|
|
|
"cidr" => n["cidrBlock"],
|
|
|
|
|
"vpcId" => n["vpcId"],
|
|
|
|
|
"subnetId" => n["subnetId"],
|
|
|
|
|
"name" => n["subnetId"],
|
|
|
|
|
"zone" => n["availabilityZone"]
|
|
|
|
|
}
|
2014-05-08 15:34:26 +04:00
|
|
|
end
|
2014-06-18 15:11:47 +04:00
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def servers
|
|
|
|
|
list = self.compute.describe_instances.body["reservationSet"]
|
2015-10-28 14:16:56 +03:00
|
|
|
list.select{|l| l["instancesSet"][0]["instanceState"]["name"].to_s == "running"}.map do |server|
|
2014-06-18 15:11:47 +04:00
|
|
|
convert_server server["instancesSet"][0]
|
2014-05-08 15:34:26 +04:00
|
|
|
end
|
2014-06-18 15:11:47 +04:00
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def server id
|
|
|
|
|
list = self.compute.describe_instances('instance-id' => [id]).body["reservationSet"]
|
|
|
|
|
convert_server list[0]["instancesSet"][0]
|
|
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2015-08-05 17:38:32 +03:00
|
|
|
def create_server s, image, flavor, subnets, groups, out, options={}
|
2014-06-18 15:11:47 +04:00
|
|
|
out << "Creating server for project '#{s.project} - #{s.deploy_env}'\n"
|
|
|
|
|
options = {
|
2015-08-05 14:05:14 +03:00
|
|
|
"InstanceType" => flavor,
|
|
|
|
|
# "Placement.AvailabilityZone" => s.options[:availability_zone],
|
2016-01-27 15:44:59 +03:00
|
|
|
"KeyName" => self.ssh_key,
|
2016-03-15 13:22:16 +03:00
|
|
|
"PrivateIpAddress" => s.private_ip,
|
2016-03-15 17:56:58 +03:00
|
|
|
"EbsOptimized" => ebs_optimized?(flavor),
|
|
|
|
|
"BlockDeviceMapping" => ephemeral_storages_mappings(flavor)
|
2014-06-18 15:11:47 +04:00
|
|
|
}
|
|
|
|
|
vpcId = nil
|
2015-08-05 14:05:14 +03:00
|
|
|
unless subnets.empty?
|
|
|
|
|
options["SubnetId"] = subnets[0]
|
2015-11-13 17:22:55 +03:00
|
|
|
network = self.networks.detect{|n| n["name"] == options["SubnetId"]}
|
|
|
|
|
vpcId = network["vpcId"] if network
|
2014-06-18 15:11:47 +04:00
|
|
|
if vpcId.nil?
|
|
|
|
|
out << "Can not get 'vpcId' by subnet name '#{options["SubnetId"]}'\n"
|
2014-05-08 15:34:26 +04:00
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
end
|
2015-08-05 14:05:14 +03:00
|
|
|
options["SecurityGroupId"] = extract_group_ids(groups, vpcId).join(",")
|
2014-06-18 15:11:47 +04:00
|
|
|
|
|
|
|
|
aws_server = nil
|
|
|
|
|
compute = self.compute
|
|
|
|
|
begin
|
2015-08-05 14:05:14 +03:00
|
|
|
aws_server = compute.run_instances(image, 1, 1, options)
|
2014-06-18 15:11:47 +04:00
|
|
|
rescue Excon::Errors::Unauthorized => ue
|
|
|
|
|
#root = XML::Parser.string(ue.response.body).parse.root
|
|
|
|
|
#msg = root.children.find { |node| node.name == "Message" }
|
|
|
|
|
#code = root.children.find { |node| node.name == "Code" }
|
|
|
|
|
code = "TODO"
|
|
|
|
|
msg = ue.response.body
|
|
|
|
|
out << "\nERROR: Unauthorized (#{code}: #{msg})"
|
|
|
|
|
return false
|
|
|
|
|
rescue Fog::Compute::AWS::Error => e
|
|
|
|
|
out << e.message
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
abody = aws_server.body
|
|
|
|
|
instance = abody["instancesSet"][0]
|
|
|
|
|
s.id = instance["instanceId"]
|
|
|
|
|
|
|
|
|
|
out << "\nWaiting for server..."
|
|
|
|
|
|
|
|
|
|
details, state = nil, instance["instanceState"]["name"]
|
|
|
|
|
until state == "running"
|
|
|
|
|
sleep(2)
|
|
|
|
|
details = compute.describe_instances("instance-id" => [s.id]).body["reservationSet"][0]["instancesSet"][0]
|
|
|
|
|
state = details["instanceState"]["name"].to_s
|
|
|
|
|
next if state == "pending" or state == "running"
|
|
|
|
|
out << "Server returns state '#{state}'"
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
s.public_ip = details["ipAddress"]
|
|
|
|
|
s.private_ip = details["privateIpAddress"]
|
2015-11-23 14:55:53 +03:00
|
|
|
tags = server_tags(s)
|
|
|
|
|
compute.create_tags(s.id, tags)
|
2015-09-21 17:41:40 +03:00
|
|
|
out << "\nServer tags: #{tags.inspect}\n"
|
2014-06-18 15:11:47 +04:00
|
|
|
out << "\nDone\n\n"
|
|
|
|
|
out << s.info
|
|
|
|
|
|
|
|
|
|
true
|
|
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2015-11-23 14:55:53 +03:00
|
|
|
def server_tags server
|
|
|
|
|
{
|
|
|
|
|
"Name" => server.chef_node_name,
|
|
|
|
|
"cid:project" => server.project,
|
|
|
|
|
"cid:deployEnv" => server.deploy_env,
|
|
|
|
|
"cid:user" => server.created_by,
|
|
|
|
|
"cid:remoteUser" => server.remote_user
|
2015-09-16 14:07:46 +03:00
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def delete_server s
|
|
|
|
|
r = self.compute.terminate_instances(s.id)
|
|
|
|
|
i = r.body["instancesSet"][0]
|
|
|
|
|
old_state = i["previousState"]["name"]
|
|
|
|
|
state = i["currentState"]["name"]
|
|
|
|
|
return r.status == 200 ? "Server with id '#{s.id}' changed state '#{old_state}' to '#{state}'" : r.body
|
|
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def pause_server s
|
|
|
|
|
es = self.server s.id
|
|
|
|
|
if es["state"] == "running"
|
|
|
|
|
self.compute.stop_instances [ s.id ]
|
|
|
|
|
return nil
|
|
|
|
|
else
|
|
|
|
|
return es["state"]
|
2014-05-08 15:34:26 +04:00
|
|
|
end
|
2014-06-18 15:11:47 +04:00
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def unpause_server s
|
|
|
|
|
es = self.server s.id
|
|
|
|
|
if es["state"] == "stopped"
|
|
|
|
|
self.compute.start_instances [ s.id ]
|
|
|
|
|
return nil
|
|
|
|
|
else
|
|
|
|
|
return es["state"]
|
2014-05-08 15:34:26 +04:00
|
|
|
end
|
2014-06-18 15:11:47 +04:00
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2015-08-03 18:01:50 +03:00
|
|
|
def set_tags instance_id, tags
|
2015-08-04 09:56:03 +03:00
|
|
|
raise ConflictException.new("You can not change 'Name' tag") if tags.key?("Name")
|
2015-08-03 18:01:50 +03:00
|
|
|
compute.create_tags(instance_id, tags)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def unset_tags instance_id, tags
|
2015-08-04 09:56:03 +03:00
|
|
|
raise ConflictException.new("You can not change 'Name' tag") if tags.key?("Name")
|
2015-08-03 18:01:50 +03:00
|
|
|
compute.delete_tags(instance_id, tags)
|
|
|
|
|
end
|
|
|
|
|
|
2014-06-20 12:59:17 +04:00
|
|
|
def compute
|
|
|
|
|
connection_compute(connection_options)
|
|
|
|
|
end
|
2015-08-17 11:25:20 +03:00
|
|
|
|
|
|
|
|
def create_stack(stack, out)
|
|
|
|
|
begin
|
|
|
|
|
out << "Creating stack for project '#{stack.project}' and environment '#{stack.deploy_env}'...\n"
|
|
|
|
|
stack.name = create_default_stack_name(stack) unless stack.name
|
|
|
|
|
out << "Stack name: #{stack.name}\n"
|
|
|
|
|
out << "Stack template: #{stack.stack_template}\n"
|
|
|
|
|
out << "Stack parameters: #{stack.parameters}\n"
|
2016-02-26 14:27:14 +03:00
|
|
|
out << "Stack tags: #{JSON.pretty_generate(stack_tags(stack))}\n"
|
2015-08-18 17:53:39 +03:00
|
|
|
out.flush
|
2015-08-17 11:25:20 +03:00
|
|
|
response = cloud_formation.create_stack(stack.name,
|
|
|
|
|
{
|
2016-01-27 15:44:59 +03:00
|
|
|
'TemplateURL' => stack.stack_template_model.template_url,
|
2015-08-18 16:09:41 +03:00
|
|
|
'Parameters' => stack.parameters || {},
|
2015-09-21 15:54:33 +03:00
|
|
|
'Capabilities' => ['CAPABILITY_IAM'],
|
2015-11-23 14:55:53 +03:00
|
|
|
'Tags' => stack_tags(stack)
|
2015-08-17 11:25:20 +03:00
|
|
|
}
|
|
|
|
|
)
|
2015-08-18 17:41:17 +03:00
|
|
|
stack.id = response.body['StackId']
|
2015-08-18 16:27:35 +03:00
|
|
|
out << "Stack id: #{stack.id}\n"
|
2015-08-18 17:53:39 +03:00
|
|
|
out.flush
|
2015-08-17 11:25:20 +03:00
|
|
|
rescue Excon::Errors::Conflict => e
|
|
|
|
|
raise ProviderErrors::NameConflict
|
|
|
|
|
rescue Excon::Errors::BadRequest => br
|
|
|
|
|
response = ::Chef::JSONCompat.from_json(br.response.body)
|
|
|
|
|
if response['code'] == 400
|
|
|
|
|
out << "\nERROR: Bad request (400): #{response['explanation']}"
|
|
|
|
|
out << "\n"
|
|
|
|
|
raise InvalidRecord.new(response['explanation'])
|
|
|
|
|
else
|
|
|
|
|
out << "\nERROR: Unknown server error (#{response['code']}): #{response['explanation']}"
|
|
|
|
|
out << "\n"
|
|
|
|
|
raise InvalidRecord.new(response['explanation'])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2015-11-23 14:55:53 +03:00
|
|
|
def stack_tags stack
|
|
|
|
|
{
|
|
|
|
|
"StackTemplate" => stack.stack_template,
|
|
|
|
|
"cid:project" => stack.project,
|
|
|
|
|
"cid:deployEnv" => stack.deploy_env,
|
|
|
|
|
"cid:user" => stack.owner
|
2016-02-26 14:27:14 +03:00
|
|
|
}.merge(stack.tags)
|
2015-09-16 14:07:46 +03:00
|
|
|
end
|
|
|
|
|
|
2015-11-23 16:34:14 +03:00
|
|
|
def update_stack(stack, params)
|
|
|
|
|
cloud_formation.update_stack(stack.name, params)
|
2015-09-16 14:07:46 +03:00
|
|
|
end
|
|
|
|
|
|
2015-08-21 19:03:53 +03:00
|
|
|
def validate_stack_template template
|
2015-12-11 13:15:36 +03:00
|
|
|
#r = cloud_formation.validate_template({'TemplateBody' => template})
|
|
|
|
|
#pp r.body
|
|
|
|
|
true
|
2015-08-21 19:03:53 +03:00
|
|
|
end
|
|
|
|
|
|
2015-08-17 11:25:20 +03:00
|
|
|
def delete_stack(stack)
|
2015-08-17 17:50:24 +03:00
|
|
|
cloud_formation.delete_stack(stack.name)
|
2015-08-17 11:25:20 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def stack_details(stack)
|
2015-09-21 17:34:20 +03:00
|
|
|
b = cloud_formation.describe_stacks({'StackName' => stack.name}).body
|
2016-02-24 21:26:44 +03:00
|
|
|
details = b['Stacks'].detect{|s| s.key?("StackStatus")} || {}
|
|
|
|
|
{
|
|
|
|
|
stack_status: details['StackStatus'],
|
|
|
|
|
raw: details
|
|
|
|
|
}
|
2015-08-17 11:25:20 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def stack_resources(stack)
|
2015-08-17 17:50:24 +03:00
|
|
|
cloud_formation.describe_stack_resources({'StackName' => stack.name}).body['StackResources']
|
2015-08-17 11:25:20 +03:00
|
|
|
end
|
|
|
|
|
|
2015-11-17 13:23:13 +03:00
|
|
|
def stack_events(stack)
|
2015-11-17 16:46:30 +03:00
|
|
|
cloud_formation.describe_stack_events(stack.name).body['StackEvents'].map{|se| {"timestamp" => se["Timestamp"], "stack_name" => se["StackName"], "stack_id" => se["StackId"], "event_id" => se["EventId"], "reason" => se["ResourceStatusReason"], "status" => se["ResourceStatus"]}}.sort{|se1, se2| se1["timestamp"] <=> se2["timestamp"]}
|
2015-11-17 13:23:13 +03:00
|
|
|
end
|
|
|
|
|
|
2015-08-17 11:25:20 +03:00
|
|
|
def stack_servers(stack)
|
2015-09-16 12:33:37 +03:00
|
|
|
resources = compute.describe_instances(
|
2015-09-16 12:14:01 +03:00
|
|
|
'tag-key' => 'aws:cloudformation:stack-id',
|
|
|
|
|
'tag-value' => stack.id
|
|
|
|
|
).body["reservationSet"]
|
|
|
|
|
|
2016-04-04 13:17:07 +03:00
|
|
|
|
|
|
|
|
# There may be not only instances but autoscaling groups with several instances.
|
|
|
|
|
# Handle such situations.
|
2015-09-16 12:33:37 +03:00
|
|
|
instances = resources.map { |resource| resource["instancesSet"] }.flatten
|
2016-04-04 13:17:07 +03:00
|
|
|
instances.delete_if {|i| i['instanceState']['name'] == 'terminated'}
|
2015-09-16 12:33:37 +03:00
|
|
|
|
|
|
|
|
instances.map do |instance|
|
2015-08-18 20:01:17 +03:00
|
|
|
{
|
2015-09-16 12:52:56 +03:00
|
|
|
'name' => [stack.name, instance_name(instance)].join('-'),
|
2015-09-16 12:33:37 +03:00
|
|
|
'id' => instance["instanceId"],
|
|
|
|
|
'key_name' => instance["keyName"],
|
|
|
|
|
'private_ip' => instance["privateIpAddress"],
|
|
|
|
|
'public_ip' => instance["ipAddress"],
|
2015-11-03 13:08:31 +03:00
|
|
|
'tags' => instance["tagSet"]
|
2015-08-18 20:01:17 +03:00
|
|
|
}
|
2015-08-18 19:36:48 +03:00
|
|
|
end
|
2015-08-17 11:25:20 +03:00
|
|
|
end
|
|
|
|
|
|
2015-08-18 16:02:55 +03:00
|
|
|
def create_default_stack_name s
|
2015-08-28 17:00:48 +03:00
|
|
|
"stack-#{self.ssh_key}-#{s.project}-#{s.deploy_env}-#{Time.now.to_i}".gsub('_', '-')
|
2015-08-18 16:02:55 +03:00
|
|
|
end
|
2015-11-17 12:14:02 +03:00
|
|
|
|
2016-04-04 13:17:07 +03:00
|
|
|
def stack_id_of_autoscaling_group(id)
|
|
|
|
|
response = auto_scaling.describe_auto_scaling_groups('AutoScalingGroupNames' => [id])
|
|
|
|
|
tags = response.body['DescribeAutoScalingGroupsResult']['AutoScalingGroups'].first['Tags']
|
|
|
|
|
stack_id_tag = tags.find {|t| t['Key'] == 'aws:cloudformation:stack-id'}
|
|
|
|
|
if stack_id_tag
|
|
|
|
|
stack_id_tag['Value']
|
|
|
|
|
end
|
|
|
|
|
rescue StandardError => e
|
2016-04-15 17:05:50 +03:00
|
|
|
puts "An error occured while analyzing group '#{id}'"
|
|
|
|
|
puts response.body
|
2016-04-04 13:17:07 +03:00
|
|
|
nil
|
|
|
|
|
end
|
|
|
|
|
|
2015-11-17 12:14:02 +03:00
|
|
|
def describe_vpcs
|
|
|
|
|
self.compute.describe_vpcs.body["vpcSet"].select{|v| v["state"] == "available"}.map{|v| {"vpc_id" => v["vpcId"], "cidr" => v["cidrBlock"] } }
|
|
|
|
|
end
|
2016-01-27 15:44:59 +03:00
|
|
|
|
|
|
|
|
def store_stack_template(filename, json)
|
|
|
|
|
store_file(stack_templates_bucket, filename, json)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def store_file(bucket, filename, body)
|
|
|
|
|
{
|
|
|
|
|
'url' => bucket.files.create(key: filename, body: body, public: true).public_url
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
private
|
2015-09-16 12:14:01 +03:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def convert_groups list
|
|
|
|
|
res = {}
|
|
|
|
|
list.each do |g|
|
2014-11-20 15:08:42 +03:00
|
|
|
next if g["groupName"].nil?
|
2014-06-18 15:11:47 +04:00
|
|
|
res[g["groupName"]] = {
|
|
|
|
|
"description" => g["groupDescription"],
|
|
|
|
|
"id" => g["groupId"]
|
|
|
|
|
}
|
|
|
|
|
rules = []
|
|
|
|
|
g["ipPermissions"].each do |r|
|
|
|
|
|
cidr = r["ipRanges"][0] || {}
|
|
|
|
|
rules.push({
|
|
|
|
|
"protocol" => r["ipProtocol"],
|
|
|
|
|
"from" => r["fromPort"],
|
|
|
|
|
"to" => r["toPort"],
|
|
|
|
|
"cidr" => cidr["cidrIp"]
|
|
|
|
|
})
|
2014-05-08 15:34:26 +04:00
|
|
|
end
|
2014-06-18 15:11:47 +04:00
|
|
|
res[g["groupName"]]["rules"] = rules
|
2014-05-08 15:34:26 +04:00
|
|
|
end
|
2014-06-18 15:11:47 +04:00
|
|
|
res
|
|
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def convert_server s
|
|
|
|
|
{
|
|
|
|
|
"state" => s["instanceState"]["name"],
|
|
|
|
|
"name" => s["tagSet"]["Name"],
|
|
|
|
|
"image" => s["imageId"],
|
|
|
|
|
"flavor" => s["instanceType"],
|
|
|
|
|
"keypair" => s["keyName"],
|
|
|
|
|
"instance_id" => s["instanceId"],
|
|
|
|
|
"dns_name" => s["dnsName"],
|
|
|
|
|
"zone" => s["placement"]["availabilityZone"],
|
|
|
|
|
"private_ip" => s["privateIpAddress"],
|
|
|
|
|
"public_ip" => s["ipAddress"],
|
|
|
|
|
"launched_at" => s["launchTime"]
|
|
|
|
|
}
|
|
|
|
|
end
|
2014-05-08 15:34:26 +04:00
|
|
|
|
2014-06-18 15:11:47 +04:00
|
|
|
def extract_group_ids names, vpcId
|
|
|
|
|
return [] if names.nil?
|
|
|
|
|
p = nil
|
|
|
|
|
p = {"vpc-id" => vpcId} unless vpcId.nil?
|
|
|
|
|
groups = self.groups(p)
|
|
|
|
|
r = names.map do |name|
|
|
|
|
|
groups[name]["id"]
|
2014-05-08 15:34:26 +04:00
|
|
|
end
|
2014-06-18 15:11:47 +04:00
|
|
|
r
|
|
|
|
|
end
|
2015-08-17 11:25:20 +03:00
|
|
|
|
2016-01-27 15:44:59 +03:00
|
|
|
def storage
|
|
|
|
|
@storage ||= Fog::Storage.new(connection_options)
|
|
|
|
|
end
|
|
|
|
|
|
2016-04-04 13:17:07 +03:00
|
|
|
def cloud_formation
|
|
|
|
|
@cloud_formation ||= Fog::AWS::CloudFormation.new(connection_options)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def auto_scaling
|
|
|
|
|
@auto_scaling ||= Fog::AWS::AutoScaling.new(connection_options)
|
|
|
|
|
end
|
|
|
|
|
|
2016-01-27 15:44:59 +03:00
|
|
|
def stack_templates_bucket
|
|
|
|
|
bucket_name = DevopsConfig.config[:aws_stack_templates_bucket] || 'stacktemplatesnibrdev'
|
|
|
|
|
bucket = storage.directories.get(bucket_name)
|
|
|
|
|
bucket ||= storage.directories.create(key: bucket_name)
|
|
|
|
|
end
|
|
|
|
|
|
2015-09-16 12:52:56 +03:00
|
|
|
def instance_name(instance)
|
|
|
|
|
return instance["tagSet"]["Name"] if instance["tagSet"]["Name"]
|
|
|
|
|
if instance['tagSet']['aws:autoscaling:groupName']
|
|
|
|
|
instance["instanceId"]
|
|
|
|
|
else
|
|
|
|
|
instance['tagSet']['aws:cloudformation:logical-id']
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2016-03-15 17:56:58 +03:00
|
|
|
# When you create an instance with one of these flavors within AWS console,
|
|
|
|
|
# EbsOptimized is automatically set to true. But in case of creating within API we should set it manually.
|
|
|
|
|
def ebs_optimized?(flavor)
|
2016-03-15 13:22:16 +03:00
|
|
|
always_ebs_optimized = ['c4.large', 'c4.xlarge', 'c4.2xlarge', 'c4.4xlarge', 'c4.8xlarge', 'd2.xlarge', 'd2.2xlarge', 'd2.4xlarge', 'd2.8xlarge', 'm4.large', 'm4.xlarge', 'm4.2xlarge', 'm4.4xlarge', 'm4.10xlarge']
|
2016-03-15 17:56:58 +03:00
|
|
|
always_ebs_optimized.include?(flavor)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# When you create an instance with with ephemeral storages available within AWS console,
|
|
|
|
|
# they are mapped automatically. But in case of creating within API we should map them manually.
|
2016-03-16 22:39:19 +03:00
|
|
|
# Result example: [{'VirtualName' => 'ephemeral0', 'DeviceName' => '/dev/xvdb'}]
|
2016-03-15 17:56:58 +03:00
|
|
|
def ephemeral_storages_mappings(flavor)
|
|
|
|
|
require 'fog/aws/models/compute/flavors'
|
|
|
|
|
details = Fog::Compute::AWS::FLAVORS.detect {|f| f[:id] == flavor}
|
|
|
|
|
return [] unless details
|
|
|
|
|
|
|
|
|
|
mappings = []
|
|
|
|
|
details[:instance_store_volumes].times do |i|
|
|
|
|
|
mappings << {
|
|
|
|
|
'VirtualName' => "ephemeral#{i}",
|
|
|
|
|
'DeviceName' => "/dev/xvd#{('b'.ord + i).chr}"
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
mappings
|
2016-03-15 13:22:16 +03:00
|
|
|
end
|
|
|
|
|
|
2014-05-08 15:34:26 +04:00
|
|
|
end
|
|
|
|
|
end
|