1
0
Fork 0
mirror of https://github.com/fog/fog-aws.git synced 2022-11-09 13:50:52 -05:00

initial import

* take the liberty of correcting Aws naming
This commit is contained in:
Josh Lane 2014-12-30 14:25:09 -08:00
parent 095fa8763f
commit d48d376e9c
1261 changed files with 72105 additions and 5 deletions

View file

@ -5,7 +5,7 @@ require 'fog/aws/version'
Gem::Specification.new do |spec|
spec.name = "fog-aws"
spec.version = Fog::Aws::VERSION
spec.version = Fog::AWS::VERSION
spec.authors = ["Josh Lane"]
spec.email = ["me@joshualane.com"]
spec.summary = %q{Module for the 'fog' gem to support Amazon Web Services.}
@ -24,4 +24,6 @@ Gem::Specification.new do |spec|
spec.add_dependency "fog-core"
spec.add_dependency "fog-xml"
spec.add_dependency "fog-json"
spec.add_dependency "ipaddress"
end

View file

@ -1,7 +1,31 @@
require "fog/aws/version"
require 'fog/aws/version'
module Fog
module Aws
# Your code goes here...
module AWS
end
end
require 'fog/aws/core'
require 'fog/aws/auto_scaling'
require 'fog/aws/beanstalk'
require 'fog/aws/cdn'
require 'fog/aws/cloud_formation'
require 'fog/aws/cloud_watch'
require 'fog/aws/compute'
require 'fog/aws/data_pipeline'
require 'fog/aws/dns'
require 'fog/aws/dynamodb'
require 'fog/aws/elasticache'
require 'fog/aws/elb'
require 'fog/aws/emr'
require 'fog/aws/glacier'
require 'fog/aws/iam'
require 'fog/aws/rds'
require 'fog/aws/redshift'
require 'fog/aws/ses'
require 'fog/aws/simpledb'
require 'fog/aws/sns'
require 'fog/aws/sqs'
require 'fog/aws/storage'
require 'fog/aws/sts'

279
lib/fog/aws/auto_scaling.rb Normal file
View file

@ -0,0 +1,279 @@
require 'fog/aws/core'
module Fog
module AWS
class AutoScaling < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
class IdentifierTaken < Fog::Errors::Error; end
class ResourceInUse < Fog::Errors::Error; end
class ValidationError < Fog::Errors::Error; end
requires :aws_access_key_id, :aws_secret_access_key
recognizes :host, :path, :port, :scheme, :persistent, :region, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
request_path 'fog/aws/requests/auto_scaling'
request :create_auto_scaling_group
request :create_launch_configuration
request :create_or_update_tags
request :delete_auto_scaling_group
request :delete_launch_configuration
request :delete_notification_configuration
request :delete_policy
request :delete_scheduled_action
request :delete_tags
request :describe_adjustment_types
request :describe_auto_scaling_groups
request :describe_auto_scaling_instances
request :describe_auto_scaling_notification_types
request :describe_launch_configurations
request :describe_metric_collection_types
request :describe_notification_configurations
request :describe_policies
request :describe_scaling_activities
request :describe_scaling_process_types
request :describe_scheduled_actions
request :describe_tags
request :describe_termination_policy_types
request :disable_metrics_collection
request :enable_metrics_collection
request :execute_policy
request :put_notification_configuration
request :put_scaling_policy
request :put_scheduled_update_group_action
request :resume_processes
request :set_desired_capacity
request :set_instance_health
request :suspend_processes
request :terminate_instance_in_auto_scaling_group
request :update_auto_scaling_group
model_path 'fog/aws/models/auto_scaling'
model :activity
collection :activities
model :configuration
collection :configurations
model :group
collection :groups
model :instance
collection :instances
model :policy
collection :policies
ExpectedOptions = {}
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
attr_accessor :region
# Initialize connection to AutoScaling
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# as = AutoScaling.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
#
# ==== Returns
# * AutoScaling object with connection to Aws.
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@connection_options = options[:connection_options] || {}
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.auto_scaling'
options[:region] ||= 'us-east-1'
@region = options[:region]
@host = options[:host] || "autoscaling.#{options[:region]}.amazonaws.com"
@path = options[:path] || '/'
@port = options[:port] || 443
@persistent = options[:persistent] || false
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
setup_credentials(options)
end
def reload
@connection.reset
end
private
def request(params)
refresh_credentials_if_expired
idempotent = params.delete(:idempotent)
parser = params.delete(:parser)
body, headers = Aws.signed_params_v4(
params,
{ 'Content-Type' => 'application/x-www-form-urlencoded' },
{
:aws_session_token => @aws_session_token,
:method => 'POST',
:signer => @signer,
:host => @host,
:path => @path,
:port => @port,
:version => '2011-01-01'
}
)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(body, headers, idempotent, parser)
end
else
_request(body, headers, idempotent, parser)
end
end
def _request(body, headers, idempotent, parser)
begin
@connection.request({
:body => body,
:expects => 200,
:idempotent => idempotent,
:headers => headers,
:method => 'POST',
:parser => parser
})
rescue Excon::Errors::HTTPStatusError => error
match = Fog::AWS::Errors.match_error(error)
raise if match.empty?
raise case match[:code]
when 'AlreadyExists'
Fog::AWS::AutoScaling::IdentifierTaken.slurp(error, match[:message])
when 'ResourceInUse'
Fog::AWS::AutoScaling::ResourceInUse.slurp(error, match[:message])
when 'ValidationError'
Fog::AWS::AutoScaling::ValidationError.slurp(error, match[:message])
else
Fog::AWS::AutoScaling::Error.slurp(error, "#{match[:code]} => #{match[:message]}")
end
end
end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key, @region, 'autoscaling')
end
end
class Mock
include Fog::AWS::CredentialFetcher::ConnectionMethods
attr_accessor :region
def self.data
@data ||= Hash.new do |hash, region|
owner_id = Fog::AWS::Mock.owner_id
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:adjustment_types => [
'ChangeInCapacity',
'ExactCapacity',
'PercentChangeInCapacity'
],
:auto_scaling_groups => {},
:scaling_policies => {},
:health_states => [
'Healthy',
'Unhealthy'
],
:launch_configurations => {},
:metric_collection_types => {
:granularities => [
'1Minute'
],
:metrics => [
'GroupMinSize',
'GroupMaxSize',
'GroupDesiredCapacity',
'GroupInServiceInstances',
'GroupPendingInstances',
'GroupTerminatingInstances',
'GroupTotalInstances'
]
},
:notification_configurations => {},
:notification_types => [
'autoscaling:EC2_INSTANCE_LAUNCH',
'autoscaling:EC2_INSTANCE_LAUNCH_ERROR',
'autoscaling:EC2_INSTANCE_TERMINATE',
'autoscaling:EC2_INSTANCE_TERMINATE_ERROR',
'autoscaling:TEST_NOTIFICATION'
],
:owner_id => owner_id,
:process_types => [
'AZRebalance',
'AddToLoadBalancer',
'AlarmNotification',
'HealthCheck',
'Launch',
'ReplaceUnhealthy',
'ScheduledActions',
'Terminate'
],
:termination_policy_types => [
'ClosestToNextInstanceHour',
'Default',
'NewestInstance',
'OldestInstance',
'OldestLaunchConfiguration'
]
}
end
end
end
def self.reset
@data = nil
end
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
setup_credentials(options)
@region = options[:region] || 'us-east-1'
unless ['ap-northeast-1', 'ap-southeast-1', 'ap-southeast-2', 'eu-central-1', 'eu-west-1', 'sa-east-1', 'us-east-1', 'us-west-1', 'us-west-2'].include?(@region)
raise ArgumentError, "Unknown region: #{@region.inspect}"
end
end
def region_data
self.class.data[@region]
end
def data
self.region_data[@aws_access_key_id]
end
def reset_data
self.region_data.delete(@aws_access_key_id)
end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
end
end
end
end
end

156
lib/fog/aws/beanstalk.rb Normal file
View file

@ -0,0 +1,156 @@
require 'fog/aws/core'
module Fog
module AWS
class ElasticBeanstalk < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
class InvalidParameterError < Fog::Errors::Error; end
requires :aws_access_key_id, :aws_secret_access_key
recognizes :region, :host, :path, :port, :scheme, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
request_path 'fog/aws/requests/beanstalk'
request :check_dns_availability
request :create_application
request :create_application_version
request :create_configuration_template
request :create_environment
request :create_storage_location
request :delete_application
request :delete_application_version
request :delete_configuration_template
request :delete_environment_configuration
request :describe_applications
request :describe_application_versions
request :describe_configuration_options
request :describe_configuration_settings
request :describe_environment_resources
request :describe_environments
request :describe_events
request :list_available_solution_stacks
request :rebuild_environment
request :request_environment_info
request :restart_app_server
request :retrieve_environment_info
request :swap_environment_cnames
request :terminate_environment
request :update_application
request :update_application_version
request :update_configuration_template
request :update_environment
request :validate_configuration_settings
model_path 'fog/aws/models/beanstalk'
model :application
collection :applications
model :environment
collection :environments
model :event
collection :events
model :template
collection :templates
model :version
collection :versions
class Mock
def initialize(options={})
Fog::Mock.not_implemented
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@connection_options = options[:connection_options] || {}
options[:region] ||= 'us-east-1'
@host = options[:host] || "elasticbeanstalk.#{options[:region]}.amazonaws.com"
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.beanstalk'
@region = options[:region]
setup_credentials(options)
end
def reload
@connection.reset
end
# Returns an array of available solutions stack details
def solution_stacks
list_available_solution_stacks.body['ListAvailableSolutionStacksResult']['SolutionStackDetails']
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key, @region, 'elasticbeanstalk')
end
def request(params)
refresh_credentials_if_expired
idempotent = params.delete(:idempotent)
parser = params.delete(:parser)
body, headers = Aws.signed_params_v4(
params,
{ 'Content-Type' => 'application/x-www-form-urlencoded' },
{
:signer => @signer,
:aws_session_token => @aws_session_token,
:method => "POST",
:host => @host,
:path => @path,
:port => @port,
:version => '2010-12-01'
}
)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(body, headers, idempotent, parser)
end
else
_request(body, headers, idempotent, parser)
end
end
def _request(body, headers, idempotent, parser)
@connection.request({
:body => body,
:expects => 200,
:headers => headers,
:idempotent => idempotent,
:method => 'POST',
:parser => parser
})
rescue Excon::Errors::HTTPStatusError => error
match = Fog::AWS::Errors.match_error(error)
raise if match.empty?
raise case match[:code]
when 'InvalidParameterValue'
Fog::AWS::ElasticBeanstalk::InvalidParameterError.slurp(error, match[:message])
else
Fog::AWS::ElasticBeanstalk::Error.slurp(error, "#{match[:code]} => #{match[:message]}")
end
end
end
end
end
end

205
lib/fog/aws/cdn.rb Normal file
View file

@ -0,0 +1,205 @@
require 'fog/aws/core'
module Fog
module CDN
class Aws < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
requires :aws_access_key_id, :aws_secret_access_key
recognizes :host, :path, :port, :scheme, :version, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
model_path 'fog/aws/models/cdn'
model :distribution
collection :distributions
model :streaming_distribution
collection :streaming_distributions
request_path 'fog/aws/requests/cdn'
request 'delete_distribution'
request 'delete_streaming_distribution'
request 'get_distribution'
request 'get_distribution_list'
request 'get_invalidation_list'
request 'get_invalidation'
request 'get_streaming_distribution'
request 'get_streaming_distribution_list'
request 'post_distribution'
request 'post_streaming_distribution'
request 'post_invalidation'
request 'put_distribution_config'
request 'put_streaming_distribution_config'
class Mock
def self.data
@data ||= Hash.new do |hash, key|
hash[key] = {
:distributions => {},
:streaming_distributions => {},
:invalidations => {}
}
end
end
def self.reset
@data = nil
end
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
setup_credentials(options)
end
def data
self.class.data[@aws_access_key_id]
end
def reset_data
self.class.data.delete(@aws_access_key_id)
end
def signature(params)
"foo"
end
def setup_credentials(options={})
@aws_access_key_id = options[:aws_access_key_id]
end
def self.distribution_id
random_id(14)
end
def self.generic_id
random_id(14)
end
def self.domain_name
"#{random_id(12).downcase}.cloudfront.net"
end
def self.random_id(length)
Fog::Mock.random_selection("abcdefghijklmnopqrstuvwxyz0123456789", length).upcase
end
CDN_ERRORS = {
:access_denies => {:code => 'AccessDenied',:msg => 'Access denied.',:status => 403},
:inappropriate_xml => {:code => 'InappropriateXML',:msg => 'The XML document you provided was well-formed and valid, but not appropriate for this operation.',:status => 400},
:internal_error => {:code => 'InternalError',:msg => 'We encountered an internal error. Please try again.',:status => 500},
:invalid_action => {:code => 'InvalidAction',:msg => 'The action specified is not valid.',:status => 400},
:invalid_argument => {:code => 'InvalidArgument',:msg => '%s', :status => 400},
:not_implemented => {:code => 'NotImplemented', :msg => 'Not implemented.',:status => 501},
:no_such_distribution => { :code => 'NoSuchDistribution', :msg => 'The specified distribution does not exist', :status => 404 },
:no_such_streaming_distribution => { :code => 'NoSuchStreamingDistribution', :msg => 'The specified streaming distribution does not exist', :status => 404 },
:no_such_invalidation => { :code => 'NoSuchInvalidation', :msg => 'The specified invalidation does not exist', :status => 404 },
:cname_exists => { :code => 'CNAMEAlreadyExists', :msg => 'One or more of the CNAMEs you provided are already associated with a different distribution', :status => 409 },
:illegal_update => { :code => 'IllegalUpdate', :msg => 'Origin and CallerReference cannot be updated.', :status => 400 },
:invalid_if_match_version => { :code => 'InvalidIfMatchVersion', :msg => 'The If-Match version is missing or not valid for the distribution.', :status => 400},
:distribution_not_disabled => { :code => 'DistributionNotDisabled', :msg => 'The distribution you are trying to delete has not been disabled.', :status => 409 },
}
def self.error(code, argument = '')
if error = CDN_ERRORS[code]
raise_error(error[:status], error[:code], error[:msg] % argument)
end
end
def self.raise_error(status, code, message='')
response = Excon::Response.new
response.status = status
response.body = <<EOF
<ErrorResponse xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/">
<Error>
<Type>Sender</Type>
<Code>#{code}</Code>
<Message>#{message}.</Message>
</Error>
<RequestId>#{Fog::AWS::Mock.request_id}</RequestId>
</ErrorResponse>
EOF
raise(Excon::Errors.status_error({:expects => 201}, response))
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to Cloudfront
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# cdn = Fog::AWS::CDN.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
#
# ==== Returns
# * cdn object with connection to aws.
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
setup_credentials(options)
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.cdn'
@connection_options = options[:connection_options] || {}
@host = options[:host] || 'cloudfront.amazonaws.com'
@path = options[:path] || '/'
@persistent = options.fetch(:persistent, true)
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@version = options[:version] || '2010-11-01'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
end
def reload
@connection.reset
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@hmac = Fog::HMAC.new('sha1', @aws_secret_access_key)
end
def request(params, &block)
refresh_credentials_if_expired
params[:headers] ||= {}
params[:headers]['Date'] = Fog::Time.now.to_date_header
params[:headers]['x-amz-security-token'] = @aws_session_token if @aws_session_token
params[:headers]['Authorization'] = "Aws #{@aws_access_key_id}:#{signature(params)}"
params[:path] = "/#{@version}/#{params[:path]}"
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(params, &block)
end
else
_request(params, &block)
end
end
def _request(params, &block)
@connection.request(params, &block)
end
def signature(params)
string_to_sign = params[:headers]['Date']
signed_string = @hmac.sign(string_to_sign)
Base64.encode64(signed_string).chomp!
end
end
end
end
end

View file

@ -0,0 +1,133 @@
require 'fog/aws/core'
module Fog
module AWS
class CloudFormation < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
requires :aws_access_key_id, :aws_secret_access_key
recognizes :host, :path, :port, :scheme, :persistent, :region, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
request_path 'fog/aws/requests/cloud_formation'
request :create_stack
request :update_stack
request :delete_stack
request :describe_stack_events
request :describe_stack_resources
request :describe_stacks
request :get_template
request :validate_template
request :list_stacks
request :list_stack_resources
class Mock
def initialize(options={})
Fog::Mock.not_implemented
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to CloudFormation
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# cf = CloudFormation.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
#
# ==== Returns
# * CloudFormation object with connection to Aws.
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.cloud_formation'
@connection_options = options[:connection_options] || {}
options[:region] ||= 'us-east-1'
@region = options[:region]
@host = options[:host] || "cloudformation.#{options[:region]}.amazonaws.com"
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
setup_credentials(options)
end
def reload
@connection.reset
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key, @region, 'cloudformation')
end
def request(params)
refresh_credentials_if_expired
idempotent = params.delete(:idempotent)
parser = params.delete(:parser)
body, headers = Fog::AWS.signed_params_v4(
params,
{ 'Content-Type' => 'application/x-www-form-urlencoded' },
{
:signer => @signer,
:aws_session_token => @aws_session_token,
:host => @host,
:path => @path,
:port => @port,
:version => '2010-05-15',
:method => 'POST'
}
)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(body, headers, idempotent, parser)
end
else
_request(body, headers, idempotent, parser)
end
end
def _request(body, headers, idempotent, parser)
@connection.request({
:body => body,
:expects => 200,
:idempotent => idempotent,
:headers => headers,
:method => 'POST',
:parser => parser
})
rescue Excon::Errors::HTTPStatusError => error
match = Fog::AWS::Errors.match_error(error)
raise if match.empty?
raise case match[:code]
when 'NotFound', 'ValidationError'
Fog::AWS::CloudFormation::NotFound.slurp(error, match[:message])
else
Fog::AWS::CloudFormation::Error.slurp(error, "#{match[:code]} => #{match[:message]}")
end
end
end
end
end
end

167
lib/fog/aws/cloud_watch.rb Normal file
View file

@ -0,0 +1,167 @@
require 'fog/aws/core'
module Fog
module AWS
class CloudWatch < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
requires :aws_access_key_id, :aws_secret_access_key
recognizes :region, :host, :path, :port, :scheme, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
request_path 'fog/aws/requests/cloud_watch'
request :list_metrics
request :get_metric_statistics
request :put_metric_data
request :describe_alarms
request :put_metric_alarm
request :delete_alarms
request :describe_alarm_history
request :enable_alarm_actions
request :disable_alarm_actions
request :describe_alarms_for_metric
request :set_alarm_state
model_path 'fog/aws/models/cloud_watch'
model :metric
collection :metrics
model :metric_statistic
collection :metric_statistics
model :alarm_datum
collection :alarm_data
model :alarm_history
collection :alarm_histories
model :alarm
collection :alarms
class Mock
def self.data
@data ||= Hash.new do |hash, region|
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:metric_alarms => {}
}
end
end
end
def self.reset
@data = nil
end
def initialize(options={})
@aws_access_key_id = options[:aws_access_key_id]
@region = options[:region] || 'us-east-1'
unless ['ap-northeast-1', 'ap-southeast-1', 'ap-southeast-2', 'eu-central-1', 'eu-west-1', 'sa-east-1', 'us-east-1', 'us-west-1', 'us-west-2'].include?(@region)
raise ArgumentError, "Unknown region: #{@region.inspect}"
end
end
def data
self.class.data[@region][@aws_access_key_id]
end
def reset_data
self.class.data[@region].delete(@aws_access_key_id)
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to Cloudwatch
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# elb = CloudWatch.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
# * region<~String> - optional region to use. For instance, 'eu-west-1', 'us-east-1', etc.
#
# ==== Returns
# * CloudWatch object with connection to Aws.
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@connection_options = options[:connection_options] || {}
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.cloud_watch'
options[:region] ||= 'us-east-1'
@region = options[:region]
@host = options[:host] || "monitoring.#{options[:region]}.amazonaws.com"
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
setup_credentials(options)
end
def reload
@connection.reset
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key,@region,'monitoring')
end
def request(params)
refresh_credentials_if_expired
idempotent = params.delete(:idempotent)
parser = params.delete(:parser)
body, headers = Aws.signed_params_v4(
params,
{ 'Content-Type' => 'application/x-www-form-urlencoded' },
{
:signer => @signer,
:aws_session_token => @aws_session_token,
:host => @host,
:path => @path,
:port => @port,
:version => '2010-08-01',
:method => 'POST'
}
)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(body, headers, idempotent, parser)
end
else
_request(body, headers, idempotent, parser)
end
end
def _request(body, headers, idempotent, parser)
@connection.request({
:body => body,
:expects => 200,
:headers => headers,
:idempotent => idempotent,
:method => 'POST',
:parser => parser
})
end
end
end
end
end

543
lib/fog/aws/compute.rb Normal file
View file

@ -0,0 +1,543 @@
require 'fog/aws/core'
module Fog
module Compute
class Aws < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
requires :aws_access_key_id, :aws_secret_access_key
recognizes :endpoint, :region, :host, :path, :port, :scheme, :persistent, :aws_session_token, :use_iam_profile, :aws_credentials_expire_at, :instrumentor, :instrumentor_name, :version
secrets :aws_secret_access_key, :hmac, :aws_session_token
model_path 'fog/aws/models/compute'
model :address
collection :addresses
model :dhcp_options
collection :dhcp_options
model :flavor
collection :flavors
model :image
collection :images
model :internet_gateway
collection :internet_gateways
model :key_pair
collection :key_pairs
model :network_acl
collection :network_acls
model :network_interface
collection :network_interfaces
model :route_table
collection :route_tables
model :security_group
collection :security_groups
model :server
collection :servers
model :snapshot
collection :snapshots
model :tag
collection :tags
model :volume
collection :volumes
model :spot_request
collection :spot_requests
model :subnet
collection :subnets
model :vpc
collection :vpcs
request_path 'fog/aws/requests/compute'
request :allocate_address
request :assign_private_ip_addresses
request :associate_address
request :associate_dhcp_options
request :attach_network_interface
request :associate_route_table
request :attach_internet_gateway
request :attach_volume
request :authorize_security_group_ingress
request :cancel_spot_instance_requests
request :create_dhcp_options
request :create_internet_gateway
request :create_image
request :create_key_pair
request :create_network_acl
request :create_network_acl_entry
request :create_network_interface
request :create_placement_group
request :create_route
request :create_route_table
request :create_security_group
request :create_snapshot
request :create_spot_datafeed_subscription
request :create_subnet
request :create_tags
request :create_volume
request :create_vpc
request :copy_image
request :copy_snapshot
request :delete_dhcp_options
request :delete_internet_gateway
request :delete_key_pair
request :delete_network_acl
request :delete_network_acl_entry
request :delete_network_interface
request :delete_security_group
request :delete_placement_group
request :delete_route
request :delete_route_table
request :delete_snapshot
request :delete_spot_datafeed_subscription
request :delete_subnet
request :delete_tags
request :delete_volume
request :delete_vpc
request :deregister_image
request :describe_account_attributes
request :describe_addresses
request :describe_availability_zones
request :describe_dhcp_options
request :describe_images
request :describe_instances
request :describe_internet_gateways
request :describe_reserved_instances
request :describe_instance_status
request :describe_key_pairs
request :describe_network_acls
request :describe_network_interface_attribute
request :describe_network_interfaces
request :describe_route_tables
request :describe_placement_groups
request :describe_regions
request :describe_reserved_instances_offerings
request :describe_security_groups
request :describe_snapshots
request :describe_spot_datafeed_subscription
request :describe_spot_instance_requests
request :describe_spot_price_history
request :describe_subnets
request :describe_tags
request :describe_volumes
request :describe_volume_status
request :describe_vpcs
request :describe_vpc_attribute
request :detach_network_interface
request :detach_internet_gateway
request :detach_volume
request :disassociate_address
request :disassociate_route_table
request :get_console_output
request :get_password_data
request :import_key_pair
request :modify_image_attribute
request :modify_instance_attribute
request :modify_network_interface_attribute
request :modify_snapshot_attribute
request :modify_subnet_attribute
request :modify_volume_attribute
request :modify_vpc_attribute
request :purchase_reserved_instances_offering
request :reboot_instances
request :release_address
request :replace_network_acl_association
request :replace_network_acl_entry
request :replace_route
request :register_image
request :request_spot_instances
request :reset_network_interface_attribute
request :revoke_security_group_ingress
request :run_instances
request :terminate_instances
request :start_instances
request :stop_instances
request :monitor_instances
request :unmonitor_instances
class InvalidURIError < Exception; end
# deprecation
class Real
def modify_image_attributes(*params)
Fog::Logger.deprecation("modify_image_attributes is deprecated, use modify_image_attribute instead [light_black](#{caller.first})[/]")
modify_image_attribute(*params)
end
# http://docs.aws.amazon.com/AwsEC2/latest/UserGuide/ec2-supported-platforms.html
def supported_platforms
describe_account_attributes.body["accountAttributeSet"].find{ |h| h["attributeName"] == "supported-platforms" }["values"]
end
end
class Mock
MOCKED_TAG_TYPES = {
'ami' => 'image',
'i' => 'instance',
'snap' => 'snapshot',
'vol' => 'volume',
'igw' => 'internet_gateway',
'acl' => 'network_acl',
'vpc' => 'vpc'
}
include Fog::AWS::CredentialFetcher::ConnectionMethods
include Fog::AWS::RegionMethods
def self.data
@data ||= Hash.new do |hash, region|
hash[region] = Hash.new do |region_hash, key|
owner_id = Fog::AWS::Mock.owner_id
security_group_id = Fog::AWS::Mock.security_group_id
region_hash[key] = {
:deleted_at => {},
:addresses => {},
:images => {},
:image_launch_permissions => Hash.new do |permissions_hash, image_key|
permissions_hash[image_key] = {
:users => []
}
end,
:instances => {},
:reserved_instances => {},
:key_pairs => {},
:limits => { :addresses => 5 },
:owner_id => owner_id,
:security_groups => {
'default' => {
'groupDescription' => 'default group',
'groupName' => 'default',
'groupId' => security_group_id,
'ipPermissionsEgress' => [],
'ipPermissions' => [
{
'groups' => [{'groupName' => 'default', 'userId' => owner_id, 'groupId' => security_group_id }],
'fromPort' => -1,
'toPort' => -1,
'ipProtocol' => 'icmp',
'ipRanges' => []
},
{
'groups' => [{'groupName' => 'default', 'userId' => owner_id, 'groupId' => security_group_id}],
'fromPort' => 0,
'toPort' => 65535,
'ipProtocol' => 'tcp',
'ipRanges' => []
},
{
'groups' => [{'groupName' => 'default', 'userId' => owner_id, 'groupId' => security_group_id}],
'fromPort' => 0,
'toPort' => 65535,
'ipProtocol' => 'udp',
'ipRanges' => []
}
],
'ownerId' => owner_id
},
'amazon-elb-sg' => {
'groupDescription' => 'amazon-elb-sg',
'groupName' => 'amazon-elb-sg',
'groupId' => 'amazon-elb',
'ownerId' => 'amazon-elb',
'ipPermissionsEgree' => [],
'ipPermissions' => [],
},
},
:network_acls => {},
:network_interfaces => {},
:snapshots => {},
:volumes => {},
:internet_gateways => {},
:tags => {},
:tag_sets => Hash.new do |tag_set_hash, resource_id|
tag_set_hash[resource_id] = {}
end,
:subnets => [],
:vpcs => [],
:dhcp_options => [],
:route_tables => [],
:account_attributes => [
{
"values" => ["5"],
"attributeName" => "vpc-max-security-groups-per-interface"
},
{
"values" => ["20"],
"attributeName" => "max-instances"
},
{
"values" => ["EC2", "VPC"],
"attributeName" => "supported-platforms"
},
{
"values" => ["none"],
"attributeName" => "default-vpc"
},
{
"values" => ["5"],
"attributeName" => "max-elastic-ips"
},
{
"values" => ["5"],
"attributeName" => "vpc-max-elastic-ips"
}
]
}
end
end
end
def self.reset
@data = nil
end
attr_accessor :region
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@aws_credentials_expire_at = Time::now + 20
setup_credentials(options)
@region = options[:region] || 'us-east-1'
if @endpoint = options[:endpoint]
endpoint = URI.parse(@endpoint)
@host = endpoint.host or raise InvalidURIError.new("could not parse endpoint: #{@endpoint}")
@path = endpoint.path
@port = endpoint.port
@scheme = endpoint.scheme
else
@host = options[:host] || "ec2.#{options[:region]}.amazonaws.com"
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
end
validate_aws_region(@host, @region)
end
def region_data
self.class.data[@region]
end
def data
self.region_data[@aws_access_key_id]
end
def reset_data
self.region_data.delete(@aws_access_key_id)
end
def visible_images
images = self.data[:images].values.reduce({}) do |h, image|
h.update(image['imageId'] => image)
end
self.region_data.each do |aws_access_key_id, data|
data[:image_launch_permissions].each do |image_id, list|
if list[:users].include?(self.data[:owner_id])
images.update(image_id => data[:images][image_id])
end
end
end
images
end
def supported_platforms
describe_account_attributes.body["accountAttributeSet"].find{ |h| h["attributeName"] == "supported-platforms" }["values"]
end
def enable_ec2_classic
set_supported_platforms(%w[EC2 VPC])
end
def disable_ec2_classic
set_supported_platforms(%w[VPC])
end
def set_supported_platforms(values)
self.data[:account_attributes].find { |h| h["attributeName"] == "supported-platforms" }["values"] = values
end
def tagged_resources(resources)
Array(resources).map do |resource_id|
if match = resource_id.match(/^(\w+)-[a-z0-9]{8}/i)
id = match.captures.first
else
raise(Fog::Service::NotFound.new("Unknown resource id #{resource_id}"))
end
if MOCKED_TAG_TYPES.has_key? id
type = MOCKED_TAG_TYPES[id]
else
raise(Fog::Service::NotFound.new("Mocking tags of resource #{resource_id} has not been implemented"))
end
case type
when 'image'
unless visible_images.has_key? resource_id
raise(Fog::Service::NotFound.new("Cannot tag #{resource_id}, the image does not exist"))
end
when 'vpc'
if self.data[:vpcs].select {|v| v['vpcId'] == resource_id }.empty?
raise(Fog::Service::NotFound.new("Cannot tag #{resource_id}, the vpc does not exist"))
end
else
unless self.data[:"#{type}s"][resource_id]
raise(Fog::Service::NotFound.new("Cannot tag #{resource_id}, the #{type} does not exist"))
end
end
{ 'resourceId' => resource_id, 'resourceType' => type }
end
end
def apply_tag_filters(resources, filters, resource_id_key)
tag_set_fetcher = lambda {|resource| self.data[:tag_sets][resource[resource_id_key]] }
# tag-key: match resources tagged with this key (any value)
if filters.key?('tag-key')
value = filters.delete('tag-key')
resources = resources.select{|r| tag_set_fetcher[r].key?(value)}
end
# tag-value: match resources tagged with this value (any key)
if filters.key?('tag-value')
value = filters.delete('tag-value')
resources = resources.select{|r| tag_set_fetcher[r].values.include?(value)}
end
# tag:key: match resources tagged with a key-value pair. Value may be an array, which is OR'd.
tag_filters = {}
filters.keys.each do |key|
tag_filters[key.gsub('tag:', '')] = filters.delete(key) if /^tag:/ =~ key
end
for tag_key, tag_value in tag_filters
resources = resources.select{|r| tag_value == tag_set_fetcher[r][tag_key]}
end
resources
end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
include Fog::AWS::RegionMethods
# Initialize connection to EC2
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# sdb = SimpleDB.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
# * region<~String> - optional region to use. For instance,
# 'eu-west-1', 'us-east-1', and etc.
# * aws_session_token<~String> - when using Session Tokens or Federated Users, a session_token must be presented
#
# ==== Returns
# * EC2 object with connection to aws.
attr_accessor :region
def initialize(options={})
@connection_options = options[:connection_options] || {}
@region = options[:region] ||= 'us-east-1'
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.compute'
@version = options[:version] || '2014-06-15'
@use_iam_profile = options[:use_iam_profile]
setup_credentials(options)
if @endpoint = options[:endpoint]
endpoint = URI.parse(@endpoint)
@host = endpoint.host or raise InvalidURIError.new("could not parse endpoint: #{@endpoint}")
@path = endpoint.path
@port = endpoint.port
@scheme = endpoint.scheme
else
@host = options[:host] || "ec2.#{options[:region]}.amazonaws.com"
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
end
validate_aws_region(@host, @region)
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
end
def reload
@connection.reset
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key,@region,'ec2')
end
def request(params)
refresh_credentials_if_expired
idempotent = params.delete(:idempotent)
parser = params.delete(:parser)
body, headers = Fog::AWS.signed_params_v4(
params,
{'Content-Type' => 'application/x-www-form-urlencoded'},
{
:host => @host,
:path => @path,
:port => @port,
:version => @version,
:signer => @signer,
:aws_session_token => @aws_session_token,
:method => "POST"
}
)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(body, headers, idempotent, parser)
end
else
_request(body, headers, idempotent, parser)
end
end
def _request(body, headers, idempotent, parser)
@connection.request({
:body => body,
:expects => 200,
:headers => headers,
:idempotent => idempotent,
:method => 'POST',
:parser => parser
})
rescue Excon::Errors::HTTPStatusError => error
match = Fog::AWS::Errors.match_error(error)
raise if match.empty?
raise case match[:code]
when 'NotFound', 'Unknown'
Fog::Compute::AWS::NotFound.slurp(error, match[:message])
else
Fog::Compute::AWS::Error.slurp(error, "#{match[:code]} => #{match[:message]}")
end
end
end
end
end
end

