aws_csshx 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ *.swo
5
+ *.swp
6
+ Manifest
7
+ .rvmrc
@@ -0,0 +1,8 @@
1
+ ### aws_csshx 0.1.1 2012-05-04
2
+
3
+ * Added command line switches (Eric Lubow)
4
+ * Added config file support using .csshrc (Eric Lubow)
5
+
6
+ ### aws_csshx 0.1.0 2012-05-01
7
+
8
+ * Initial vesion (Russell Bradberry)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in aws_csshx.gemspec
4
+ gemspec
@@ -0,0 +1,18 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ aws_csshx (0.0.1)
5
+ right_aws
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ right_aws (3.0.4)
11
+ right_http_connection (>= 1.2.5)
12
+ right_http_connection (1.3.0)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ aws_csshx!
@@ -0,0 +1,8 @@
1
+ # AWS CSSHX Wrapper
2
+
3
+ This is a wrapper script for ClusterSSHX (csshx). It allows the user the ability to ssh to all machines in an AWS security group using a specific key and user for those machines.
4
+
5
+ ## Installation
6
+
7
+ gem install aws_csshx
8
+
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/TODO.md ADDED
@@ -0,0 +1,3 @@
1
+ ### TODO List for aws_csshx
2
+
3
+ * Add ability to use -H/--hosts to tack on additional hosts to the SSH cluster
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "aws_csshx/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "aws_csshx"
7
+ s.version = AwsCsshx::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Russell Bradberry", "Eric Lubow"]
10
+ s.email = ["eric@lubow.org"]
11
+ s.homepage = ""
12
+ s.summary = %q{csshx wrapper that interacts with your AWS account for group ssh sessions}
13
+ s.description = %q{csshx wrapper that interacts with your AWS account for group ssh sessions}
14
+
15
+ s.add_dependency 'right_aws'
16
+
17
+ s.rubyforge_project = "aws_csshx"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
+ require 'aws_csshx'
5
+
6
+ exit AwsCsshx::Application.run!(*ARGV)
@@ -0,0 +1,8 @@
1
+ require 'etc'
2
+ require 'right_aws'
3
+
4
+ require 'aws_csshx/application'
5
+ require 'aws_csshx/configuration_file'
6
+ require 'aws_csshx/misc'
7
+ require 'aws_csshx/options'
8
+ require 'aws_csshx/version'
@@ -0,0 +1,94 @@
1
+ module AwsCsshx
2
+ class Application
3
+ attr :options
4
+
5
+ class << self
6
+
7
+ def csshx_exists?
8
+ `which csshx > /dev/null 2>&1`
9
+ end
10
+
11
+ def aws_settings_exist?
12
+ @options[:aws_access_key] and @options[:aws_secret_key] and @options[:aws_region] and File.exists?(@options[:ec2_private_key])
13
+ end
14
+
15
+ def has_servers?(list)
16
+ server_list.count > 0 ? true : false
17
+ end
18
+
19
+ def run!(*arguments)
20
+ @options = {}
21
+
22
+ # No need to go further unless csshX exists
23
+ abort('csshX file is required') unless csshx_exists?
24
+
25
+ begin
26
+ # First we load the config file and then process the command line
27
+ # options since they take precedence.
28
+
29
+ # Load the config file if it exists
30
+ conf_file = "#{Etc.getpwuid.dir}/.csshrc"
31
+ if File.exists?(conf_file)
32
+ config = AwsCsshx::ConfigurationFile.new(conf_file)
33
+ @options = config.options
34
+ end
35
+
36
+ command_line_options = AwsCsshx::Options.new(arguments)
37
+ @options.merge!(command_line_options[:options])
38
+ @options = AwsCsshx::Misc.symbolize_hash_keys(@options)
39
+
40
+ # Load the new config file if different
41
+ if conf_file != @options[:conf] and File.exists?(conf_file)
42
+ config = AwsCsshx::ConfigurationFile.new(@options[:conf])
43
+ end
44
+
45
+ # Deal with the option issues
46
+ if command_line_options[:invalid_argument]
47
+ $stderr.puts command_line_options[:invalid_argument]
48
+ @options[:help] = true
49
+ end
50
+
51
+ # Show the version screen and bounce if requested
52
+ if @options[:version]
53
+ puts "#{$0} #{AwsCsshx::VERSION}"
54
+ return 0
55
+ end
56
+
57
+ # Show the help screen and bounce if requested
58
+ if @options[:help]
59
+ puts command_line_options.opts
60
+ return 0
61
+ end
62
+
63
+ # Stop here without all our AWS settings
64
+ abort("Invalid AWS settings") unless aws_settings_exist?
65
+
66
+ abort("Cannot continue without AWS security group (-g)") unless @options[:group]
67
+ @server_list = aws_server_list_by_group @options[:group]
68
+
69
+ if has_servers? @server_list
70
+ `csshx --login #{@options[:login]} --ssh_args='-i #{@options[:ec2_private_key]}' #{@server_list.join(' ')}`
71
+ puts "Opened connections to #{@server_list.count} servers in the '#{@options[:group]}' security group."
72
+ else
73
+ puts "No servers found...bailing out!"
74
+ end
75
+ rescue Exception => e
76
+ puts "Error: #{e.inspect}"
77
+ puts "Trace: #{e.backtrace.join('\n')}"
78
+ end
79
+
80
+ # Exit cleanly
81
+ return 0
82
+ end
83
+
84
+ def aws_server_list_by_group(group)
85
+ @ec2_api ||= RightAws::Ec2.new(@options[:aws_access_key], @options[:aws_secret_key])
86
+
87
+ @ec2_api.describe_instances.reject{|i| i[:aws_state] != "running"}.map do |instance|
88
+ instance[:dns_name] if instance[:groups].map{|g| g[:group_name]}.include?(group)
89
+ end.compact
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,82 @@
1
+ # TODO Create config option errors handling class
2
+ # TODO Ensure environment variables exist before blindly setting options to them
3
+ module AwsCsshx
4
+ class ConfigurationFile
5
+ attr :options
6
+
7
+ CONFIG_OPTS = %q{ec2_private_key aws_access_key aws_secret_key aws_region}
8
+
9
+ def initialize(conf)
10
+ @config_file = conf
11
+ @options = {}
12
+ if File.exists?(conf)
13
+ load_config_from_file @config_file
14
+ else
15
+ raise FileDoesNotExist, "Config file #{@config_file} cannot be found."
16
+ end
17
+ end
18
+
19
+ # Iterate over the config file line by line and throw away things not in our config opts array
20
+ def load_config_from_file(file)
21
+ f = File.open(file, "r")
22
+ f.each_line do |line|
23
+ field,value = line.split('=')
24
+ next if field.nil? or value.nil?
25
+ field.strip!.downcase!
26
+ value.strip!
27
+ next unless CONFIG_OPTS.include?(field)
28
+ @options[field] =
29
+ if field == 'ec2_private_key' then set_ec2_private_key(value)
30
+ elsif field == 'aws_access_key' then set_aws_access_key(value)
31
+ elsif field == 'aws_secret_key' then set_aws_secret_key(value)
32
+ elsif field == 'aws_region' then set_aws_region(value)
33
+ else puts "No such option #{field} skipping..."
34
+ end
35
+ end
36
+ end
37
+
38
+
39
+ #
40
+ # Private(ish) methods for config settings
41
+ #
42
+
43
+ def set_aws_region(val)
44
+ if val
45
+ val
46
+ elsif ENV['AWS_REGION']
47
+ ENV['AWS_REGION']
48
+ else
49
+ 'us-east-1'
50
+ end
51
+ end
52
+
53
+ def set_aws_secret_key(val)
54
+ if val
55
+ val
56
+ elsif ENV['AWS_SECRET_KEY']
57
+ ENV['AWS_SECRET_KEY']
58
+ elsif ENV['AMAZON_SECRET_ACCESS_KEY']
59
+ ENV['AMAZON_SECRET_ACCESS_KEY']
60
+ end
61
+ end
62
+
63
+ def set_aws_access_key(val)
64
+ if val
65
+ val
66
+ elsif ENV['AWS_ACCESS_KEY']
67
+ ENV['AWS_ACCESS_KEY']
68
+ elsif ENV['AMAZON_ACCESS_KEY_ID']
69
+ ENV['AMAZON_ACCESS_KEY_ID']
70
+ end
71
+ end
72
+
73
+ def set_ec2_private_key(key_file)
74
+ if File.exists?(key_file)
75
+ key_file
76
+ else
77
+ puts "#{key_file} does not exist, using default."
78
+ ENV['EC2_PRIVATE_KEY']
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,13 @@
1
+ module AwsCsshx
2
+ class Misc
3
+ class << self
4
+
5
+ def symbolize_hash_keys(hash)
6
+ hsh = {}
7
+ hash.each_pair { |k,v| hsh[k.downcase.to_sym] = v }
8
+ hsh
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,89 @@
1
+ module AwsCsshx
2
+ class Options < Hash
3
+ attr_reader :opts, :orig_args
4
+
5
+ def initialize(args)
6
+ super()
7
+
8
+ user_home = ENV['HOME']
9
+
10
+ @orig_args = args.clone
11
+
12
+ options = {}
13
+
14
+ require 'optparse'
15
+ @opts = OptionParser.new do |o|
16
+ o.banner = "Usage: #{File.basename($0)} <file1> <file2> ..."
17
+
18
+ o.separator ""
19
+ o.separator "AWS Options"
20
+
21
+ options[:group] = 'default'
22
+ o.on( '-g', '--group <group>', 'AWS security group name to use for the csshX sessions' ) do |group|
23
+ options[:group] = group
24
+ end
25
+
26
+ o.on( '-i', '--aws-identity <identity>', 'Use this keyfile as your SSH private key' ) do |identity|
27
+ options[:ec2_private_key] = identity
28
+ end
29
+
30
+ o.on( '-r', '--aws-region <region>', 'AWS region to query for the csshX sessions (default: us-east-1)' ) do |region|
31
+ options[:aws_region] = region
32
+ end
33
+
34
+ o.separator ""
35
+ o.separator "csshX Options"
36
+
37
+ options[:login] = 'root'
38
+ o.on( '-l', '--login <login>', 'User login to use for the csshX sessions (default: root)' ) do |login|
39
+ options[:login] = login
40
+ end
41
+
42
+ options[:csshx_opts] = ''
43
+ o.on( '-o', '--csshx-opts <csshx_opts>', 'Pass the options listed directly to csshx' ) do |csshx_opts|
44
+ options[:csshx_opts] = csshx_opts
45
+ end
46
+
47
+ options[:iterm2] = false
48
+ o.on( '-2', '--iterm2', 'Use csshX.iterm instead of csshx' ) do |iterm2|
49
+ options[:iterm2] = true
50
+ end
51
+
52
+ o.separator ""
53
+
54
+ options[:conf] = "#{Etc.getpwuid.dir}/.csshrc"
55
+ o.on( '-c', '--conf <file>', 'aws_csshX config file (default: .csshrc)' ) do |file|
56
+ if File.exists?(file)
57
+ options[:conf] = file
58
+ else
59
+ raise FileDoesNotExist, "Config file #{file} cannot be found."
60
+ end
61
+ end
62
+
63
+ o.on('-V', '--version', "Display version information") do
64
+ options[:version] = true
65
+ end
66
+
67
+ options[:help] = false
68
+ o.on( '-h', '--help', 'Display this help screen' ) do
69
+ options[:help] = true
70
+ end
71
+
72
+ o.separator ""
73
+ o.separator "Examples:"
74
+ o.separator " Cluster SSH to all machines in the 'utility' security group:"
75
+ o.separator " #{File.basename($0)} -g utility"
76
+ o.separator ""
77
+ end
78
+
79
+ begin
80
+ @opts.parse!(args)
81
+ self[:options] = options
82
+ rescue OptionParser::InvalidOption => e
83
+ self[:invalid_argument] = e.message
84
+ @opts.parse(args, flags={ :delete_invalid_opts => true })
85
+ self[:options] = options
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,3 @@
1
+ module AwsCsshx
2
+ VERSION = "0.1.1"
3
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aws_csshx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Russell Bradberry
9
+ - Eric Lubow
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-05-04 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: right_aws
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ description: csshx wrapper that interacts with your AWS account for group ssh sessions
32
+ email:
33
+ - eric@lubow.org
34
+ executables:
35
+ - aws_csshx
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - .gitignore
40
+ - Changelog.md
41
+ - Gemfile
42
+ - Gemfile.lock
43
+ - README.md
44
+ - Rakefile
45
+ - TODO.md
46
+ - aws_csshx.gemspec
47
+ - bin/aws_csshx
48
+ - lib/aws_csshx.rb
49
+ - lib/aws_csshx/application.rb
50
+ - lib/aws_csshx/configuration_file.rb
51
+ - lib/aws_csshx/misc.rb
52
+ - lib/aws_csshx/options.rb
53
+ - lib/aws_csshx/version.rb
54
+ homepage: ''
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project: aws_csshx
74
+ rubygems_version: 1.8.18
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: csshx wrapper that interacts with your AWS account for group ssh sessions
78
+ test_files: []