From e1f625f9f2868cadce6740f9cb47475289b180bc Mon Sep 17 00:00:00 2001 From: Pan Thomakos Date: Wed, 17 Aug 2011 14:31:33 -0700 Subject: [PATCH] Added Fog::CurrentMachine#ip_address. This function allows you to get the ip address of the current machine. I found this useful because I wanted to add my personal or production machine to a specific RDS security group. The call is quite simple and connects to amazon's checkip website. The class is threadsafe and I have included specs with it as well. I have also added the Fog::AWS::RDS::SecurityGroup#authorize_me function to make adding the current machine to a given RDS security group very easy. --- lib/fog/aws/models/rds/security_group.rb | 11 +++++++ lib/fog/core/current_machine.rb | 38 ++++++++++++++++++++++++ spec/core/current_machine_spec.rb | 22 ++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 lib/fog/core/current_machine.rb create mode 100644 spec/core/current_machine_spec.rb diff --git a/lib/fog/aws/models/rds/security_group.rb b/lib/fog/aws/models/rds/security_group.rb index f1c53e679..dbf508697 100644 --- a/lib/fog/aws/models/rds/security_group.rb +++ b/lib/fog/aws/models/rds/security_group.rb @@ -1,4 +1,5 @@ require 'fog/core/model' +require 'fog/core/current_machine' module Fog module AWS @@ -43,6 +44,16 @@ module Fog authorize_ingress({'CIDRIP' => cidrip}) end + # Add the current machine to the RDS security group. + def authorize_me + authorize_ip_address(Fog::CurrentMachine.ip_address) + end + + # Add the ip address to the RDS security group. + def authorize_ip_address(ip) + authorize_cidrip("#{ip}/32") + end + def authorize_ingress(opts) data = connection.authorize_db_security_group_ingress(id, opts).body['AuthorizeDBSecurityGroupIngressResult']['DBSecurityGroup'] merge_attributes(data) diff --git a/lib/fog/core/current_machine.rb b/lib/fog/core/current_machine.rb new file mode 100644 index 000000000..a46991857 --- /dev/null +++ b/lib/fog/core/current_machine.rb @@ -0,0 +1,38 @@ +require 'net/http' +require 'uri' + +module Fog + class CurrentMachine + @@lock = Mutex.new + AMAZON_AWS_CHECK_IP = 'http://checkip.amazonaws.com' + + def self.ip_address= ip_address + @@lock.synchronize do + @@ip_address = ip_address + end + end + + # Get the ip address of the machine from which this command is run. It is + # recommended that you surround calls to this function with a timeout block + # to ensure optimum performance in the case where the amazonaws checkip + # service is unavailable. + # + # @example Get the current ip address + # begin + # Timeout::timeout(5) do + # puts "Your ip address is #{Fog::CurrentMachine.ip_address}" + # end + # rescue Timeout::Error + # puts "Service timeout" + # end + # + # @raise [Net::HTTPExceptions] if the net/http request fails. + def self.ip_address + @@lock.synchronize do + @@ip_address ||= Net::HTTP \ + .get_response(URI.parse(AMAZON_AWS_CHECK_IP)) \ + .body.chomp + end + end + end +end diff --git a/spec/core/current_machine_spec.rb b/spec/core/current_machine_spec.rb new file mode 100644 index 000000000..7ea0a8568 --- /dev/null +++ b/spec/core/current_machine_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' +require 'fog/core/current_machine' + +describe Fog::CurrentMachine do + context '#ip_address' do + before(:each){ described_class.ip_address = nil } + + it 'should be threadsafe' do + Net::HTTP.should_receive(:get_response).once{ Struct.new(:body).new('') } + + (1..10).map { + Thread.new { described_class.ip_address } + }.each{ |t| t.join } + end + + it 'should remove trailing endline characters' do + Net::HTTP.stub(:get_response){ Struct.new(:body).new("192.168.0.1\n") } + + described_class.ip_address.should == '192.168.0.1' + end + end +end