343
lib/fog/aws/core.rb Normal file
View file

@ -0,0 +1,343 @@
require 'fog/core'
require 'fog/xml'
require 'fog/json'
require 'fog/aws/credential_fetcher'
require 'fog/aws/region_methods'
require 'fog/aws/signaturev4'
module Fog
module AWS
extend Fog::Provider
service(:auto_scaling, 'AutoScaling')
service(:beanstalk, 'ElasticBeanstalk')
service(:cdn, 'CDN')
service(:compute, 'Compute')
service(:cloud_formation, 'CloudFormation')
service(:cloud_watch, 'CloudWatch')
service(:data_pipeline, 'DataPipeline')
service(:dynamodb, 'DynamoDB')
service(:dns, 'DNS')
service(:elasticache, 'Elasticache')
service(:elb, 'ELB')
service(:emr, 'EMR')
service(:glacier, 'Glacier')
service(:iam, 'IAM')
service(:rds, 'RDS')
service(:redshift, 'Redshift')
service(:ses, 'SES')
service(:simpledb, 'SimpleDB')
service(:sns, 'SNS')
service(:sqs, 'SQS')
service(:sts, 'STS')
service(:storage, 'Storage')
def self.indexed_param(key, values)
params = {}
unless key.include?('%d')
key << '.%d'
end
[*values].each_with_index do |value, index|
if value.respond_to?('keys')
k = format(key, index + 1)
value.each do | vkey, vvalue |
params["#{k}.#{vkey}"] = vvalue
end
else
params[format(key, index + 1)] = value
end
end
params
end
def self.serialize_keys(key, value, options = {})
case value
when Hash
value.each do | k, v |
options.merge!(serialize_keys("#{key}.#{k}", v))
end
return options
when Array
value.each_with_index do | it, idx |
options.merge!(serialize_keys("#{key}.member.#{(idx + 1)}", it))
end
return options
else
return {key => value}
end
end
def self.indexed_request_param(name, values)
idx = -1
Array(values).reduce({}) do |params, value|
params["#{name}.#{idx += 1}"] = value
params
end
end
def self.indexed_filters(filters)
params = {}
filters.keys.each_with_index do |key, key_index|
key_index += 1
params[format('Filter.%d.Name', key_index)] = key
[*filters[key]].each_with_index do |value, value_index|
value_index += 1
params[format('Filter.%d.Value.%d', key_index, value_index)] = value
end
end
params
end
def self.escape(string)
string.gsub(/([^a-zA-Z0-9_.\-~]+)/) {
"%" + $1.unpack("H2" * $1.bytesize).join("%").upcase
}
end
def self.signed_params_v4(params, headers, options={})
date = Fog::Time.now
params = params.merge('Version' => options[:version])
headers = headers.merge('Host' => options[:host], 'x-amz-date' => date.to_iso8601_basic)
headers['x-amz-security-token'] = options[:aws_session_token] if options[:aws_session_token]
body = ''
for key in params.keys.sort
unless (value = params[key]).nil?
body << "#{key}=#{escape(value.to_s)}&"
end
end
body.chop!
headers['Authorization'] = options[:signer].sign({:method => options[:method], :headers => headers, :body => body, :query => {}, :path => options[:path]}, date)
return body, headers
end
def self.signed_params(params, options = {})
params.merge!({
'AwsAccessKeyId' => options[:aws_access_key_id],
'SignatureMethod' => 'HmacSHA256',
'SignatureVersion' => '2',
'Timestamp' => Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
'Version' => options[:version]
})
params.merge!({
'SecurityToken' => options[:aws_session_token]
}) if options[:aws_session_token]
body = ''
for key in params.keys.sort
unless (value = params[key]).nil?
body << "#{key}=#{escape(value.to_s)}&"
end
end
string_to_sign = "POST\n#{options[:host]}:#{options[:port]}\n#{options[:path]}\n" << body.chop
signed_string = options[:hmac].sign(string_to_sign)
body << "Signature=#{escape(Base64.encode64(signed_string).chomp!)}"
body
end
class Mock
def self.arn(vendor, account_id, path, region = nil)
"arn:aws:#{vendor}:#{region}:#{account_id}:#{path}"
end
def self.availability_zone(region)
"#{region}#{Fog::Mock.random_selection('abcd', 1)}"
end
def self.box_usage
sprintf("%0.10f", rand / 100).to_f
end
def self.console_output
# "[ 0.000000] Linux version 2.6.18-xenU-ec2-v1.2 (root@domU-12-31-39-07-51-82) (gcc version 4.1.2 20070626 (Red Hat 4.1.2-13)) #2 SMP Wed Aug 19 09:04:38 EDT 2009"
Base64.decode64("WyAwLjAwMDAwMF0gTGludXggdmVyc2lvbiAyLjYuMTgteGVuVS1lYzItdjEu\nMiAocm9vdEBkb21VLTEyLTMxLTM5LTA3LTUxLTgyKSAoZ2NjIHZlcnNpb24g\nNC4xLjIgMjAwNzA2MjYgKFJlZCBIYXQgNC4xLjItMTMpKSAjMiBTTVAgV2Vk\nIEF1ZyAxOSAwOTowNDozOCBFRFQgMjAwOQ==\n")
end
def self.dns_name_for(ip_address)
"ec2-#{ip_address.gsub('.','-')}.compute-1.amazonaws.com"
end
def self.private_dns_name_for(ip_address)
"ip-#{ip_address.gsub('.','-')}.ec2.internal"
end
def self.image
path = []
(rand(3) + 2).times do
path << Fog::Mock.random_letters(rand(9) + 8)
end
{
"imageOwnerId" => Fog::Mock.random_letters(rand(5) + 4),
"blockDeviceMapping" => [],
"productCodes" => [],
"kernelId" => kernel_id,
"ramdiskId" => ramdisk_id,
"imageState" => "available",
"imageId" => image_id,
"architecture" => "i386",
"isPublic" => true,
"imageLocation" => path.join('/'),
"imageType" => "machine",
"rootDeviceType" => ["ebs","instance-store"][rand(2)],
"rootDeviceName" => "/dev/sda1"
}
end
def self.image_id
"ami-#{Fog::Mock.random_hex(8)}"
end
def self.key_fingerprint
fingerprint = []
20.times do
fingerprint << Fog::Mock.random_hex(2)
end
fingerprint.join(':')
end
def self.instance_id
"i-#{Fog::Mock.random_hex(8)}"
end
def self.ip_address
Fog::Mock.random_ip
end
def self.private_ip_address
ip_address.gsub(/^\d{1,3}\./,"10.")
end
def self.kernel_id
"aki-#{Fog::Mock.random_hex(8)}"
end
def self.key_material
OpenSSL::PKey::RSA.generate(1024).to_s
end
def self.owner_id
Fog::Mock.random_numbers(12)
end
def self.ramdisk_id
"ari-#{Fog::Mock.random_hex(8)}"
end
def self.request_id
request_id = []
request_id << Fog::Mock.random_hex(8)
3.times do
request_id << Fog::Mock.random_hex(4)
end
request_id << Fog::Mock.random_hex(12)
request_id.join('-')
end
class << self
alias_method :reserved_instances_id, :request_id
alias_method :reserved_instances_offering_id, :request_id
alias_method :sqs_message_id, :request_id
alias_method :sqs_sender_id, :request_id
end
def self.reservation_id
"r-#{Fog::Mock.random_hex(8)}"
end
def self.snapshot_id
"snap-#{Fog::Mock.random_hex(8)}"
end
def self.volume_id
"vol-#{Fog::Mock.random_hex(8)}"
end
def self.security_group_id
"sg-#{Fog::Mock.random_hex(8)}"
end
def self.network_acl_id
"acl-#{Fog::Mock.random_hex(8)}"
end
def self.network_acl_association_id
"aclassoc-#{Fog::Mock.random_hex(8)}"
end
def self.network_interface_id
"eni-#{Fog::Mock.random_hex(8)}"
end
def self.internet_gateway_id
"igw-#{Fog::Mock.random_hex(8)}"
end
def self.dhcp_options_id
"dopt-#{Fog::Mock.random_hex(8)}"
end
def self.vpc_id
"vpc-#{Fog::Mock.random_hex(8)}"
end
def self.subnet_id
"subnet-#{Fog::Mock.random_hex(8)}"
end
def self.zone_id
"zone-#{Fog::Mock.random_hex(8)}"
end
def self.change_id
Fog::Mock.random_letters_and_numbers(14)
end
def self.nameservers
[
'ns-2048.awsdns-64.com',
'ns-2049.awsdns-65.net',
'ns-2050.awsdns-66.org',
'ns-2051.awsdns-67.co.uk'
]
end
def self.key_id(length=21)
#Probably close enough
Fog::Mock.random_selection('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',length)
end
def self.rds_address(db_name,region)
"#{db_name}.#{Fog::Mock.random_letters(rand(12) + 4)}.#{region}.rds.amazonaws.com"
end
end
def self.parse_security_group_options(group_name, options)
options ||= Hash.new
if group_name.is_a?(Hash)
options = group_name
elsif group_name
if options.key?('GroupName')
raise Fog::Compute::AWS::Error, 'Arguments specified both group_name and GroupName in options'
end
options = options.clone
options['GroupName'] = group_name
end
name_specified = options.key?('GroupName') && !options['GroupName'].nil?
group_id_specified = options.key?('GroupId') && !options['GroupId'].nil?
unless name_specified || group_id_specified
raise Fog::Compute::AWS::Error, 'Neither GroupName nor GroupId specified'
end
if name_specified && group_id_specified
options.delete('GroupName')
end
options
end
module Errors
def self.match_error(error)
matcher = lambda {|s| s.match(/(?:.*<Code>(.*)<\/Code>)(?:.*<Message>(.*)<\/Message>)/m)}
[error.message, error.response.body].each(&Proc.new {|s|
match = matcher.call(s)
return {:code => match[1].split('.').last, :message => match[2]} if match
})
{} # we did not match the message or response body
end
end
end
end

View file

@ -0,0 +1,63 @@
require "fog/json"
module Fog
module AWS
module CredentialFetcher
INSTANCE_METADATA_HOST = "http://169.254.169.254"
INSTANCE_METADATA_PATH = "/latest/meta-data/iam/security-credentials/"
module ServiceMethods
def fetch_credentials(options)
if options[:use_iam_profile]
begin
connection = options[:connection] || Excon.new(INSTANCE_METADATA_HOST)
role_name = connection.get(:path => INSTANCE_METADATA_PATH, :expects => 200).body
role_data = connection.get(:path => INSTANCE_METADATA_PATH+role_name, :expects => 200).body
session = Fog::JSON.decode(role_data)
credentials = {}
credentials[:aws_access_key_id] = session['AccessKeyId']
credentials[:aws_secret_access_key] = session['SecretAccessKey']
credentials[:aws_session_token] = session['Token']
credentials[:aws_credentials_expire_at] = Time.xmlschema session['Expiration']
#these indicate the metadata service is unavailable or has no profile setup
credentials
rescue Excon::Errors::Error => e
Fog::Logger.warning("Unable to fetch credentials: #{e.message}")
super
end
else
super
end
end
end
module ConnectionMethods
def refresh_credentials_if_expired
refresh_credentials if credentials_expired?
end
private
def credentials_expired?
@use_iam_profile &&
(!@aws_credentials_expire_at ||
(@aws_credentials_expire_at && Fog::Time.now > @aws_credentials_expire_at - 15)) #new credentials become available from around 5 minutes before expiration time
end
def refresh_credentials
if @use_iam_profile
new_credentials = service.fetch_credentials :use_iam_profile => @use_iam_profile
if new_credentials.any?
setup_credentials new_credentials
return true
else
false
end
else
false
end
end
end
end
end
end

View file

@ -0,0 +1,126 @@
require 'fog/aws/core'
module Fog
module AWS
class DataPipeline < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
requires :aws_access_key_id, :aws_secret_access_key
recognizes :region, :host, :path, :port, :scheme, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
request_path 'fog/aws/requests/data_pipeline'
request :activate_pipeline
request :create_pipeline
request :delete_pipeline
request :describe_pipelines
request :list_pipelines
request :put_pipeline_definition
request :get_pipeline_definition
request :query_objects
request :describe_objects
model_path 'fog/aws/models/data_pipeline'
model :pipeline
collection :pipelines
class Mock
def initialize(options={})
Fog::Mock.not_implemented
end
end
class Real
attr_reader :region
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to DataPipeline
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# datapipeline = DataPipeline.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
# * region<~String> - optional region to use. For instance, 'eu-west-1', 'us-east-1' and etc.
#
# ==== Returns
# * DataPipeline object with connection to Aws.
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.data_pipeline'
@connection_options = options[:connection_options] || {}
@version = '2012-10-29'
@region = options[:region] || 'us-east-1'
@host = options[:host] || "datapipeline.#{@region}.amazonaws.com"
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
setup_credentials(options)
end
def owner_id
@owner_id ||= security_groups.get('default').owner_id
end
def reload
@connection.reset
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new(@aws_access_key_id, @aws_secret_access_key, @region, 'datapipeline')
end
def request(params)
refresh_credentials_if_expired
# Params for all DataPipeline requests
params.merge!({
:expects => 200,
:method => :post,
:path => '/',
})
date = Fog::Time.now
params[:headers] = {
'Date' => date.to_date_header,
'Host' => @host,
'X-Amz-Date' => date.to_iso8601_basic,
'Content-Type' => 'application/x-amz-json-1.1',
'Content-Length' => params[:body].bytesize.to_s,
}.merge!(params[:headers] || {})
params[:headers]['x-amz-security-token'] = @aws_session_token if @aws_session_token
params[:headers]['Authorization'] = @signer.sign(params, date)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(params)
end
else
_request(params)
end
end
def _request(params)
@connection.request(params)
end
end
end
end
end

154
lib/fog/aws/dns.rb Normal file
View file

@ -0,0 +1,154 @@
require 'fog/aws/core'
module Fog
module DNS
class Aws < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
requires :aws_access_key_id, :aws_secret_access_key
recognizes :host, :path, :port, :scheme, :version, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
model_path 'fog/aws/models/dns'
model :record
collection :records
model :zone
collection :zones
request_path 'fog/aws/requests/dns'
request :create_health_check
request :create_hosted_zone
request :delete_health_check
request :get_health_check
request :get_hosted_zone
request :delete_hosted_zone
request :list_health_checks
request :list_hosted_zones
request :change_resource_record_sets
request :list_resource_record_sets
request :get_change
class Mock
def self.data
@data ||= Hash.new do |hash, region|
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:buckets => {},
:limits => {
:duplicate_domains => 5
},
:zones => {},
:changes => {}
}
end
end
end
def self.reset
@data = nil
end
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
setup_credentials(options)
@region = options[:region]
end
def data
self.class.data[@region][@aws_access_key_id]
end
def reset_data
self.class.data[@region].delete(@aws_access_key_id)
end
def signature(params)
"foo"
end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to Route 53 DNS service
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# dns = Fog::AWS::DNS.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
#
# ==== Returns
# * dns object with connection to aws.
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
setup_credentials(options)
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.dns'
@connection_options = options[:connection_options] || {}
@host = options[:host] || 'route53.amazonaws.com'
@path = options[:path] || '/'
@persistent = options.fetch(:persistent, true)
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@version = options[:version] || '2013-04-01'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
end
def reload
@connection.reset
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@hmac = Fog::HMAC.new('sha1', @aws_secret_access_key)
end
def request(params, &block)
refresh_credentials_if_expired
params[:headers] ||= {}
params[:headers]['Date'] = Fog::Time.now.to_date_header
params[:headers]['x-amz-security-token'] = @aws_session_token if @aws_session_token
params[:headers]['X-Amzn-Authorization'] = "Aws3-HTTPS AwsAccessKeyId=#{@aws_access_key_id},Algorithm=HmacSHA1,Signature=#{signature(params)}"
params[:path] = "/#{@version}/#{params[:path]}"
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(params, &block)
end
else
_request(params, &block)
end
end
def _request(params, &block)
@connection.request(params, &block)
end
def signature(params)
string_to_sign = params[:headers]['Date']
signed_string = @hmac.sign(string_to_sign)
Base64.encode64(signed_string).chomp!
end
end
end
end
end

152
lib/fog/aws/dynamodb.rb Normal file
View file

@ -0,0 +1,152 @@
require 'fog/aws/core'
module Fog
module AWS
class DynamoDB < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
requires :aws_access_key_id, :aws_secret_access_key
recognizes :aws_session_token, :host, :path, :port, :scheme, :persistent, :region, :use_iam_profile, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
request_path 'fog/aws/requests/dynamodb'
request :batch_get_item
request :batch_write_item
request :create_table
request :delete_item
request :delete_table
request :describe_table
request :get_item
request :list_tables
request :put_item
request :query
request :scan
request :update_item
request :update_table
class Mock
def self.data
@data ||= Hash.new do |hash, key|
hash[key] = {
:domains => {}
}
end
end
def self.reset
@data = nil
end
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
setup_credentials(options)
end
def data
self.class.data[@aws_access_key_id]
end
def reset_data
self.class.data.delete(@aws_access_key_id)
end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to DynamoDB
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# ddb = DynamoDB.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
#
# ==== Returns
# * DynamoDB object with connection to aws
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@region = options[:region] || 'us-east-1'
setup_credentials(options)
@connection_options = options[:connection_options] || {}
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.dynamodb'
@host = options[:host] || "dynamodb.#{@region}.amazonaws.com"
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || '443'
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new(@aws_access_key_id, @aws_secret_access_key, @region, 'dynamodb')
end
def reload
@connection.reset
end
def request(params)
refresh_credentials_if_expired
# defaults for all dynamodb requests
params.merge!({
:expects => 200,
:method => :post,
:path => '/'
})
# setup headers and sign with signature v4
date = Fog::Time.now
params[:headers] = {
'Content-Type' => 'application/x-amz-json-1.0',
'Date' => date.to_iso8601_basic,
'Host' => @host,
}.merge!(params[:headers])
params[:headers]['x-amz-security-token'] = @aws_session_token if @aws_session_token
params[:headers]['Authorization'] = @signer.sign(params, date)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(params)
end
else
_request(params)
end
end
def _request(params)
response = @connection.request(params)
unless response.body.empty?
response.body = Fog::JSON.decode(response.body)
end
response
end
end
end
end
end

216
lib/fog/aws/elasticache.rb Normal file
View file

@ -0,0 +1,216 @@
require 'fog/aws/core'
module Fog
module AWS
class Elasticache < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
class IdentifierTaken < Fog::Errors::Error; end
class InvalidInstance < Fog::Errors::Error; end
class AuthorizationAlreadyExists < Fog::Errors::Error; end
requires :aws_access_key_id, :aws_secret_access_key
recognizes :region, :host, :path, :port, :scheme, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
request_path 'fog/aws/requests/elasticache'
request :create_cache_cluster
request :delete_cache_cluster
request :describe_cache_clusters
request :modify_cache_cluster
request :reboot_cache_cluster
request :create_cache_parameter_group
request :delete_cache_parameter_group
request :describe_cache_parameter_groups
request :modify_cache_parameter_group
request :reset_cache_parameter_group
request :describe_engine_default_parameters
request :describe_cache_parameters
request :describe_reserved_cache_nodes
request :create_cache_security_group
request :delete_cache_security_group
request :describe_cache_security_groups
request :authorize_cache_security_group_ingress
request :revoke_cache_security_group_ingress
request :create_cache_subnet_group
request :describe_cache_subnet_groups
request :delete_cache_subnet_group
request :describe_events
model_path 'fog/aws/models/elasticache'
model :cluster
collection :clusters
model :security_group
collection :security_groups
model :parameter_group
collection :parameter_groups
model :subnet_group
collection :subnet_groups
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.elasticache'
options[:region] ||= 'us-east-1'
@region = options[:region]
@host = options[:host] || "elasticache.#{options[:region]}.amazonaws.com"
@path = options[:path] || '/'
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new(
"#{@scheme}://#{@host}:#{@port}#{@path}", options[:persistent]
)
setup_credentials(options)
end
def reload
@connection.reset
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key, @region, 'elasticache')
end
def request(params)
refresh_credentials_if_expired
idempotent = params.delete(:idempotent)
parser = params.delete(:parser)
body, headers = Fog::AWS.signed_params_v4(
params,
{ 'Content-Type' => 'application/x-www-form-urlencoded' },
{
:signer => @signer,
:aws_session_token => @aws_session_token,
:method => 'POST',
:host => @host,
:path => @path,
:port => @port,
:version => '2013-06-15'
}
)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(body, headers, idempotent, parser)
end
else
_request(body, headers, idempotent, parser)
end
end
def _request(body, headers, idempotent, parser)
@connection.request({
:body => body,
:expects => 200,
:headers => headers,
:idempotent => idempotent,
:method => 'POST',
:parser => parser
})
rescue Excon::Errors::HTTPStatusError => error
match = Fog::AWS::Errors.match_error(error)
raise if match.empty?
raise case match[:code]
when 'CacheSecurityGroupNotFound', 'CacheParameterGroupNotFound', 'CacheClusterNotFound'
Fog::AWS::Elasticache::NotFound.slurp(error, match[:message])
when 'CacheSecurityGroupAlreadyExists'
Fog::AWS::Elasticache::IdentifierTaken.slurp(error, match[:message])
when 'InvalidParameterValue'
Fog::AWS::Elasticache::InvalidInstance.slurp(error, match[:message])
else
Fog::AWS::Elasticache::Error.slurp(error, "#{match[:code]} => #{match[:message]}")
end
end
end
class Mock
include Fog::AWS::CredentialFetcher::ConnectionMethods
def self.data
@data ||= Hash.new do |hash, region|
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:clusters => {}, # cache cluster data, indexed by cluster ID
:security_groups => {}, # security groups
:subnet_groups => {},
:parameter_groups => {"default.memcached1.4" => { "CacheParameterGroupFamily"=>"memcached1.4",
"Description"=>"Default parameter group for memcached1.4",
"CacheParameterGroupName"=>"default.memcached1.4"
},
"default.redis2.6" => {"CacheParameterGroupFamily"=>"redis2.6",
"Description"=>"Default parameter group for redis2.6",
"CacheParameterGroupName"=>"default.redis2.6"
}
}
}
end
end
end
def self.reset
@data = nil
end
def initialize(options={})
@aws_credentials_expire_at = Time::now + 20
setup_credentials(options)
@region = options[:region] || 'us-east-1'
unless ['ap-northeast-1', 'ap-southeast-1', 'eu-west-1', 'us-east-1',
'us-west-1', 'us-west-2', 'sa-east-1'].include?(@region)
raise ArgumentError, "Unknown region: #{@region.inspect}"
end
end
def region_data
self.class.data[@region]
end
def data
self.region_data[@aws_access_key_id]
end
def reset_data
self.region_data.delete(@aws_access_key_id)
end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
end
# returns an Array of (Mock) elasticache nodes, representated as Hashes
def create_cache_nodes(cluster_id, num_nodes = 1, port = '11211')
(1..num_nodes).map do |node_number|
node_id = "%04d" % node_number
{ # each hash represents a cache cluster node
"CacheNodeId" => node_id,
"Port" => port,
"ParameterGroupStatus" => "in-sync",
"CacheNodeStatus" => "available",
"CacheNodeCreateTime" => Time.now.utc.to_s,
"Address" =>
"#{cluster_id}.#{node_id}.use1.cache.amazonaws.com"
}
end
end
end
end
end
end

240
lib/fog/aws/elb.rb Normal file
View file

