opsicle 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 382eb43575e7839130f2b9aeb764eb073f00eb55
4
- data.tar.gz: d2daa070bd8e667242c07655c9c9fe2f615a1a6b
3
+ metadata.gz: c70b5f91d3917104411e5e0b6cc183406b1b8016
4
+ data.tar.gz: 61418c77bb81f7adccd36dfed093ea482e59077c
5
5
  SHA512:
6
- metadata.gz: 2e3f9d74f4a3e204639c113564faae10f2714f7347a348044de701da4573fb76a915097ea482cc0c81d7b6d9d71365705b0ad11a10e8d16a1f52b10d43a970b4
7
- data.tar.gz: eaf95944a7eaa244811546b382e5c1b05ed4cdd9522290e93f353173ad2adf97727dcf46db1c7a7c396e7da154189e39cec13387720c7e39eface42f2e0c57fb
6
+ metadata.gz: 39ceb8570c356e6a74411a4f5307771ee7cfc1bddb9ddb958d26209a3a8366225c8f5e8d695b075be0b2744a472acd35cb74eade46841f29bd5cd65b98d8a5b4
7
+ data.tar.gz: d1322f7a77cfb0c3e5e416fe9a7d3632a13908704f9a0e1d32adcdb8969705d4c50c04de01653f19c6aedb0bfcda659ec1c1b1be0db89f4034c545979996b869
data/bin/opsicle CHANGED
@@ -2,6 +2,8 @@
2
2
  require 'rubygems'
3
3
  require 'gli'
4
4
  require 'opsicle'
5
+ require 'json'
6
+ require 'yaml'
5
7
 
6
8
  include GLI::App
7
9
 
@@ -181,4 +183,29 @@ command :instances do |c|
181
183
  end
182
184
  end
183
185
 
186
+
187
+ desc "Update properties on a OpsWorks resource."
188
+ arg_name '<environment> <type>'
189
+ command 'update' do |c|
190
+ valid_types = %w[app elastic_ip instance layer my_user_profile rds_db_instance stack user_profile volume]
191
+ c.flag [:j, :json], :desc => 'JSON of values to update.', :type => String
192
+ c.flag [:y, :yaml_file], :desc => 'YAML file of values to update.', :type => String
193
+
194
+ c.action do |global_options, options, args|
195
+ raise ArgumentError, "Environment is required" unless args.first
196
+ raise ArgumentError, "Resource type is required" unless args[1]
197
+ raise ArgumentError, "Invalid type: #{args[1]}. Valid types: #{valid_types}" unless valid_types.include?(args[1])
198
+ if options[:json]
199
+ values = JSON.parse(options[:json])
200
+ elsif options[:yaml_file]
201
+ yaml_file = File.expand_path(options[:yaml_file])
202
+ values = YAML.load_file(yaml_file)
203
+ else
204
+ raise ArgumentError, "Values required in JSON or YAML flag."
205
+ end
206
+
207
+ Opsicle::Update.new(*args).execute(values, global_options.merge(options))
208
+ end
209
+ end
210
+
184
211
  exit run(ARGV)
@@ -5,6 +5,7 @@ require "opsicle/commands/chef_update"
5
5
  require "opsicle/commands/execute_recipes"
6
6
  require "opsicle/commands/list"
7
7
  require "opsicle/commands/list_instances"
8
+ require "opsicle/commands/update"
8
9
  require "opsicle/commands/ssh"
9
10
  require "opsicle/commands/ssh_key"
10
11
  require "opsicle/commands/ssh_clean_keys"
@@ -0,0 +1,57 @@
1
+ require 'hashdiff'
2
+ require 'opsicle/output'
3
+
4
+ module Opsicle
5
+ class Update
6
+ attr_reader :client, :type
7
+
8
+ def initialize(environment, type)
9
+ @client = Client.new(environment)
10
+ @type = type
11
+ end
12
+
13
+ def execute(values, options)
14
+ before = describe
15
+ update(values)
16
+ after = describe
17
+ print(before, after)
18
+ end
19
+
20
+ def describe
21
+ api_method = "describe_#{@type}s"
22
+ api_opts = {
23
+ :"#{@type}_ids" => [client.config.opsworks_config[:"#{@type}_id"]]
24
+ }
25
+ client.api_call(api_method, api_opts)[:"#{@type}s"][0]
26
+ end
27
+
28
+ def update(values)
29
+ api_method = "update_#{@type}"
30
+ api_opts = values.merge(:"#{@type}_id" => client.config.opsworks_config[:"#{@type}_id"])
31
+ client.api_call(api_method, api_opts)
32
+ end
33
+
34
+ def print(before, after)
35
+ diff = HashDiff.diff(before, after)
36
+ Output.say("Changes: #{diff.size}")
37
+ Output.terminal.say(Terminal::Table.new headings: %w[Change Key Before After], rows: format_diff(diff)) if diff.size > 0
38
+ end
39
+
40
+ def format_diff(diff)
41
+ diff.map { |change|
42
+ case change[0]
43
+ when '-'
44
+ change.insert(3, nil)
45
+ change.map! { |i| Output.format(i, :removal) }
46
+ when '+'
47
+ change.insert(2, nil)
48
+ change.map! { |i| Output.format(i, :addition) }
49
+ when '~'
50
+ change.map! { |i| Output.format(i, :modification) }
51
+ end
52
+ change
53
+ }
54
+ end
55
+
56
+ end
57
+ end
@@ -15,14 +15,21 @@ module Opsicle
15
15
  :verbose => [:bold, :magenta],
