opsicle 0.8.2 → 0.9.0
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.
- checksums.yaml +4 -4
- data/bin/opsicle +18 -7
- data/lib/opsicle/commands/deploy.rb +3 -1
- data/lib/opsicle/commands/execute_recipes.rb +4 -3
- data/lib/opsicle/commands/ssh_clean_keys.rb +29 -0
- data/lib/opsicle/commands.rb +1 -0
- data/lib/opsicle/version.rb +1 -1
- data/spec/opsicle/commands/deploy_spec.rb +13 -5
- data/spec/opsicle/commands/execute_recipes_spec.rb +8 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97dd611664d6cade219eb35829d9cc111636ab1b
|
4
|
+
data.tar.gz: 1ba96878b0d09b05dc2df05222507af9b4cfec48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: beb8719a0691650d14a661a10b2b9cd5c79e63ae4d0f41d302a2ac30ed0b2585b09844914570bef34a1a73ca0515c2e091653da3344b8e78440f3d53c8ddf624
|
7
|
+
data.tar.gz: 3dfa883fabc57e83e0d04d56d6e41edbf52034c2c459c46a0ee97b09101ef7ea1c33f6179db86d927fad58a032977cf220752be93d413635d6ac0c55d6ad2751
|
data/bin/opsicle
CHANGED
@@ -48,6 +48,7 @@ command :deploy do |c|
|
|
48
48
|
c.switch [:g, :migrate], :desc => "Deploy with migrations"
|
49
49
|
c.switch [:m, :monitor], :desc => "Run the Stack Monitor on deploy", :default_value => true
|
50
50
|
c.switch [:t, :track], :desc => "Tracks to deploy and exits when completed. Exits with non-zero if the deploy fails."
|
51
|
+
c.flag [:j, :json], :desc => 'Custom json to add to the deploy', :type => String
|
51
52
|
c.action do |global_options, options, args|
|
52
53
|
raise ArgumentError, 'You must specify an environment' unless args.first
|
53
54
|
Opsicle::Deploy.new(args.first).execute global_options.merge(options)
|
@@ -84,6 +85,15 @@ command 'ssh-key' do |c|
|
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
88
|
+
desc "Clear an environment's keys from your ssh known_hosts file"
|
89
|
+
arg_name '<environment>'
|
90
|
+
command 'ssh-clean-keys' do |c|
|
91
|
+
c.action do |global_options, options, args|
|
92
|
+
raise ArgumentError, "Environment is required" unless args.first
|
93
|
+
Opsicle::SSHCleanKeys.new(args.first).execute global_options.merge(options)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
87
97
|
desc "Launch the Opsicle Stack Monitor for the given environment stack"
|
88
98
|
arg_name '<environment>'
|
89
99
|
command 'monitor' do |c|
|
@@ -147,13 +157,14 @@ desc "Execute arbitrary recipes on the Stack"
|
|
147
157
|
arg_name '<environment>'
|
148
158
|
arg_name '<recipe>'
|
149
159
|
command 'execute-recipes' do |c|
|
150
|
-
c.switch [:m, :monitor],
|
151
|
-
c.switch [:e, :eip],
|
152
|
-
c.switch [:t, :track],
|
153
|
-
c.flag
|
154
|
-
c.flag
|
155
|
-
c.flag
|
156
|
-
c.flag
|
160
|
+
c.switch [:m, :monitor], :desc => "Run the Stack Monitor on deploy", :default_value => true
|
161
|
+
c.switch [:e, :eip], :desc => "Executes recipes on a single instance with an elastic IP", :default_value => false
|
162
|
+
c.switch [:t, :track], :desc => "Tracks to deploy and exits when completed. Exits with non-zero if the deploy fails."
|
163
|
+
c.flag [:j, :json], :desc => 'Custom json to add to the deploy', :type => String
|
164
|
+
c.flag [:r, :recipes], :desc => 'The recipes to execute', :type => Array, :required => true
|
165
|
+
c.flag [:i, :instance_ids], :desc => 'The specific instances to execute recipes on', :type => Array
|
166
|
+
c.flag [:l, :layers], :desc => 'The specific layers to execute recipes on', :type => Array
|
167
|
+
c.flag [:a, :ip_addresses], :desc => 'The specific ip addresses of instance to execute recipes on', :type => Array
|
157
168
|
c.action do |global_options, options, args|
|
158
169
|
raise ArgumentError, "Environment is required" unless args.first
|
159
170
|
|
@@ -17,7 +17,9 @@ module Opsicle
|
|
17
17
|
#http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/OpsWorks/Client.html#create_deployment-instance_method
|
18
18
|
command_args = {}
|
19
19
|
command_args["migrate"] = [options[:migrate].to_s] if options[:migrate]
|
20
|
-
|
20
|
+
command_opts = {}
|
21
|
+
command_opts["custom_json"] = options.delete(:json) if options[:json]
|
22
|
+
response = client.run_command('deploy', command_args, command_opts)
|
21
23
|
|
22
24
|
launch_stack_monitor(response, options)
|
23
25
|
end
|
@@ -19,18 +19,19 @@ module Opsicle
|
|
19
19
|
command_args["recipes"] = options[:recipes]
|
20
20
|
command_opts = {}
|
21
21
|
command_opts["instance_ids"] = determine_instance_ids(options)
|
22
|
+
command_opts["custom_json"] = options.delete(:json) if options[:json]
|
22
23
|
command_opts.reject! {|key,value| value.nil?}
|
23
24
|
|
24
25
|
response = client.run_command('execute_recipes', command_args, command_opts)
|
25
26
|
launch_stack_monitor(response, options)
|
26
27
|
end
|
27
|
-
|
28
|
+
|
28
29
|
def determine_instance_ids(options)
|
29
30
|
if options[:instance_ids]
|
30
31
|
options[:instance_ids]
|
31
32
|
elsif options[:layers]
|
32
33
|
determine_from_layers(options[:layers])
|
33
|
-
elsif options[:ip_addresses]
|
34
|
+
elsif options[:ip_addresses]
|
34
35
|
determine_from_ips(options[:ip_addresses])
|
35
36
|
elsif options[:eip]
|
36
37
|
determine_from_eip
|
@@ -38,7 +39,7 @@ module Opsicle
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def determine_from_ips(ips)
|
41
|
-
if instances = Opsicle::Instances.find_by_ip(client, ips)
|
42
|
+
if instances = Opsicle::Instances.find_by_ip(client, ips)
|
42
43
|
instances.map { |instance| instance[:instance_id] }
|
43
44
|
else
|
44
45
|
raise NoInstanceError, "Unable to find instances with given IP"
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Opsicle
|
2
|
+
class SSHCleanKeys
|
3
|
+
attr_reader :client
|
4
|
+
|
5
|
+
def initialize(environment)
|
6
|
+
@client = Client.new(environment)
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute(options={})
|
10
|
+
instances.each do |instance|
|
11
|
+
# Fun note: public_dns will be for the elastic ip (if elastic_ip?)
|
12
|
+
host_keys = [:elastic_ip, :public_ip, :public_dns]
|
13
|
+
hosts = host_keys.map { |key| instance[key] }
|
14
|
+
hosts = hosts.reject { |i| i.nil? }
|
15
|
+
hosts.uniq.each do |host|
|
16
|
+
# Is this properly escaped against expansion?
|
17
|
+
command = "ssh-keygen -R #{host}"
|
18
|
+
Output.say_verbose "Executing: #{command}"
|
19
|
+
system(command)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def instances
|
25
|
+
client.api_call(:describe_instances, { stack_id: client.config.opsworks_config[:stack_id] })
|
26
|
+
.data[:instances]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/opsicle/commands.rb
CHANGED
data/lib/opsicle/version.rb
CHANGED
@@ -10,7 +10,7 @@ module Opsicle
|
|
10
10
|
let(:monitor) { double(:start => nil) }
|
11
11
|
before do
|
12
12
|
allow(Client).to receive(:new).with('derp').and_return(client)
|
13
|
-
allow(client).to receive(:run_command).with('deploy', {}).and_return({deployment_id: 'derp'})
|
13
|
+
allow(client).to receive(:run_command).with('deploy', {}, {}).and_return({deployment_id: 'derp'})
|
14
14
|
|
15
15
|
allow(Monitor::App).to receive(:new).and_return(monitor)
|
16
16
|
allow(monitor).to receive(:start)
|
@@ -20,7 +20,7 @@ module Opsicle
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it "creates a new deployment and opens stack monitor" do
|
23
|
-
expect(client).to receive(:run_command).with('deploy', {}).and_return({deployment_id: 'derp'})
|
23
|
+
expect(client).to receive(:run_command).with('deploy', {}, {}).and_return({deployment_id: 'derp'})
|
24
24
|
expect(subject).to_not receive(:open_deploy)
|
25
25
|
expect(Monitor::App).to receive(:new).with('derp', :monitor => true)
|
26
26
|
|
@@ -28,7 +28,7 @@ module Opsicle
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it "creates a new deployment that exits the stack monitor on completion" do
|
31
|
-
expect(client).to receive(:run_command).with('deploy', {}).and_return({deployment_id: 'derp'})
|
31
|
+
expect(client).to receive(:run_command).with('deploy', {}, {}).and_return({deployment_id: 'derp'})
|
32
32
|
expect(subject).to_not receive(:open_deploy)
|
33
33
|
expect(Monitor::App).to receive(:new).with('derp', :monitor => true, :deployment_id => 'derp')
|
34
34
|
|
@@ -36,17 +36,25 @@ module Opsicle
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "creates a new deployment with migrations" do
|
39
|
-
expect(client).to receive(:run_command).with('deploy', {"migrate"=>["true"]}).and_return({deployment_id: 'derp'})
|
39
|
+
expect(client).to receive(:run_command).with('deploy', {"migrate"=>["true"]}, {}).and_return({deployment_id: 'derp'})
|
40
40
|
expect(subject).to_not receive(:open_deploy)
|
41
41
|
subject.execute({ monitor: false, migrate: true })
|
42
42
|
end
|
43
43
|
|
44
44
|
it "creates a new deployment migrations explicitly disabled" do
|
45
|
-
expect(client).to receive(:run_command).with('deploy', {}).and_return({deployment_id: 'derp'})
|
45
|
+
expect(client).to receive(:run_command).with('deploy', {}, {}).and_return({deployment_id: 'derp'})
|
46
46
|
expect(subject).to_not receive(:open_deploy)
|
47
47
|
subject.execute({ monitor: false, migrate: false })
|
48
48
|
end
|
49
49
|
|
50
|
+
it "pass custom json to the deploy if provided" do
|
51
|
+
expect(client).to receive(:run_command).with('deploy', {}, { 'custom_json' => '{ "expire_css": true }' }).and_return({deployment_id: 'derp'})
|
52
|
+
expect(subject).to_not receive(:open_deploy)
|
53
|
+
expect(Monitor::App).to_not receive(:new)
|
54
|
+
|
55
|
+
subject.execute({ json: '{ "expire_css": true }' })
|
56
|
+
end
|
57
|
+
|
50
58
|
it "opens the OpsWorks deployments screen if browser option is given" do
|
51
59
|
expect(subject).to receive(:open_deploy)
|
52
60
|
expect(Monitor::App).to_not receive(:new)
|
@@ -53,6 +53,14 @@ module Opsicle
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
context "custom_json provided" do
|
57
|
+
let(:custom_json) { '{ "expire_css": true }' }
|
58
|
+
it "creates a new execute_recipes deployment and passes along the custom json" do
|
59
|
+
expect(client).to receive(:run_command).with('execute_recipes', {"recipes" => ['herp']}, {"custom_json" => custom_json}).and_return({deployment_id: 'derp'})
|
60
|
+
subject.execute({ monitor: false, json: custom_json, recipes: recipes })
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
56
64
|
it "opens the OpsWorks deployments screen if browser option is given" do
|
57
65
|
expect(subject).to receive(:open_deploy)
|
58
66
|
expect(Monitor::App).to_not receive(:new)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opsicle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Fleener
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-01-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- lib/opsicle/commands/list.rb
|
185
185
|
- lib/opsicle/commands/list_instances.rb
|
186
186
|
- lib/opsicle/commands/ssh.rb
|
187
|
+
- lib/opsicle/commands/ssh_clean_keys.rb
|
187
188
|
- lib/opsicle/commands/ssh_key.rb
|
188
189
|
- lib/opsicle/config.rb
|
189
190
|
- lib/opsicle/deploy_helper.rb
|
@@ -248,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
248
249
|
version: '0'
|
249
250
|
requirements: []
|
250
251
|
rubyforge_project:
|
251
|
-
rubygems_version: 2.
|
252
|
+
rubygems_version: 2.4.2
|
252
253
|
signing_key:
|
253
254
|
specification_version: 4
|
254
255
|
summary: An opsworks specific abstraction on top of the aws sdk
|
@@ -272,4 +273,3 @@ test_files:
|
|
272
273
|
- spec/opsicle/monitor/subpanel_spec.rb
|
273
274
|
- spec/opsicle/s3_bucket_spec.rb
|
274
275
|
- spec/spec_helper.rb
|
275
|
-
has_rdoc:
|