@ -0,0 +1,240 @@
require 'fog/aws/core'
module Fog
module AWS
class ELB < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
class DuplicatePolicyName < Fog::Errors::Error; end
class IdentifierTaken < Fog::Errors::Error; end
class InvalidInstance < Fog::Errors::Error; end
class InvalidConfigurationRequest < Fog::Errors::Error; end
class PolicyNotFound < Fog::Errors::Error; end
class PolicyTypeNotFound < Fog::Errors::Error; end
class Throttled < Fog::Errors::Error; end
class TooManyPolicies < Fog::Errors::Error; end
class ValidationError < Fog::Errors::Error; end
requires :aws_access_key_id, :aws_secret_access_key
recognizes :region, :host, :path, :port, :scheme, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
request_path 'fog/aws/requests/elb'
request :configure_health_check
request :create_app_cookie_stickiness_policy
request :create_lb_cookie_stickiness_policy
request :create_load_balancer
request :create_load_balancer_listeners
request :create_load_balancer_policy
request :delete_load_balancer
request :delete_load_balancer_listeners
request :delete_load_balancer_policy
request :deregister_instances_from_load_balancer
request :describe_instance_health
request :describe_load_balancers
request :describe_load_balancer_attributes
request :describe_load_balancer_policies
request :describe_load_balancer_policy_types
request :disable_availability_zones_for_load_balancer
request :enable_availability_zones_for_load_balancer
request :modify_load_balancer_attributes
request :register_instances_with_load_balancer
request :set_load_balancer_listener_ssl_certificate
request :set_load_balancer_policies_of_listener
request :attach_load_balancer_to_subnets
request :detach_load_balancer_from_subnets
request :apply_security_groups_to_load_balancer
request :set_load_balancer_policies_for_backend_server
request :add_tags
request :describe_tags
request :remove_tags
model_path 'fog/aws/models/elb'
model :load_balancer
collection :load_balancers
model :policy
collection :policies
model :listener
collection :listeners
model :backend_server_description
collection :backend_server_descriptions
class Mock
require 'fog/aws/elb/policy_types'
def self.data
@data ||= Hash.new do |hash, region|
owner_id = Fog::AWS::Mock.owner_id
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:owner_id => owner_id,
:load_balancers => {},
:policy_types => Fog::AWS::ELB::Mock::POLICY_TYPES
}
end
end
end
def self.dns_name(name, region)
"#{name}-#{Fog::Mock.random_hex(8)}.#{region}.elb.amazonaws.com"
end
def self.reset
@data = nil
end
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@region = options[:region] || 'us-east-1'
setup_credentials(options)
unless ['ap-northeast-1', 'ap-southeast-1', 'ap-southeast-2', 'eu-central-1', 'eu-west-1', 'us-east-1', 'us-west-1', 'us-west-2', 'sa-east-1'].include?(@region)
raise ArgumentError, "Unknown region: #{@region.inspect}"
end
end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key,@region,'elasticloadbalancing')
end
def data
self.class.data[@region][@aws_access_key_id]
end
def reset_data
self.class.data[@region].delete(@aws_access_key_id)
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to ELB
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# elb = ELB.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
# * region<~String> - optional region to use. For instance, 'eu-west-1', 'us-east-1', etc.
#
# ==== Returns
# * ELB object with connection to Aws.
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@connection_options = options[:connection_options] || {}
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.elb'
options[:region] ||= 'us-east-1'
@region = options[:region]
@host = options[:host] || "elasticloadbalancing.#{@region}.amazonaws.com"
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
setup_credentials(options)
end
def reload
@connection.reset
end
private
def setup_credentials(options={})
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key,@region,'elasticloadbalancing')
end
def request(params)
refresh_credentials_if_expired
idempotent = params.delete(:idempotent)
parser = params.delete(:parser)
body, headers = Fog::AWS.signed_params_v4(
params,
{ 'Content-Type' => 'application/x-www-form-urlencoded' },
{
:aws_session_token => @aws_session_token,
:signer => @signer,
:host => @host,
:path => @path,
:port => @port,
:version => '2012-06-01',
:method => 'POST'
}
)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(body, headers, idempotent, parser)
end
else
_request(body, headers, idempotent, parser)
end
end
def _request(body, headers, idempotent, parser)
@connection.request({
:body => body,
:expects => 200,
:headers => headers,
:idempotent => idempotent,
:method => 'POST',
:parser => parser
})
rescue Excon::Errors::HTTPStatusError => error
match = Fog::AWS::Errors.match_error(error)
raise if match.empty?
raise case match[:code]
when 'CertificateNotFound'
Fog::AWS::IAM::NotFound.slurp(error, match[:message])
when 'DuplicateLoadBalancerName'
Fog::AWS::ELB::IdentifierTaken.slurp(error, match[:message])
when 'DuplicatePolicyName'
Fog::AWS::ELB::DuplicatePolicyName.slurp(error, match[:message])
when 'InvalidInstance'
Fog::AWS::ELB::InvalidInstance.slurp(error, match[:message])
when 'InvalidConfigurationRequest'
# when do they fucking use this shit?
Fog::AWS::ELB::InvalidConfigurationRequest.slurp(error, match[:message])
when 'LoadBalancerNotFound'
Fog::AWS::ELB::NotFound.slurp(error, match[:message])
when 'PolicyNotFound'
Fog::AWS::ELB::PolicyNotFound.slurp(error, match[:message])
when 'PolicyTypeNotFound'
Fog::AWS::ELB::PolicyTypeNotFound.slurp(error, match[:message])
when 'Throttling'
Fog::AWS::ELB::Throttled.slurp(error, match[:message])
when 'TooManyPolicies'
Fog::AWS::ELB::TooManyPolicies.slurp(error, match[:message])
when 'ValidationError'
Fog::AWS::ELB::ValidationError.slurp(error, match[:message])
else
Fog::AWS::ELB::Error.slurp(error, "#{match[:code]} => #{match[:message]}")
end
end
end
end
end
end

View file

@ -0,0 +1,477 @@
class Fog::AWS::ELB::Mock
POLICY_TYPES = [{
"Description" => "",
"PolicyAttributeTypeDescriptions" => [{
"AttributeName"=>"CookieName",
"AttributeType"=>"String",
"Cardinality"=>"ONE",
"DefaultValue"=>"",
"Description"=>""
}],
"PolicyTypeName"=>"AppCookieStickinessPolicyType"
},
{
"Description" => "",
"PolicyAttributeTypeDescriptions" => [{
"AttributeName"=>"CookieExpirationPeriod",
"AttributeType"=>"String",
"Cardinality"=>"ONE",
"DefaultValue"=>"",
"Description"=>""
}],
"PolicyTypeName"=>"LBCookieStickinessPolicyType"
},
{
"Description" => "Policy containing a list of public keys to accept when authenticating the back-end server(s). This policy cannot be applied directly to back-end servers or listeners but must be part of a BackendServerAuthenticationPolicyType.",
"PolicyAttributeTypeDescriptions" => [{
"AttributeName"=>"PublicKey",
"AttributeType"=>"String",
"Cardinality"=>"ONE",
"DefaultValue"=>"",
"Description"=>""
}],
"PolicyTypeName"=>"PublicKeyPolicyType"
},
{
"Description" => "Listener policy that defines the ciphers and protocols that will be accepted by the load balancer. This policy can be associated only with HTTPS/SSL listeners.",
"PolicyAttributeTypeDescriptions" => [{
"AttributeName"=>"Protocol-SSLv2",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EDH-DSS-DES-CBC3-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-RSA-CAMELLIA128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DES-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-RC4-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-CAMELLIA128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"PSK-RC4-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"PSK-AES128-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-EDH-RSA-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"CAMELLIA128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-DSS-AES128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EDH-RSA-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-RSA-SEED-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-DES-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-RSA-CAMELLIA256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-DES-CBC3-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DES-CBC3-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-RC2-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EDH-DSS-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"PSK-AES256-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-AES256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-DES-CBC3-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"AES128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"DHE-DSS-SEED-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-CAMELLIA256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-RC4-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EDH-RSA-DES-CBC3-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-DES-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"Protocol-TLSv1",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"PSK-3DES-EDE-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"SEED-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-DSS-CAMELLIA256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"IDEA-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"RC2-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-AES128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"RC4-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"AES256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"Protocol-SSLv3",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"EXP-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DES-CBC3-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"DHE-RSA-AES128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-EDH-DSS-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-RC2-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-RSA-AES256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"KRB5-DES-CBC3-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"TRUE",
"Description"=>""
},
{
"AttributeName"=>"EXP-RC2-CBC-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-ADH-RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-RC4-MD5",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"CAMELLIA256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-DSS-CAMELLIA128-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-KRB5-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"EXP-ADH-DES-CBC-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"DHE-DSS-AES256-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
},
{
"AttributeName"=>"ADH-SEED-SHA",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"FALSE",
"Description"=>""
}],
"PolicyTypeName"=>"SSLNegotiationPolicyType"
},
{
"Description"=>"Policy that controls whether to include the IP address and port of the originating request for TCP messages. This policy operates on TCP/SSL listeners only",
"PolicyAttributeTypeDescriptions"=>[{
"AttributeName"=>"ProxyProtocol",
"AttributeType"=>"Boolean",
"Cardinality"=>"ONE",
"DefaultValue"=>"",
"Description"=>""
}],
"PolicyTypeName"=>"ProxyProtocolPolicyType"
}]
end

139
lib/fog/aws/emr.rb Normal file
View file

@ -0,0 +1,139 @@
require 'fog/aws/core'
module Fog
module AWS
class EMR < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
class IdentifierTaken < Fog::Errors::Error; end
requires :aws_access_key_id, :aws_secret_access_key
recognizes :region, :host, :path, :port, :scheme, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
request_path 'fog/aws/requests/emr'
request :add_instance_groups
request :add_job_flow_steps
request :describe_job_flows
request :modify_instance_groups
request :run_job_flow
request :set_termination_protection
request :terminate_job_flows
# model_path 'fog/aws/models/rds'
# model :server
# collection :servers
# model :snapshot
# collection :snapshots
# model :parameter_group
# collection :parameter_groups
#
# model :parameter
# collection :parameters
#
# model :security_group
# collection :security_groups
class Mock
def initialize(options={})
Fog::Mock.not_implemented
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to EMR
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# emr = EMR.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
# * region<~String> - optional region to use. For instance, in 'eu-west-1', 'us-east-1' and etc.
#
# ==== Returns
# * EMR object with connection to Aws.
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@connection_options = options[:connection_options] || {}
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.emr'
options[:region] ||= 'us-east-1'
@host = options[:host] || "elasticmapreduce.#{options[:region]}.amazonaws.com"
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
@region = options[:region]
setup_credentials(options)
end
def reload
@connection.reset
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key, @region, 'elasticmapreduce')
end
def request(params)
refresh_credentials_if_expired
idempotent = params.delete(:idempotent)
parser = params.delete(:parser)
body, headers = Fog::AWS.signed_params_v4(
params,
{ 'Content-Type' => 'application/x-www-form-urlencoded' },
{
:signer => @signer,
:aws_session_token => @aws_session_token,
:method => 'POST',
:host => @host,
:path => @path,
:port => @port,
:version => '2009-03-31' #'2010-07-28'
}
)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(body, headers, idempotent, parser)
end
else
_request(body, headers, idempotent, parser)
end
end
def _request(body, headers, idempotent, parser)
@connection.request({
:body => body,
:expects => 200,
:headers => headers,
:idempotent => idempotent,
:method => 'POST',
:parser => parser
})
end
end
end
end
end

179
lib/fog/aws/glacier.rb Normal file
View file

@ -0,0 +1,179 @@
require 'fog/aws/core'
module Fog
module AWS
class Glacier < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
requires :aws_access_key_id, :aws_secret_access_key
recognizes :region, :host, :path, :port, :scheme, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :instrumentor, :instrumentor_name
request_path 'fog/aws/requests/glacier'
request :abort_multipart_upload
request :complete_multipart_upload
request :create_archive
request :create_vault
request :delete_archive
request :delete_vault
request :delete_vault_notification_configuration
request :describe_job
request :describe_vault
request :get_job_output
request :get_vault_notification_configuration
request :initiate_job
request :initiate_multipart_upload
request :list_jobs
request :list_multipart_uploads
request :list_parts
request :list_vaults
request :set_vault_notification_configuration
request :upload_part
model_path 'fog/aws/models/glacier'
model :vault
collection :vaults
MEGABYTE = 1024*1024
class TreeHash
def self.digest(body)
new.add_part(body)
end
def reduce_digests(digests)
while digests.length > 1
digests = digests.each_slice(2).map do |pair|
if pair.length == 2
Digest::SHA256.digest(pair[0]+pair[1])
else
pair.first
end
end
end
digests.first
end
def initialize
@digests = []
end
def add_part(bytes)
part = self.digest_for_part(bytes)
@digests << part
part.unpack('H*').first
end
def digest_for_part(body)
chunk_count = [body.bytesize / MEGABYTE + (body.bytesize % MEGABYTE > 0 ? 1 : 0), 1].max
if body.respond_to? :byteslice
digests_for_part = chunk_count.times.map {|chunk_index| Digest::SHA256.digest(body.byteslice(chunk_index * MEGABYTE, MEGABYTE))}
else
if body.respond_to? :encoding
old_encoding = body.encoding
body.force_encoding('BINARY')
end
digests_for_part = chunk_count.times.map {|chunk_index| Digest::SHA256.digest(body.slice(chunk_index * MEGABYTE, MEGABYTE))}
if body.respond_to? :encoding
body.force_encoding(old_encoding)
end
end
reduce_digests(digests_for_part)
end
def hexdigest
digest.unpack('H*').first
end
def digest
reduce_digests(@digests)
end
end
class Mock
def initialize(options={})
Fog::Mock.not_implemented
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to Glacier
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# ses = SES.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
# * region<~String> - optional region to use. For instance, 'us-east-1' and etc.
#
# ==== Returns
# * Glacier object with connection to Aws.
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@region = options[:region] || 'us-east-1'
setup_credentials(options)
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.glacier'
@connection_options = options[:connection_options] || {}
@host = options[:host] || "glacier.#{@region}.amazonaws.com"
@version = '2012-06-01'
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key,@region,'glacier')
end
def request(params, &block)
refresh_credentials_if_expired
date = Fog::Time.now
params[:headers]['Date'] = date.to_date_header
params[:headers]['x-amz-date'] = date.to_iso8601_basic
params[:headers]['Host'] = @host
params[:headers]['x-amz-glacier-version'] = @version
params[:headers]['x-amz-security-token'] = @aws_session_token if @aws_session_token
params[:headers]['Authorization'] = @signer.sign params, date
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(params, &block)
end
else
_request(params, &block)
end
end
def _request(params, &block)
response = @connection.request(params, &block)
if response.headers['Content-Type'] == 'application/json' && response.body.size > 0 #body will be empty if the streaming form has been used
response.body = Fog::JSON.decode(response.body)
end
response
end
end
end
end
end

260
lib/fog/aws/iam.rb Normal file
View file

@ -0,0 +1,260 @@
require 'fog/aws/core'
module Fog
module AWS
class IAM < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
class EntityAlreadyExists < Fog::AWS::IAM::Error; end
class KeyPairMismatch < Fog::AWS::IAM::Error; end
class LimitExceeded < Fog::AWS::IAM::Error; end
class MalformedCertificate < Fog::AWS::IAM::Error; end
class ValidationError < Fog::AWS::IAM::Error; end
requires :aws_access_key_id, :aws_secret_access_key
recognizes :host, :path, :port, :scheme, :persistent, :instrumentor, :instrumentor_name, :aws_session_token, :use_iam_profile, :aws_credentials_expire_at
request_path 'fog/aws/requests/iam'
request :add_user_to_group
request :add_role_to_instance_profile
request :create_access_key
request :create_account_alias
request :create_group
request :create_instance_profile
request :create_login_profile
request :create_role
request :create_user
request :delete_access_key
request :delete_account_password_policy
request :delete_account_alias
request :delete_group
request :delete_group_policy
request :delete_instance_profile
request :delete_login_profile
request :delete_role
request :delete_role_policy
request :delete_server_certificate
request :delete_signing_certificate
request :delete_user
request :delete_user_policy
request :get_account_summary
request :get_account_password_policy
request :get_group
request :get_group_policy
request :get_instance_profile
request :get_role_policy
request :get_login_profile
request :get_server_certificate
request :get_role
request :get_user
request :get_user_policy
request :list_access_keys
request :list_account_aliases
request :list_group_policies
request :list_groups
request :list_groups_for_user
request :list_instance_profiles
request :list_instance_profiles_for_role
request :list_mfa_devices
request :list_roles
request :list_role_policies
request :list_server_certificates
request :list_signing_certificates
request :list_user_policies
request :list_users
request :put_group_policy
request :put_role_policy
request :put_user_policy
request :remove_role_from_instance_profile
request :remove_user_from_group
request :update_access_key
request :update_group
request :update_login_profile
request :update_account_password_policy
request :update_server_certificate
request :update_signing_certificate
request :update_user
request :upload_server_certificate
request :upload_signing_certificate
model_path 'fog/aws/models/iam'
model :user
collection :users
model :policy
collection :policies
model :access_key
collection :access_keys
model :role
collection :roles
class Mock
def self.data
@data ||= Hash.new do |hash, key|
hash[key] = {
:owner_id => Fog::AWS::Mock.owner_id,
:server_certificates => {},
:access_keys => [{
"Status" => "Active",
"AccessKeyId" => key
}],
:devices => [{
:enable_date => Time.now,
:serial_number => 'R1234',
:user_name => 'Bob'
}],
:users => Hash.new do |uhash, ukey|
uhash[ukey] = {
:user_id => Fog::AWS::Mock.key_id,
:path => '/',
:arn => "arn:aws:iam::#{Fog::AWS::Mock.owner_id}:user/#{ukey}",
:access_keys => [],
:created_at => Time.now,
:policies => {}
}
end,
:groups => Hash.new do |ghash, gkey|
ghash[gkey] = {
:group_id => Fog::AWS::Mock.key_id,
:arn => "arn:aws:iam::#{Fog::AWS::Mock.owner_id}:group/#{gkey}",
:members => [],
:created_at => Time.now,
:policies => {}
}
end
}
end
end
def self.reset
@data = nil
end
def self.server_certificate_id
Fog::Mock.random_hex(16)
end
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@aws_credentials_expire_at = Time::now + 20
setup_credentials(options)
end
def data
self.class.data[@aws_access_key_id]
end
def reset_data
self.class.data.delete(@aws_access_key_id)
end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
end
end
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to IAM
#
# ==== Notes
# options parameter must include values for :aws_access_key_id and
# :aws_secret_access_key in order to create a connection
#
# ==== Examples
# iam = IAM.new(
# :aws_access_key_id => your_aws_access_key_id,
# :aws_secret_access_key => your_aws_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
#
# ==== Returns
# * IAM object with connection to Aws.
def initialize(options={})
@use_iam_profile = options[:use_iam_profile]
@connection_options = options[:connection_options] || {}
@instrumentor = options[:instrumentor]
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.iam'
@host = options[:host] || 'iam.amazonaws.com'
@path = options[:path] || '/'
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
setup_credentials(options)
end
def reload
@connection.reset
end
private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
#global services that have no region are signed with the us-east-1 region
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key,'us-east-1','iam')
end
def request(params)
refresh_credentials_if_expired
idempotent = params.delete(:idempotent)
parser = params.delete(:parser)
body, headers = Fog::AWS.signed_params_v4(
params,
{ 'Content-Type' => 'application/x-www-form-urlencoded' },
{
:signer => @signer,
:aws_session_token => @aws_session_token,
:host => @host,
:path => @path,
:port => @port,
:version => '2010-05-08',
:method => 'POST'
}
)
if @instrumentor
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
_request(body, headers, idempotent, parser)
end
else
_request(body, headers, idempotent, parser)
end
end
def _request(body, headers, idempotent, parser)
@connection.request({
:body => body,
:expects => 200,
:idempotent => idempotent,
:headers => headers,
:method => 'POST',
:parser => parser
})
rescue Excon::Errors::HTTPStatusError => error
match = Fog::AWS::Errors.match_error(error)
raise if match.empty?
raise case match[:code]
when 'CertificateNotFound', 'NoSuchEntity'
Fog::AWS::IAM::NotFound.slurp(error, match[:message])
when 'EntityAlreadyExists', 'KeyPairMismatch', 'LimitExceeded', 'MalformedCertificate', 'ValidationError'
Fog::AWS::IAM.const_get(match[:code]).slurp(error, match[:message])
else
Fog::AWS::IAM::Error.slurp(error, "#{match[:code]} => #{match[:message]}")
end
end
end
end
end
end

View file

@ -0,0 +1,37 @@
require 'fog/aws/models/auto_scaling/activity'
module Fog
module AWS
class AutoScaling
class Activities < Fog::Collection
model Fog::AWS::AutoScaling::Activity
attribute :filters
# Creates a new scaling policy.
def initialize(attributes={})
self.filters = attributes
super(attributes)
end
def all(filters_arg = filters)
data = []
next_token = nil
filters = filters_arg
loop do
result = service.describe_scaling_activities(filters.merge('NextToken' => next_token)).body['DescribeScalingActivitiesResult']
data += result['Activities']
next_token = result['NextToken']
break if next_token.nil?
end
load(data)
end
def get(identity)
data = service.describe_scaling_activities('ActivityId' => identity).body['DescribeScalingActivitiesResult']['Activities'].first
new(data) unless data.nil?
end
end
end
end
end

View file

@ -0,0 +1,27 @@
require 'fog/core/model'
module Fog
module AWS
class AutoScaling
class Activity < Fog::Model
identity :id, :aliases => 'ActivityId'
attribute :auto_scaling_group_name, :aliases => 'AutoScalingGroupName'
attribute :cause, :aliases => 'Cause'
attribute :description, :aliases => 'Description'
attribute :end_time, :aliases => 'EndTime'
attribute :progress, :aliases => 'Progress'
attribute :start_time, :aliases => 'StartTime'
attribute :status_code, :aliases => 'StatusCode'
attribute :status_message, :aliases => 'StatusMessage'
def group
service.groups.get(attributes['AutoScalingGroupName'])
end
def save
raise "Operation not supported"
end
end
end
end
end

View file

@ -0,0 +1,69 @@
require 'fog/core/model'
module Fog
module AWS
class AutoScaling
class Configuration < Fog::Model
identity :id, :aliases => 'LaunchConfigurationName'
attribute :arn, :aliases => 'LaunchConfigurationARN'
attribute :associate_public_ip, :aliases => 'AssociatePublicIpAddress'
attribute :block_device_mappings, :aliases => 'BlockDeviceMappings'
attribute :created_at, :aliases => 'CreatedTime'
attribute :ebs_optimized, :aliases => 'EbsOptimized'
attribute :iam_instance_profile, :aliases => 'IamInstanceProfile'
attribute :image_id, :aliases => 'ImageId'
#attribute :instance_monitoring, :aliases => 'InstanceMonitoring'
attribute :instance_monitoring, :aliases => 'InstanceMonitoring', :squash => 'Enabled'
attribute :instance_type, :aliases => 'InstanceType'
attribute :kernel_id, :aliases => 'KernelId'
attribute :key_name, :aliases => 'KeyName'
attribute :ramdisk_id, :aliases => 'RamdiskId'
attribute :security_groups, :aliases => 'SecurityGroups'
attribute :user_data, :aliases => 'UserData'
attribute :spot_price, :aliases => 'SpotPrice'
attribute :placement_tenancy, :aliases => 'PlacementTenancy'
def initialize(attributes={})
#attributes[:availability_zones] ||= %w(us-east-1a us-east-1b us-east-1c us-east-1d)
#attributes['ListenerDescriptions'] ||= [{
# 'Listener' => {'LoadBalancerPort' => 80, 'InstancePort' => 80, 'Protocol' => 'http'},
# 'PolicyNames' => []
#}]
#attributes['Policies'] ||= {'AppCookieStickinessPolicies' => [], 'LBCookieStickinessPolicies' => []}
super
end
def ready?
# AutoScaling requests are synchronous
true
end
def save
requires :id
requires :image_id
requires :instance_type
options = Hash[self.class.aliases.map { |key, value| [key, send(value)] }]
options.delete_if { |key, value| value.nil? }
service.create_launch_configuration(image_id, instance_type, id, options) #, listeners.map{|l| l.to_params})
# reload instead of merge attributes b/c some attrs (like HealthCheck)
# may be set, but only the DNS name is returned in the create_load_balance
# API call
reload
end
def reload
super
self
end
def destroy
requires :id
service.delete_launch_configuration(id)
end
end
end
end
end

View file

@ -0,0 +1,33 @@
require 'fog/aws/models/auto_scaling/configuration'
module Fog
module AWS
class AutoScaling
class Configurations < Fog::Collection
model Fog::AWS::AutoScaling::Configuration
# Creates a new launch configuration
def initialize(attributes={})
super
end
def all
data = []
next_token = nil
loop do
result = service.describe_launch_configurations('NextToken' => next_token).body['DescribeLaunchConfigurationsResult']
data += result['LaunchConfigurations']
next_token = result['NextToken']
break if next_token.nil?
end
load(data)
end
def get(identity)
data = service.describe_launch_configurations('LaunchConfigurationNames' => identity).body['DescribeLaunchConfigurationsResult']['LaunchConfigurations'].first
new(data) unless data.nil?
end
end
end
end
end

View file

@ -0,0 +1,150 @@
require 'fog/core/model'
module Fog
module AWS
class AutoScaling
class Group < Fog::Model
identity :id, :aliases => 'AutoScalingGroupName'
attribute :arn, :aliases => 'AutoScalingGroupARN'
attribute :availability_zones, :aliases => 'AvailabilityZones'
attribute :created_at, :aliases => 'CreatedTime'
attribute :default_cooldown, :aliases => 'DefaultCooldown'
attribute :desired_capacity, :aliases => 'DesiredCapacity'
attribute :enabled_metrics, :aliases => 'EnabledMetrics'
attribute :health_check_grace_period, :aliases => 'HealthCheckGracePeriod'
attribute :health_check_type, :aliases => 'HealthCheckType'
attribute :instances, :aliases => 'Instances'
attribute :launch_configuration_name, :aliases => 'LaunchConfigurationName'
attribute :load_balancer_names, :aliases => 'LoadBalancerNames'
attribute :max_size, :aliases => 'MaxSize'
attribute :min_size, :aliases => 'MinSize'
attribute :placement_group, :aliases => 'PlacementGroup'
attribute :suspended_processes, :aliases => 'SuspendedProcesses'
attribute :tags, :aliases => 'Tags'
attribute :termination_policies, :aliases => 'TerminationPolicies'
attribute :vpc_zone_identifier, :aliases => 'VPCZoneIdentifier'
def initialize(attributes={})
self.instances = []
self.default_cooldown = 300
self.desired_capacity = 0
self.enabled_metrics = []
self.health_check_grace_period = 0
self.health_check_type = 'EC2'
self.load_balancer_names = []
self.max_size = 0
self.min_size = 0
self.suspended_processes = []
self.tags = {}
self.termination_policies = ['Default']
super
end
def activities
requires :id
data = []
next_token = nil
loop do
result = service.describe_scaling_activities('AutoScalingGroupName' => id, 'NextToken' => next_token).body['DescribeScalingActivitiesResult']
data += result['Activities']
next_token = result['NextToken']
break if next_token.nil?
end
Fog::AWS::AutoScaling::Activities.new({
:data => data,
:service => service,
#:load_balancer => self
})
end
def configuration
requires :launch_configuration_name
service.configurations.get(launch_configuration_name)
end
def disable_metrics_collection(metrics = {})
requires :id
service.disable_metrics_collection(id, 'Metrics' => metrics)
reload
end
def enable_metrics_collection(granularity = '1Minute', metrics = {})
requires :id
service.enable_metrics_collection(id, granularity, 'Metrics' => metrics)
reload
end
def instances
Fog::AWS::AutoScaling::Instances.new(:service => service).load(attributes[:instances])
end
def instances_in_service
attributes[:instances].select {|hash| hash['LifecycleState'] == 'InService'}.map {|hash| hash['InstanceId']}
end
def instances_out_service
attributes[:instances].select {|hash| hash['LifecycleState'] == 'OutOfService'}.map {|hash| hash['InstanceId']}
end
def resume_processes(processes = [])
requires :id
service.resume_processes(id, 'ScalingProcesses' => processes)
reload
end
def suspend_processes(processes = [])
requires :id
service.suspend_processes(id, 'ScalingProcesses' => processes)
reload
end
def ready?
# Is this useful?
#instances_in_service.length == desired_capacity
#instances_in_service.length >= min_size
true
end
def save
requires :id
requires :availability_zones
requires :launch_configuration_name
requires :max_size
requires :min_size
service.create_auto_scaling_group(id, availability_zones, launch_configuration_name, max_size, min_size, filtered_options(:create_auto_scaling_group))
reload
end
#def reload
# super
# self
#end
def destroy(options = { :force => false })
requires :id
opts = {}
opts.merge!({'ForceDelete' => true}) if options[:force]
service.delete_auto_scaling_group(id, opts)
end
def update
requires :id
service.update_auto_scaling_group(id, filtered_options(:update_auto_scaling_group) )
reload
end
def filtered_options(method)
Hash[options.select{|k,_| ExpectedOptions[method].include?(k)}]
end
def options
ret = Hash[self.class.aliases.map { |key, value| [key, send(value)] }]
ret.delete_if { |key, value| value.nil? }
ret
end
end
end
end
end

View file

@ -0,0 +1,37 @@
require 'fog/aws/models/auto_scaling/group'
module Fog
module AWS
class AutoScaling
class Groups < Fog::Collection
model Fog::AWS::AutoScaling::Group
attribute :filters
# Creates a new auto scaling group.
def initialize(attributes={})
self.filters = attributes
super
end
def all(filters_arg = filters)
data = []
next_token = nil
filters = filters_arg
loop do
result = service.describe_auto_scaling_groups(filters.merge('NextToken' => next_token)).body['DescribeAutoScalingGroupsResult']
data += result['AutoScalingGroups']
next_token = result['NextToken']
break if next_token.nil?
end
load(data)
end
def get(identity)
data = service.describe_auto_scaling_groups('AutoScalingGroupNames' => identity).body['DescribeAutoScalingGroupsResult']['AutoScalingGroups'].first
new(data) unless data.nil?
end
end
end
end
end

View file

@ -0,0 +1,58 @@
require 'fog/core/model'
module Fog
module AWS
class AutoScaling
class Instance < Fog::Model
identity :id, :aliases => 'InstanceId'
attribute :auto_scaling_group_name, :aliases => 'AutoScalingGroupName'
attribute :availability_zone, :aliases => 'AvailabilityZone'
attribute :health_status, :aliases => 'HealthStatus'
attribute :launch_configuration_name, :aliases => 'LaunchConfigurationName'
attribute :life_cycle_state, :aliases => 'LifecycleState'
def initialize(attributes={})
super
end
def group
service.groups.get(attributes['AutoScalingGroupName'])
end
def configuration
service.configurations.get(attributes['LaunchConfigurationName'])
end
def set_health(health_status, options)
requires :id
service.set_instance_health(health_status, id, options)
reload
end
def terminate(should_decrement_desired_capacity)
requires :id
service.terminate_instance_in_auto_scaling_group(id, should_decrement_desired_capacity)
reload
end
def healthy?
health_status == 'Healthy'
end
def ready?
life_cycle_state == 'InService'
end
def reload
super
self
end
#def destroy
# requires :id
# service.delete_auto_scaling_group(id)
#end
end
end
end
end

