mirror of
https://github.com/fog/fog-aws.git
synced 2022-11-09 13:50:52 -05:00
219 lines
11 KiB
Ruby
219 lines
11 KiB
Ruby
module Fog
|
|
module AWS
|
|
class ELB
|
|
class Real
|
|
require 'fog/aws/parsers/elb/create_load_balancer'
|
|
|
|
# Create a new Elastic Load Balancer
|
|
#
|
|
# ==== Parameters
|
|
# * availability_zones<~Array> - List of availability zones for the ELB
|
|
# * lb_name<~String> - Name for the new ELB -- must be unique
|
|
# * listeners<~Array> - Array of Hashes describing ELB listeners to assign to the ELB
|
|
# * 'Protocol'<~String> - Protocol to use. Either HTTP, HTTPS, TCP or SSL.
|
|
# * 'LoadBalancerPort'<~Integer> - The port that the ELB will listen to for outside traffic
|
|
# * 'InstancePort'<~Integer> - The port on the instance that the ELB will forward traffic to
|
|
# * 'InstanceProtocol'<~String> - Protocol for sending traffic to an instance. Either HTTP, HTTPS, TCP or SSL.
|
|
# * 'SSLCertificateId'<~String> - ARN of the server certificate
|
|
# ==== Returns
|
|
# * response<~Excon::Response>:
|
|
# * body<~Hash>:
|
|
# * 'ResponseMetadata'<~Hash>:
|
|
# * 'RequestId'<~String> - Id of request
|
|
# * 'CreateLoadBalancerResult'<~Hash>:
|
|
# * 'DNSName'<~String> - DNS name for the newly created ELB
|
|
def create_load_balancer(availability_zones, lb_name, listeners, options = {})
|
|
params = Fog::AWS.indexed_param('AvailabilityZones.member', [*availability_zones])
|
|
params.merge!(Fog::AWS.indexed_param('Subnets.member.%d', options[:subnet_ids]))
|
|
params.merge!(Fog::AWS.serialize_keys('Scheme', options[:scheme]))
|
|
params.merge!(Fog::AWS.indexed_param('SecurityGroups.member.%d', options[:security_groups]))
|
|
|
|
listener_protocol = []
|
|
listener_lb_port = []
|
|
listener_instance_port = []
|
|
listener_instance_protocol = []
|
|
listener_ssl_certificate_id = []
|
|
listeners.each do |listener|
|
|
listener_protocol.push(listener['Protocol'])
|
|
listener_lb_port.push(listener['LoadBalancerPort'])
|
|
listener_instance_port.push(listener['InstancePort'])
|
|
listener_instance_protocol.push(listener['InstanceProtocol'])
|
|
listener_ssl_certificate_id.push(listener['SSLCertificateId'])
|
|
end
|
|
|
|
params.merge!(Fog::AWS.indexed_param('Listeners.member.%d.Protocol', listener_protocol))
|
|
params.merge!(Fog::AWS.indexed_param('Listeners.member.%d.LoadBalancerPort', listener_lb_port))
|
|
params.merge!(Fog::AWS.indexed_param('Listeners.member.%d.InstancePort', listener_instance_port))
|
|
params.merge!(Fog::AWS.indexed_param('Listeners.member.%d.InstanceProtocol', listener_instance_protocol))
|
|
params.merge!(Fog::AWS.indexed_param('Listeners.member.%d.SSLCertificateId', listener_ssl_certificate_id))
|
|
|
|
request({
|
|
'Action' => 'CreateLoadBalancer',
|
|
'LoadBalancerName' => lb_name,
|
|
:parser => Fog::Parsers::AWS::ELB::CreateLoadBalancer.new
|
|
}.merge!(params))
|
|
end
|
|
end
|
|
|
|
class Mock
|
|
def create_load_balancer(availability_zones, lb_name, listeners = [], options = {})
|
|
response = Excon::Response.new
|
|
response.status = 200
|
|
|
|
raise Fog::AWS::ELB::IdentifierTaken if self.data[:load_balancers].key? lb_name
|
|
|
|
certificate_ids = Fog::AWS::IAM::Mock.data[@aws_access_key_id][:server_certificates].map {|n, c| c['Arn'] }
|
|
|
|
listeners = [*listeners].map do |listener|
|
|
if listener['SSLCertificateId'] and !certificate_ids.include? listener['SSLCertificateId']
|
|
raise Fog::AWS::IAM::NotFound.new('CertificateNotFound')
|
|
end
|
|
{'Listener' => listener, 'PolicyNames' => []}
|
|
end
|
|
|
|
dns_name = Fog::AWS::ELB::Mock.dns_name(lb_name, @region)
|
|
|
|
availability_zones = [*availability_zones].compact
|
|
subnet_ids = options[:subnet_ids] || []
|
|
region = if availability_zones.any?
|
|
availability_zones.first.gsub(/[a-z]$/, '')
|
|
elsif subnet_ids.any?
|
|
# using Hash here for Rubt 1.8.7 support.
|
|
Hash[
|
|
Fog::Compute::AWS::Mock.data.select do |_, region_data|
|
|
region_data[@aws_access_key_id][:subnets].any? do |region_subnets|
|
|
subnet_ids.include? region_subnets['subnetId']
|
|
end
|
|
end
|
|
].keys[0]
|
|
else
|
|
'us-east-1'
|
|
end
|
|
supported_platforms = Fog::Compute::AWS::Mock.data[region][@aws_access_key_id][:account_attributes].find { |h| h["attributeName"] == "supported-platforms" }["values"]
|
|
subnets = Fog::Compute::AWS::Mock.data[region][@aws_access_key_id][:subnets].select {|e| subnet_ids.include?(e["subnetId"]) }
|
|
|
|
# http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/default-vpc.html
|
|
elb_location = if supported_platforms.include?("EC2")
|
|
if subnet_ids.empty?
|
|
'EC2-Classic'
|
|
else
|
|
'EC2-VPC'
|
|
end
|
|
else
|
|
if subnet_ids.empty?
|
|
'EC2-VPC-Default'
|
|
else
|
|
'VPC'
|
|
end
|
|
end
|
|
|
|
security_group = case elb_location
|
|
when 'EC2-Classic'
|
|
Fog::Compute::AWS::Mock.data[region][@aws_access_key_id][:security_groups]['amazon-elb-sg']
|
|
when 'EC2-VPC-Default'
|
|
# find or create default vpc
|
|
compute = Fog::Compute::AWS::new(:aws_access_key_id => @aws_access_key_id, :aws_secret_access_key => @aws_secret_access_key)
|
|
unless vpc = compute.vpcs.all.first
|
|
vpc = compute.vpcs.create('cidr_block' => '10.0.0.0/24')
|
|
end
|
|
|
|
default_sg = Fog::Compute::AWS::Mock.data[region][@aws_access_key_id][:security_groups].values.find { |sg|
|
|
sg['groupName'] =~ /^default_elb/ &&
|
|
sg["vpcId"] == vpc.id
|
|
}
|
|
|
|
unless default_sg
|
|
default_sg = {
|
|
'groupDescription' => 'default_elb security group',
|
|
'groupName' => "default_elb_#{Fog::Mock.random_hex(6)}",
|
|
'groupId' => Fog::AWS::Mock.security_group_id,
|
|
'ipPermissionsEgress' => [],
|
|
'ipPermissions' => [],
|
|
'ownerId' => self.data[:owner_id],
|
|
'vpcId' => vpc.id
|
|
}
|
|
Fog::Compute::AWS::Mock.data[region][@aws_access_key_id][:security_groups]['default'] = default_sg
|
|
end
|
|
|
|
default_sg
|
|
when 'EC2-VPC'
|
|
# find or create default vpc security group
|
|
vpc_id = subnets.first["vpcId"]
|
|
default_sg = Fog::Compute::AWS::Mock.data[region][@aws_access_key_id][:security_groups].values.find { |sg|
|
|
sg['groupName'] == 'default' &&
|
|
sg["vpcId"] == vpc_id
|
|
}
|
|
|
|
unless default_sg
|
|
default_sg = {
|
|
'groupDescription' => 'default elb security group',
|
|
'groupName' => 'default',
|
|
'groupId' => Fog::AWS::Mock.security_group_id,
|
|
'ipPermissionsEgress' => [],
|
|
'ipPermissions' => [],
|
|
'ownerId' => self.data[:owner_id],
|
|
'vpcId' => vpc_id
|
|
}
|
|
Fog::Compute::AWS::Mock.data[region][@aws_access_key_id][:security_groups]['default'] = default_sg
|
|
end
|
|
|
|
default_sg
|
|
end
|
|
self.data[:tags] ||= {}
|
|
self.data[:tags][lb_name] = {}
|
|
|
|
self.data[:load_balancers][lb_name] = {
|
|
'AvailabilityZones' => availability_zones,
|
|
'BackendServerDescriptions' => [],
|
|
# Hack to facilitate not updating the local data structure
|
|
# (BackendServerDescriptions) until we do a subsequent
|
|
# describe as that is how AWS behaves.
|
|
'BackendServerDescriptionsRemote' => [],
|
|
'Subnets' => options[:subnet_ids] || [],
|
|
'Scheme' => options[:scheme].nil? ? 'internet-facing' : options[:scheme],
|
|
'SecurityGroups' => options[:security_groups].nil? ? [] : options[:security_groups],
|
|
'CanonicalHostedZoneName' => '',
|
|
'CanonicalHostedZoneNameID' => '',
|
|
'CreatedTime' => Time.now,
|
|
'DNSName' => dns_name,
|
|
'HealthCheck' => {
|
|
'HealthyThreshold' => 10,
|
|
'Timeout' => 5,
|
|
'UnhealthyThreshold' => 2,
|
|
'Interval' => 30,
|
|
'Target' => 'TCP:80'
|
|
},
|
|
'Instances' => [],
|
|
'ListenerDescriptions' => listeners,
|
|
'LoadBalancerAttributes' => {
|
|
'ConnectionDraining' => {'Enabled' => false, 'Timeout' => 300},
|
|
'CrossZoneLoadBalancing' => {'Enabled' => false},
|
|
'ConnectionSettings' => {'IdleTimeout' => 60}
|
|
},
|
|
'LoadBalancerName' => lb_name,
|
|
'Policies' => {
|
|
'AppCookieStickinessPolicies' => [],
|
|
'LBCookieStickinessPolicies' => [],
|
|
'OtherPolicies' => [],
|
|
'Proper' => []
|
|
},
|
|
'SourceSecurityGroup' => {
|
|
'GroupName' => security_group['groupName'],
|
|
'OwnerAlias' => ''
|
|
}
|
|
}
|
|
response.body = {
|
|
'ResponseMetadata' => {
|
|
'RequestId' => Fog::AWS::Mock.request_id
|
|
},
|
|
'CreateLoadBalancerResult' => {
|
|
'DNSName' => dns_name
|
|
}
|
|
}
|
|
|
|
response
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|