opssh 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in opssh.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Oliver Grimm
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # Opssh
2
+
3
+ Opssh is a tiny tool, that utilizes the [OpsWorks API](http://docs.aws.amazon.com/opsworks/latest/APIReference/Welcome.html) to gather information, about stacks and their instances, required to start a SSH session on a single AWS EC2 instance.
4
+
5
+ You can select the stack and the desired instance interactively:
6
+
7
+ =============================================================
8
+
9
+ Opssh - ssh to your OpsWorks instance
10
+
11
+ =============================================================
12
+
13
+
14
+ Available OpsWorks stacks:
15
+ -----------------------------
16
+ [1]. My Fancy Todo App
17
+ [2]. Google-Clone
18
+ [3]. Next big thing
19
+ [4]. Blog in 5 minutes example
20
+ [5]. Continuous Integration
21
+
22
+ --> Please select stack:
23
+
24
+
25
+ ## Installation
26
+
27
+ $ gem install opssh
28
+
29
+ ## Usage
30
+
31
+ Just invoke
32
+
33
+ $ opssh
34
+
35
+ Hint: Opssh caches API requests by default in `~/.opssh_api_cache` to improve speed.
36
+
37
+ Use the `-n` option if you want to avoid caching.
38
+
39
+ $ opssh -n
40
+
41
+ Clear the API cache with
42
+
43
+ $ opssh -c
44
+
45
+
46
+ ## Configuration
47
+
48
+ Opssh will create a configuration file in `~/.opssh`. It's a [YAML](http://en.wikipedia.org/wiki/YAML) file.
49
+
50
+ The configuration can contain your AWS credentials and/or your customized ssh command.
51
+
52
+ ### AWS Credentials
53
+
54
+ To add credentials for your [IAM](http://aws.amazon.com/iam/) user with permissions to access the OpsWorks API remove the comments and put in the keys:
55
+
56
+
57
+ aws_credentials:
58
+ access_key_id: YOURKEYGOESHERE
59
+ secret_access_key: YOURSECRETKEYGOESHERE
60
+
61
+
62
+ **HINT**:
63
+ If you don't want to store credentials in the configuration file, you can use [environment variables](http://en.wikipedia.org/wiki/Environment_variable), as well. Opssh expects them to be declared as *OPSWORKS_ACCESS_KEY_ID* and *OPSWORKS_SECRET_ACCESS_KEY*.
64
+
65
+
66
+ ##Custom ssh command
67
+
68
+ You need special ssh options, e.g. to use a specific ssh key or to provide a certain login name? No problem, just put it in `ssh_command` in the config:
69
+
70
+ ssh_command: ssh -l yoursshusername -i /path/to/your/privatekey
71
+
72
+
73
+ Opssh will then add the public DNS name of your instance to `ssh_command`.
74
+
75
+ ## History
76
+
77
+ This is a port of [Scassh](https://github.com/pixelpogo/scassh), which was build for Scalarium, the ancestor of OpsWorks.
78
+
79
+ ## Contributing
80
+
81
+ 1. Fork it
82
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
83
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
84
+ 4. Push to the branch (`git push origin my-new-feature`)
85
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/opssh ADDED
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.expand_path("../../lib", __FILE__))
4
+
5
+ require 'optparse'
6
+ require 'ostruct'
7
+ require 'opssh'
8
+
9
+
10
+ options = OpenStruct.new
11
+ OptionParser.new do |opts|
12
+
13
+ opts.banner = "Opssh"
14
+ opts.define_head "SSH to your AWS OpsWorks instances easily"
15
+ opts.separator ""
16
+ opts.separator "Options:"
17
+
18
+ opts.on_tail("--help", "Show this message") do
19
+ puts opts
20
+ puts "\nSee #{Opssh::Config.config_file} for further configuration.\n\n"
21
+ exit
22
+ end
23
+
24
+ opts.on_tail("-v", "--version", "Show version") do
25
+ puts "Opssh #{Opssh::VERSION}"
26
+ exit
27
+ end
28
+
29
+ opts.on_tail("-n", "--no-cache", "Disable API caching"){ options.caching_enabled = false }
30
+
31
+ opts.on_tail("-c", "--clear-cache", "Clear OpsWorks API cache") do
32
+ Opssh::Api::reset_cache
33
+ options.cache_cleared = true
34
+ end
35
+
36
+ begin
37
+ opts.parse!
38
+ rescue OptionParser::ParseError
39
+ puts opts
40
+ exit 1
41
+ end
42
+
43
+ end
44
+
45
+ begin
46
+ stack, instance = nil
47
+
48
+ choice = Opssh::Choice.new
49
+ choice.caching_enabled = options.caching_enabled unless options.caching_enabled.nil?
50
+
51
+ system "clear"
52
+
53
+ puts "\n============================================================="
54
+ puts "\n Opssh - ssh to your OpsWorks instances"
55
+ puts "\n=============================================================\n"
56
+
57
+ puts "\n\nOpsWorks API cache cleared..." if options.cache_cleared
58
+
59
+ puts "\n\n"
60
+ puts "\nAvailable OpsWorks stacks:"
61
+ puts "-----------------------------\n"
62
+ stack = choice.select_stack while stack.nil?
63
+
64
+ system "clear"
65
+ puts "\nYou chose stack #{stack[:name]}\n"
66
+
67
+ puts "\nAvailable Instances:"
68
+ puts "----------------------\n"
69
+ instance = choice.select_instance(stack[:id]) while instance.nil?
70
+
71
+ system "clear"
72
+ puts "\nYou chose instance #{instance[:name]}"
73
+
74
+ puts "Initializing SSH connection to #{instance[:public_dns]}..."
75
+ exec "#{Opssh::Config.ssh} #{instance[:public_dns]}"
76
+
77
+ rescue Exception => e
78
+ puts e.message
79
+ end
80
+
81
+
82
+
data/lib/opssh.rb ADDED
@@ -0,0 +1,4 @@
1
+ require "opssh/version"
2
+ require "opssh/config"
3
+ require "opssh/api"
4
+ require "opssh/choice"
data/lib/opssh/api.rb ADDED
@@ -0,0 +1,85 @@
1
+ require 'aws-sdk'
2
+ require 'json'
3
+ require 'yaml'
4
+ require 'tmpdir'
5
+ require 'etc'
6
+ require 'fileutils'
7
+
8
+ module Opssh
9
+
10
+ module Api
11
+
12
+ def stacks
13
+ get_cache('all_stacks') do
14
+ api("describe_stacks")[:stacks].map{|s| {:name => s[:name], :id => s[:stack_id]}}
15
+ end
16
+ end
17
+
18
+ def instances(stack_id)
19
+ get_cache("stack-#{stack_id}---instances") do
20
+ instances_list = api("describe_instances",{:stack_id => stack_id})
21
+ instances_list = instances_list[:instances].select{|instance| instance[:status] == 'online'}
22
+ instances_list.map! do |instance|
23
+ { :name => instance[:hostname],
24
+ :public_dns => instance[:public_dns],
25
+ :availability_zone => instance[:availability_zone]
26
+ }
27
+ end
28
+ end
29
+ end
30
+
31
+ def reset_cache(verbose=false)
32
+ Opssh::Api.reset_cache(verbose)
33
+ end
34
+
35
+ def self.reset_cache(verbose=false)
36
+ File.unlink(cache_file) rescue ""
37
+ end
38
+
39
+ private
40
+
41
+ def api(action, options={})
42
+ opsworks = AWS::OpsWorks.new(Opssh::Config.aws_credentials)
43
+ opsworks.client.send(action, options)
44
+ end
45
+
46
+ def get_cache(*args)
47
+ cache = load_cache
48
+ cache_id = args.first.to_s
49
+ return cache[cache_id] unless cache[cache_id].nil? || !caching_enabled?
50
+ set_cache(cache_id, yield)
51
+ end
52
+
53
+
54
+ def set_cache(cache_id, value)
55
+ cache = load_cache
56
+ cache[cache_id] = value
57
+ write_cache(cache) if caching_enabled?
58
+ value
59
+ end
60
+
61
+ def load_cache
62
+ File.exist?(cache_file) ? YAML.load_file(cache_file) : {}
63
+ end
64
+
65
+ def write_cache(cache)
66
+ FileUtils.touch(cache_file)
67
+ FileUtils.chmod(0600, cache_file, :verbose => @verbose)
68
+ File.open(cache_file, 'w') {|f| f.write(cache.to_yaml)}
69
+ cache
70
+ end
71
+
72
+ def cache_file
73
+ Opssh::Api.cache_file
74
+ end
75
+
76
+ def self.cache_file
77
+ Etc.getpwuid.dir. + "/.opssh_api_cache"
78
+ end
79
+
80
+ def caching_enabled?
81
+ true
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,49 @@
1
+ require 'highline/import'
2
+
3
+ module Opssh
4
+
5
+ class Choice
6
+
7
+ include Api
8
+
9
+ attr_accessor :caching_enabled
10
+
11
+ def initialize
12
+ @caching_enabled = true
13
+ end
14
+
15
+ def select_stack
16
+ stack_list = stacks
17
+ raise "Sorry, no stacks available." if stack_list.size < 1
18
+ show_list(stack_list)
19
+ index = ask("\n--> Please select stack:")
20
+ puts "Index: #{index} and #{stack_list[index.to_i - 1].inspect}"
21
+ stack_list[index.to_i - 1] rescue nil unless index.to_i == 0
22
+ end
23
+
24
+ def select_instance(stack_id)
25
+ instance_list = instances(stack_id)
26
+ raise "Sorry, no instance available in this stack." if instance_list.size < 1
27
+ show_list(instance_list)
28
+ index = ask("\n--> Please select instance:")
29
+ instance_list[index.to_i - 1] rescue nil unless index.to_i == 0
30
+ end
31
+
32
+ private
33
+
34
+ def show_list(list)
35
+ list.sort!{|x,y| x[:name] <=> y[:name] }
36
+ list.each_index do |index|
37
+ item = "[#{index + 1}]."
38
+ puts "#{item.rjust(6)} #{list[index][:name]}"
39
+ end
40
+ end
41
+
42
+ def caching_enabled?
43
+ @caching_enabled
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
@@ -0,0 +1,80 @@
1
+ require 'tmpdir'
2
+ require 'etc'
3
+ require 'fileutils'
4
+
5
+ module Opssh
6
+
7
+ class Config
8
+
9
+ def self.aws_credentials
10
+ credentials = aws_credentials_from_config
11
+ credentials = aws_credentials_from_env if credentials.nil?
12
+ raise "Can't find your AWS credentials! Please set them via #{config_file} or ENV variables" if credentials.nil?
13
+ credentials
14
+ end
15
+
16
+ def self.ssh
17
+ config = load_config
18
+ if config.class == Hash && config.has_key?('ssh_command')
19
+ config['ssh_command']
20
+ else
21
+ "ssh"
22
+ end
23
+ end
24
+
25
+ def self.config_file
26
+ Etc.getpwuid.dir. + "/.opssh"
27
+ end
28
+
29
+ private
30
+
31
+ def self.load_config
32
+ write_config_file unless File.exist?(config_file)
33
+ YAML.load_file(config_file)
34
+ end
35
+
36
+ def self.write_config_file
37
+ File.open(config_file, 'w') {|f| f.write(example_config_content)}
38
+ end
39
+
40
+ def self.aws_credentials_from_config
41
+ config = load_config
42
+ return if config.nil?
43
+ if config.class == Hash && config['aws_credentials'].class == Hash
44
+ config['aws_credentials']
45
+ else
46
+ nil
47
+ end
48
+ end
49
+
50
+ def self.aws_credentials_from_env
51
+ if !ENV['OPSWORKS_ACCESS_KEY_ID'].nil? && !ENV['OPSWORKS_SECRET_ACCESS_KEY'].nil?
52
+ {'access_key_id' => ENV['OPSWORKS_ACCESS_KEY_ID'], 'secret_access_key' => ENV['OPSWORKS_SECRET_ACCESS_KEY']}
53
+ end
54
+ end
55
+
56
+
57
+ def self.example_config_content
58
+ <<-END.gsub(/^ {6}/, '')
59
+ #===============================
60
+ # YOUR OPSSH CONFIGURATION FILE
61
+ #===============================
62
+ #
63
+ # Opssh expects your AWS credentials either to be
64
+ # defined here or in environment variables named
65
+ # OPSWORKS_ACCESS_KEY_ID and OPSWORKS_SECRET_ACCESS_KEY
66
+ #
67
+ #aws_credentials:
68
+ # access_key_id: YOURKEYGOESHERE
69
+ # secret_access_key: YOURSECRETKEYGOESHERE
70
+ #
71
+ # If you need special ssh options, you can specify them here
72
+ # as well.
73
+ #
74
+ #ssh_command: ssh -l yoursshusername -i /path/to/your/privatekey
75
+ END
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,3 @@
1
+ module Opssh
2
+ VERSION = "0.0.1"
3
+ end
data/opssh.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/opssh/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Oliver Grimm"]
6
+ gem.email = ["olly@pixelpogo.de"]
7
+ gem.description = %q{Opssh is a tiny tool, that utilizes the AWS Opsworks API to gather information, about stacks and their instances, required to start a SSH session on a single AWS EC2 instance.}
8
+ gem.summary = %q{ssh to your Opsworks/EC2 instances easily}
9
+ gem.homepage = "https://github.com/pixelpogo/opssh"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "opssh"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Opssh::VERSION
17
+
18
+ gem.add_runtime_dependency "json"
19
+ gem.add_runtime_dependency "highline"
20
+ gem.add_runtime_dependency "aws-sdk", '>= 1.8.3'
21
+
22
+ gem.add_development_dependency "rspec"
23
+
24
+ end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+ require 'tmpdir'
3
+
4
+ describe Opssh::Api do
5
+
6
+ class ApiHelper
7
+ include Opssh::Api
8
+ def cache_file
9
+ Dir.tmpdir + "/.opssh-rspec-cache"
10
+ end
11
+ end
12
+
13
+ let(:api_helper) { ApiHelper.new }
14
+
15
+ before :each do
16
+ # clear temporary cache file ...
17
+ File.unlink(Dir.tmpdir + "/.opssh-rspec-cache") rescue ""
18
+ end
19
+
20
+ context "#stacks" do
21
+ it "should return list of available stacks" do
22
+ example = { :stacks => [
23
+ { :name => "Monitoring", :stack_id => "d30104ef" },
24
+ { :name => "Reports", :stack_id => "ffa0116d" },
25
+ { :name => "RailsApp", :stack_id => "ac263281" }
26
+ ] }
27
+
28
+ api_helper.stub(:api).with("describe_stacks").and_return(example)
29
+ api_helper.stacks.size.should be(3)
30
+ end
31
+
32
+ it "should return empty list in case of no available stacks" do
33
+ example = { :stacks => [] }
34
+ api_helper.stub(:api).with("describe_stacks").and_return(example)
35
+ api_helper.stacks.size.should be(0)
36
+ end
37
+
38
+ it "should return stack hashes with all required keys" do
39
+ example = { :stacks => [
40
+ { :name => "Monitoring", :stack_id => "d30104ef" },
41
+ { :name => "Reports", :stack_id => "ffa0116d" },
42
+ { :name => "RailsApp", :stack_id => "ac263281" }
43
+ ] }
44
+
45
+ api_helper.stub(:api).with("describe_stacks").and_return(example)
46
+ api_helper.stacks.each do |stack|
47
+ stack.should have_key(:name)
48
+ stack.should have_key(:id)
49
+ end
50
+ end
51
+ end
52
+
53
+ context "#instances" do
54
+ it "should return list of available instances of a given stack" do
55
+ example = { :instances => [
56
+ { :hostname => "rails-app1", :public_dns => "ra1.aws-amazon.com", :status => "online", :availability_zone => "eu-west-1a"},
57
+ { :hostname => "db-master1", :public_dns => "db1.aws-amazon.com", :status => "online", :availability_zone => "eu-west-1a"},
58
+ { :hostname => "worker1", :public_dns => "w1.aws.aws-amazon.com", :status => "online", :availability_zone => "eu-west-1a"}
59
+ ] }
60
+
61
+ api_helper.stub(:api).with("describe_instances", {:stack_id =>"fake-id"}).and_return(example)
62
+ api_helper.instances("fake-id").size.should be(3)
63
+ end
64
+
65
+ it "should ignore instances with status other than 'online'" do
66
+ example = { :instances => [
67
+ { :name => "rails-app1", :public_dns => "ra1.aws-amazon.com", :status => "running_setup", :availability_zone => "eu-west-1a"},
68
+ { :hostname => "db-master1", :public_dns => "db1.aws-amazon.com", :status => "setup_failed", :availability_zone => "eu-west-1a"},
69
+ { :hostname => "worker1", :public_dns => "w1.aws.aws-amazon.com", :status => "connection_lost", :availability_zone => "eu-west-1a"}
70
+ ] }
71
+
72
+ api_helper.stub(:api).with("describe_instances", {:stack_id =>"fake-id"}).and_return(example)
73
+ api_helper.instances("fake-id").size.should be(0)
74
+ end
75
+
76
+
77
+ it "should return instance hashes with all required keys" do
78
+ example = { :instances => [
79
+ { :hostname => "rails-app1", :public_dns => "ra1.aws-amazon.com", :status => "online", :availability_zone => "eu-west-1a"},
80
+ { :hostname => "db-master1", :public_dns => "db1.aws-amazon.com", :status => "online", :availability_zone => "eu-west-1a"},
81
+ { :hostname => "worker1", :public_dns => "w1.aws.aws-amazon.com", :status => "online", :availability_zone => "eu-west-1a"}
82
+ ] }
83
+
84
+ api_helper.stub(:api).with("describe_instances", {:stack_id =>"fake-id"}).and_return(example)
85
+ api_helper.instances("fake-id").each do |instance|
86
+ instance.should have_key(:name)
87
+ instance.should have_key(:public_dns)
88
+ instance.should have_key(:availability_zone)
89
+ end
90
+ end
91
+ end
92
+
93
+ context "caching" do
94
+
95
+ it "should cache stacks" do
96
+ example = { :stacks => [
97
+ { :name => "Monitoring", :stack_id => "d30104ef" }
98
+ ] }
99
+
100
+ api_helper.stub(:api).with("describe_stacks").and_return(example)
101
+ api_helper.stacks # --> response goes to cache
102
+ cache = api_helper.send("load_cache")
103
+ cache['all_stacks'].should =~ [ { :name => "Monitoring", :id => "d30104ef" } ]
104
+ end
105
+
106
+ it "should cache instances" do
107
+ example = { :instances => [
108
+ { :hostname => "rails-app1", :public_dns => "ra1.aws-amazon.com", :status => "online", :availability_zone => "eu-west-1a"}
109
+ ] }
110
+
111
+ api_helper.stub(:api).with("describe_instances", {:stack_id =>"fake-id"}).and_return(example)
112
+ api_helper.instances("fake-id") # ---> response goes to cache
113
+ cache = api_helper.send("load_cache")
114
+ cache['stack-fake-id---instances'].should =~ [{ :name => "rails-app1", :public_dns => "ra1.aws-amazon.com", :availability_zone => "eu-west-1a"}]
115
+ end
116
+
117
+ it "should be disengageable" do
118
+ example = { :stacks => [
119
+ { :name => "Monitoring", :stack_id => "d30104ef" }
120
+ ] }
121
+
122
+ api_helper.stub(:api).with("describe_stacks").and_return(example)
123
+ api_helper.stub(:caching_enabled?).and_return(false)
124
+ api_helper.should_receive(:set_cache).with(any_args()).twice
125
+ api_helper.stacks # no caching!
126
+ api_helper.stacks # no caching!
127
+ end
128
+
129
+ end
130
+
131
+
132
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Opssh::Config do
4
+
5
+ context "#aws_credentials" do
6
+ it "should use aws_credentials from config file" do
7
+ keys = { 'aws_credentials' => { 'access_key_id' => "Foo", 'secret_access_key' => "Bar" } }
8
+ Opssh::Config.stub(:load_config).and_return(keys)
9
+ Opssh::Config.aws_credentials.should == keys['aws_credentials']
10
+ end
11
+
12
+ it "should use aws_credentials from ENV variables" do
13
+ ENV['OPSWORKS_ACCESS_KEY_ID'] = "Foo"
14
+ ENV['OPSWORKS_SECRET_ACCESS_KEY'] = "Bar"
15
+ Opssh::Config.stub(:load_config).and_return({})
16
+ Opssh::Config.aws_credentials.should == { 'access_key_id' => "Foo", 'secret_access_key' => "Bar" }
17
+ end
18
+ end
19
+
20
+ context "#ssh" do
21
+ it "should return custom ssh command from config file" do
22
+ conf = {'aws_credentials' => {}, 'ssh_command' => "ssh -l yoursshusername -i /path/to/your/privatekey"}
23
+ Opssh::Config.stub(:load_config).and_return(conf)
24
+ Opssh::Config.ssh.should == conf['ssh_command']
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ require 'opssh'
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # Require this file using `require "spec_helper"` to ensure that it is only
6
+ # loaded once.
7
+ #
8
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+
14
+ # Run specs in random order to surface order dependencies. If you find an
15
+ # order dependency and want to debug it, you can fix the order by providing
16
+ # the seed, which is printed after each run.
17
+ # --seed 1234
18
+ config.order = 'random'
19
+
20
+
21
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: opssh
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Oliver Grimm
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-11 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: &70221739274540 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70221739274540
25
+ - !ruby/object:Gem::Dependency
26
+ name: highline
27
+ requirement: &70221739268860 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70221739268860
36
+ - !ruby/object:Gem::Dependency
37
+ name: aws-sdk
38
+ requirement: &70221739266720 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 1.8.3
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70221739266720
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &70221739265880 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70221739265880
58
+ description: Opssh is a tiny tool, that utilizes the AWS Opsworks API to gather information,
59
+ about stacks and their instances, required to start a SSH session on a single AWS
60
+ EC2 instance.
61
+ email:
62
+ - olly@pixelpogo.de
63
+ executables:
64
+ - opssh
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - .gitignore
69
+ - .rspec
70
+ - Gemfile
71
+ - LICENSE
72
+ - README.md
73
+ - Rakefile
74
+ - bin/opssh
75
+ - lib/opssh.rb
76
+ - lib/opssh/api.rb
77
+ - lib/opssh/choice.rb
78
+ - lib/opssh/config.rb
79
+ - lib/opssh/version.rb
80
+ - opssh.gemspec
81
+ - spec/opssh/api_spec.rb
82
+ - spec/opssh/config_spec.rb
83
+ - spec/spec_helper.rb
84
+ homepage: https://github.com/pixelpogo/opssh
85
+ licenses: []
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 1.8.10
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: ssh to your Opsworks/EC2 instances easily
108
+ test_files:
109
+ - spec/opssh/api_spec.rb
110
+ - spec/opssh/config_spec.rb
111
+ - spec/spec_helper.rb