View file

@ -0,0 +1,28 @@
require 'fog/aws/models/auto_scaling/instance'
module Fog
module AWS
class AutoScaling
class Instances < Fog::Collection
model Fog::AWS::AutoScaling::Instance
def all
data = []
next_token = nil
loop do
result = service.describe_auto_scaling_instances('NextToken' => next_token).body['DescribeAutoScalingInstancesResult']
data += result['AutoScalingInstances']
next_token = result['NextToken']
break if next_token.nil?
end
load(data)
end
def get(identity)
data = service.describe_auto_scaling_instances('InstanceIds' => identity).body['DescribeAutoScalingInstancesResult']['AutoScalingInstances'].first
new(data) unless data.nil?
end
end
end
end
end

View file

@ -0,0 +1,37 @@
require 'fog/aws/models/auto_scaling/policy'
module Fog
module AWS
class AutoScaling
class Policies < Fog::Collection
model Fog::AWS::AutoScaling::Policy
attribute :filters
# Creates a new scaling policy.
def initialize(attributes={})
self.filters = attributes
super(attributes)
end
def all(filters_arg = filters)
data = []
next_token = nil
self.filters = filters_arg
loop do
result = service.describe_policies(filters.merge('NextToken' => next_token)).body['DescribePoliciesResult']
data += result['ScalingPolicies']
next_token = result['NextToken']
break if next_token.nil?
end
load(data)
end
def get(identity, auto_scaling_group = nil)
data = service.describe_policies('PolicyNames' => identity, 'AutoScalingGroupName' => auto_scaling_group).body['DescribePoliciesResult']['ScalingPolicies'].first
new(data) unless data.nil?
end
end
end
end
end

View file

@ -0,0 +1,46 @@
require 'fog/core/model'
module Fog
module AWS
class AutoScaling
class Policy < Fog::Model
identity :id, :aliases => 'PolicyName'
attribute :arn, :aliases => 'PolicyARN'
attribute :adjustment_type, :aliases => 'AdjustmentType'
attribute :alarms, :aliases => 'Alarms'
attribute :auto_scaling_group_name, :aliases => 'AutoScalingGroupName'
attribute :cooldown, :aliases => 'Cooldown'
attribute :min_adjustment_step, :aliases => 'MinAdjustmentStep'
attribute :scaling_adjustment, :aliases => 'ScalingAdjustment'
def initialize(attributes)
attributes['AdjustmentType'] ||= 'ChangeInCapacity'
attributes['ScalingAdjustment'] ||= 1
super
end
# TODO: implement #alarms
# TODO: implement #auto_scaling_group
def save
requires :id
requires :adjustment_type
requires :auto_scaling_group_name
requires :scaling_adjustment
options = Hash[self.class.aliases.map { |key, value| [key, send(value)] }]
options.delete_if { |key, value| value.nil? }
service.put_scaling_policy(adjustment_type, auto_scaling_group_name, id, scaling_adjustment, options)
reload
end
def destroy
requires :id
requires :auto_scaling_group_name
service.delete_policy(auto_scaling_group_name, id)
end
end
end
end
end

View file

@ -0,0 +1,59 @@
require 'fog/core/model'
module Fog
module AWS
class ElasticBeanstalk
class Application < Fog::Model
identity :name, :aliases => 'ApplicationName'
attribute :template_names, :aliases => 'ConfigurationTemplates'
attribute :created_at, :aliases => 'DateCreated'
attribute :updated_at, :aliases => 'DateUpdated'
attribute :description, :aliases => 'Description'
attribute :version_names, :aliases => 'Versions'
def initialize(attributes={})
super
end
def environments
requires :name
service.environments.all({'ApplicationName' => name})
end
def events
requires :name
service.events.all({'ApplicationName' => name})
end
def templates
requires :name
service.templates.all({'ApplicationName' => name})
end
def versions
requires :name
service.versions.all({'ApplicationName' => name})
end
def destroy
requires :name
service.delete_application(name)
true
end
def save
requires :name
options = {
'ApplicationName' => name
}
options['Description'] = description unless description.nil?
data = service.create_application(options).body['CreateApplicationResult']['Application']
merge_attributes(data)
true
end
end
end
end
end

View file

@ -0,0 +1,23 @@
require 'fog/core/collection'
require 'fog/aws/models/beanstalk/application'
module Fog
module AWS
class ElasticBeanstalk
class Applications < Fog::Collection
model Fog::AWS::ElasticBeanstalk::Application
def all(application_names=[])
data = service.describe_applications(application_names).body['DescribeApplicationsResult']['Applications']
load(data) # data is an array of attribute hashes
end
def get(application_name)
if data = service.describe_applications([application_name]).body['DescribeApplicationsResult']['Applications'].first
new(data)
end
end
end
end
end
end

View file

@ -0,0 +1,145 @@
require 'fog/core/model'
module Fog
module AWS
class ElasticBeanstalk
class Environment < Fog::Model
identity :name, :aliases => 'EnvironmentName'
attribute :id, :aliases => 'EnvironmentId'
attribute :application_name, :aliases => 'ApplicationName'
attribute :cname, :aliases => 'CNAME'
attribute :cname_prefix, :aliases => 'CNAMEPrefix'
attribute :created_at, :aliases => 'DateCreated'
attribute :updated_at, :aliases => 'DateUpdated'
attribute :updated_at, :aliases => 'DateUpdated'
attribute :description, :aliases => 'Description'
attribute :endpoint_url, :aliases => 'EndpointURL'
attribute :health, :aliases => 'Health'
attribute :resources, :aliases => 'Resources'
attribute :solution_stack_name, :aliases => 'SolutionStackName'
attribute :status, :aliases => 'Status'
attribute :template_name, :aliases => 'TemplateName'
attribute :version_label, :aliases => 'VersionLabel'
attribute :option_settings, :aliases => 'OptionSettings'
attribute :options_to_remove, :aliases => 'OptionsToRemove'
def healthy?
health == 'Green'
end
def ready?
status == 'Ready'
end
def terminated?
status == 'Terminated'
end
# Returns the current live resources for this environment
def live_resources
requires :id
data = service.describe_environment_resources({'EnvironmentId' => id}).body['DescribeEnvironmentResourcesResult']['EnvironmentResources']
data.delete('EnvironmentName') # Delete the environment name from the result, only return actual resources
data
end
# Returns the load balancer object associated with the environment.
def load_balancer(elb_connection = Fog::AWS[:elb])
if resources.nil?
elb_connection.load_balancers.get(live_resources['LoadBalancers'].first['Name'])
else
elb_connection.load_balancers.get(resources['LoadBalancer']['LoadBalancerName'])
end
end
# Return events related to this version
def events
requires :id
service.events.all({'EnvironmentId' => id})
end
# Restarts the app servers in this environment
def restart_app_server
requires :id
service.restart_app_server({'EnvironmentId' => id})
reload
end
# Rebuilds the environment
def rebuild
requires :id
service.rebuild_environment({'EnvironmentId' => id})
reload
end
def swap_cnames(source)
requires :name
service.swap_environment_cnames({
'SourceEnvironmentName' => source.name,
'DestinationEnvironmentName' => name
})
source.reload
reload
end
# Return the version object for this environment
def version
requires :application_name, :version_label
service.versions.get(application_name, version_label)
end
# Update the running version of this environment
def version=(new_version)
requires :id
if new_version.is_a?(String)
new_version_label = new_version
elsif new_version.is_a?(Fog::AWS::ElasticBeanstalk::Version)
new_version_label = new_version.label
else
raise "Unknown type for new_version, must be either String or Fog::AWS::ElasticBeanstalk::Version"
end
if new_version.nil?
raise "Version label not specified."
end
data = service.update_environment({
'EnvironmentId' => id,
'VersionLabel' => new_version_label
}).body['UpdateEnvironmentResult']
merge_attributes(data)
end
def destroy
requires :id
service.terminate_environment({'EnvironmentId' => id})
true
end
def save
requires :name, :application_name
requires_one :template_name, :solution_stack_name
options = {
'ApplicationName' => application_name,
'CNAMEPrefix' => cname_prefix,
'Description' => description,
'EnvironmentName' => name,
'OptionSettings' => option_settings,
'OptionsToRemove' => options_to_remove,
'SolutionStackName' => solution_stack_name,
'TemplateName' => template_name,
'VersionLabel' => version_label
}
options.delete_if {|key, value| value.nil?}
data = service.create_environment(options).body['CreateEnvironmentResult']
merge_attributes(data)
true
end
end
end
end
end

View file

@ -0,0 +1,27 @@
require 'fog/core/collection'
require 'fog/aws/models/beanstalk/environment'
module Fog
module AWS
class ElasticBeanstalk
class Environments < Fog::Collection
model Fog::AWS::ElasticBeanstalk::Environment
def all(options={})
data = service.describe_environments(options).body['DescribeEnvironmentsResult']['Environments']
load(data) # data is an array of attribute hashes
end
# Gets an environment given a name.
#
def get(environment_name)
options = { 'EnvironmentNames' => [environment_name] }
if data = service.describe_environments(options).body['DescribeEnvironmentsResult']['Environments'].first
new(data)
end
end
end
end
end
end

View file

@ -0,0 +1,18 @@
require 'fog/core/model'
module Fog
module AWS
class ElasticBeanstalk
class Event < Fog::Model
attribute :application_name, :aliases => 'ApplicationName'
attribute :environment_name, :aliases => 'EnvironmentName'
attribute :date, :aliases => 'EventDate'
attribute :message, :aliases => 'Message'
attribute :request_id, :aliases => 'RequestId'
attribute :severity, :aliases => 'Severity'
attribute :template_name, :aliases => 'TemplateName'
attribute :version_label, :aliases => 'VersionLabel'
end
end
end
end

View file

@ -0,0 +1,17 @@
require 'fog/core/collection'
require 'fog/aws/models/beanstalk/event'
module Fog
module AWS
class ElasticBeanstalk
class Events < Fog::Collection
model Fog::AWS::ElasticBeanstalk::Event
def all(options={})
data = service.describe_events(options).body['DescribeEventsResult']['Events']
load(data) # data is an array of attribute hashes
end
end
end
end
end

View file

@ -0,0 +1,76 @@
require 'fog/core/model'
module Fog
module AWS
class ElasticBeanstalk
class Template < Fog::Model
attribute :name, :aliases => 'TemplateName'
attribute :application_name, :aliases => 'ApplicationName'
attribute :created_at, :aliases => 'DateCreated'
attribute :updated_at, :aliases => 'DateUpdated'
attribute :deployment_status, :aliases => 'DeploymentStatus'
attribute :description, :aliases => 'Description'
attribute :environment_id
attribute :environment_name, :aliases => 'EnvironmentName'
attribute :solution_stack_name, :aliases => 'SolutionStackName'
attribute :source_configuration
attribute :option_settings, :aliases => 'OptionSettings'
def initialize(attributes={})
super
end
# Returns an array of options that may be set on this template
def options
requires :name, :application_name
data = service.describe_configuration_options({
'ApplicationName' => application_name,
'TemplateName' => name
})
data.body['DescribeConfigurationOptionsResult']['Options']
end
def destroy
requires :name, :application_name
service.delete_configuration_template(application_name, name)
true
end
def save
requires :name, :application_name
options = {
'ApplicationName' => application_name,
'Description' => description,
'EnvironmentId' => environment_id,
'OptionSettings' => option_settings,
'SolutionStackName' => solution_stack_name,
'SourceConfiguration' => source_configuration,
'TemplateName' => name
}
options.delete_if {|key, value| value.nil?}
data = service.create_configuration_template(options).body['CreateConfigurationTemplateResult']
merge_attributes(data)
true
end
def modify(new_attributes)
requires :name, :application_name
options = {
'ApplicationName' => application_name,
'Description' => new_attributes[:description],
'OptionSettings' => new_attributes[:option_settings],
'TemplateName' => name
}
options.delete_if {|key, value| value.nil?}
data = service.update_configuration_template(options).body['UpdateConfigurationTemplateResult']
merge_attributes(data)
true
end
end
end
end
end

View file

@ -0,0 +1,68 @@
require 'fog/core/collection'
require 'fog/aws/models/beanstalk/template'
module Fog
module AWS
class ElasticBeanstalk
class Templates < Fog::Collection
model Fog::AWS::ElasticBeanstalk::Template
# Describes all configuration templates, may optionally pass an ApplicationName filter
#
# Note: This is currently an expensive operation requiring multiple API calls due to a lack of
# a describe configuration templates call in the Aws API.
def all(options={})
application_filter = []
if options.key?('ApplicationName')
application_filter << options['ApplicationName']
end
# Initialize with empty array
data = []
applications = service.describe_applications(application_filter).body['DescribeApplicationsResult']['Applications']
applications.each { |application|
application['ConfigurationTemplates'].each { |template_name|
begin
options = {
'ApplicationName' => application['ApplicationName'],
'TemplateName' => template_name
}
settings = service.describe_configuration_settings(options).body['DescribeConfigurationSettingsResult']['ConfigurationSettings']
if settings.length == 1
# Add to data
data << settings.first
end
rescue Fog::AWS::ElasticBeanstalk::InvalidParameterError
# Ignore
end
}
}
load(data) # data is an array of attribute hashes
end
def get(application_name, template_name)
options = {
'ApplicationName' => application_name,
'TemplateName' => template_name
}
result = nil
# There is no describe call for templates, so we must use describe_configuration_settings. Unfortunately,
# it throws an exception if template name doesn't exist, which is inconsistent, catch and return nil
begin
data = service.describe_configuration_settings(options).body['DescribeConfigurationSettingsResult']['ConfigurationSettings']
if data.length == 1
result = new(data.first)
end
rescue Fog::AWS::ElasticBeanstalk::InvalidParameterError
end
result
end
end
end
end
end

View file

@ -0,0 +1,77 @@
require 'fog/core/model'
module Fog
module AWS
class ElasticBeanstalk
class Version < Fog::Model
attribute :label, :aliases => 'VersionLabel'
attribute :application_name, :aliases => 'ApplicationName'
attribute :created_at, :aliases => 'DateCreated'
attribute :updated_at, :aliases => 'DateUpdated'
attribute :description, :aliases => 'Description'
attribute :source_bundle, :aliases => 'SourceBundle'
attribute :auto_create_application # FIXME - should be write only
def initialize(attributes={})
super
end
# Return events related to this version
def events
requires :label, :application_name
service.events.all({
'ApplicationName' => application_name,
'VersionLabel' => label
})
end
# Returns environments running this version
def environments
requires :label, :application_name
service.environments.all({
'ApplicationName' => application_name,
'VersionLabel' => label
})
end
def destroy(delete_source_bundle = nil)
requires :label, :application_name
service.delete_application_version(application_name, label, delete_source_bundle)
true
end
def save
requires :label, :application_name
options = {
'ApplicationName' => application_name,
'AutoCreateApplication' => auto_create_application,
'Description' => description,
'SourceBundle' => source_bundle,
'VersionLabel' => label
}
options.delete_if {|key, value| value.nil?}
data = service.create_application_version(options).body['CreateApplicationVersionResult']['ApplicationVersion']
merge_attributes(data)
true
end
# Updates the version label with the current property values. Currently only updates description
def update
requires :label, :application_name
options = {
'ApplicationName' => application_name,
'Description' => description,
'VersionLabel' => label
}
options.delete_if {|key, value| value.nil?}
data = service.update_application_version(options).body['UpdateApplicationVersionResult']['ApplicationVersion']
merge_attributes(data)
end
end
end
end
end

View file

@ -0,0 +1,29 @@
require 'fog/core/collection'
require 'fog/aws/models/beanstalk/version'
module Fog
module AWS
class ElasticBeanstalk
class Versions < Fog::Collection
model Fog::AWS::ElasticBeanstalk::Version
def all(options={})
data = service.describe_application_versions(options).body['DescribeApplicationVersionsResult']['ApplicationVersions']
load(data) # data is an array of attribute hashes
end
def get(application_name, version_label)
if data = service.describe_application_versions({
'ApplicationName' => application_name,
'VersionLabels' => [version_label]
}).body['DescribeApplicationVersionsResult']['ApplicationVersions']
if data.length == 1
new(data.first)
end
end
end
end
end
end
end

View file

@ -0,0 +1,90 @@
require 'fog/core/model'
require 'fog/aws/models/cdn/invalidations'
require 'fog/aws/models/cdn/distribution_helper'
module Fog
module CDN
class Aws
class Distribution < Fog::Model
include Fog::CDN::AWS::DistributionHelper
identity :id, :aliases => 'Id'
attribute :caller_reference, :aliases => 'CallerReference'
attribute :last_modified_time, :aliases => 'LastModifiedTime'
attribute :status, :aliases => 'Status'
attribute :s3_origin, :aliases => 'S3Origin'
attribute :custom_origin, :aliases => 'CustomOrigin'
attribute :cname, :aliases => 'CNAME'
attribute :comment, :aliases => 'Comment'
attribute :enabled, :aliases => 'Enabled'
attribute :in_progress_invalidation_batches, :aliases => 'InProgressInvalidationBatches'
attribute :logging, :aliases => 'Logging'
attribute :trusted_signers, :aliases => 'TrustedSigners'
attribute :default_root_object,:aliases => 'DefaultRootObject'
attribute :domain, :aliases => 'DomainName'
attribute :etag, :aliases => ['Etag', 'ETag']
# items part of DistributionConfig
CONFIG = [ :caller_reference, :origin, :cname, :comment, :enabled, :logging, :trusted_signers, :default_root_object ]
def initialize(new_attributes = {})
super(distribution_config_to_attributes(new_attributes))
end
def invalidations
@invalidations ||= begin
Fog::CDN::AWS::Invalidations.new(
:distribution => self,
:service => service
)
end
end
def save
requires_one :s3_origin, :custom_origin
options = attributes_to_options
response = identity ? put_distribution_config(identity, etag, options) : post_distribution(options)
etag = response.headers['ETag']
merge_attributes(response.body)
true
end
private
def delete_distribution(identity, etag)
service.delete_distribution(identity, etag)
end
def put_distribution_config(identity, etag, options)
service.put_distribution_config(identity, etag, options)
end
def post_distribution(options = {})
service.post_distribution(options)
end
def attributes_to_options
options = {
'CallerReference' => caller_reference,
'S3Origin' => s3_origin,
'CustomOrigin' => custom_origin,
'CNAME' => cname,
'Comment' => comment,
'Enabled' => enabled,
'Logging' => logging,
'TrustedSigners' => trusted_signers,
'DefaultRootObject' => default_root_object
}
options.reject! { |k,v| v.nil? }
options.reject! { |k,v| v.respond_to?(:empty?) && v.empty? }
options
end
def distribution_config_to_attributes(new_attributes = {})
new_attributes.merge(new_attributes.delete('DistributionConfig') || {})
end
end
end
end
end

View file

@ -0,0 +1,60 @@
require 'fog/core/collection'
module Fog
module CDN
class Aws
module DistributionHelper
def destroy
requires :identity, :etag, :caller_reference
raise "Distribution must be disabled to be deleted" unless disabled?
delete_distribution(identity, etag)
true
end
def enabled?
requires :identity
!!enabled and ready?
end
def disabled?
requires :identity
not enabled? and ready?
end
def custom_origin?
requires :identity
not custom_origin.nil?
end
def ready?
requires :identity
status == 'Deployed'
end
def enable
requires :identity
reload if etag.nil? or caller_reference.nil?
unless enabled?
self.enabled = true
response = put_distribution_config(identity, etag, attributes_to_options)
etag = response.headers['ETag']
merge_attributes(response.body)
end
true
end
def disable
requires :identity
reload if etag.nil? or caller_reference.nil?
if enabled?
self.enabled = false
response = put_distribution_config(identity, etag, attributes_to_options)
etag = response.headers['ETag']
merge_attributes(response.body)
end
true
end
end
end
end
end

View file

@ -0,0 +1,30 @@
require 'fog/core/collection'
require 'fog/aws/models/cdn/distribution'
require 'fog/aws/models/cdn/distributions_helper'
module Fog
module CDN
class Aws
class Distributions < Fog::Collection
include Fog::CDN::AWS::DistributionsHelper
model Fog::CDN::AWS::Distribution
attribute :marker, :aliases => 'Marker'
attribute :max_items, :aliases => 'MaxItems'
attribute :is_truncated, :aliases => 'IsTruncated'
def get_distribution(dist_id)
service.get_distribution(dist_id)
end
def list_distributions(options = {})
service.get_distribution_list(options)
end
alias_method :each_distribution_this_page, :each
alias_method :each, :each_distribution
end
end
end
end

View file

@ -0,0 +1,45 @@
require 'fog/core/collection'
module Fog
module CDN
class Aws
module DistributionsHelper
def all(options = {})
merge_attributes(options)
data = list_distributions(options).body
merge_attributes('IsTruncated' => data['IsTruncated'], 'Marker' => data['Marker'], 'MaxItems' => data['MaxItems'])
if summary = data['DistributionSummary']
load(summary.map { |a| { 'DistributionConfig' => a } })
else
load((data['StreamingDistributionSummary'] || {}).map { |a| { 'StreamingDistributionConfig' => a }})
end
end
def get(dist_id)
response = get_distribution(dist_id)
data = response.body.merge({'ETag' => response.headers['ETag']})
new(data)
rescue Excon::Errors::NotFound
nil
end
def each_distribution
if !block_given?
self
else
subset = dup.all
subset.each_distribution_this_page {|f| yield f}
while subset.is_truncated
subset = subset.all('Marker' => subset.marker, 'MaxItems' => 1000)
subset.each_distribution_this_page {|f| yield f}
end
self
end
end
end
end
end
end

View file

@ -0,0 +1,60 @@
require 'fog/core/model'
module Fog
module CDN
class Aws
class Invalidation < Fog::Model
identity :id, :aliases => 'Id'
attribute :status, :aliases => 'Status'
attribute :create_time, :aliases => 'CreateTime'
attribute :caller_reference, :aliases => 'CallerReference'
attribute :paths, :aliases => 'Paths'
def initialize(new_attributes={})
new_attributes[:caller_reference] ||= Time.now.utc.to_i.to_s
super(invalidation_to_attributes(new_attributes))
end
def distribution
@distribution
end
def ready?
requires :id, :status
status == 'Completed'
end
def save
requires :paths, :caller_reference
raise "Submitted invalidation cannot be submitted again" if persisted?
response = service.post_invalidation(distribution.identity, paths, caller_reference)
merge_attributes(invalidation_to_attributes(response.body))
true
end
def destroy
# invalidations can't be removed, but tests are requiring they do :)
true
end
private
def distribution=(dist)
@distribution = dist
end
def invalidation_to_attributes(new_attributes={})
invalidation_batch = new_attributes.delete('InvalidationBatch') || {}
if invalidation_batch['Path']
new_attributes[:paths] = invalidation_batch['Path']
end
if invalidation_batch['CallerReference']
new_attributes[:caller_reference] = invalidation_batch['CallerReference']
end
new_attributes
end
end
end
end
end

View file

@ -0,0 +1,50 @@
require 'fog/core/collection'
require 'fog/aws/models/cdn/invalidation'
module Fog
module CDN
class Aws
class Invalidations < Fog::Collection
attribute :is_truncated, :aliases => ['IsTruncated']
attribute :max_items, :aliases => ['MaxItems']
attribute :next_marker, :aliases => ['NextMarker']
attribute :marker, :aliases => ['Marker']
attribute :distribution
model Fog::CDN::AWS::Invalidation
def all(options = {})
requires :distribution
options[:max_items] ||= max_items
options.delete_if {|key, value| value.nil?}
data = service.get_invalidation_list(distribution.identity, options).body
merge_attributes(data.reject {|key, value| !['IsTruncated', 'MaxItems', 'NextMarker', 'Marker'].include?(key)})
load(data['InvalidationSummary'])
end
def get(invalidation_id)
requires :distribution
data = service.get_invalidation(distribution.identity, invalidation_id).body
if data
invalidation = new(data)
else
nil
end
rescue Excon::Errors::NotFound
nil
end
def new(attributes = {})
requires :distribution
super({ :distribution => distribution }.merge!(attributes))
end
end
end
end
end

View file

@ -0,0 +1,74 @@
require 'fog/core/model'
require 'fog/aws/models/cdn/invalidations'
require 'fog/aws/models/cdn/distribution_helper'
module Fog
module CDN
class Aws
class StreamingDistribution < Fog::Model
include Fog::CDN::AWS::DistributionHelper
identity :id, :aliases => 'Id'
attribute :caller_reference, :aliases => 'CallerReference'
attribute :last_modified_time, :aliases => 'LastModifiedTime'
attribute :status, :aliases => 'Status'
attribute :s3_origin, :aliases => 'S3Origin'
attribute :cname, :aliases => 'CNAME'
attribute :comment, :aliases => 'Comment'
attribute :enabled, :aliases => 'Enabled'
attribute :logging, :aliases => 'Logging'
attribute :domain, :aliases => 'DomainName'
attribute :etag, :aliases => ['Etag', 'ETag']
# items part of DistributionConfig
CONFIG = [ :caller_reference, :cname, :comment, :enabled, :logging ]
def initialize(new_attributes = {})
super(distribution_config_to_attributes(new_attributes))
end
def save
requires_one :s3_origin
options = attributes_to_options
response = identity ? put_distribution_config(identity, etag, options) : post_distribution(options)
etag = response.headers['ETag']
merge_attributes(response.body)
true
end
private
def delete_distribution(identity, etag)
service.delete_streaming_distribution(identity, etag)
end
def put_distribution_config(identity, etag, options)
service.put_streaming_distribution_config(identity, etag, options)
end
def post_distribution(options = {})
service.post_streaming_distribution(options)
end
def attributes_to_options
options = {
'CallerReference' => caller_reference,
'S3Origin' => s3_origin,
'CNAME' => cname,
'Comment' => comment,
'Enabled' => enabled,
'Logging' => logging,
}
options.reject! { |k,v| v.nil? }
options.reject! { |k,v| v.respond_to?(:empty?) && v.empty? }
options
end
def distribution_config_to_attributes(new_attributes = {})
new_attributes.merge(new_attributes.delete('StreamingDistributionConfig') || {})
end
end
end
end
end

View file

@ -0,0 +1,30 @@
require 'fog/core/collection'
require 'fog/aws/models/cdn/streaming_distribution'
require 'fog/aws/models/cdn/distributions_helper'
module Fog
module CDN
class Aws
class StreamingDistributions < Fog::Collection
include Fog::CDN::AWS::DistributionsHelper
model Fog::CDN::AWS::StreamingDistribution
attribute :marker, :aliases => 'Marker'
attribute :max_items, :aliases => 'MaxItems'
attribute :is_truncated, :aliases => 'IsTruncated'
def get_distribution(dist_id)
service.get_streaming_distribution(dist_id)
end
def list_distributions(options = {})
service.get_streaming_distribution_list(options)
end
alias_method :each_distribution_this_page, :each
alias_method :each, :each_distribution
end
end
end
end

View file

@ -0,0 +1,60 @@
require 'fog/core/model'
module Fog
module AWS
class CloudWatch
class Alarm < Fog::Model
identity :id, :aliases => 'AlarmName'
attribute :actions_enabled, :aliases => 'ActionsEnabled'
attribute :alarm_actions, :aliases => 'AlarmActions'
attribute :arn, :aliases => 'AlarmArn'
attribute :alarm_configuration_updated_timestamp, :aliases => 'AlarmConfigurationUpdatedTimestamp'
attribute :alarm_description, :aliases => 'AlarmDescription'
attribute :comparison_operator, :aliases => 'ComparisonOperator'
attribute :dimensions, :aliases => 'Dimensions'
attribute :evaluation_periods, :aliases => 'EvaluationPeriods'
attribute :insufficient_data_actions, :aliases => 'InsufficientDataActions'
attribute :metric_name, :aliases => 'MetricName'
attribute :namespace, :aliases => 'Namespace'
attribute :ok_actions, :aliases => 'OKActions'
attribute :period, :aliases => 'Period'
attribute :state_reason, :aliases => 'StateReason'
attribute :state_reason_data, :aliases => 'StateReasonData'
attribute :state_updated_timestamp, :aliases => 'StateUpdatedTimestamp'
attribute :state_value, :aliases => 'StateValue'
attribute :statistic, :aliases => 'Statistic'
attribute :threshold, :aliases => 'Threshold'
attribute :unit, :aliases => 'Unit'
def initialize(attributes)
attributes['EvaluationPeriods'] ||= 1
attributes['Namespace'] ||= 'Aws/EC2'
super
end
def save
requires :id
requires :comparison_operator
requires :evaluation_periods
requires :metric_name
requires :namespace
requires :period
requires :statistic
requires :threshold
options = Hash[self.class.aliases.map { |key, value| [key, send(value)] }]
options.delete_if { |key, value| value.nil? }
service.put_metric_alarm(options)
reload
end
def destroy
requires :id
service.delete_alarms(id)
end
end
end
end
end

View file

