opsicle 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Y2VhNTY1NzFlMTEwZjllOGE1Y2JmY2JlYWM4ODIyMzFlZDA3MzBmMA==
4
+ MWY2NTQzM2MwYjY3NDE2OGEzOGE4NTk2NDQzZjVkMjhjOGVlOThiZQ==
5
5
  data.tar.gz: !binary |-
6
- YjNjZGFmZmRlZmYyYzgxMTIzYTA2OWM1NzI0YmZjY2ZlYWM4NjQ5OA==
6
+ MjEyZmMwMDZmODBlYTkxOGY1NzcxZWRhNGM4NWZmMzJiYzNmMDEwNA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NDc0OTUxMTNlYWUzMDhiZDRlZTY3ODYzOWNiODliMmU5MGRlNjU1NGNkZDYz
10
- MjI2Yzk3ODVjMmFjMGZiMzFlMjU2MWNkNGFhN2ZiODcxNzcyOTFmZjA2OWZi
11
- MTA2ZmRjOWQ2ODhjYjdiYWZkNjEzY2YyMjc1OTlhMDlkZWI3MTM=
9
+ MTNiYTM1NDY4MTIwYmE2OTA2ZGViOGM1YzMwZWQyZDY1NTQyM2ZhZmE1NjVh
10
+ Mjg5NTg3YzZmYmU3NDcxY2Q5NWE2N2MyYWE0YzkwN2I2YzVkZGVmNmMwMzk3
11
+ NWU3ZTdiMTBiMzI3Zjc2ZGUwMTBkYzRjYzMzZTNjYThjNTdlNTY=
12
12
  data.tar.gz: !binary |-
13
- ZmI2ZmYxN2ViYmEyYmFjNTEwMjI1ZTEzNWUwYWZlODBhZWVmMzBmNzUzNWJm
14
- NDYzYWU2MDg4MDAxYzBkNzNmYWQ2YTU4MjE3MjgwMTViNThhZmUyMjZjMWE4
15
- MDE4MGEyNzdjN2NhZWQxZTZiYzNjZDkxNTQ2YzhkY2IyNThmMjY=
13
+ NzQyMTc1ZDI3NjMwNGRiMWQ4NjhlNzVjMjE0MjI4MzU4OWZiNTFiNmZmYWNm
14
+ OGZkOTYzYWJiMWQ3NWVkMDY3MTVmYWUzODRiYWJjNzM3YjM3ZDk3Mzc4MmY4
15
+ NjhjNjQ3OWY5ZTQ0NDE2N2FhYjE1OWYyNjg3YzQ4ZjUyMGEwN2E=
@@ -1,7 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.0
4
+ - 2.1
4
5
  - 1.9.3
5
6
  - jruby-19mode # JRuby in 1.9 mode
6
- - rbx-2.1.1
7
7
  script: bundle exec rspec
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- opsicle (0.0.4)
4
+ opsicle (0.1.0)
5
5
  aws-sdk (~> 1.30)
6
6
  commander
7
7
  terminal-table