16
16
  :debug => [:bold, :cyan],
17
17
  :success => [:bold, :green],
18
+ :addition => [:bold, :green],
19
+ :removal => [:bold, :red],
20
+ :modification => [:bold, :yellow],
18
21
  )
19
22
  end
20
23
 
21
24
  def self.say(msg, log_style=:normal)
25
+ terminal.say format(msg, log_style)
26
+ end
27
+
28
+ def self.format(msg, log_style=:normal)
22
29
  if $color
23
- terminal.say "<%= color('#{msg}', '#{log_style}') %>"
30
+ terminal.color(msg.to_s, log_style)
24
31
  else
25
- terminal.say msg
32
+ msg
26
33
  end
27
34
  end
28
35
 
@@ -1,3 +1,3 @@
1
1
  module Opsicle
2
- VERSION = "0.12.0"
2
+ VERSION = "0.13.0"
3
3
  end
@@ -0,0 +1,71 @@
1
+ require "spec_helper"
2
+ require "opsicle"
3
+
4
+ module Opsicle
5
+ describe Update do
6
+ subject { Update.new("env", "type") }
7
+ let(:client) { double }
8
+ let(:env) { "env" }
9
+ let(:type) { "type" }
10
+ let(:values) { { :foo => "bar" } }
11
+
12
+ before do
13
+ allow(Client).to receive(:new).with('env') { client }
14
+ allow(client).to receive_message_chain("config.opsworks_config.[]") { 123 }
15
+ end
16
+
17
+ context "#execute" do
18
+ it "should update and print results" do
19
+ allow(subject).to receive(:describe) { "tacos" }
20
+ expect(subject).to receive(:print).with("tacos", "tacos")
21
+ api_opts = values.merge(:type_id => 123)
22
+ expect(client).to receive(:api_call).with("update_type", api_opts)
23
+ subject.execute(values, api_opts)
24
+ end
25
+ end
26
+
27
+ context "#describe" do
28
+ it "should return data for type" do
29
+ expect(client).to receive(:api_call).with("describe_types", :type_ids => [123]).and_return(:types => [])
30
+ subject.describe
31
+ end
32
+ end
33
+
34
+ context "#update" do
35
+ it "should update values for type" do
36
+ api_opts = values.merge(:type_id => 123)
37
+ expect(client).to receive(:api_call).with("update_type", api_opts)
38
+ subject.update(values)
39
+ end
40
+ end
41
+
42
+ context "#print" do
43
+ it "should print no changes without table" do
44
+ allow(HashDiff).to receive(:diff) { [] }
45
+ expect(Output).to receive(:say).with("Changes: 0") { nil }
46
+ expect(Output).to_not receive(:terminal)
47
+ subject.print(nil, nil)
48
+ end
49
+ it "should print changes with table" do
50
+ allow(HashDiff).to receive(:diff) { [%w[- nyan 1], %w[+ cat 2],%w[~ taco 3 4]] }
51
+ expect(Output).to receive(:say).with("Changes: 3") { nil }
52
+ expect(Output).to receive_message_chain("terminal.say")
53
+ subject.print(nil, nil)
54
+ end
55
+ end
56
+
57
+ context "#format_diff" do
58
+ let(:diff) { [%w[- nyan 1], %w[+ cat 2],%w[~ taco 3 4]] }
59
+ let(:formatted_diff) {
60
+ [%w[r- rnyan r1 r], %w[a+ acat a a2], %w[m~ mtaco m3 m4]]
61
+ }
62
+
63
+ it "should align columns and colorize" do
64
+ allow(Output).to receive(:format).with(anything, :removal) { |arg| "r#{arg}"}
65
+ allow(Output).to receive(:format).with(anything, :addition) { |arg| "a#{arg}"}
66
+ allow(Output).to receive(:format).with(anything, :modification) { |arg| "m#{arg}"}
67
+ expect(subject.format_diff(diff)).to eq(formatted_diff)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,61 @@
1
+ require "spec_helper"
2
+ require "opsicle"
3
+
4
+ module Opsicle
5
+ describe Output do
6
+ subject { Output }
7
+ let(:terminal) { double(:say => nil, :color => nil) }
8
+ let(:msg) { "message" }
9
+ let(:colored_msg) { "COLOURmessageCOLOUR" }
10
+
11
+ before do
12
+ allow(subject).to receive(:terminal).and_return(terminal)
13
+ $color = true
14
+ $verbose = false
15
+ end
16
+
17
+ context "#say" do
18
+ it "should say a formatted message" do
19
+ allow(terminal).to receive(:color).and_return(colored_msg)
20
+ expect(terminal).to receive(:say).with(colored_msg)
21
+ subject.say(msg)
22
+ end
23
+ it "should say a message without color" do
24
+ $color = false
25
+ expect(terminal).to receive(:say).with(msg)
26
+ subject.say(msg)
27
+ end
28
+ end
29
+
30
+ context "#format" do
31
+ it "should color message" do
32
+ allow(terminal).to receive(:color).and_return(colored_msg)
33
+ expect(subject.format(msg)).to eq(colored_msg)
34
+ end
35
+ it "should not color message" do
36
+ $color = false
37
+ expect(subject.format(msg)).to eq(msg)
38
+ end
39
+ end
40
+
41
+ context "#say_verbose" do
42
+ it "should not say a verbose message" do
43
+ expect(terminal).to_not receive(:say)
44
+ subject.say_verbose(msg)
45
+ end
46
+ it "should say a verbose message" do
47
+ $verbose = true
48
+ expect(terminal).to receive(:say)
49
+ subject.say_verbose(msg)
50
+ end
51
+ end
52
+
53
+ context "#ask" do
54
+ it "should ask" do
55
+ expect(terminal).to receive(:ask)
56
+ subject.ask
57
+ end
58
+ end
59
+
60
+ end
61
+ end
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.12.0
4
+ version: 0.13.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: 2015-03-26 00:00:00.000000000 Z
12
+ date: 2015-03-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk
@@ -95,6 +95,20 @@ dependencies:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0.5'
98
+ - !ruby/object:Gem::Dependency
99
+ name: hashdiff
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '0.2'
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '0.2'
98
112
  - !ruby/object:Gem::Dependency