@ -0,0 +1,38 @@
require 'fog/core/collection'
require 'fog/aws/models/cloud_watch/alarm_datum'
module Fog
module AWS
class CloudWatch
class AlarmData < Fog::Collection
model Fog::AWS::CloudWatch::AlarmDatum
def all(conditions={})
data = service.describe_alarms(conditions).body['DescribeAlarmsResult']['MetricAlarms']
load(data) # data is an array of attribute hashes
end
def get(namespace, metric_name, dimensions=nil, period=nil, statistic=nil, unit=nil)
list_opts = {'Namespace' => namespace, 'MetricName' => metric_name}
if dimensions
dimensions_array = dimensions.map do |name, value|
{'Name' => name, 'Value' => value}
end
list_opts.merge!('Dimensions' => dimensions_array)
end
if period
list_opts.merge!('Period' => period)
end
if statistic
list_opts.merge!('Statistic' => statistic)
end
if unit
list_opts.merge!('Unit' => unit)
end
data = service.describe_alarms_for_metric(list_opts).body['DescribeAlarmsForMetricResult']['MetricAlarms']
load(data)
end
end
end
end
end

View file

@ -0,0 +1,65 @@
require 'fog/core/model'
module Fog
module AWS
class CloudWatch
class AlarmDatum < Fog::Model
attribute :alarm_name, :aliases => 'AlarmName'
attribute :metric_name, :aliases => 'MetricName'
attribute :namespace, :aliases => 'Namespace'
attribute :dimensions, :aliases => 'Dimensions'
attribute :alarm_description, :aliases => 'AlarmDescription'
attribute :alarm_arn, :aliases => 'AlarmArn'
attribute :state_value, :aliases => 'StateValue'
attribute :statistic, :aliases => 'Statistic'
attribute :comparison_operator, :aliases => 'ComparisonOperator'
attribute :state_reason, :aliases => 'StateReason'
attribute :action_enabled, :aliases => 'ActionsEnabled'
attribute :period, :aliases => 'Period'
attribute :evaluation_periods, :aliases => 'EvaluationPeriods'
attribute :threshold, :aliases => 'Threshold'
attribute :alarm_actions, :aliases => 'AlarmActions'
attribute :ok_actions, :aliases => 'OKActions'
attribute :insufficient_actions, :aliases => 'InsufficientDataActions'
attribute :unit, :aliases => 'Unit'
attribute :state_updated_timestamp, :aliases => 'StateUpdatedTimestamp'
attribute :alarm_configuration_updated_timestamp, :aliases => 'AlarmConfigurationUpdatedTimestamp'
def save
requires :alarm_name
requires :comparison_operator
requires :evaluation_periods
requires :metric_name
requires :namespace
requires :period
requires :statistic
requires :threshold
alarm_definition = {
'AlarmName' => alarm_name,
'ComparisonOperator' => comparison_operator,
'EvaluationPeriods' => evaluation_periods,
'MetricName' => metric_name,
'Namespace' => namespace,
'Period' => period,
'Statistic' => statistic,
'Threshold' => threshold
}
alarm_definition.merge!('ActionsEnabled' => action_enabled) if action_enabled
alarm_definition.merge!('AlarmActions' => alarm_actions) if alarm_actions
alarm_definition.merge!('AlarmDescription' => alarm_description) if alarm_description
#dimension is an array of Name/Value pairs, ex. [{'Name'=>'host', 'Value'=>'localhost'},{'Name'=>'version', 'Value'=>'0.11.0'}]
alarm_definition.merge!('Dimensions' => dimensions) if dimensions
alarm_definition.merge!('InsufficientDataActions' => insufficient_actions) if insufficient_actions
alarm_definition.merge!('OKActions' => ok_actions) if ok_actions
alarm_definition.merge!('Unit' => unit) if unit
service.put_metric_alarm(alarm_definition)
true
end
end
end
end
end

View file

@ -0,0 +1,17 @@
require 'fog/core/collection'
require 'fog/aws/models/cloud_watch/alarm_history'
module Fog
module AWS
class CloudWatch
class AlarmHistories < Fog::Collection
model Fog::AWS::CloudWatch::AlarmHistory
def all(conditions={})
data = service.describe_alarm_history(conditions).body['DescribeAlarmHistoryResult']['AlarmHistoryItems']
load(data) # data is an array of attribute hashes
end
end
end
end
end

View file

@ -0,0 +1,15 @@
require 'fog/core/model'
module Fog
module AWS
class CloudWatch
class AlarmHistory < Fog::Model
attribute :alarm_name, :aliases => 'AlarmName'
attribute :end_date, :aliases => 'EndDate'
attribute :history_item_type, :aliases => 'HistoryItemType'
attribute :max_records, :aliases => 'MaxRecords'
attribute :start_date, :aliases => 'StartDate'
end
end
end
end

View file

@ -0,0 +1,45 @@
require 'fog/core/collection'
require 'fog/aws/models/cloud_watch/alarm'
module Fog
module AWS
class CloudWatch
class Alarms < Fog::Collection
model Fog::AWS::CloudWatch::Alarm
def all
data = []
next_token = nil
loop do
body = service.describe_alarms('NextToken' => next_token).body
data += body['DescribeAlarmsResult']['MetricAlarms']
next_token = body['ResponseMetadata']['NextToken']
break if next_token.nil?
end
load(data)
end
def get(identity)
data = service.describe_alarms('AlarmNames' => identity).body['DescribeAlarmsResult']['MetricAlarms'].first
new(data) unless data.nil?
end
#alarm_names is an array of alarm names
def delete(alarm_names)
service.delete_alarms(alarm_names)
true
end
def disable(alarm_names)
service.disable_alarm_actions(alarm_names)
true
end
def enable(alarm_names)
service.enable_alarm_actions(alarm_names)
true
end
end
end
end
end

View file

@ -0,0 +1,13 @@
require 'fog/core/model'
module Fog
module AWS
class CloudWatch
class Metric < Fog::Model
attribute :name, :aliases => 'MetricName'
attribute :namespace, :aliases => 'Namespace'
attribute :dimensions, :aliases => 'Dimensions'
end
end
end
end

View file

@ -0,0 +1,44 @@
require 'fog/core/model'
module Fog
module AWS
class CloudWatch
class MetricStatistic < Fog::Model
attribute :label, :aliases => 'Label'
attribute :minimum, :aliases => 'Minimum'
attribute :maximum, :aliases => 'Maximum'
attribute :sum, :aliases => 'Sum'
attribute :average, :aliases => 'Average'
attribute :sample_count, :aliases => 'SampleCount'
attribute :timestamp, :aliases => 'Timestamp'
attribute :unit, :aliases => 'Unit'
attribute :metric_name, :aliases => 'MetricName'
attribute :namespace, :aliases => 'Namespace'
attribute :dimensions, :aliases => 'Dimensions'
attribute :value
def save
requires :metric_name
requires :namespace
requires :unit
put_opts = {'MetricName' => metric_name, 'Unit' => unit}
put_opts.merge!('Dimensions' => dimensions) if dimensions
if value
put_opts.merge!('Value' => value)
else
put_opts.merge!('StatisticValues' => {
'Minimum' => minimum,
'Maximum' => maximum,
'Sum' => sum,
'Average' => average,
'SampleCount' => sample_count
})
end
service.put_metric_data(namespace, [put_opts])
true
end
end
end
end
end

View file

@ -0,0 +1,22 @@
require 'fog/core/collection'
require 'fog/aws/models/cloud_watch/metric_statistic'
module Fog
module AWS
class CloudWatch
class MetricStatistics < Fog::Collection
model Fog::AWS::CloudWatch::MetricStatistic
def all(conditions)
metricName = conditions['MetricName']
namespace = conditions['Namespace']
dimensions = conditions['Dimensions']
get_metric_opts = {"StartTime" => (Time.now-3600).iso8601, "EndTime" => Time.now.iso8601, "Period" => 300}.merge(conditions)
data = service.get_metric_statistics(get_metric_opts).body['GetMetricStatisticsResult']['Datapoints']
data.map! { |datum| datum.merge('MetricName' => metricName, 'Namespace' => namespace, 'Dimensions' => dimensions) }
load(data) # data is an array of attribute hashes
end
end
end
end
end

View file

@ -0,0 +1,50 @@
require 'fog/core/collection'
require 'fog/aws/models/cloud_watch/metric'
module Fog
module AWS
class CloudWatch
class Metrics < Fog::Collection
attribute :next_token, :aliases => 'NextToken'
model Fog::AWS::CloudWatch::Metric
def all(conditions={})
result = service.list_metrics(conditions).body['ListMetricsResult']
merge_attributes("NextToken" => result["NextToken"])
load(result['Metrics']) # an array of attribute hashes
end
alias_method :each_metric_this_page, :each
def each
if !block_given?
self
else
subset = dup.all
subset.each_metric_this_page {|m| yield m }
while next_token = subset.next_token
subset = subset.all("NextToken" => next_token)
subset.each_metric_this_page {|m| yield m }
end
self
end
end
def get(namespace, metric_name, dimensions=nil)
list_opts = {'Namespace' => namespace, 'MetricName' => metric_name}
if dimensions
dimensions_array = dimensions.map do |name, value|
{'Name' => name, 'Value' => value}
end
# list_opts.merge!('Dimensions' => dimensions_array)
end
if data = service.list_metrics(list_opts).body['ListMetricsResult']['Metrics'].first
new(data)
end
end
end
end
end
end

View file

@ -0,0 +1,74 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class Address < Fog::Model
identity :public_ip, :aliases => 'publicIp'
attribute :allocation_id, :aliases => 'allocationId'
attribute :association_id, :aliases => 'associationId'
attribute :server_id, :aliases => 'instanceId'
attribute :network_interface_id, :aliases => 'networkInterfaceId'
attribute :network_interface_owner_id, :aliases => 'networkInterfaceOwnerId'
attribute :domain
def initialize(attributes = {})
# assign server first to prevent race condition with persisted?
self.server = attributes.delete(:server)
super
end
def destroy
requires :public_ip
service.release_address(allocation_id || public_ip)
true
end
def server=(new_server)
if new_server
associate(new_server)
else
disassociate
end
end
def server
service.servers.get(server_id)
end
def save
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
data = service.allocate_address(domain).body
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
if @server
self.server = @server
end
true
end
private
def associate(new_server)
unless persisted?
@server = new_server
else
@server = nil
self.server_id = new_server.id
service.associate_address(server_id, public_ip, network_interface_id, allocation_id)
end
end
def disassociate
@server = nil
self.server_id = nil
if persisted?
service.disassociate_address(public_ip)
end
end
end
end
end
end

View file

@ -0,0 +1,96 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/address'
module Fog
module Compute
class Aws
class Addresses < Fog::Collection
attribute :filters
attribute :server
model Fog::Compute::AWS::Address
# Used to create an IP address
#
# ==== Returns
#
#>> Aws.addresses.create
# <Fog::AWS::Compute::Address
# public_ip="4.88.524.95",
# server_id=nil
# >
#
# The IP address can be retrieved by running Aws.addresses.get("test"). See get method below.
#
def initialize(attributes)
self.filters ||= {}
super
end
# Aws.addresses.all
#
# ==== Returns
#
# Returns an array of all IP addresses
#
#>> Aws.addresses.all
# <Fog::AWS::Compute::Addresses
# filters={},
# server=nil
# [
# <Fog::AWS::Compute::Address
# public_ip="76.7.46.54",
# server_id=nil
# >,
# .......
# <Fog::AWS::Compute::Address
# public_ip="4.88.524.95",
# server_id=nil
# >
# ]
# >
#>>
def all(filters_arg = filters)
unless filters_arg.is_a?(Hash)
Fog::Logger.deprecation("all with #{filters_arg.class} param is deprecated, use all('public-ip' => []) instead [light_black](#{caller.first})[/]")
filters_arg = {'public-ip' => [*filters_arg]}
end
self.filters = filters_arg
data = service.describe_addresses(filters).body
load(
data['addressesSet'].map do |address|
address.reject {|key, value| value.nil? || value.empty? }
end
)
if server
self.replace(self.select {|address| address.server_id == server.id})
end
self
end
# Used to retrieve an IP address
#
# public_ip is required to get the associated IP information.
#
# You can run the following command to get the details:
# Aws.addresses.get("76.7.46.54")
def get(public_ip)
if public_ip
self.class.new(:service => service).all('public-ip' => public_ip).first
end
end
def new(attributes = {})
if server
super({ :server => server }.merge!(attributes))
else
super(attributes)
end
end
end
end
end
end

View file

@ -0,0 +1,66 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class DhcpOption < Fog::Model
identity :id, :aliases => 'dhcpOptionsId'
attribute :dhcp_configuration_set, :aliases => 'dhcpConfigurationSet'
attribute :tag_set, :aliases => 'tagSet'
def initialize(attributes={})
super
end
# Associates an existing dhcp configration set with a VPC
#
# dhcp_option.attach(dopt-id, vpc-id)
#
# ==== Returns
#
# True or false depending on the result
#
def associate(vpc_id)
requires :id
service.associate_dhcp_options(id, vpc_id)
reload
end
# Removes an existing dhcp configuration set
#
# dhcp_option.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires :id
service.delete_dhcp_options(id)
true
end
# Create a dhcp configuration set
#
# >> g = Aws.dhcp_options.new()
# >> g.save
#
# == Returns:
#
# requestId and a dhcpOptions object
#
def save
requires :dhcp_configuration_set
data = service.create_dhcp_options(dhcp_configuration_set).body['dhcpOptionsSet'].first
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
true
true
end
end
end
end
end

View file

@ -0,0 +1,87 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/dhcp_option'
module Fog
module Compute
class Aws
class DhcpOptions < Fog::Collection
attribute :filters
model Fog::Compute::AWS::DhcpOption
# Creates a new dhcp option
#
# Aws.dhcp_options.new
#
# ==== Returns
#
# Returns the details of the new DHCP options
#
#>> Aws.dhcp_options.new
#=> <Fog::Compute::AWS::DhcpOption
#id=nil,
#dhcp_configuration_set=nil,
#tag_set=nil
#>
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all DhcpOptions that have been created
#
# Aws.dhcp_options.all
#
# ==== Returns
#
# Returns an array of all DhcpOptions
#
#>> Aws.dhcp_options.all
#<Fog::Compute::AWS::DhcpOptions
#filters={}
#[
#<Fog::Compute::AWS::DhcpOption
#id="dopt-some-id",
#dhcp_configuration_set={"vpcId"=>"vpc-some-id", "state"=>"available"},
#tag_set={}
#>
#]
#>
#
def all(filters_arg = filters)
unless filters_arg.is_a?(Hash)
Fog::Logger.warning("all with #{filters_arg.class} param is deprecated, use all('internet-gateway-id' => []) instead [light_black](#{caller.first})[/]")
filters_arg = {'dhcp-options-id' => [*filters_arg]}
end
filters = filters_arg
data = service.describe_dhcp_options(filters).body
load(data['dhcpOptionsSet'])
end
# Used to retrieve an DhcpOption
#
# You can run the following command to get the details:
# Aws.dhcp_options.get("dopt-12345678")
#
# ==== Returns
#
#>> Aws.dhcp_options.get("dopt-12345678")
#=> <Fog::Compute::AWS::DhcpOption
#id="dopt-12345678",
#dhcp_configuration_set={"vpcId"=>"vpc-12345678", "state"=>"available"},
#tag_set={}
#>
#
def get(dhcp_options_id)
if dhcp_options_id
self.class.new(:service => service).all('dhcp-options-id' => dhcp_options_id).first
end
end
end
end
end
end

View file

@ -0,0 +1,19 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class Flavor < Fog::Model
identity :id
attribute :bits
attribute :cores
attribute :disk
attribute :name
attribute :ram
attribute :ebs_optimized_available
attribute :instance_store_volumes
end
end
end
end

View file

@ -0,0 +1,606 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/flavor'
module Fog
module Compute
class Aws
FLAVORS = [
{
:id => 't1.micro',
:name => 'Micro Instance',
:bits => 0,
:cores => 2,
:disk => 0,
:ram => 613,
:ebs_optimized_available => false,
:instance_store_volumes => 0
},
{
:id => 't2.micro',
:name => 'Micro Instance',
:bits => 64,
:cores => 1,
:disk => 0,
:ram => 1024,
:ebs_optimized_available => false,
:instance_store_volumes => 0
},
{
:id => 't2.small',
:name => 'Micro Instance',
:bits => 64,
:cores => 1,
:disk => 0,
:ram => 2048,
:ebs_optimized_available => false,
:instance_store_volumes => 0
},
{
:id => 't2.medium',
:name => 'Micro Instance',
:bits => 64,
:cores => 2,
:disk => 0,
:ram => 4096,
:ebs_optimized_available => false,
:instance_store_volumes => 0
},
{
:id => 'm1.small',
:name => 'Small Instance',
:bits => 32,
:cores => 1,
:disk => 160,
:ram => 1740.8,
:ebs_optimized_available => false,
:instance_store_volumes => 1
},
{
:id => 'm1.medium',
:name => 'Medium Instance',
:bits => 32,
:cores => 2,
:disk => 400,
:ram => 3750,
:ebs_optimized_available => false,
:instance_store_volumes => 1
},
{
:id => 'm1.large',
:name => 'Large Instance',
:bits => 64,
:cores => 4,
:disk => 850,
:ram => 7680,
:ebs_optimized_available => true,
:instance_store_volumes => 2
},
{
:id => 'm1.xlarge',
:name => 'Extra Large Instance',
:bits => 64,
:cores => 8,
:disk => 1690,
:ram => 15360,
:ebs_optimized_available => true,
:instance_store_volumes => 4
},
{
:id => 'c1.medium',
:bits => 32,
:cores => 5,
:disk => 350,
:name => 'High-CPU Medium',
:ram => 1740.8,
:ebs_optimized_available => false,
:instance_store_volumes => 1
},
{
:id => 'c1.xlarge',
:name => 'High-CPU Extra Large',
:bits => 64,
:cores => 20,
:disk => 1690,
:ram => 7168,
:ebs_optimized_available => true,
:instance_store_volumes => 4
},
{
:id => 'c3.large',
:name => 'C3 Large',
:bits => 64,
:cores => 7,
:disk => 32,
:ram => 3750,
:ebs_optimized_available => false,
:instance_store_volumes => 2
},
{
:id => 'c3.xlarge',
:name => 'C3 Extra Large',
:bits => 64,
:cores => 14,
:disk => 80,
:ram => 7168,
:ebs_optimized_available => true,
:instance_store_volumes => 2
},
{
:id => 'c3.2xlarge',
:name => 'C3 Double Extra Large',
:bits => 64,
:cores => 28,
:disk => 160,
:ram => 15360,
:ebs_optimized_available => true,
:instance_store_volumes => 2
},
{
:id => 'c3.4xlarge',
:name => 'C3 Quadruple Extra Large',
:bits => 64,
:cores => 55,
:disk => 320,
:ram => 30720,
:ebs_optimized_available => true,
:instance_store_volumes => 2
},
{
:id => 'c3.8xlarge',
:name => 'C3 Eight Extra Large',
:bits => 64,
:cores => 108,
:disk => 640,
:ram => 61440,
:ebs_optimized_available => false,
:instance_store_volumes => 2
},
{
:id => 'g2.2xlarge',
:name => 'GPU Double Extra Large',
:bits => 64,
:cores => 26,
:disk => 60,
:ram => 15360,
:ebs_optimized_available => true,
:instance_store_volumes => 0
},
{
:id => 'hs1.8xlarge',
:name => 'High Storage Eight Extra Large',
:bits => 64,
:cores => 35,
:disk => 50331648,
:ram => 119808,
:ebs_optimized_available => false,
:instance_store_volumes => 24
},
{
:id => 'm2.xlarge',
:name => 'High-Memory Extra Large',
:bits => 64,
:cores => 6.5,
:disk => 420,
:ram => 17510.4,
:ebs_optimized_available => false,
:instance_store_volumes => 1
},
{
:id => 'm2.2xlarge',
:name => 'High Memory Double Extra Large',
:bits => 64,
:cores => 13,
:disk => 850,
:ram => 35020.8,
:ebs_optimized_available => true,
:instance_store_volumes => 1
},
{
:id => 'm2.4xlarge',
:name => 'High Memory Quadruple Extra Large',
:bits => 64,
:cores => 26,
:disk => 1690,
:ram => 70041.6,
:ebs_optimized_available => true,
:instance_store_volumes => 2
},
{
:id => 'cr1.8xlarge',
:name => 'High Memory Eight Extra Large',
:bits => 64,
:cores => 88,
:disk => 240,
:ram => 249856,
:ebs_optimized_available => false,
:instance_store_volumes => 2
},
{
:id => 'm3.medium',
:name => 'M3 Medium',
:bits => 64,
:cores => 3,
:disk => 4,
:ram => 3840,
:ebs_optimized_available => false,
:instance_store_volumes => 0
},
{
:id => 'm3.large',
:name => 'M3 Large',
:bits => 64,
:cores => 6.5,
:disk => 32,
:ram => 7168,
:ebs_optimized_available => false,
:instance_store_volumes => 1
},
{
:id => 'm3.xlarge',
:name => 'M3 Extra Large',
:bits => 64,
:cores => 13,
:disk => 80,
:ram => 15360,
:ebs_optimized_available => true,
:instance_store_volumes => 2
},
{
:id => 'm3.2xlarge',
:name => 'M3 Double Extra Large',
:bits => 64,
:cores => 26,
:disk => 160,
:ram => 30720,
:ebs_optimized_available => true,
:instance_store_volumes => 2
},
{
:id => "hi1.4xlarge",
:name => "High I/O Quadruple Extra Large Instance",
:bits => 64,
:cores => 35,
:disk => 2048,
:ram => 61952,
:ebs_optimized_available => false,
:instance_store_volumes => 2
},
{
:id => 'cc1.4xlarge',
:name => 'Cluster Compute Quadruple Extra Large',
:bits => 64,
:cores => 33.5,
:disk => 1690,
:ram => 23552,
:ebs_optimized_available => false,
:instance_store_volumes => 0
},
{
:id => 'cc2.8xlarge',
:name => 'Cluster Compute Eight Extra Large',
:bits => 64,
:cores => 88,
:disk => 3370,
:ram => 61952,
:ebs_optimized_available => false,
:instance_store_volumes => 4
},
{
:id => 'cg1.4xlarge',
:name => 'Cluster GPU Quadruple Extra Large',
:bits => 64,
:cores => 33.5,
:disk => 1690,
:ram => 22528,
:ebs_optimized_available => false,
:instance_store_volumes => 2
},
{
:id => 'i2.xlarge',
:name => 'I2 Extra Large',
:bits => 64,
:cores => 14,
:disk => 800,
:ram => 31232,
:ebs_optimized_available => true,
:instance_store_volumes => 1
},
{
:id => 'i2.2xlarge',
:name => 'I2 Double Extra Large',
:bits => 64,
:cores => 27,
:disk => 1600,
:ram => 62464,
:ebs_optimized_available => true,
:instance_store_volumes => 2
},
{
:id => 'i2.4xlarge',
:name => 'I2 Quadruple Extra Large',
:bits => 64,
:cores => 53,
:disk => 3200,
:ram => 124928,
:ebs_optimized_available => true,
:instance_store_volumes => 4
},
{
:id => 'i2.8xlarge',
:name => 'I2 Eight Extra Large',
:bits => 64,
:cores => 104,
:disk => 6400,
:ram => 249856,
:ebs_optimized_available => false,
:instance_store_volumes => 8
},
{
:id => "r3.large",
:name => "R3 Large",
:bits => 64,
:cores => 2,
:ram => 15360,
:disk => 32,
:ebs_optimized_available => true,
:instance_store_volumes => 1
},
{
:id => "r3.xlarge",
:name => "R3 Extra Large",
:bits => 64,
:cores => 4,
:ram => 31232,
:disk => 80,
:ebs_optimized_available => true,
:instance_store_volumes => 1
},
{
:id => "r3.2xlarge",
:name => "R3 Double Extra Large",
:bits => 64,
:cores => 8,
:ram => 62464,
:disk => 160,
:ebs_optimized_available => true,
:instance_store_volumes => 1
},
{
:id => "r3.4xlarge",
:name => "R3 Quadruple Extra Large",
:bits => 64,
:cores => 16,
:ram => 124928,
:disk => 320,
:ebs_optimized_available => true,
:instance_store_volumes => 1
},
{
:id => "r3.8xlarge",
:name => "R3 Eight Extra Large",
:bits => 64,
:cores => 32,
:ram => 249856,
:disk => 640,
:ebs_optimized_available => true,
:instance_store_volumes => 2
}
]
class Flavors < Fog::Collection
model Fog::Compute::AWS::Flavor
# Returns an array of all flavors that have been created
#
# Aws.flavors.all
#
# ==== Returns
#
# Returns an array of all available instances and their general information
#
#>> Aws.flavors.all
# <Fog::AWS::Compute::Flavors
# [
# <Fog::AWS::Compute::Flavor
# id="t1.micro",
# bits=0,
# cores=2,
# disk=0,
# name="Micro Instance",
# ram=613,
# ebs_optimized_available=false,
# instance_store_volumes=0
# >,
# <Fog::AWS::Compute::Flavor
# id="m1.small",
# bits=32,
# cores=1,
# disk=160,
# name="Small Instance",
# ram=1740.8,
# ebs_optimized_available=false,
# instance_store_volumes=1
# >,
# <Fog::AWS::Compute::Flavor
# id="m1.medium",
# bits=32,
# cores=2,
# disk=400,
# name="Medium Instance",
# ram=3750,
# ebs_optimized_available=false,
# instance_store_volumes=1
# >,
# <Fog::AWS::Compute::Flavor
# id="m1.large",
# bits=64,
# cores=4,
# disk=850,
# name="Large Instance",
# ram=7680,
# ebs_optimized_available=true
# instance_store_volumes=2
# >,
# <Fog::AWS::Compute::Flavor
# id="m1.xlarge",
# bits=64,
# cores=8,
# disk=1690,
# name="Extra Large Instance",
# ram=15360,
# ebs_optimized_available=true,
# instance_store_volumes=4
#
# >,
# <Fog::AWS::Compute::Flavor
# id="c1.medium",
# bits=32,
# cores=5,
# disk=350,
# name="High-CPU Medium",
# ram=1740.8,
# ebs_optimized_available=false,
# instance_store_volumes=1
# >,
# <Fog::AWS::Compute::Flavor
# id="c1.xlarge",
# bits=64,
# cores=20,
# disk=1690,
# name="High-CPU Extra Large",
# ram=7168,
# ebs_optimized_available=true,
# instance_store_volumes=4
# >,
# <Fog::AWS::Compute::Flavor
# id="m2.xlarge",
# bits=64,
# cores=6.5,
# disk=420,
# name="High-Memory Extra Large",
# ram=17510.4,
# ebs_optimized_available=false,
# instance_store_volumes=1
# >,
# <Fog::AWS::Compute::Flavor
# id="m2.2xlarge",
# bits=64,
# cores=13,
# disk=850,
# name="High Memory Double Extra Large",
# ram=35020.8,
# ebs_optimized_available=true,
# instance_store_volumes=1
# >,
# <Fog::AWS::Compute::Flavor
# id="m2.4xlarge",
# bits=64,
# cores=26,
# disk=1690,
# name="High Memory Quadruple Extra Large",
# ram=70041.6,
# ebs_optimized_available=true,
# instance_store_volumes=2
# >,
# <Fog::AWS::Compute::Flavor
# id="cc1.4xlarge",
# bits=64,
# cores=33.5,
# disk=1690,
# name="Cluster Compute Quadruple Extra Large",
# ram=23552,
# ebs_optimized_available=false,
# instance_store_volumes=0
# >,
# <Fog::Compute::AWS::Flavor
# id="m3.xlarge",
# bits=64,
# cores=13,
# disk=0,
# name="M3 Extra Large",
# ram=15360,
# ebs_optimized_available=true,
# instance_store_volumes=2
# >,
# <Fog::Compute::AWS::Flavor
# id="m3.2xlarge",
# bits=64,
# cores=26,
# disk=0,
# name="M3 Double Extra Large",
# ram=30720,
# ebs_optimized_available=true,
# instance_store_volumes=2
# >,
# <Fog::AWS::Compute::Flavor
# id="cc2.8xlarge",
# bits=64,
# cores=88,
# disk=3370,
# name="Cluster Compute Eight Extra Large",
# ram=61952,
# ebs_optimized_available=false,
# instance_store_volumes=4
# >,
# <Fog::AWS::Compute::Flavor
# id="cg1.4xlarge",
# bits=64,
# cores=33.5,
# disk=1690,
# name="Cluster GPU Quadruple Extra Large",
# ram=22528,
# ebs_optimized_available=false,
# instance_store_volumes=2
# >
# ]
# >
#
def all
load(Fog::Compute::AWS::FLAVORS)
self
end
# Used to retrieve a flavor
# flavor_id is required to get the associated flavor information.
# flavors available currently:
#
# t1.micro
# m1.small, m1.medium, m1.large, m1.xlarge
# c1.medium, c1.xlarge
# c3.large, c3.xlarge, c3.2xlarge, c3.4xlarge, c3.8xlarge
# g2.2xlarge
# hs1.8xlarge
# m2.xlarge, m2.2xlarge, m2.4xlarge
# m3.xlarge, m3.2xlarge
# cr1.8xlarge
# cc1.4xlarge
# cc2.8xlarge
# cg1.4xlarge
# i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge
#
# You can run the following command to get the details:
# Aws.flavors.get("t1.micro")
#
# ==== Returns
#
#>> Aws.flavors.get("t1.micro")
# <Fog::AWS::Compute::Flavor
# id="t1.micro",
# bits=0,
# cores=2,
# disk=0,
# name="Micro Instance",
# ram=613
# ebs_optimized_available=false
# instance_store_volumes=0
#>
#
def get(flavor_id)
self.class.new(:service => service).all.find {|flavor| flavor.id == flavor_id}
end
end
end
end
end