@@ -1,8 +1,11 @@
1
- Opsworks CLI - opsicle
2
- ---------------------
1
+ #Opsicle, an OpsWorks CLI
2
+ A gem bringing the glory of OpsWorks to your command line.
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/opsicle.png)](http://badge.fury.io/rb/opsicle)
5
+ [![Build Status](https://travis-ci.org/sportngin/opsicle.png?branch=master)](https://travis-ci.org/sportngin/opsicle)
6
+
7
+ ##Deployment Commands
3
8
 
4
- Deployment Commands
5
- --------------
6
9
  ```bash
7
10
  # Run a basic deploy for the current app
8
11
  opsicle deploy staging
@@ -10,18 +13,20 @@ opsicle deploy staging
10
13
  # Run the deploy for production
11
14
  opsicle deploy production
12
15
 
13
- ```
16
+ # SSH to a server instance in the given environment stack (ex: staging)
17
+ opsicle ssh staging
14
18
 
15
- ```bash
16
19
  # Run other opsworks commands
17
20
  opsicle update_custom_cookbooks staging
18
21
 
19
22
  # Trigger the setup event
20
23
  opsicle setup staging
21
- ````
24
+ ```
25
+
26
+ Opsicle accepts a `--verbose` flag to show additional information as commands are run.
27
+
28
+ ##Set up an Application to use opsicle
22
29
 
23
- Setup an Application to use opsicle
24
- -------
25
30
  ```yaml
26
31
  # your_app_root/.opsicle
27
32
 
@@ -9,23 +9,34 @@ program :version, Opsicle::VERSION
9
9
  program :description, 'Opsworks Command Line Utility Belt'
10
10
  program :help, 'Documentation', 'For documentation and help in setting up your configuration files, '\
11
11
  'see Opsicle\'s GitHub repo: https://github.com/sportngin/opsicle'
12
+
13
+ global_option '--verbose'
14
+
12
15
  default_command :help
13
16
 
14
17
  command :deploy do |c|
15
18
  c.syntax = "opsicle deploy <environment>"
16
- c.description = "Deploy Your current app to the given Opswork Stack"
19
+ c.description = "Deploy your current app to the given OpsWorks stack"
17
20
  c.action do |args, options|
18
21
  raise ArgumentError, "Environment is required" unless args.first
19
- Opsicle::Deploy.new(args.first).execute
22
+ Opsicle::Deploy.new(args.first).execute(options.__hash__)
20
23
  end
21
24
  end
22
25
 
23
26
  command :list do |c|
24
27
  c.syntax = "opsicle list <environment>"
25
- c.description = "List all apps the given environment"
28
+ c.description = "List all apps in the given environment"
26
29
  c.action do |args, options|
27
30
  raise ArgumentError, "Environment is required" unless args.first
28
- Opsicle::List.new(args.first).execute
31
+ Opsicle::List.new(args.first).execute(options.__hash__)
29
32
  end
33
+ end
30
34
 
35
+ command :ssh do |c|
36
+ c.syntax = "opsicle ssh <environment>"
37
+ c.description = "SSH access to instances in the given Opsworks stack"
38
+ c.action do |args, options|
39
+ raise ArgumentError, "Environment is required" unless args.first
40
+ Opsicle::SSH.new(args.first).execute(options.__hash__)
41
+ end
31
42
  end
@@ -1,4 +1,11 @@
1
+ Signal.trap("INT") do
2
+ puts ""
3
+ puts "Exiting..."
4
+ exit 1
5
+ end
6
+
1
7
  require "opsicle/version"
2
8
  require "opsicle/deploy"
3
9
  require "opsicle/list"
10
+ require "opsicle/ssh"
4
11
 
@@ -16,7 +16,7 @@ module Opsicle
16
16
  end
17
17
 
18
18
  def api_call(command, options={})
19
- aws_client.send(command, options)
19
+ aws_client.public_send(command, options)
20
20
  end
21
21
 
22
22
  def command_options(command, options={})
@@ -28,7 +28,10 @@ module Opsicle
28
28
 
29
29
  def load_config(file)
30
30
  raise MissingConfig, "Missing configuration file: #{file} Run 'opsicle help'" unless File.exist?(file)
31
- symbolize_keys(YAML.load_file(file))[environment] rescue {}
31
+ env_config = symbolize_keys(YAML.load_file(file))[environment] rescue {}
32
+ raise MissingEnvironment, "Configuration for the \'#{environment}\' environment could not be found in #{file}" unless env_config != nil
33
+
34
+ env_config
32
35
  end
33
36
 
34
37
  # We want all ouf our YAML loaded keys to be symbols
@@ -49,6 +52,7 @@ module Opsicle
49
52
  end
50
53
 
51
54
  MissingConfig = Class.new(StandardError)
55
+ MissingEnvironment = Class.new(StandardError)
52
56
 
53
57
  end
54
58
  end
@@ -9,7 +9,7 @@ module Opsicle
9
9
  @client = Client.new(environment)
10
10
  end
11
11
 
12
- def execute
12
+ def execute(options={})
13
13
  response = client.run_command('deploy')
14
14
  open_deploy(response[:deployment_id])
15
15
  end
@@ -10,7 +10,7 @@ module Opsicle
10
10
  @client = Client.new(environment)
11
11
  end
12
12
 
13
- def execute
13
+ def execute(options={})
14
14
  stack_ids = get_stacks
15
15
  apps = get_apps(stack_ids)
16
16
  print(apps)
@@ -0,0 +1,39 @@
1
+ require 'aws-sdk'
2
+ require_relative 'client'
3
+
4
+ module Opsicle
5
+ class SSH
6
+ attr_reader :client
7
+
8
+ def initialize(environment)
9
+ @client = Client.new(environment)
10
+ end
11
+
12
+ def execute(options={})
13
+ if instances.length == 1
14
+ choice = 1
15
+ else
16
+ say "Choose an Opsworks instance: \n"
17
+ instances.each_index do |x|
18
+ say "#{x+1}) #{instances[x][:hostname]}"
19
+ end
20
+ choice = ask("? ", Integer) { |q| q.in = 1..instances.length }
21
+ end
22
+
23
+ instance_ip = instances[choice-1][:elastic_ip] || instances[choice-1][:public_ip]
24
+
25
+ command = "ssh #{ssh_username}@#{instance_ip}"
26
+ say "<%= color('Executing shell command: #{command}', YELLOW) %>" if options[:verbose] == true
27
+ system(command)
28
+ end
29
+
30
+ def instances
31
+ client.api_call(:describe_instances, { stack_id: client.config.opsworks_config[:stack_id] })
32
+ .data[:instances]
33
+ end
34
+
35
+ def ssh_username
36
+ client.api_call(:describe_my_user_profile)[:user_profile][:ssh_username]
37
+ end
38
+ end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module Opsicle
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,86 @@
1
+ require "spec_helper"
2
+ require "opsicle/ssh"
3
+
4
+ module Opsicle
5
+ describe SSH do
6
+ subject { SSH.new('derp') }
7
+ let(:client) { double(config: double(opsworks_config: {stack_id: "1234"})) }
8
+ let(:api_call) { double }
9
+ before do
10
+ Client.stub(:new).with('derp').and_return(client)
11
+ end
12
+
13
+ context "#execute" do
14
+ before do
15
+ subject.stub(:say) { "What instance do you want, huh?" }
16
+ subject.stub(:ask).and_return(2)
17
+ subject.stub(:ssh_username) {"mrderpyman2014"}
18
+ end
19
+
20
+ it "should execute ssh with a selected Opsworks instance IP" do
21
+ subject.stub(:instances) {[
22
+ { hostname: "host1", elastic_ip: "123.123.123.123" },
23
+ { hostname: "host2", elastic_ip: "789.789.789.789" }
24
+ ]}
25
+
26
+ subject.should_receive(:system).with("ssh mrderpyman2014@789.789.789.789")
27
+ subject.execute
28
+ end
29
+
30
+ it "should execute ssh with public_ip listings as well as elastic_ip" do
31
+ subject.stub(:instances) {[
32
+ { hostname: "host1", elastic_ip: "678.678.678.678" },
33
+ { hostname: "host2", public_ip: "987.987.987.987" }
34
+ ]}
35
+
36
+ subject.should_receive(:system).with("ssh mrderpyman2014@987.987.987.987")
37
+ subject.execute
38
+ end
39
+
40
+ it "should execute ssh favoring an elastic_ip over a public_ip if both exist" do
41
+ subject.stub(:instances) {[
42
+ { hostname: "host1", elastic_ip: "678.678.678.678" },
43
+ { hostname: "host2", public_ip: "987.987.987.987", elastic_ip: "132.132.132.132" }
44
+ ]}
45
+
46
+ subject.should_receive(:system).with("ssh mrderpyman2014@132.132.132.132")
47
+ subject.execute
48
+ end
49
+
50
+ it "should execute ssh right away if there is only one Opsworks instance available" do
51
+ subject.stub(:instances) {[
52
+ { hostname: "host3", elastic_ip: "456.456.456.456" }
53
+ ]}
54
+
55
+ subject.should_receive(:system).with("ssh mrderpyman2014@456.456.456.456")
56
+ subject.should_not_receive(:ask)
57
+ subject.execute
58
+ end
59
+ end
60
+
61
+ context "#client" do
62
+ it "generates a new aws client from the given configs" do
63
+ Client.should_receive(:new).with('derp')
64
+ subject.client
65
+ end
66
+ end
67
+
68
+ context "#instances" do
69
+ it "makes a describe_instances API call" do
70
+ client.stub(:api_call).with(:describe_instances, {stack_id: "1234"})
71
+ .and_return(api_call)
72
+ api_call.should_receive(:data).and_return(instances: {:foo => :bar})
73
+ subject.instances.should == {:foo => :bar}
74
+ end
75
+ end
76
+
77
+ context "#ssh_username" do
78
+ it "makes a describe_my_user_profile API call" do
79
+ client.stub(:api_call).with(:describe_my_user_profile)
80
+ .and_return({user_profile: {:ssh_username => "captkirk01"}})
81
+ subject.ssh_username.should == "captkirk01"
82
+ end
83
+ end
84
+
85
+ end
86
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opsicle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Fleener
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-31 00:00:00.000000000 Z
11
+ date: 2014-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -146,12 +146,14 @@ files:
146
146
  - lib/opsicle/config.rb
147
147
  - lib/opsicle/deploy.rb
148
148
  - lib/opsicle/list.rb
149
+ - lib/opsicle/ssh.rb
149
150
  - lib/opsicle/version.rb
150
151
  - opsicle.gemspec
151
152
  - spec/opsicle/client_spec.rb
152
153
  - spec/opsicle/config_spec.rb
153
154
  - spec/opsicle/deploy_spec.rb
154
155
  - spec/opsicle/list_spec.rb
156
+ - spec/opsicle/ssh_spec.rb
155
157
  - spec/spec_helper.rb
156
158
  homepage: https://github.com/sportngin/opsicle
157
159
  licenses:
@@ -182,4 +184,5 @@ test_files:
182
184
  - spec/opsicle/config_spec.rb
183
185
  - spec/opsicle/deploy_spec.rb
184
186
  - spec/opsicle/list_spec.rb
187
+ - spec/opsicle/ssh_spec.rb
185
188
  - spec/spec_helper.rb