99
113
  name: bundler
100
114
  requirement: !ruby/object:Gem::Requirement
@@ -186,6 +200,7 @@ files:
186
200
  - lib/opsicle/commands/ssh.rb
187
201
  - lib/opsicle/commands/ssh_clean_keys.rb
188
202
  - lib/opsicle/commands/ssh_key.rb
203
+ - lib/opsicle/commands/update.rb
189
204
  - lib/opsicle/config.rb
190
205
  - lib/opsicle/deploy_helper.rb
191
206
  - lib/opsicle/deployment.rb
@@ -218,6 +233,7 @@ files:
218
233
  - spec/opsicle/commands/list_spec.rb
219
234
  - spec/opsicle/commands/ssh_key_spec.rb
220
235
  - spec/opsicle/commands/ssh_spec.rb
236
+ - spec/opsicle/commands/update_spec.rb
221
237
  - spec/opsicle/config_spec.rb
222
238
  - spec/opsicle/errors_spec.rb
223
239
  - spec/opsicle/instances_spec.rb
@@ -227,6 +243,7 @@ files:
227
243
  - spec/opsicle/monitor/screen_spec.rb
228
244
  - spec/opsicle/monitor/spy/deployments_spec.rb
229
245
  - spec/opsicle/monitor/subpanel_spec.rb
246
+ - spec/opsicle/output_spec.rb
230
247
  - spec/opsicle/s3_bucket_spec.rb
231
248
  - spec/spec_helper.rb
232
249
  homepage: https://github.com/sportngin/opsicle
@@ -262,6 +279,7 @@ test_files:
262
279
  - spec/opsicle/commands/list_spec.rb
263
280
  - spec/opsicle/commands/ssh_key_spec.rb
264
281
  - spec/opsicle/commands/ssh_spec.rb
282
+ - spec/opsicle/commands/update_spec.rb
265
283
  - spec/opsicle/config_spec.rb
266
284
  - spec/opsicle/errors_spec.rb
267
285
  - spec/opsicle/instances_spec.rb
@@ -271,5 +289,6 @@ test_files:
271
289
  - spec/opsicle/monitor/screen_spec.rb
272
290
  - spec/opsicle/monitor/spy/deployments_spec.rb
273
291
  - spec/opsicle/monitor/subpanel_spec.rb
292
+ - spec/opsicle/output_spec.rb
274
293
  - spec/opsicle/s3_bucket_spec.rb
275
294
  - spec/spec_helper.rb