View file

@ -0,0 +1,45 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class Image < Fog::Model
identity :id, :aliases => 'imageId'
attribute :architecture
attribute :block_device_mapping, :aliases => 'blockDeviceMapping'
attribute :description
attribute :location, :aliases => 'imageLocation'
attribute :owner_id, :aliases => 'imageOwnerId'
attribute :owner_alias, :aliases => 'imageOwnerAlias'
attribute :state, :aliases => 'imageState'
attribute :type, :aliases => 'imageType'
attribute :is_public, :aliases => 'isPublic'
attribute :kernel_id, :aliases => 'kernelId'
attribute :platform
attribute :product_codes, :aliases => 'productCodes'
attribute :ramdisk_id, :aliases => 'ramdiskId'
attribute :root_device_type, :aliases => 'rootDeviceType'
attribute :root_device_name, :aliases => 'rootDeviceName'
attribute :tags, :aliases => 'tagSet'
attribute :name
attribute :virtualization_type, :aliases => 'virtualizationType'
def deregister(delete_snapshot = false)
service.deregister_image(id)
if(delete_snapshot && root_device_type == "ebs")
block_device = block_device_mapping.find {|block_device| block_device['deviceName'] == root_device_name}
service.snapshots.new(:id => block_device['snapshotId']).destroy
else
true
end
end
def ready?
state == 'available'
end
end
end
end
end

View file

@ -0,0 +1,59 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/image'
module Fog
module Compute
class Aws
class Images < Fog::Collection
attribute :filters
model Fog::Compute::AWS::Image
# Creates a new Amazon machine image
#
# Aws.images.new
#
# ==== Returns
#
# Returns the details of the new image
#
#>> Aws.images.new
# <Fog::AWS::Compute::Image
# id=nil,
# architecture=nil,
# block_device_mapping=nil,
# location=nil,
# owner_id=nil,
# state=nil,
# type=nil,
# is_public=nil,
# kernel_id=nil,
# platform=nil,
# product_codes=nil,
# ramdisk_id=nil,
# root_device_type=nil,
# root_device_name=nil,
# tags=nil
# >
#
def initialize(attributes)
self.filters ||= {}
super
end
def all(filters_arg = filters)
filters = filters_arg
data = service.describe_images(filters).body
load(data['imagesSet'])
end
def get(image_id)
if image_id
self.class.new(:service => service).all('image-id' => image_id).first
end
end
end
end
end
end

View file

@ -0,0 +1,78 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class InternetGateway < Fog::Model
identity :id, :aliases => 'internetGatewayId'
attribute :attachment_set, :aliases => 'attachmentSet'
attribute :tag_set, :aliases => 'tagSet'
def initialize(attributes={})
super
end
# Attaches an existing internet gateway
#
# internet_gateway.attach(igw-id, vpc-id)
#
# ==== Returns
#
# True or false depending on the result
#
def attach(vpc_id)
requires :id
service.attach_internet_gateway(id, vpc_id)
reload
end
# Detaches an existing internet gateway
#
# internet_gateway.detach(igw-id, vpc-id)
#
# ==== Returns
#
# True or false depending on the result
#
def detach(vpc_id)
requires :id
service.detach_internet_gateway(id, vpc_id)
reload
end
# Removes an existing internet gateway
#
# internet_gateway.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires :id
service.delete_internet_gateway(id)
true
end
# Create an internet gateway
#
# >> g = Aws.internet_gateways.new()
# >> g.save
#
# == Returns:
#
# requestId and a internetGateway object
#
def save
data = service.create_internet_gateway.body['internetGatewaySet'].first
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
true
true
end
end
end
end
end

View file

@ -0,0 +1,87 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/internet_gateway'
module Fog
module Compute
class Aws
class InternetGateways < Fog::Collection
attribute :filters
model Fog::Compute::AWS::InternetGateway
# Creates a new internet gateway
#
# Aws.internet_gateways.new
#
# ==== Returns
#
# Returns the details of the new InternetGateway
#
#>> Aws.internet_gateways.new
#=> <Fog::Compute::AWS::InternetGateway
#id=nil,
#attachment_set=nil,
#tag_set=nil
#>
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all InternetGateways that have been created
#
# Aws.internet_gateways.all
#
# ==== Returns
#
# Returns an array of all InternetGateways
#
#>> Aws.internet_gateways.all
#<Fog::Compute::AWS::InternetGateways
#filters={}
#[
#<Fog::Compute::AWS::InternetGateway
#id="igw-some-id",
#attachment_set={"vpcId"=>"vpc-some-id", "state"=>"available"},
#tag_set={}
#>
#]
#>
#
def all(filters_arg = filters)
unless filters_arg.is_a?(Hash)
Fog::Logger.warning("all with #{filters_arg.class} param is deprecated, use all('internet-gateway-id' => []) instead [light_black](#{caller.first})[/]")
filters_arg = {'internet-gateway-id' => [*filters_arg]}
end
filters = filters_arg
data = service.describe_internet_gateways(filters).body
load(data['internetGatewaySet'])
end
# Used to retrieve an InternetGateway
#
# You can run the following command to get the details:
# Aws.internet_gateways.get("igw-12345678")
#
# ==== Returns
#
#>> Aws.internet_gateways.get("igw-12345678")
#=> <Fog::Compute::AWS::InternetGateway
#id="igw-12345678",
#attachment_set={"vpcId"=>"vpc-12345678", "state"=>"available"},
#tag_set={}
#>
#
def get(internet_gateway_id)
if internet_gateway_id
self.class.new(:service => service).all('internet-gateway-id' => internet_gateway_id).first
end
end
end
end
end
end

View file

@ -0,0 +1,53 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class KeyPair < Fog::Model
identity :name, :aliases => 'keyName'
attribute :fingerprint, :aliases => 'keyFingerprint'
attribute :private_key, :aliases => 'keyMaterial'
attr_accessor :public_key
def destroy
requires :name
service.delete_key_pair(name)
true
end
def save
requires :name
data = if public_key
service.import_key_pair(name, public_key).body
else
service.create_key_pair(name).body
end
new_attributes = data.reject {|key,value| !['keyFingerprint', 'keyMaterial', 'keyName'].include?(key)}
merge_attributes(new_attributes)
true
end
def write(path="#{ENV['HOME']}/.ssh/fog_#{Fog.credential.to_s}_#{name}.pem")
if writable?
split_private_key = private_key.split(/\n/)
File.open(path, "w") do |f|
split_private_key.each {|line| f.puts line}
f.chmod 0600
end
"Key file built: #{path}"
else
"Invalid private key"
end
end
def writable?
!!(private_key && ENV.key?('HOME'))
end
end
end
end
end

View file

@ -0,0 +1,84 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/key_pair'
module Fog
module Compute
class Aws
class KeyPairs < Fog::Collection
attribute :filters
attribute :key_name
model Fog::Compute::AWS::KeyPair
# Used to create a key pair. There are 3 arguments and only name is required. You can generate a new key_pair as follows:
# Aws.key_pairs.create(:name => "test", :fingerprint => "123", :private_key => '234234')
#
# ==== Returns
#
#<Fog::AWS::Compute::KeyPair
# name="test",
# fingerprint="3a:d3:e5:17:e5:e7:f7:de:fe:db:1b:c2:55:7d:94:0b:07:2e:05:aa",
# private_key="-----BEGIN RSA PRIVATE KEY-----\nf/VtfXJ/ekTSlRS2GSItBSzMrEGoZ+EXeMOuiA7HFkDcgKt6aBiOX9Bysiyfc1rIrgWdFKqXBRJA\nrtvBPa3/32koMPV4FxG7RZrPuKLITmFoEV86M0DSLo+ErlOPuDChfrR9dk6eI17/o1VmSvYsIpDc\njvbgx+tt7ZEPvduoUag7YdnUI0f20fttsdXjMlyDg9pPOVF3/hqucqOb3t5y9lvVJJxdTnEDFSjb\nvodpaDT9+ssw4IsQsZEIvfL0hK+Lt4phbclUWfG7JVnYfdd2u4zU6Nqe0+3qoR0ZOH4/zaUko7z8\n7JMbJqs5bmdWfnQTrvbJ13545FRI/W48ZRJxqPcj0t2MzasbT4gMgtNJrSadq78RkRJjNTu4lZmK\nvJejkBZPicHvo5IRSEbDc90Rhdh0aZNifXn0d0DSV2N6Ywo2o1lwRAi3/l6XSjukyRpTPcMr14MP\ntGwS1Tvez41Oa7Y96VfsJB2xtKc6LGRFiPUg2ZAEHU15Q9bIISVzHXgdAcef1bsh8UN/fDBrTusm\nvJisQ+dLaPH7cZ03od+XTwJc+IyeL4RqWuASE0NNfEVJMS+qcpt0WeNzfG0C27SwIcfEKL0sC0kn\nCfX2WpZDg7T5xN+88ftKJaN9tymxTgvoJVS1/WKvWBAXVozKp4f6K8wKmwf7VdUt/FWbUi54LW02\nf1ONkaYEOVwDgWlGxVSx43MWqvVdT2MPFNEBL7OA1LPwCO2nyQQ9UM9gCE65S9Najf939Bq8xwqx\nGNFlLmaH6biZUyL8ewRJ8Y7rMQ5cXy/gHZywjkuoyLQ8vVpmVpb7r1FaM/AYSr5l6gJEWdqbJleN\ntnhjPeE6qXISzIUBvwKzzgFTyW8ZHQtgbP3bHEiPG2/OjKHnLUoOId/eetcE+ovIxWsBrTDbf2SV\nYUD91u+W9K35eX89ZaIiohLNg4z9+QHCs4rcWyOXEfprBKcP2QU5+Y9ysnXLAmZt6QhInaAsUpQZ\nyhImA24UqvqrK0yyGhf/quouK7q0QkVQR+f7nGClIaphJkxO/xylrnK/pYObr4s3B8kmksuHiYOu\n1yz6SeRkj8F9dxkRmzbBK/G0tLkxIElDbM7icI9gsEO7vvgaR/K8hSDi0RkFPG43I20tU8PqwHe7\nR4jFW+6sB2+9FDeLn+qkoDSaxzmAuIRW082z/r7rJVIpFEo14hNhQYkNXpH40+P/hA9RFgvhZe8M\nvK4rz/eu246Kij6kObieTfpZhgGHqvtU8x5cnqEZOz5Hc5m4B+gMaTA53kFSPOA0pn6gqgiuYEdI\nZUhO8P1PkNqkmLz7NJRnz3qpAo6RisAxPBVr2WdSg4bP0YpGS/0TE4OOJwGLldx6dCsX60++mn0q\n1fhNw8oyZiguYMAeEEDWP8x/bsRaFz5L8uQVnnnj8ei1oTmZ+Uw9/48snWYcurL2jsbuWhhE0NTt\nfe/cqov7ZaZHs+Tr20ZBEDEqUEWr/MMskj/ZSVxnza1G/hztFJMAThF9ZJoGQkHWHfXCGOLLGY+z\nqi0SC8EIeu8PUxjO2SRj9S9o/Dwg3iHyM3pj57kD7fDNnl3Ed6LMoCXoaQV8BdMX4xh=\n-----END RSA PRIVATE KEY-----"
#>
#
# The key_pair can be retrieved by running Aws.key_pairs.get("test"). See get method below.
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all key pairs that have been created
#
# Aws.key_pairs.all
#
# ==== Returns
#
# <Fog::AWS::Compute::KeyPairs
# key_name=nil
# [
# <Fog::AWS::Compute::KeyPair
# name="test",
# fingerprint="1f:26:3d:83:e7:4f:48:74:c3:1c:e6:b3:c7:f6:ec:d8:cb:09:b3:7f",
# private_key=nil
# >
# ]
#>
#
def all(filters_arg = filters)
unless filters_arg.is_a?(Hash)
Fog::Logger.deprecation("all with #{filters_arg.class} param is deprecated, use all('key-name' => []) instead [light_black](#{caller.first})[/]")
filters_arg = {'key-name' => [*filters_arg]}
end
filters = filters_arg
data = service.describe_key_pairs(filters).body
load(data['keySet'])
end
# Used to retrieve a key pair that was created with the Aws.key_pairs.create method.
# The name is required to get the associated key_pair information.
#
# You can run the following command to get the details:
# Aws.key_pairs.get("test")
#
# ==== Returns
#
#>> Aws.key_pairs.get("test")
# <Fog::AWS::Compute::KeyPair
# name="test",
# fingerprint="1f:26:3d:83:e7:4f:48:74:c3:1c:e6:b3:c7:f6:ec:d8:cb:09:b3:7f",
# private_key=nil
# >
#
def get(key_name)
if key_name
self.class.new(:service => service).all('key-name' => key_name).first
end
end
end
end
end
end

View file

@ -0,0 +1,180 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class NetworkAcl < Fog::Model
ICMP = 1
TCP = 6
UDP = 17
identity :network_acl_id, :aliases => 'networkAclId'
attribute :vpc_id, :aliases => 'vpcId'
attribute :default
attribute :entries, :aliases => 'entrySet'
attribute :associations, :aliases => 'associationSet'
attribute :tags, :aliases => 'tagSet'
# Add an inbound rule, shortcut method for #add_rule
def add_inbound_rule(rule_number, protocol, rule_action, cidr_block, options = {})
add_rule(rule_number, protocol, rule_action, cidr_block, false, options)
end
# Add an outbound rule, shortcut method for #add_rule
def add_outbound_rule(rule_number, protocol, rule_action, cidr_block, options = {})
add_rule(rule_number, protocol, rule_action, cidr_block, true, options)
end
# Add a new rule
#
# network_acl.add_rule(100, Fog::Compute::AWS::NetworkAcl::TCP, 'allow', '0.0.0.0/0', true, 'PortRange.From' => 22, 'PortRange.To' => 22)
#
# ==== Parameters
# * rule_number<~Integer> - The rule number for the entry, between 100 and 32766
# * protocol<~Integer> - The IP protocol to which the rule applies. You can use -1 to mean all protocols.
# * rule_action<~String> - Allows or denies traffic that matches the rule. (either allow or deny)
# * cidr_block<~String> - The CIDR range to allow or deny
# * egress<~Boolean> - Indicates whether this rule applies to egress traffic from the subnet (true) or ingress traffic to the subnet (false).
# * options<~Hash>:
# * 'Icmp.Code' - ICMP code, required if protocol is 1
# * 'Icmp.Type' - ICMP type, required if protocol is 1
# * 'PortRange.From' - The first port in the range, required if protocol is 6 (TCP) or 17 (UDP)
# * 'PortRange.To' - The last port in the range, required if protocol is 6 (TCP) or 17 (UDP)
#
# ==== Returns
#
# True or false depending on the result
#
def add_rule(rule_number, protocol, rule_action, cidr_block, egress, options = {})
requires :network_acl_id
service.create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress, options)
true
end
# Remove an inbound rule, shortcut method for #remove_rule
def remove_inbound_rule(rule_number)
remove_rule(rule_number, false)
end
# Remove an outbound rule, shortcut method for #remove_rule
def remove_outbound_rule(rule_number)
remove_rule(rule_number, true)
end
# Update a specific rule number
#
# network_acl.remove_rule(100, true)
#
# ==== Parameters
# * rule_number<~Integer> - The rule number for the entry, between 100 and 32766
# * egress<~Boolean> - Indicates whether this rule applies to egress traffic from the subnet (true) or ingress traffic to the subnet (false).
#
# ==== Returns
#
# True or false depending on the result
#
def remove_rule(rule_number, egress)
requires :network_acl_id
service.delete_network_acl_entry(network_acl_id, rule_number, egress)
true
end
# Update an inbound rule, shortcut method for #update_rule
def update_inbound_rule(rule_number, protocol, rule_action, cidr_block, options = {})
update_rule(rule_number, protocol, rule_action, cidr_block, false, options)
end
# Update an outbound rule, shortcut method for #update_rule
def update_outbound_rule(rule_number, protocol, rule_action, cidr_block, options = {})
update_rule(rule_number, protocol, rule_action, cidr_block, true, options)
end
# Update a specific rule number
#
# network_acl.update_rule(100, Fog::Compute::AWS::NetworkAcl::TCP, 'allow', '0.0.0.0/0', true, 'PortRange.From' => 22, 'PortRange.To' => 22)
#
# ==== Parameters
# * rule_number<~Integer> - The rule number for the entry, between 100 and 32766
# * protocol<~Integer> - The IP protocol to which the rule applies. You can use -1 to mean all protocols.
# * rule_action<~String> - Allows or denies traffic that matches the rule. (either allow or deny)
# * cidr_block<~String> - The CIDR range to allow or deny
# * egress<~Boolean> - Indicates whether this rule applies to egress traffic from the subnet (true) or ingress traffic to the subnet (false).
# * options<~Hash>:
# * 'Icmp.Code' - ICMP code, required if protocol is 1
# * 'Icmp.Type' - ICMP type, required if protocol is 1
# * 'PortRange.From' - The first port in the range, required if protocol is 6 (TCP) or 17 (UDP)
# * 'PortRange.To' - The last port in the range, required if protocol is 6 (TCP) or 17 (UDP)
#
# ==== Returns
#
# True or false depending on the result
#
def update_rule(rule_number, protocol, rule_action, cidr_block, egress, options = {})
requires :network_acl_id
service.replace_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress, options)
true
end
# Associate a subnet with this network ACL
#
# network_acl.associate_with(subnet)
#
# ==== Parameters
# * subnet<~Subnet> - Subnet object to associate with this network ACL
#
# ==== Returns
#
# True or false depending on the result
#
def associate_with(subnet)
requires :network_acl_id
# We have to manually find out the network ACL the subnet is currently associated with
old_id = service.network_acls.all('association.subnet-id' => subnet.subnet_id).first.associations.find { |a| a['subnetId'] == subnet.subnet_id }['networkAclAssociationId']
service.replace_network_acl_association(old_id, network_acl_id)
true
end
# Removes an existing network ACL
#
# network_acl.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires :network_acl_id
service.delete_network_acl(network_acl_id)
true
end
# Create a network ACL
#
# >> g = Aws.network_acls.new(:vpc_id => 'vpc-abcdefgh')
# >> g.save
def save
requires :vpc_id
data = service.create_network_acl(vpc_id).body['networkAcl']
new_attributes = data.reject { |key,value| key == 'tagSet' }
merge_attributes(new_attributes)
if tags = self.tags
# expect eventual consistency
Fog.wait_for { self.reload rescue nil }
service.create_tags(
self.identity,
tags
)
end
true
end
end
end
end
end

View file

@ -0,0 +1,136 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/network_acl'
module Fog
module Compute
class Aws
class NetworkAcls < Fog::Collection
attribute :filters
model Fog::Compute::AWS::NetworkAcl
# Creates a new network ACL
#
# Aws.network_acls.new
#
# ==== Returns
#
# Returns the details of the new network ACL
#
#>> <Fog::Compute::AWS::NetworkAcl
# network_acl_id=nil,
# vpc_id=nil,
# default=nil,
# entries=nil,
# associations=nil,
# tags=nil
# >
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all network ACLs that have been created
#
# Aws.network_acls.all
#
# ==== Returns
#
# Returns an array of all network ACLs
#
#>> Aws.network_acls.all
# <Fog::AWS::Compute::NetworkAcls
# filters={}
# [
# <Fog::Compute::AWS::NetworkAcl
# network_acl_id="acl-abcdefgh",
# vpc_id="vpc-abcdefgh",
# default=true,
# entries=[
# {
# "icmpTypeCode" => {},
# "portRange" => {},
# "ruleNumber" => 32767,
# "protocol" => -1,
# "ruleAction" => "deny",
# "egress" => false,
# "cidrBlock" => "0.0.0.0/0"
# },
# {
# "icmpTypeCode" => {},
# "portRange" => {},
# "ruleNumber" => 32767,
# "protocol" => -1,
# "ruleAction" => "deny",
# "egress" => true,
# "cidrBlock" => "0.0.0.0/0"
# }
# ],
# associations=[
# {
# "networkAclAssociationId" => "aclassoc-abcdefgh",
# "networkAclId" => "acl-abcdefgh",
# "subnetId" => "subnet-abcdefgh"
# }
# ],
# tags={}
# >
# ]
# >
#
def all(filters_arg = filters)
filters = filters_arg
data = service.describe_network_acls(filters).body
load(data['networkAclSet'])
end
# Used to retrieve a network interface
# network interface id is required to get any information
#
# You can run the following command to get the details:
# Aws.network_interfaces.get("eni-11223344")
#
# ==== Returns
#
#>> Aws.network_acls.get("acl-abcdefgh")
# <Fog::Compute::AWS::NetworkAcl
# network_acl_id="acl-abcdefgh",
# vpc_id="vpc-abcdefgh",
# default=true,
# entries=[
# {
# "icmpTypeCode" => {},
# "portRange" => {},
# "ruleNumber" => 32767,
# "protocol" => -1,
# "ruleAction" => "deny",
# "egress" => false,
# "cidrBlock" => "0.0.0.0/0"
# },
# {
# "icmpTypeCode" => {},
# "portRange" => {},
# "ruleNumber" => 32767,
# "protocol" => -1,
# "ruleAction" => "deny",
# "egress" => true,
# "cidrBlock" => "0.0.0.0/0"
# }
# ],
# associations=[
# {
# "networkAclAssociationId" => "aclassoc-abcdefgh",
# "networkAclId" => "acl-abcdefgh",
# "subnetId" => "subnet-abcdefgh"
# }
# ],
# tags={}
# >
def get(nacl_id)
self.class.new(:service => service).all('network-acl-id' => nacl_id).first if nacl_id
end
end
end
end
end

View file

@ -0,0 +1,73 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class NetworkInterface < Fog::Model
identity :network_interface_id, :aliases => 'networkInterfaceId'
attribute :state
attribute :request_id, :aliases => 'requestId'
attribute :network_interface_id, :aliases => 'networkInterfaceId'
attribute :subnet_id, :aliases => 'subnetId'
attribute :vpc_id, :aliases => 'vpcId'
attribute :availability_zone, :aliases => 'availabilityZone'
attribute :description, :aliases => 'description'
attribute :owner_id, :aliases => 'ownerId'
attribute :requester_id, :aliases => 'requesterId'
attribute :requester_managed, :aliases => 'requesterManaged'
attribute :status, :aliases => 'status'
attribute :mac_address, :aliases => 'macAddress'
attribute :private_ip_address, :aliases => 'privateIpAddress'
attribute :private_ip_addresses, :aliases => 'privateIpAddresses'
attribute :private_dns_name, :aliases => 'privateDnsName'
attribute :source_dest_check, :aliases => 'sourceDestCheck'
attribute :group_set, :aliases => 'groupSet'
attribute :attachment, :aliases => 'attachment'
attribute :association, :aliases => 'association'
attribute :tag_set, :aliases => 'tagSet'
# Removes an existing network interface
#
# network_interface.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires :network_interface_id
service.delete_network_interface(network_interface_id)
true
end
# Create a network_interface
#
# >> g = Aws.network_interfaces.new(:subnet_id => "subnet-someId", options)
# >> g.save
#
# options is an optional hash which may contain 'PrivateIpAddress', 'Description', 'GroupSet'
#
# == Returns:
#
# requestId and a networkInterface object
#
def save
requires :subnet_id
options = {
'PrivateIpAddress' => private_ip_address,
'Description' => description,
'GroupSet' => group_set,
}
options.delete_if {|key, value| value.nil?}
data = service.create_network_interface(subnet_id, options).body['networkInterface']
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
true
end
end
end
end
end

View file

@ -0,0 +1,133 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/network_interface'
module Fog
module Compute
class Aws
class NetworkInterfaces < Fog::Collection
attribute :filters
model Fog::Compute::AWS::NetworkInterface
# Creates a new network interface
#
# Aws.network_interfaces.new
#
# ==== Returns
#
# Returns the details of the new network interface
#
#>> Aws.network_interfaces.new
# <Fog::AWS::Compute::NetworkInterface
# network_interface_id=nil
# state=nil
# request_id=nil
# network_interface_id=nil
# subnet_id=nil
# vpc_id=nil
# availability_zone=nil
# description=nil
# owner_id=nil
# requester_id=nil
# requester_managed=nil
# status=nil
# mac_address=nil
# private_ip_address=nil
# private_dns_name=nil
# source_dest_check=nil
# group_set=nil
# attachment=nil
# association=nil
# tag_set=nil
# >
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all network interfaces that have been created
#
# Aws.network_interfaces.all
#
# ==== Returns
#
# Returns an array of all network interfaces
#
#>> Aws.network_interfaves.all
# <Fog::AWS::Compute::NetworkInterfaces
# filters={}
# [
# <Fog::Compute::AWS::NetworkInterface
# network_interface_id="eni-da5dc7ca",
# state=nil,
# request_id=nil,
# subnet_id="a9db1bcd-d215-a56f-b0ab-2398d7f37217",
# vpc_id="mock-vpc-id",
# availability_zone="mock-zone",
# description=nil,
# owner_id="",
# requester_id=nil,
# requester_managed="false",
# status="available",
# mac_address="00:11:22:33:44:55",
# private_ip_address="10.0.0.2",
# private_dns_name=nil,
# source_dest_check=true,
# group_set={},
# attachment={},
# association={},
# tag_set={}
# >
# ]
# >
#
def all(filters_arg = filters)
filters = filters_arg
data = service.describe_network_interfaces(filters).body
load(data['networkInterfaceSet'])
end
# Used to retrieve a network interface
# network interface id is required to get any information
#
# You can run the following command to get the details:
# Aws.network_interfaces.get("eni-11223344")
#
# ==== Returns
#
#>> Aws.NetworkInterface.get("eni-11223344")
# <Fog::AWS::Compute::NetworkInterface
# network_interface_id="eni-da5dc7ca",
# state=nil,
# request_id=nil,
# subnet_id="a9db1bcd-d215-a56f-b0ab-2398d7f37217",
# vpc_id="mock-vpc-id",
# availability_zone="mock-zone",
# description=nil,
# owner_id="",
# requester_id=nil,
# requester_managed="false",
# status="available",
# mac_address="00:11:22:33:44:55",
# private_ip_address="10.0.0.2",
# private_dns_name=nil,
# source_dest_check=true,
# group_set={},
# attachment={},
# association={},
# tag_set={}
# >
#
def get(nic_id)
if nic_id
self.class.new(:service => service).all('network-interface-id' => nic_id).first
end
end
end
end
end
end

View file

@ -0,0 +1,66 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class RouteTable < Fog::Model
identity :id, :aliases => 'routeTableId'
attribute :vpc_id, :aliases => 'vpcId'
attribute :routes, :aliases => 'routeSet'
attribute :associations, :aliases => 'associationSet'
attribute :tags, :aliases => 'tagSet'
def initialize(attributes={})
super
end
# Remove an existing route table
#
# route_tables.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires :id
service.delete_route_table(id)
true
end
# Create a route table
#
# >> routetable = connection.route_tables.new
# >> routetable.save
#
# == Returns:
#
# True or an exception depending on the result. Keep in mind that this *creates* a new route table.
#
def save
requires :vpc_id
data = service.create_route_table(vpc_id).body['routeTable'].first
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
true
end
private
def associationSet=(new_association_set)
merge_attributes(new_association_set.first || {})
end
def routeSet=(new_route_set)
merge_attributes(new_route_set || {})
end
end
end
end
end

View file

@ -0,0 +1,88 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/route_table'
module Fog
module Compute
class Aws
class RouteTables < Fog::Collection
attribute :filters
model Fog::Compute::AWS::RouteTable
# Creates a new route table
#
# Aws.route_tables.new
#
# ==== Returns
#
# Returns the details of the new route table
#
#>> Aws.route_tables.new
# <Fog::Compute::AWS::RouteTable
# id=nil,
# vpc_id=nil,
# routes=nil,
# associations=nil,
# tags=nil
# >
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all route tables that have been created
#
# Aws.route_tables.all
#
# ==== Returns
#
# Returns an array of all route tables
#
#>> Aws.route_tables.all
# <Fog::Compute::AWS::RouteTables
# filters={}
# [
# <Fog::Compute::AWS::RouteTable
# id="rtb-41e8552f",
# TODO
# >
# ]
# >
#
def all(filters_arg = filters)
unless filters_arg.is_a?(Hash)
Fog::Logger.warning("all with #{filters_arg.class} param is deprecated, use all('route-table-id' => []) instead [light_black](#{caller.first})[/]")
filters_arg = {'route-table-id' => [*filters_arg]}
end
filters = filters_arg
data = service.describe_route_tables(filters).body
load(data['routeTableSet'])
end
# Used to retrieve a route table
# route_table_id is required to get the associated route table information.
#
# You can run the following command to get the details:
# Aws.route_tables.get("rtb-41e8552f")
#
# ==== Returns
#
#>> Aws.route_tables.get("rtb-41e8552f")
# <Fog::Compute::AWS::RouteTable
# id="rtb-41e8552f",
# TODO
# >
#
def get(route_table_id)
if route_table_id
self.class.new(:service => service).all('route-table-id' => route_table_id).first
end
end
end
end
end
end

View file

