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 +8 -8
- data/.travis.yml +1 -1
- data/Gemfile.lock +1 -1
- data/README.markdown +14 -9
- data/bin/opsicle +15 -4
- data/lib/opsicle.rb +7 -0
- data/lib/opsicle/client.rb +1 -1
- data/lib/opsicle/config.rb +5 -1
- data/lib/opsicle/deploy.rb +1 -1
- data/lib/opsicle/list.rb +1 -1
- data/lib/opsicle/ssh.rb +39 -0
- data/lib/opsicle/version.rb +1 -1
- data/spec/opsicle/ssh_spec.rb +86 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MWY2NTQzM2MwYjY3NDE2OGEzOGE4NTk2NDQzZjVkMjhjOGVlOThiZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjEyZmMwMDZmODBlYTkxOGY1NzcxZWRhNGM4NWZmMzJiYzNmMDEwNA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTNiYTM1NDY4MTIwYmE2OTA2ZGViOGM1YzMwZWQyZDY1NTQyM2ZhZmE1NjVh
|
10
|
+
Mjg5NTg3YzZmYmU3NDcxY2Q5NWE2N2MyYWE0YzkwN2I2YzVkZGVmNmMwMzk3
|
11
|
+
NWU3ZTdiMTBiMzI3Zjc2ZGUwMTBkYzRjYzMzZTNjYThjNTdlNTY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NzQyMTc1ZDI3NjMwNGRiMWQ4NjhlNzVjMjE0MjI4MzU4OWZiNTFiNmZmYWNm
|
14
|
+
OGZkOTYzYWJiMWQ3NWVkMDY3MTVmYWUzODRiYWJjNzM3YjM3ZDk3Mzc4MmY4
|
15
|
+
NjhjNjQ3OWY5ZTQ0NDE2N2FhYjE1OWYyNjg3YzQ4ZjUyMGEwN2E=
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/README.markdown
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
|
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
|
|
data/bin/opsicle
CHANGED
@@ -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
|
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
|
data/lib/opsicle.rb
CHANGED
data/lib/opsicle/client.rb
CHANGED
data/lib/opsicle/config.rb
CHANGED
@@ -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
|
data/lib/opsicle/deploy.rb
CHANGED
data/lib/opsicle/list.rb
CHANGED
data/lib/opsicle/ssh.rb
ADDED
@@ -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
|
data/lib/opsicle/version.rb
CHANGED
@@ -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
|
+
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-
|
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
|