@ -0,0 +1,322 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class SecurityGroup < Fog::Model
identity :name, :aliases => 'groupName'
attribute :description, :aliases => 'groupDescription'
attribute :group_id, :aliases => 'groupId'
attribute :ip_permissions, :aliases => 'ipPermissions'
attribute :ip_permissions_egress, :aliases => 'ipPermissionsEgress'
attribute :owner_id, :aliases => 'ownerId'
attribute :vpc_id, :aliases => 'vpcId'
attribute :tags, :aliases => 'tagSet'
# Authorize access by another security group
#
# >> g = Aws.security_groups.all(:description => "something").first
# >> g.authorize_group_and_owner("some_group_name", "1234567890")
#
# == Parameters:
# group::
# The name of the security group you're granting access to.
#
# owner::
# The owner id for security group you're granting access to.
#
# == Returns:
#
# An excon response object representing the result
#
# <Excon::Response:0x101fc2ae0
# @status=200,
# @body={"requestId"=>"some-id-string",
# "return"=>true},
# headers{"Transfer-Encoding"=>"chunked",
# "Date"=>"Mon, 27 Dec 2010 22:12:57 GMT",
# "Content-Type"=>"text/xml;charset=UTF-8",
# "Server"=>"AmazonEC2"}
#
def authorize_group_and_owner(group, owner = nil)
Fog::Logger.deprecation("authorize_group_and_owner is deprecated, use authorize_port_range with :group option instead")
requires_one :name, :group_id
service.authorize_security_group_ingress(
name,
'GroupId' => group_id,
'SourceSecurityGroupName' => group,
'SourceSecurityGroupOwnerId' => owner
)
end
# Authorize a new port range for a security group
#
# >> g = Aws.security_groups.all(:description => "something").first
# >> g.authorize_port_range(20..21)
#
# == Parameters:
# range::
# A Range object representing the port range you want to open up. E.g., 20..21
#
# options::
# A hash that can contain any of the following keys:
# :cidr_ip (defaults to "0.0.0.0/0")
# :group - ("account:group_name" or "account:group_id"), cannot be used with :cidr_ip
# :ip_protocol (defaults to "tcp")
#
# == Returns:
#
# An excon response object representing the result
#
# <Excon::Response:0x101fc2ae0
# @status=200,
# @body={"requestId"=>"some-id-string",
# "return"=>true},
# headers{"Transfer-Encoding"=>"chunked",
# "Date"=>"Mon, 27 Dec 2010 22:12:57 GMT",
# "Content-Type"=>"text/xml;charset=UTF-8",
# "Server"=>"AmazonEC2"}
#
def authorize_port_range(range, options = {})
requires_one :name, :group_id
ip_permission = {
'FromPort' => range.min,
'ToPort' => range.max,
'IpProtocol' => options[:ip_protocol] || 'tcp'
}
if options[:group].nil?
ip_permission['IpRanges'] = [
{ 'CidrIp' => options[:cidr_ip] || '0.0.0.0/0' }
]
else
ip_permission['Groups'] = [
group_info(options[:group])
]
end
service.authorize_security_group_ingress(
name,
'GroupId' => group_id,
'IpPermissions' => [ ip_permission ]
)
end
# Removes an existing security group
#
# security_group.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires_one :name, :group_id
if group_id.nil?
service.delete_security_group(name)
else
service.delete_security_group(nil, group_id)
end
true
end
# Revoke access by another security group
#
# >> g = Aws.security_groups.all(:description => "something").first
# >> g.revoke_group_and_owner("some_group_name", "1234567890")
#
# == Parameters:
# group::
# The name of the security group you're revoking access to.
#
# owner::
# The owner id for security group you're revoking access access to.
#
# == Returns:
#
# An excon response object representing the result
#
# <Excon::Response:0x101fc2ae0
# @status=200,
# @body={"requestId"=>"some-id-string",
# "return"=>true},
# headers{"Transfer-Encoding"=>"chunked",
# "Date"=>"Mon, 27 Dec 2010 22:12:57 GMT",
# "Content-Type"=>"text/xml;charset=UTF-8",
# "Server"=>"AmazonEC2"}
#
def revoke_group_and_owner(group, owner = nil)
Fog::Logger.deprecation("revoke_group_and_owner is deprecated, use revoke_port_range with :group option instead")
requires_one :name, :group_id
service.revoke_security_group_ingress(
name,
'GroupId' => group_id,
'SourceSecurityGroupName' => group,
'SourceSecurityGroupOwnerId' => owner
)
end
# Revoke an existing port range for a security group
#
# >> g = Aws.security_groups.all(:description => "something").first
# >> g.revoke_port_range(20..21)
#
# == Parameters:
# range::
# A Range object representing the port range you want to open up. E.g., 20..21
#
# options::
# A hash that can contain any of the following keys:
# :cidr_ip (defaults to "0.0.0.0/0")
# :group - ("account:group_name" or "account:group_id"), cannot be used with :cidr_ip
# :ip_protocol (defaults to "tcp")
#
# == Returns:
#
# An excon response object representing the result
#
# <Excon::Response:0x101fc2ae0
# @status=200,
# @body={"requestId"=>"some-id-string",
# "return"=>true},
# headers{"Transfer-Encoding"=>"chunked",
# "Date"=>"Mon, 27 Dec 2010 22:12:57 GMT",
# "Content-Type"=>"text/xml;charset=UTF-8",
# "Server"=>"AmazonEC2"}
#
def revoke_port_range(range, options = {})
requires_one :name, :group_id
ip_permission = {
'FromPort' => range.min,
'ToPort' => range.max,
'IpProtocol' => options[:ip_protocol] || 'tcp'
}
if options[:group].nil?
ip_permission['IpRanges'] = [
{ 'CidrIp' => options[:cidr_ip] || '0.0.0.0/0' }
]
else
ip_permission['Groups'] = [
group_info(options[:group])
]
end
service.revoke_security_group_ingress(
name,
'GroupId' => group_id,
'IpPermissions' => [ ip_permission ]
)
end
# Reload a security group
#
# >> g = Aws.security_groups.get(:name => "some_name")
# >> g.reload
#
# == Returns:
#
# Up to date model or an exception
def reload
if group_id.nil?
super
service.delete_security_group(name)
else
requires :group_id
data = begin
collection.get_by_id(group_id)
rescue Excon::Errors::SocketError
nil
end
return unless data
merge_attributes(data.attributes)
self
end
end
# Create a security group
#
# >> g = Aws.security_groups.new(:name => "some_name", :description => "something")
# >> g.save
#
# == Returns:
#
# True or an exception depending on the result. Keep in mind that this *creates* a new security group.
# As such, it yields an InvalidGroup.Duplicate exception if you attempt to save an existing group.
#
def save
requires :description, :name
data = service.create_security_group(name, description, vpc_id).body
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
if tags = self.tags
# expect eventual consistency
Fog.wait_for { self.reload rescue nil }
service.create_tags(
self.group_id,
tags
)
end
true
end
private
#
# +group_arg+ may be a string or a hash with one key & value.
#
# If group_arg is a string, it is assumed to be the group name,
# and the UserId is assumed to be self.owner_id.
#
# The "account:group" form is deprecated.
#
# If group_arg is a hash, the key is the UserId and value is the group.
def group_info(group_arg)
if Hash === group_arg
account = group_arg.keys.first
group = group_arg.values.first
elsif group_arg.match(/:/)
account, group = group_arg.split(':')
Fog::Logger.deprecation("'account:group' argument is deprecated. Use {account => group} or just group instead")
else
requires :owner_id
account = owner_id
group = group_arg
end
info = { 'UserId' => account }
if group.start_with?("sg-")
# we're dealing with a security group id
info['GroupId'] = group
else
# this has to be a security group name
info['GroupName'] = group
end
info
end
end
end
end
end

View file

@ -0,0 +1,117 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/security_group'
module Fog
module Compute
class Aws
class SecurityGroups < Fog::Collection
attribute :filters
model Fog::Compute::AWS::SecurityGroup
# Creates a new security group
#
# Aws.security_groups.new
#
# ==== Returns
#
# Returns the details of the new image
#
#>> Aws.security_groups.new
# <Fog::AWS::Compute::SecurityGroup
# name=nil,
# description=nil,
# ip_permissions=nil,
# owner_id=nil
# vpc_id=nil
# >
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all security groups that have been created
#
# Aws.security_groups.all
#
# ==== Returns
#
# Returns an array of all security groups
#
#>> Aws.security_groups.all
# <Fog::AWS::Compute::SecurityGroups
# filters={}
# [
# <Fog::AWS::Compute::SecurityGroup
# name="default",
# description="default group",
# ip_permissions=[{"groups"=>[{"groupName"=>"default", "userId"=>"312571045469"}], "fromPort"=>-1, "toPort"=>-1, "ipRanges"=>[], "ipProtocol"=>"icmp"}, {"groups"=>[{"groupName"=>"default", "userId"=>"312571045469"}], "fromPort"=>0, "toPort"=>65535, "ipRanges"=>[], "ipProtocol"=>"tcp"}, {"groups"=>[{"groupName"=>"default", "userId"=>"312571045469"}], "fromPort"=>0, "toPort"=>65535, "ipRanges"=>[], "ipProtocol"=>"udp"}],
# owner_id="312571045469"
# vpc_id=nill
# >
# ]
# >
#
def all(filters_arg = filters)
unless filters_arg.is_a?(Hash)
Fog::Logger.deprecation("all with #{filters_arg.class} param is deprecated, use all('group-name' => []) instead [light_black](#{caller.first})[/]")
filters_arg = {'group-name' => [*filters_arg]}
end
self.filters = filters_arg
data = service.describe_security_groups(filters).body
load(data['securityGroupInfo'])
end
# Used to retrieve a security group
# group name is required to get the associated flavor information.
#
# You can run the following command to get the details:
# Aws.security_groups.get("default")
#
# ==== Returns
#
#>> Aws.security_groups.get("default")
# <Fog::AWS::Compute::SecurityGroup
# name="default",
# description="default group",
# ip_permissions=[{"groups"=>[{"groupName"=>"default", "userId"=>"312571045469"}], "fromPort"=>-1, "toPort"=>-1, "ipRanges"=>[], "ipProtocol"=>"icmp"}, {"groups"=>[{"groupName"=>"default", "userId"=>"312571045469"}], "fromPort"=>0, "toPort"=>65535, "ipRanges"=>[], "ipProtocol"=>"tcp"}, {"groups"=>[{"groupName"=>"default", "userId"=>"312571045469"}], "fromPort"=>0, "toPort"=>65535, "ipRanges"=>[], "ipProtocol"=>"udp"}],
# owner_id="312571045469"
# vpc_id=nil
# >
#
def get(group_name)
if group_name
self.class.new(:service => service).all('group-name' => group_name).first
end
end
# Used to retrieve a security group
# group id is required to get the associated flavor information.
#
# You can run the following command to get the details:
# Aws.security_groups.get_by_id("default")
#
# ==== Returns
#
#>> Aws.security_groups.get_by_id("sg-123456")
# <Fog::AWS::Compute::SecurityGroup
# name="default",
# description="default group",
# ip_permissions=[{"groups"=>[{"groupName"=>"default", "userId"=>"312571045469"}], "fromPort"=>-1, "toPort"=>-1, "ipRanges"=>[], "ipProtocol"=>"icmp"}, {"groups"=>[{"groupName"=>"default", "userId"=>"312571045469"}], "fromPort"=>0, "toPort"=>65535, "ipRanges"=>[], "ipProtocol"=>"tcp"}, {"groups"=>[{"groupName"=>"default", "userId"=>"312571045469"}], "fromPort"=>0, "toPort"=>65535, "ipRanges"=>[], "ipProtocol"=>"udp"}],
# owner_id="312571045469"
# >
#
def get_by_id(group_id)
if group_id
self.class.new(:service => service).all('group-id' => group_id).first
end
end
end
end
end
end

View file

@ -0,0 +1,271 @@
require 'fog/compute/models/server'
module Fog
module Compute
class Aws
class Server < Fog::Compute::Server
extend Fog::Deprecation
deprecate :ip_address, :public_ip_address
identity :id, :aliases => 'instanceId'
attr_accessor :architecture
attribute :ami_launch_index, :aliases => 'amiLaunchIndex'
attribute :associate_public_ip, :aliases => 'associatePublicIP'
attribute :availability_zone, :aliases => 'availabilityZone'
attribute :block_device_mapping, :aliases => 'blockDeviceMapping'
attribute :network_interfaces, :aliases => 'networkInterfaces'
attribute :client_token, :aliases => 'clientToken'
attribute :disable_api_termination, :aliases => 'disableApiTermination'
attribute :dns_name, :aliases => 'dnsName'
attribute :ebs_optimized, :aliases => 'ebsOptimized'
attribute :groups
attribute :flavor_id, :aliases => 'instanceType'
attribute :hypervisor
attribute :iam_instance_profile, :aliases => 'iamInstanceProfile'
attribute :image_id, :aliases => 'imageId'
attr_accessor :instance_initiated_shutdown_behavior
attribute :kernel_id, :aliases => 'kernelId'
attribute :key_name, :aliases => 'keyName'
attribute :created_at, :aliases => 'launchTime'
attribute :lifecycle, :aliases => 'instanceLifecycle'
attribute :monitoring, :squash => 'state'
attribute :placement_group, :aliases => 'groupName'
attribute :platform, :aliases => 'platform'
attribute :product_codes, :aliases => 'productCodes'
attribute :private_dns_name, :aliases => 'privateDnsName'
attribute :private_ip_address, :aliases => 'privateIpAddress'
attribute :public_ip_address, :aliases => 'ipAddress'
attribute :ramdisk_id, :aliases => 'ramdiskId'
attribute :reason
attribute :requester_id, :aliases => 'requesterId'
attribute :root_device_name, :aliases => 'rootDeviceName'
attribute :root_device_type, :aliases => 'rootDeviceType'
attribute :security_group_ids, :aliases => 'securityGroupIds'
attribute :source_dest_check, :aliases => 'sourceDestCheck'
attribute :spot_instance_request_id, :aliases => 'spotInstanceRequestId'
attribute :state, :aliases => 'instanceState', :squash => 'name'
attribute :state_reason, :aliases => 'stateReason'
attribute :subnet_id, :aliases => 'subnetId'
attribute :tenancy
attribute :tags, :aliases => 'tagSet'
attribute :user_data
attribute :virtualization_type, :aliases => 'virtualizationType'
attribute :vpc_id, :aliases => 'vpcId'
attr_accessor :password
attr_writer :iam_instance_profile_name, :iam_instance_profile_arn
def initialize(attributes={})
self.groups ||= ["default"] unless (attributes[:subnet_id] || attributes[:security_group_ids] || attributes[:network_interfaces])
self.flavor_id ||= 't1.micro'
# Old 'connection' is renamed as service and should be used instead
prepare_service_value(attributes)
self.image_id ||= begin
self.username ||= 'ubuntu'
case @service.instance_variable_get(:@region) # Ubuntu 10.04 LTS 64bit (EBS)
when 'ap-northeast-1'
'ami-5e0fa45f'
when 'ap-southeast-1'
'ami-f092eca2'
when 'ap-southeast-2'
'ami-fb8611c1' # Ubuntu 12.04 LTS 64bit (EBS)
when 'eu-west-1'
'ami-3d1f2b49'
when 'sa-east-1'
'ami-d0429ccd'
when 'us-east-1'
'ami-3202f25b'
when 'us-west-1'
'ami-f5bfefb0'
when 'us-west-2'
'ami-e0ec60d0'
end
end
super
end
def addresses
requires :id
service.addresses(:server => self)
end
def console_output
requires :id
service.get_console_output(id)
end
def destroy
requires :id
service.terminate_instances(id)
true
end
remove_method :flavor_id
def flavor_id
@flavor && @flavor.id || attributes[:flavor_id]
end
def flavor=(new_flavor)
@flavor = new_flavor
end
def flavor
@flavor ||= service.flavors.all.find {|flavor| flavor.id == flavor_id}
end
def key_pair
requires :key_name
service.key_pairs.all({'key-name' => key_name}).first
end
def key_pair=(new_keypair)
self.key_name = new_keypair && new_keypair.name
end
def ready?
state == 'running'
end
def reboot
requires :id
service.reboot_instances(id)
true
end
def run_instance_options
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
requires :image_id
options = {
'BlockDeviceMapping' => block_device_mapping,
'NetworkInterfaces' => network_interfaces,
'ClientToken' => client_token,
'DisableApiTermination' => disable_api_termination,
'EbsOptimized' => ebs_optimized,
'IamInstanceProfile.Arn' => @iam_instance_profile_arn,
'IamInstanceProfile.Name' => @iam_instance_profile_name,
'InstanceInitiatedShutdownBehavior' => instance_initiated_shutdown_behavior,
'InstanceType' => flavor_id,
'KernelId' => kernel_id,
'KeyName' => key_name,
'Monitoring.Enabled' => monitoring,
'Placement.AvailabilityZone' => availability_zone,
'Placement.GroupName' => placement_group,
'Placement.Tenancy' => tenancy,
'PrivateIpAddress' => private_ip_address,
'RamdiskId' => ramdisk_id,
'SecurityGroup' => groups,
'SecurityGroupId' => security_group_ids,
'SubnetId' => subnet_id,
'UserData' => user_data,
}
options.delete_if {|key, value| value.nil?}
# If subnet is defined then this is a Virtual Private Cloud.
# subnet & security group cannot co-exist. Attempting to specify
# both subnet and groups will cause an error. Instead please make
# use of Security Group Ids when working in a VPC.
if subnet_id
options.delete('SecurityGroup')
if associate_public_ip
options['NetworkInterface.0.DeviceIndex'] = 0
options['NetworkInterface.0.AssociatePublicIpAddress'] = associate_public_ip
options['NetworkInterface.0.SubnetId'] = options['SubnetId']
options.delete('SubnetId')
if options['SecurityGroupId'].kind_of?(Array)
options['SecurityGroupId'].each {|id|
options["NetworkInterface.0.SecurityGroupId.#{options['SecurityGroupId'].index(id)}"] = id
}
else
options["NetworkInterface.0.SecurityGroupId.0"] = options['SecurityGroupId']
end
options.delete('SecurityGroupId')
if private_ip_address
options.delete('PrivateIpAddress')
options['NetworkInterface.0.PrivateIpAddress'] = private_ip_address
end
end
else
options.delete('SubnetId')
end
options
end
def save
servers = service.servers.save_many(self, 1, 1)
merge_attributes(servers.first.attributes)
true
end
def setup(credentials = {})
requires :ssh_ip_address, :username
require 'net/ssh'
commands = [
%{mkdir .ssh},
%{passwd -l #{username}},
%{echo "#{Fog::JSON.encode(Fog::JSON.sanitize(attributes))}" >> ~/attributes.json}
]
if public_key
commands << %{echo "#{public_key}" >> ~/.ssh/authorized_keys}
end
# wait for aws to be ready
wait_for { sshable?(credentials) }
Fog::SSH.new(ssh_ip_address, username, credentials).run(commands)
end
def start
requires :id
service.start_instances(id)
true
end
def stop(force = false)
requires :id
service.stop_instances(id, force)
true
end
def volumes
requires :id
service.volumes(:server => self)
end
#I tried to call it monitoring= and be smart with attributes[]
#but in #save a merge_attribute is called after run_instance
#thus making an un-necessary request. Use this until finding a clever solution
def monitor=(new_monitor)
if persisted?
case new_monitor
when true
response = service.monitor_instances(identity)
when false
response = service.unmonitor_instances(identity)
else
raise ArgumentError.new("only Boolean allowed here")
end
end
self.monitoring = new_monitor
end
private
def placement=(new_placement)
if new_placement.is_a?(Hash)
merge_attributes(new_placement)
else
self.attributes[:placement] = new_placement
end
end
end
end
end
end

View file

@ -0,0 +1,211 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/server'
module Fog
module Compute
class Aws
class Servers < Fog::Collection
attribute :filters
model Fog::Compute::AWS::Server
# Creates a new server
#
# Aws.servers.new
#
# ==== Returns
#
# Returns the details of the new server
#
#>> Aws.servers.new
# <Fog::AWS::Compute::Server
# id=nil,
# ami_launch_index=nil,
# availability_zone=nil,
# block_device_mapping=nil,
# network_interfaces=nil,
# client_token=nil,
# dns_name=nil,
# groups=["default"],
# flavor_id="m1.small",
# image_id=nil,
# ip_address=nil,
# kernel_id=nil,
# key_name=nil,
# created_at=nil,
# monitoring=nil,
# product_codes=nil,
# private_dns_name=nil,
# private_ip_address=nil,
# ramdisk_id=nil,
# reason=nil,
# root_device_name=nil,
# root_device_type=nil,
# state=nil,
# state_reason=nil,
# subnet_id=nil,
# tags=nil,
# user_data=nil
# >
#
def initialize(attributes)
self.filters ||= {}
super
end
def all(filters = self.filters)
unless filters.is_a?(Hash)
Fog::Logger.deprecation("all with #{filters.class} param is deprecated, use all('instance-id' => []) instead [light_black](#{caller.first})[/]")
filters = {'instance-id' => [*filters]}
end
self.filters = filters
data = service.describe_instances(filters).body
load(
data['reservationSet'].map do |reservation|
reservation['instancesSet'].map do |instance|
instance.merge(:groups => reservation['groupSet'], :security_group_ids => reservation['groupIds'])
end
end.flatten
)
end
# Create between m and n servers with the server options specified in
# new_attributes. Equivalent to this loop, but happens in 1 request:
#
# 1.upto(n).map { create(new_attributes) }
#
# See the Aws RunInstances API.
def create_many(min_servers = 1, max_servers = nil, new_attributes = {})
max_servers ||= min_servers
template = new(new_attributes)
save_many(template, min_servers, max_servers)
end
# Bootstrap between m and n servers with the server options specified in
# new_attributes. Equivalent to this loop, but happens in 1 Aws request
# and the machines' spinup will happen in parallel:
#
# 1.upto(n).map { bootstrap(new_attributes) }
#
# See the Aws RunInstances API.
def bootstrap_many(min_servers = 1, max_servers = nil, new_attributes = {})
template = service.servers.new(new_attributes)
_setup_bootstrap(template)
servers = save_many(template, min_servers, max_servers)
servers.each do |server|
server.wait_for { ready? }
server.setup(:key_data => [server.private_key])
end
servers
end
def bootstrap(new_attributes = {})
bootstrap_many(1, 1, new_attributes).first
end
# Used to retrieve a server
#
# server_id is required to get the associated server information.
#
# You can run the following command to get the details:
# Aws.servers.get("i-5c973972")
#
# ==== Returns
#
#>> Aws.servers.get("i-5c973972")
# <Fog::AWS::Compute::Server
# id="i-5c973972",
# ami_launch_index=0,
# availability_zone="us-east-1b",
# block_device_mapping=[],
# client_token=nil,
# dns_name="ec2-25-2-474-44.compute-1.amazonaws.com",
# groups=["default"],
# flavor_id="m1.small",
# image_id="test",
# ip_address="25.2.474.44",
# kernel_id="aki-4e1e1da7",
# key_name=nil,
# created_at=Mon Nov 29 18:09:34 -0500 2010,
# monitoring=false,
# product_codes=[],
# private_dns_name="ip-19-76-384-60.ec2.internal",
# private_ip_address="19.76.384.60",
# ramdisk_id="ari-0b3fff5c",
# reason=nil,
# root_device_name=nil,
# root_device_type="instance-store",
# state="running",
# state_reason={},
# subnet_id=nil,
# tags={},
# user_data=nil
# >
#
def get(server_id)
if server_id
self.class.new(:service => service).all('instance-id' => server_id).first
end
rescue Fog::Errors::NotFound
nil
end
# From a template, create between m-n servers (see the Aws RunInstances API)
def save_many(template, min_servers = 1, max_servers = nil)
max_servers ||= min_servers
data = service.run_instances(template.image_id, min_servers, max_servers, template.run_instance_options)
# For some reason, Aws sometimes returns empty results alongside the real ones. Thus the select
data.body['instancesSet'].select { |instance_set| instance_set['instanceId'] }.map do |instance_set|
server = template.dup
server.merge_attributes(instance_set)
# expect eventual consistency
if (tags = server.tags) && tags.size > 0
Fog.wait_for { server.reload rescue nil }
service.create_tags(
server.identity,
tags
)
end
server
end
end
private
def _setup_bootstrap(server)
unless server.key_name
# first or create fog_#{credential} keypair
name = Fog.respond_to?(:credential) && Fog.credential || :default
unless server.key_pair = service.key_pairs.get("fog_#{name}")
server.key_pair = service.key_pairs.create(
:name => "fog_#{name}",
:public_key => server.public_key
)
end
end
security_group = service.security_groups.get(server.groups.first)
if security_group.nil?
raise Fog::Compute::AWS::Error, "The security group" \
" #{server.groups.first} doesn't exist."
end
# make sure port 22 is open in the first security group
authorized = security_group.ip_permissions.find do |ip_permission|
ip_permission['ipRanges'].first && ip_permission['ipRanges'].first['cidrIp'] == '0.0.0.0/0' &&
ip_permission['fromPort'] == 22 &&
ip_permission['ipProtocol'] == 'tcp' &&
ip_permission['toPort'] == 22
end
unless authorized
security_group.authorize_port_range(22..22)
end
end
end
end
end
end

View file

@ -0,0 +1,53 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class Snapshot < Fog::Model
identity :id, :aliases => 'snapshotId'
attribute :description
attribute :encrypted
attribute :progress
attribute :created_at, :aliases => 'startTime'
attribute :owner_id, :aliases => 'ownerId'
attribute :state, :aliases => 'status'
attribute :tags, :aliases => 'tagSet'
attribute :volume_id, :aliases => 'volumeId'
attribute :volume_size, :aliases => 'volumeSize'
def destroy
requires :id
service.delete_snapshot(id)
true
end
def ready?
state == 'completed'
end
def save
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
requires :volume_id
data = service.create_snapshot(volume_id, description).body
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
true
end
def volume
requires :id
service.describe_volumes(volume_id)
end
private
def volume=(new_volume)
self.volume_id = new_volume.volume_id
end
end
end
end
end

View file

@ -0,0 +1,48 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/snapshot'
module Fog
module Compute
class Aws
class Snapshots < Fog::Collection
attribute :filters
attribute :volume
model Fog::Compute::AWS::Snapshot
def initialize(attributes)
self.filters ||= { 'RestorableBy' => 'self' }
super
end
def all(filters_arg = filters, options = {})
unless filters_arg.is_a?(Hash)
Fog::Logger.deprecation("all with #{filters_arg.class} param is deprecated, use all('snapshot-id' => []) instead [light_black](#{caller.first})[/]")
filters_arg = {'snapshot-id' => [*filters_arg]}
end
filters = filters_arg
data = service.describe_snapshots(filters.merge!(options)).body
load(data['snapshotSet'])
if volume
self.replace(self.select {|snapshot| snapshot.volume_id == volume.id})
end
self
end
def get(snapshot_id)
if snapshot_id
self.class.new(:service => service).all('snapshot-id' => snapshot_id).first
end
end
def new(attributes = {})
if volume
super({ 'volumeId' => volume.id }.merge!(attributes))
else
super
end
end
end
end
end
end

View file

@ -0,0 +1,119 @@
require 'fog/compute/models/server'
module Fog
module Compute
class Aws
class SpotRequest < Fog::Compute::Server
identity :id, :aliases => 'spotInstanceRequestId'
attribute :price, :aliases => 'spotPrice'
attribute :request_type, :aliases => 'type'
attribute :created_at, :aliases => 'createTime'
attribute :instance_count, :aliases => 'instanceCount'
attribute :instance_id, :aliases => 'instanceId'
attribute :state
attribute :valid_from, :aliases => 'validFrom'
attribute :valid_until, :aliases => 'validUntil'
attribute :launch_group, :aliases => 'launchGroup'
attribute :availability_zone_group, :aliases => 'availabilityZoneGroup'
attribute :product_description, :aliases => 'productDescription'
attribute :ebs_optimized, :aliases => 'LaunchSpecification.EbsOptimized'
attribute :groups, :aliases => 'LaunchSpecification.SecurityGroup'
attribute :key_name, :aliases => 'LaunchSpecification.KeyName'
attribute :availability_zone, :aliases => 'LaunchSpecification.Placement.AvailabilityZone'
attribute :flavor_id, :aliases => 'LaunchSpecification.InstanceType'
attribute :image_id, :aliases => 'LaunchSpecification.ImageId'
attribute :monitoring, :aliases => 'LaunchSpecification.Monitoring'
attribute :block_device_mapping, :aliases => 'LaunchSpecification.BlockDeviceMapping'
attribute :subnet_id, :aliases => 'LaunchSpecification.SubnetId'
attribute :iam_instance_profile, :aliases => 'LaunchSpecification.IamInstanceProfile'
attribute :tags, :aliases => 'tagSet'
attribute :fault, :squash => 'message'
attribute :user_data
attr_writer :iam_instance_profile_name, :iam_instance_profile_arn
def initialize(attributes={})
self.groups ||= ["default"]
self.flavor_id ||= 't1.micro'
self.image_id ||= begin
self.username ||= 'ubuntu'
# Old 'connection' is renamed as service and should be used instead
prepare_service_value(attributes)
case @service.instance_variable_get(:@region) # Ubuntu 10.04 LTS 64bit (EBS)
when 'ap-northeast-1'
'ami-5e0fa45f'
when 'ap-southeast-1'
'ami-f092eca2'
when 'eu-west-1'
'ami-3d1f2b49'
when 'us-east-1'
'ami-3202f25b'
when 'us-west-1'
'ami-f5bfefb0'
end
end
super
end
def destroy
requires :id
service.cancel_spot_instance_requests(id)
true
end
def key_pair
requires :key_name
service.key_pairs.all(key_name).first
end
def key_pair=(new_keypair)
self.key_name = new_keypair && new_keypair.name
end
def ready?
state == 'active'
end
def save
requires :image_id, :flavor_id, :price
options = {
'AvailabilityZoneGroup' => availability_zone_group,
'InstanceCount' => instance_count,
'LaunchGroup' => launch_group,
'LaunchSpecification.BlockDeviceMapping' => block_device_mapping,
'LaunchSpecification.KeyName' => key_name,
'LaunchSpecification.Monitoring.Enabled' => monitoring,
'LaunchSpecification.Placement.AvailabilityZone' => availability_zone,
'LaunchSpecification.SecurityGroupId' => groups,
'LaunchSpecification.EbsOptimized' => ebs_optimized,
'LaunchSpecification.UserData' => user_data,
'LaunchSpecification.SubnetId' => subnet_id,
'LaunchSpecification.IamInstanceProfile.Arn' => @iam_instance_profile_arn,
'LaunchSpecification.IamInstanceProfile.Name' => @iam_instance_profile_name,
'Type' => request_type,
'ValidFrom' => valid_from,
'ValidUntil' => valid_until }
options.delete_if {|key, value| value.nil?}
data = service.request_spot_instances(image_id, flavor_id, price, options).body
spot_instance_request = data['spotInstanceRequestSet'].first
spot_instance_request['launchSpecification'].each do |name,value|
spot_instance_request['LaunchSpecification.' + name[0,1].upcase + name[1..-1]] = value
end
spot_instance_request.merge(:groups => spot_instance_request['LaunchSpecification.GroupSet'])
spot_instance_request.merge(options)
merge_attributes( spot_instance_request )
end
end
end
end
end

View file

@ -0,0 +1,86 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/spot_request'
module Fog
module Compute
class Aws
class SpotRequests < Fog::Collection
attribute :filters
model Fog::Compute::AWS::SpotRequest
def initialize(attributes)
self.filters ||= {}
super
end
def all(filters = self.filters)
unless filters.is_a?(Hash)
Fog::Logger.deprecation("all with #{filters.class} param is deprecated, use all('spot-instance-request-id' => []) instead [light_black](#{caller.first})[/]")
filters = {'spot-instance-request-id' => [*filters]}
end
self.filters = filters
data = service.describe_spot_instance_requests(filters).body
load(
data['spotInstanceRequestSet'].map do |spot_instance_request|
spot_instance_request['LaunchSpecification.Placement.AvailabilityZone'] = spot_instance_request['launchedAvailabilityZone']
spot_instance_request['launchSpecification'].each do |name,value|
spot_instance_request['LaunchSpecification.' + name[0,1].upcase + name[1..-1]] = value
end
spot_instance_request.merge(:groups => spot_instance_request['LaunchSpecification.GroupSet'])
spot_instance_request
end.flatten
)
end
def bootstrap(new_attributes = {})
spot_request = service.spot_requests.new(new_attributes)
unless new_attributes[:key_name]
# first or create fog_#{credential} keypair
name = Fog.respond_to?(:credential) && Fog.credential || :default
unless spot_request.key_pair = service.key_pairs.get("fog_#{name}")
spot_request.key_pair = service.key_pairs.create(
:name => "fog_#{name}",
:public_key => spot_request.public_key
)
end
end
# make sure port 22 is open in the first security group
security_group = service.security_groups.get(spot_request.groups.first)
authorized = security_group.ip_permissions.find do |ip_permission|
ip_permission['ipRanges'].first && ip_permission['ipRanges'].first['cidrIp'] == '0.0.0.0/0' &&
ip_permission['fromPort'] == 22 &&
ip_permission['ipProtocol'] == 'tcp' &&
ip_permission['toPort'] == 22
end
unless authorized
security_group.authorize_port_range(22..22)
end
spot_request.save
Fog.wait_for { spot_request.reload.ready? rescue nil }
server = service.servers.get(spot_request.instance_id)
if spot_request.tags
service.create_tags(
spot_request.instance_id,
spot_request.tags
)
end
server.wait_for { ready? }
server.setup(:key_data => [spot_request.private_key])
server
end
def get(spot_request_id)
if spot_request_id
self.class.new(:service => service).all('spot-instance-request-id' => spot_request_id).first
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,61 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class Subnet < Fog::Model
identity :subnet_id, :aliases => 'subnetId'
attribute :state
attribute :vpc_id, :aliases => 'vpcId'
attribute :cidr_block, :aliases => 'cidrBlock'
attribute :available_ip_address_count, :aliases => 'availableIpAddressCount'
attribute :availability_zone, :aliases => 'availabilityZone'
attribute :tag_set, :aliases => 'tagSet'
attribute :map_public_ip_on_launch, :aliases => 'mapPublicIpOnLaunch'
def ready?
requires :state
state == 'available'
end
# Removes an existing subnet
#
# subnet.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires :subnet_id
service.delete_subnet(subnet_id)
true
end
# Create a subnet
#
# >> g = Aws.subnets.new(:vpc_id => "vpc-someId", :cidr_block => "10.0.0.0/24")
# >> g.save
#
# == Returns:
#
# requestId and a subnet object
#
def save
requires :vpc_id, :cidr_block
options = {}
options['AvailabilityZone'] = availability_zone if availability_zone
data = service.create_subnet(vpc_id, cidr_block, options).body['subnet']
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
true
true
end
end
end
end
end

View file

@ -0,0 +1,95 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/subnet'
module Fog
module Compute
class Aws
class Subnets < Fog::Collection
attribute :filters
model Fog::Compute::AWS::Subnet
# Creates a new subnet
#
# Aws.subnets.new
#
# ==== Returns
#
# Returns the details of the new Subnet
#
#>> Aws.subnets.new
# <Fog::AWS::Compute::Subnet
# subnet_id=subnet-someId,
# state=[pending|available],
# vpc_id=vpc-someId
# cidr_block=someIpRange
# available_ip_address_count=someInt
# tagset=nil
# >
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all Subnets that have been created
#
# Aws.subnets.all
#
# ==== Returns
#
# Returns an array of all VPCs
#
#>> Aws.subnets.all
# <Fog::AWS::Compute::Subnet
# filters={}
# [
# subnet_id=subnet-someId,
# state=[pending|available],
# vpc_id=vpc-someId
# cidr_block=someIpRange
# available_ip_address_count=someInt
# tagset=nil
# ]
# >
#
def all(filters_arg = filters)
unless filters_arg.is_a?(Hash)
Fog::Logger.warning("all with #{filters_arg.class} param is deprecated, use all('subnet-id' => []) instead [light_black](#{caller.first})[/]")
filters_arg = {'subnet-id' => [*filters_arg]}
end
filters = filters_arg
data = service.describe_subnets(filters).body
load(data['subnetSet'])
end
# Used to retrieve a Subnet
# subnet-id is required to get the associated VPC information.
#
# You can run the following command to get the details:
# Aws.subnets.get("subnet-12345678")
#
# ==== Returns
#
#>> Aws.subnets.get("subnet-12345678")
# <Fog::AWS::Compute::Subnet
# subnet_id=subnet-someId,
# state=[pending|available],
# vpc_id=vpc-someId
# cidr_block=someIpRange
# available_ip_address_count=someInt
# tagset=nil
# >
#
def get(subnet_id)
if subnet_id
self.class.new(:service => service).all('subnet-id' => subnet_id).first
end
end
end
end
end
end

View file

@ -0,0 +1,31 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class Tag < Fog::Model
identity :key
attribute :value
attribute :resource_id, :aliases => 'resourceId'
attribute :resource_type, :aliases => 'resourceType'
def initialize(attributes = {})
super
end
def destroy
requires :key, :resource_id
service.delete_tags(resource_id, key => value)
true
end
def save
requires :key, :resource_id
service.create_tags(resource_id, key => value)
true
end
end
end
end
end

View file

@ -0,0 +1,31 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/tag'
module Fog
module Compute
class Aws
class Tags < Fog::Collection
attribute :filters
model Fog::Compute::AWS::Tag
def initialize(attributes)
self.filters ||= {}
super
end
def all(filters_arg = filters)
filters = filters_arg
data = service.describe_tags(filters).body
load(data['tagSet'])
end
def get(key)
if key
self.class.new(:service => service).all('key' => key)
end
end
end
end
end
end

View file

@ -0,0 +1,126 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class Volume < Fog::Model
identity :id, :aliases => 'volumeId'
attribute :attached_at, :aliases => 'attachTime'
attribute :availability_zone, :aliases => 'availabilityZone'
attribute :created_at, :aliases => 'createTime'
attribute :delete_on_termination, :aliases => 'deleteOnTermination'
attribute :device
attribute :iops
attribute :server_id, :aliases => 'instanceId'
attribute :size
attribute :encrypted
attribute :snapshot_id, :aliases => 'snapshotId'
attribute :state, :aliases => 'status'
attribute :tags, :aliases => 'tagSet'
attribute :type, :aliases => 'volumeType'
def initialize(attributes = {})
# assign server first to prevent race condition with persisted?
self.server = attributes.delete(:server)
super
end
def destroy
requires :id
service.delete_volume(id)
true
end
def ready?
state == 'available'
end
def save
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
requires :availability_zone
requires_one :size, :snapshot_id
if type == 'io1'
requires :iops
end
data = service.create_volume(availability_zone, size, 'SnapshotId' => snapshot_id, 'VolumeType' => type, 'Iops' => iops, 'Encrypted' => encrypted).body
new_attributes = data.reject {|key,value| key == 'requestId'}
merge_attributes(new_attributes)
if tags = self.tags
# expect eventual consistency
Fog.wait_for { self.reload rescue nil }
service.create_tags(
self.identity,
tags
)
end
if @server
self.server = @server
end
true
end
def server
requires :server_id
service.servers.get(server_id)
end
def server=(new_server)
if new_server
attach(new_server)
else
detach
end
end
def snapshots
requires :id
service.snapshots(:volume => self)
end
def snapshot(description)
requires :id
service.create_snapshot(id, description)
end
def force_detach
detach(true)
end
private
def attachmentSet=(new_attachment_set)
merge_attributes(new_attachment_set.first || {})
end
def attach(new_server)
if !persisted?
@server = new_server
self.availability_zone = new_server.availability_zone
elsif new_server
requires :device
wait_for { ready? }
@server = nil
self.server_id = new_server.id
service.attach_volume(server_id, id, device)
reload
end
end
def detach(force = false)
@server = nil
self.server_id = nil
if persisted?
service.detach_volume(id, 'Force' => force)
reload
end
end
end
end
end
end

View file

@ -0,0 +1,117 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/volume'
module Fog
module Compute
class Aws
class Volumes < Fog::Collection
attribute :filters
attribute :server
model Fog::Compute::AWS::Volume
# Used to create a volume. There are 3 arguments and availability_zone and size are required. You can generate a new key_pair as follows:
# Aws.volumes.create(:availability_zone => 'us-east-1a', :size => 10)
#
# ==== Returns
#
#<Fog::AWS::Compute::Volume
# id="vol-1e2028b9",
# attached_at=nil,
# availability_zone="us-east-1a",
# created_at=Tue Nov 23 23:30:29 -0500 2010,
# delete_on_termination=nil,
# device=nil,
# server_id=nil,
# size=10,
# snapshot_id=nil,
# state="creating",
# tags=nil
#>
#
# The volume can be retrieved by running Aws.volumes.get("vol-1e2028b9"). See get method below.
#
def initialize(attributes)
self.filters ||= {}
super
end
# Used to return all volumes.
# Aws.volumes.all
#
# ==== Returns
#
#>>Aws.volumes.all
#<Fog::AWS::Compute::Volume
# id="vol-1e2028b9",
# attached_at=nil,
# availability_zone="us-east-1a",
# created_at=Tue Nov 23 23:30:29 -0500 2010,
# delete_on_termination=nil,
# device=nil,
# server_id=nil,
# size=10,
# snapshot_id=nil,
# state="creating",
# tags=nil
#>
#
# The volume can be retrieved by running Aws.volumes.get("vol-1e2028b9"). See get method below.
#
def all(filters_arg = filters)
unless filters_arg.is_a?(Hash)
Fog::Logger.deprecation("all with #{filters_arg.class} param is deprecated, use all('volume-id' => []) instead [light_black](#{caller.first})[/]")
filters_arg = {'volume-id' => [*filters_arg]}
end
filters = filters_arg
data = service.describe_volumes(filters).body
load(data['volumeSet'])
if server
self.replace(self.select {|volume| volume.server_id == server.id})
end
self
end
# Used to retrieve a volume
# volume_id is required to get the associated volume information.
#
# You can run the following command to get the details:
# Aws.volumes.get("vol-1e2028b9")
#
# ==== Returns
#
#>> Aws.volumes.get("vol-1e2028b9")
# <Fog::AWS::Compute::Volume
# id="vol-1e2028b9",
# attached_at=nil,
# availability_zone="us-east-1a",
# created_at=Tue Nov 23 23:30:29 -0500 2010,
# delete_on_termination=nil,
# device=nil,
# server_id=nil,
# size=10,
# snapshot_id=nil,
# state="available",
# tags={}
# >
#
def get(volume_id)
if volume_id
self.class.new(:service => service).all('volume-id' => volume_id).first
end
end
def new(attributes = {})
if server
super({ :server => server }.merge!(attributes))
else
super
end
end
end
end
end
end

View file

@ -0,0 +1,75 @@
require 'fog/core/model'
module Fog
module Compute
class Aws
class VPC < Fog::Model
identity :id, :aliases => 'vpcId'
attribute :state
attribute :cidr_block, :aliases => 'cidrBlock'
attribute :dhcp_options_id, :aliases => 'dhcpOptionsId'
attribute :tags, :aliases => 'tagSet'
attribute :tenancy, :aliases => 'instanceTenancy'
def initialize(attributes={})
self.dhcp_options_id ||= "default"
self.tenancy ||= "default"
super
end
def ready?
requires :state
state == 'available'
end
# Removes an existing vpc
#
# vpc.destroy
#
# ==== Returns
#
# True or false depending on the result
#
def destroy
requires :id
service.delete_vpc(id)
true
end
# Create a vpc
#
# >> g = Aws.vpcs.new(:cidr_block => "10.1.2.0/24")
# >> g.save
#
# == Returns:
#
# True or an exception depending on the result. Keep in mind that this *creates* a new vpc.
# As such, it yields an InvalidGroup.Duplicate exception if you attempt to save an existing vpc.
#
def save
requires :cidr_block
data = service.create_vpc(cidr_block).body['vpcSet'].first
new_attributes = data.reject {|key,value| key == 'requestId'}
new_attributes = data.reject {|key,value| key == 'requestId' || key == 'tagSet' }
merge_attributes(new_attributes)
if tags = self.tags
# expect eventual consistency
Fog.wait_for { self.reload rescue nil }
service.create_tags(
self.identity,
tags
)
end
true
end
end
end
end
end

View file

@ -0,0 +1,89 @@
require 'fog/core/collection'
require 'fog/aws/models/compute/vpc'
module Fog
module Compute
class Aws
class Vpcs < Fog::Collection
attribute :filters
model Fog::Compute::AWS::VPC
# Creates a new VPC
#
# Aws.vpcs.new
#
# ==== Returns
#
# Returns the details of the new VPC
#
#>> Aws.vpcs.new
# <Fog::AWS::VPC::VPC
# id=nil,
# state=nil,
# cidr_block=nil,
# dhcp_options_id=nil
# tags=nil
# tenancy=nil
# >
#
def initialize(attributes)
self.filters ||= {}
super
end
# Returns an array of all VPCs that have been created
#
# Aws.vpcs.all
#
# ==== Returns
#
# Returns an array of all VPCs
#
#>> Aws.vpcs.all
# <Fog::AWS::VPC::VPCs
# filters={}
# [
# <Fog::AWS::VPC::VPC
# id="vpc-12345678",
# TODO
# >
# ]
# >
#
def all(filters_arg = filters)
unless filters_arg.is_a?(Hash)
Fog::Logger.warning("all with #{filters_arg.class} param is deprecated, use all('vpc-id' => []) instead [light_black](#{caller.first})[/]")
filters_arg = {'vpc-id' => [*filters_arg]}
end
filters = filters_arg
data = service.describe_vpcs(filters).body
load(data['vpcSet'])
end
# Used to retrieve a VPC
# vpc_id is required to get the associated VPC information.
#
# You can run the following command to get the details:
# Aws.vpcs.get("vpc-12345678")
#
# ==== Returns
#
#>> Aws.vpcs.get("vpc-12345678")
# <Fog::AWS::Compute::VPC
# id="vpc-12345678",
# TODO
# >
#
def get(vpc_id)
if vpc_id
self.class.new(:service => service).all('vpc-id' => vpc_id).first
end
end
end
end
end
end

View file

@ -0,0 +1,63 @@
require 'fog/core/model'
module Fog
module AWS
class DataPipeline
class Pipeline < Fog::Model
identity :id, :aliases => 'pipelineId'
attribute :name
attribute :description
attribute :tags
attribute :user_id, :aliases => 'userId'
attribute :account_id, :aliases => 'accountId'
attribute :state, :aliases => 'pipelineState'
attribute :unique_id, :aliases => 'uniqueId'
def initialize(attributes={})
# Extract the 'fields' portion of a response to attributes
if attributes.include?('fields')
string_fields = attributes['fields'].select { |f| f.include?('stringValue') }
field_attributes = Hash[string_fields.map { |f| [f['key'][/^@(.+)$/, 1], f['stringValue']] }]
merge_attributes(field_attributes)
end
super
end
def save
requires :name
requires :unique_id
data = service.create_pipeline(unique_id, name, nil, tags)
merge_attributes(data)
true
end
def activate
requires :id
service.activate_pipeline(id)
true
end
def put(objects)
requires :id
service.put_pipeline_definition(id, objects)
true
end
def destroy
requires :id
service.delete_pipeline(id)
true
end
end
end
end
end

View file

@ -0,0 +1,33 @@
require 'fog/core/collection'
require 'fog/aws/models/data_pipeline/pipeline'
module Fog
module AWS
class DataPipeline
class Pipelines < Fog::Collection
model Fog::AWS::DataPipeline::Pipeline
def all
ids = []
begin
result = service.list_pipelines
ids << result['pipelineIdList'].map { |id| id['id'] }
end while (result['hasMoreResults'] && result['marker'])
load(service.describe_pipelines(ids.flatten)['pipelineDescriptionList'])
end
def get(id)
data = service.describe_pipelines([id])['pipelineDescriptionList'].first
new(data)
rescue Excon::Errors::BadRequest => error
data = Fog::JSON.decode(error.response.body)
raise unless data['__type'] == 'PipelineDeletedException' || data['__type'] == 'PipelineNotFoundException'
nil
end
end
end
end
end

View file

@ -0,0 +1,116 @@
require 'fog/core/model'
module Fog
module DNS
class Aws
class Record < Fog::Model
extend Fog::Deprecation
deprecate :ip, :value
deprecate :ip=, :value=
identity :name, :aliases => ['Name']
attribute :value, :aliases => ['ResourceRecords']
attribute :ttl, :aliases => ['TTL']
attribute :type, :aliases => ['Type']
attribute :status, :aliases => ['Status']
attribute :created_at, :aliases => ['SubmittedAt']
attribute :alias_target, :aliases => ['AliasTarget']
attribute :change_id, :aliases => ['Id']
attribute :region, :aliases => ['Region']
attribute :weight, :aliases => ['Weight']
attribute :set_identifier, :aliases => ['SetIdentifier']
attribute :failover, :aliases => ['Failover']
attribute :geo_location, :aliases => ['GeoLocation']
attribute :health_check_id, :aliases => ['HealthCheckId']
def initialize(attributes={})
super
end
def destroy
options = attributes_to_options('DELETE')
service.change_resource_record_sets(zone.id, [options])
true
end
def zone
@zone
end
def save
unless self.alias_target
self.ttl ||= 3600
end
options = attributes_to_options('CREATE')
data = service.change_resource_record_sets(zone.id, [options]).body
merge_attributes(data)
true
end
def modify(new_attributes)
options = []
# Delete the current attributes
options << attributes_to_options('DELETE')
# Create the new attributes
merge_attributes(new_attributes)
options << attributes_to_options('CREATE')
data = service.change_resource_record_sets(zone.id, options).body
merge_attributes(data)
true
end
# Returns true if record is insync. May only be called for newly created or modified records that
# have a change_id and status set.
def ready?
requires :change_id, :status
status == 'INSYNC'
end
def reload
# If we have a change_id (newly created or modified), then reload performs a get_change to update status.
if change_id
data = service.get_change(change_id).body
merge_attributes(data)
self
else
super
end
end
private
def zone=(new_zone)
@zone = new_zone
end
def attributes_to_options(action)
requires :name, :type, :zone
requires_one :value, :alias_target
options = {
:action => action,
:name => name,
:resource_records => [*value],
:alias_target => symbolize_keys(alias_target),
:ttl => ttl,
:type => type,
:weight => weight,
:set_identifier => set_identifier,
:region => region,
:failover => failover,
:geo_location => geo_location,
:health_check_id => health_check_id
}
unless self.alias_target
requires :ttl
options[:ttl] = ttl
end
options
end
end
end
end
end

View file

@ -0,0 +1,120 @@
require 'fog/core/collection'
require 'fog/aws/models/dns/record'
module Fog
module DNS
class Aws
class Records < Fog::Collection
attribute :is_truncated, :aliases => ['IsTruncated']
attribute :max_items, :aliases => ['MaxItems']
attribute :name
attribute :next_record_name, :aliases => ['NextRecordName']
attribute :next_record_type, :aliases => ['NextRecordType']
attribute :next_record_identifier, :aliases => ['NextRecordIdentifier']
attribute :type
attribute :identifier
attribute :zone
model Fog::DNS::AWS::Record
def all(options = {})
requires :zone
options[:max_items] ||= max_items
options[:name] ||= zone.domain
options[:type] ||= type
options[:identifier] ||= identifier
options.delete_if {|key, value| value.nil?}
data = service.list_resource_record_sets(zone.id, options).body
# NextRecordIdentifier is completely absent instead of nil, so set to nil, or iteration breaks.
data['NextRecordIdentifier'] = nil unless data.key?('NextRecordIdentifier')
merge_attributes(data.reject {|key, value| !['IsTruncated', 'MaxItems', 'NextRecordName', 'NextRecordType', 'NextRecordIdentifier'].include?(key)})
load(data['ResourceRecordSets'])
end
#
# Load all zone records into the collection.
#
def all!
data = []
merge_attributes({'NextRecordName' => nil,
'NextRecordType' => nil,
'NextRecordIdentifier' => nil,
'IsTruncated' => nil})
begin
options = {
:name => next_record_name,
:type => next_record_type,
:identifier => next_record_identifier
}
options.delete_if {|key, value| value.nil?}
batch = service.list_resource_record_sets(zone.id, options).body
# NextRecordIdentifier is completely absent instead of nil, so set to nil, or iteration breaks.
batch['NextRecordIdentifier'] = nil unless batch.key?('NextRecordIdentifier')
merge_attributes(batch.reject {|key, value| !['IsTruncated', 'MaxItems', 'NextRecordName', 'NextRecordType', 'NextRecordIdentifier'].include?(key)})
data.concat(batch['ResourceRecordSets'])
end while is_truncated
load(data)
end
#
# Aws Route 53 records are uniquely identified by a compound key of name, type, and identifier.
# #get allows one to retrieve a record using one or more of those key components.
#
# ==== Parameters
# * record_name - The name of the record to retrieve.
# * record_type - The type of record to retrieve, if nil, then the first matching record is returned.
# * record_identifier - The record set identifier to retrieve, if nil, then the first matching record is returned.
#
def get(record_name, record_type = nil, record_identifier = nil)
requires :zone
# Append a trailing period to the record_name if absent.
record_name = record_name + "." unless record_name.end_with?(".")
record_type = record_type.upcase unless record_type.nil?
options = {
:max_items => 1,
:name => record_name,
:type => record_type,
:identifier => record_identifier
}
options.delete_if {|key, value| value.nil?}
data = service.list_resource_record_sets(zone.id, options).body
# Get first record
data = data['ResourceRecordSets'].shift
if data
record = new(data)
# make sure everything matches
if record.name == record_name
if (!record_type.nil? && record.type != record_type) ||
(!record_identifier.nil? && record.set_identifier != record_identifier)
nil
else
record
end
end
else
nil
end
rescue Excon::Errors::NotFound
nil
end
def new(attributes = {})
requires :zone
super({ :zone => zone }.merge!(attributes))
end
end
end
end
end

View file

@ -0,0 +1,49 @@
require 'fog/core/model'
# require 'fog/aws/models/dns/records'
module Fog
module DNS
class Aws
class Zone < Fog::Model
identity :id, :aliases => 'Id'
attribute :caller_reference, :aliases => 'CallerReference'
attribute :change_info, :aliases => 'ChangeInfo'
attribute :description, :aliases => 'Comment'
attribute :domain, :aliases => 'Name'
attribute :nameservers, :aliases => 'NameServers'
def destroy
requires :identity
service.delete_hosted_zone(identity)
true
end
def records
@records ||= begin
Fog::DNS::AWS::Records.new(
:zone => self,
:service => service
)
end
end
def save
requires :domain
options = {}
options[:caller_ref] = caller_reference if caller_reference
options[:comment] = description if description
data = service.create_hosted_zone(domain, options).body
merge_attributes(data)
true
end
private
define_method(:HostedZone=) do |new_hosted_zone|
merge_attributes(new_hosted_zone)
end
end
end
end
end

View file

@ -0,0 +1,29 @@
require 'fog/core/collection'
require 'fog/aws/models/dns/zone'
module Fog
module DNS
class Aws
class Zones < Fog::Collection
attribute :marker, :aliases => 'Marker'
attribute :max_items, :aliases => 'MaxItems'
model Fog::DNS::AWS::Zone
def all(options = {})
options['marker'] ||= marker
options['maxitems'] ||= max_items
data = service.list_hosted_zones(options).body['HostedZones']
load(data)
end
def get(zone_id)
data = service.get_hosted_zone(zone_id).body
new(data)
rescue Excon::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,69 @@
require 'fog/core/model'
module Fog
module AWS
class Elasticache
class Cluster < Fog::Model
# simple attributes
identity :id, :aliases => 'CacheClusterId'
attribute :auto_upgrade, :aliases => 'AutoMinorVersionUpgrade'
attribute :status, :aliases => 'CacheClusterStatus'
attribute :node_type, :aliases => 'CacheNodeType'
attribute :engine, :aliases => 'Engine'
attribute :engine_version, :aliases => 'EngineVersion'
attribute :num_nodes, :aliases => 'NumCacheNodes'
attribute :zone, :aliases => 'PreferredAvailabilityZone'
attribute :port, :aliases => 'Port'
attribute :maintenance_window, :aliases => 'PreferredMaintenanceWindow'
# complex attributes
attribute :nodes, :aliases => 'CacheNodes', :type => :array
attribute :parameter_group, :aliases => 'CacheParameterGroup'
attribute :pending_values, :aliases => 'PendingModifiedValues'
attribute :create_time, :aliases => 'CacheClusterCreateTime', :type => :timestamp
attribute :security_groups, :aliases => 'CacheSecurityGroups', :type => :array
attribute :notification_config, :aliases => 'NotificationConfiguration'
attribute :cache_subnet_group_name, :aliases => 'CacheSubnetGroupName'
attribute :vpc_security_groups, :aliases => 'VpcSecurityGroups', :type => :array
attribute :s3_snapshot_location, :aliases => 'SnapshotArns', :type => :array
attr_accessor :parameter_group_name
def ready?
status == 'available'
end
def destroy
requires :id
service.delete_cache_cluster(id)
true
end
def save
requires :id
parameter_group ||= Hash.new
notification_config ||= Hash.new
service.create_cache_cluster(
id, {
:node_type => node_type,
:security_group_names => security_groups,
:num_nodes => num_nodes,
:auto_minor_version_upgrade => auto_upgrade,
:engine => engine,
:engine_version => engine_version,
:notification_topic_arn => notification_config['TopicArn'],
:port => port,
:preferred_availablility_zone => zone,
:preferred_maintenance_window => maintenance_window,
:s3_snapshot_location => s3_snapshot_location,
:parameter_group_name => parameter_group_name || parameter_group['CacheParameterGroupName'],
:cache_subnet_group_name => cache_subnet_group_name,
:vpc_security_groups => vpc_security_groups,
}
)
end
end
end
end
end

View file

@ -0,0 +1,29 @@
require 'fog/core/collection'
require 'fog/aws/models/elasticache/cluster'
module Fog
module AWS
class Elasticache
class Clusters < Fog::Collection
model Fog::AWS::Elasticache::Cluster
def all
load(
service.describe_cache_clusters(
nil, :show_node_info => true
).body['CacheClusters']
)
end
def get(identity, show_node_info = true)
new(
service.describe_cache_clusters(
identity, :show_node_info => show_node_info
).body['CacheClusters'].first
)
rescue Fog::AWS::Elasticache::NotFound
end
end
end
end
end

View file

@ -0,0 +1,28 @@
require 'fog/core/model'
module Fog
module AWS
class Elasticache
class ParameterGroup < Fog::Model
identity :id, :aliases => 'CacheParameterGroupName'
attribute :description, :aliases => 'Description'
attribute :family, :aliases => 'CacheParameterGroupFamily'
def destroy
requires :id
service.delete_cache_parameter_group(id)
true
end
def save
requires :id
service.create_cache_parameter_group(
id,
description = id,
family = 'memcached1.4'
)
end
end
end
end
end

Some files were not shown because too many files have changed in this diff Show more