opsworks-cli 0.5.0 → 0.6.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
- SHA1:
3
- metadata.gz: 1f9314cdf3a4f3ca9c386e2dc2f0e537cfa498f9
4
- data.tar.gz: cfb55e0c88b9efb9188c0fece32de6edbf83494e
2
+ SHA256:
3
+ metadata.gz: 7245edfcd7b7b42bb13b880e8e6e420eed060679712b2f1e6e4d54052387fa99
4
+ data.tar.gz: 3c8699d3f0b438b1f5a55779dd0f233cd596be5980a35cee36aeeba6ec708bd0
5
5
  SHA512:
6
- metadata.gz: c63763cc141a5bc68fc7a32632cf6b73da5ba4e316dfbc2b96c51b7b29aded201b45eb857b5cc79fc42bacbb31a9b630081ad93c8755577329297963d47f4ab9
7
- data.tar.gz: 221fe534dcb3affcc3de82ec1038fe5524c48af2a9a5ea79f69a446e9ec6b418b893cf80538de625f3dc7d91cb29f71fd5f277d1656081e018eb398ba39746ab
6
+ metadata.gz: aa0ae55d4ea9198bd44e329e933de21b2a3bf62758537c7816b70730f66a14ac770bdf8f31206c010326599c1998268869328b9382273afa9b19d1ca078e9003
7
+ data.tar.gz: a5fa63b9259cb2c9aa8f91dd44d2c0a5379f42d4b1d7794f8f93244c48428715cd69e4f456783b3656011ee1599ddae6e82f857134c0c3e58767568547ad9902
@@ -0,0 +1,14 @@
1
+ require 'thor'
2
+ require 'jsonpath'
3
+ require 'aws-sdk'
4
+ require 'active_support/core_ext/hash/slice'
5
+
6
+ require 'opsworks/errors'
7
+ require 'opsworks/resource'
8
+ require 'opsworks/app'
9
+ require 'opsworks/instance'
10
+ require 'opsworks/permission'
11
+ require 'opsworks/layer'
12
+ require 'opsworks/resource'
13
+ require 'opsworks/deployment'
14
+ require 'opsworks/stack'
@@ -1,6 +1,3 @@
1
- require 'opsworks/resource'
2
- require 'opsworks/deployment'
3
-
4
1
  module OpsWorks
5
2
  class App < Resource
6
3
  attr_accessor :id, :name, :revision
@@ -1,3 +1,4 @@
1
+ require 'opsworks'
1
2
  require 'opsworks/cli/version'
2
3
  require 'opsworks/cli/agent'
3
4
 
@@ -9,6 +9,7 @@ require_relative 'subcommands/apps'
9
9
  require_relative 'subcommands/iam'
10
10
  require_relative 'subcommands/config'
11
11
  require_relative 'subcommands/deployments'
12
+ require_relative 'subcommands/instances'
12
13
 
13
14
  module OpsWorks
14
15
  module CLI
@@ -24,6 +25,7 @@ module OpsWorks
24
25
  include Subcommands::IAM
25
26
  include Subcommands::Config
26
27
  include Subcommands::Deployments
28
+ include Subcommands::Instances
27
29
 
28
30
  desc 'version', 'Print OpsWorks CLI version'
29
31
  def version
@@ -1,5 +1,3 @@
1
- require 'opsworks/stack'
2
-
3
1
  module OpsWorks
4
2
  module CLI
5
3
  module Helpers
@@ -1,5 +1,3 @@
1
- require 'opsworks/stack'
2
-
3
1
  module OpsWorks
4
2
  module CLI
5
3
  module Helpers
@@ -1,5 +1,3 @@
1
- require 'opsworks/deployment'
2
-
3
1
  module OpsWorks
4
2
  module CLI
5
3
  module Subcommands
@@ -1,5 +1,3 @@
1
- require 'opsworks/stack'
2
-
3
1
  module OpsWorks
4
2
  module CLI
5
3
  module Subcommands
@@ -1,5 +1,3 @@
1
- require 'opsworks/stack'
2
-
3
1
  module OpsWorks
4
2
  module CLI
5
3
  module Subcommands
@@ -16,6 +16,11 @@ module OpsWorks
16
16
  end
17
17
 
18
18
  will_retry = last_deployment.map do |stack, deployment|
19
+ if deployment.nil?
20
+ say "Skipping stack #{stack.name}: no deployment"
21
+ next
22
+ end
23
+
19
24
  if deployment.status == 'successful'
20
25
  say "Skipping stack #{stack.name}: last deployment is " \
21
26
  "#{deployment.status}"
@@ -53,7 +58,7 @@ module OpsWorks
53
58
  opts[:app_id] = dep.app_id if dep.app_id
54
59
  opts[:custom_json] = dep.custom_json if dep.custom_json
55
60
 
56
- new_deployment = stack.send(:create_deployment, opts)
61
+ new_deployment = stack.create_deployment(opts)
57
62
 
58
63
  [stack, new_deployment]
59
64
  end
@@ -1,5 +1,3 @@
1
- require 'opsworks/permission'
2
-
3
1
  module OpsWorks
4
2
  module CLI
5
3
  module Subcommands
@@ -0,0 +1,65 @@
1
+ module OpsWorks
2
+ module CLI
3
+ module Subcommands
4
+ module Instances
5
+ def self.included(thor)
6
+ thor.class_eval do
7
+ desc 'instances:status [--stack STACK]',
8
+ 'Display instance status for a stack'
9
+ option :stack, type: :array
10
+ define_method 'instances:status' do
11
+ stacks = parse_stacks(options)
12
+ stacks.each do |stack|
13
+ stack.instances.each do |instance|
14
+ say [
15
+ stack.name,
16
+ instance.hostname,
17
+ instance.status
18
+ ].join("\t")
19
+ end
20
+ end
21
+ end
22
+
23
+ desc 'instances:wait [--timeout TIMEOUT] [--stack STACK]',
24
+ 'Wait for all instances to settle'
25
+ option :timeout, type: :numeric, default: 300
26
+ option :stack, type: :array
27
+ define_method 'instances:wait' do
28
+ deadline = Time.now + options[:timeout]
29
+ stacks = parse_stacks(options)
30
+
31
+ loop do
32
+ stacks = stacks.reject(&:settled?)
33
+ break if stacks.empty?
34
+
35
+ if Time.now > deadline
36
+ raise "Stacks did not settle: #{stacks.map(&:name).join(' ')}"
37
+ end
38
+
39
+ sleep 5
40
+ end
41
+ end
42
+
43
+ desc 'instances:setup [--stack STACK]',
44
+ 'Retry setup on any instances where it failed'
45
+ option :stack, type: :array
46
+ define_method 'instances:setup' do
47
+ stacks = parse_stacks(options)
48
+ stacks.each do |stack|
49
+ stack.instances.each do |instance|
50
+ next unless instance.setup_failed?
51
+ say "Running setup on #{stack.name} #{instance.hostname}"
52
+
53
+ stack.create_deployment(
54
+ command: { name: 'setup' },
55
+ instance_ids: [instance.id]
56
+ )
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,5 +1,3 @@
1
- require 'opsworks/deployment'
2
-
3
1
  module OpsWorks
4
2
  module CLI
5
3
  module Subcommands
@@ -1,5 +1,5 @@
1
1
  module OpsWorks
2
2
  module CLI
3
- VERSION = '0.5.0'.freeze
3
+ VERSION = '0.6.0'.freeze
4
4
  end
5
5
  end
@@ -1,5 +1,3 @@
1
- require 'opsworks/resource'
2
-
3
1
  module OpsWorks
4
2
  class Deployment < Resource
5
3
  attr_accessor :id, :command, :status, :created_at, :custom_json, :app_id
@@ -0,0 +1,14 @@
1
+ module OpsWorks
2
+ module Errors
3
+ class StackInFatalState < StandardError
4
+ attr_reader :stack, :instances
5
+
6
+ def initialize(stack, instances)
7
+ @stack = stack
8
+ @instances = instances
9
+ names = instances.map(&:hostname).join(' ')
10
+ super("Instances entered a fatal state on #{stack.name}: #{names}")
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,9 +1,15 @@
1
- require 'opsworks/resource'
2
-
3
1
  module OpsWorks
4
2
  class Instance < Resource
5
3
  attr_accessor :id, :hostname, :ec2_instance_id, :instance_type, :status
6
4
 
5
+ FATAL_STATUSES = %w(
6
+ connection_lost setup_failed start_failed stop_failed
7
+ ).freeze
8
+
9
+ SETTLED_STATUSES = (
10
+ FATAL_STATUSES + %w(online stopped terminated)
11
+ ).freeze
12
+
7
13
  def self.from_collection_response(client, response)
8
14
  response.data[:instances].map do |hash|
9
15
  new(
@@ -20,5 +26,17 @@ module OpsWorks
20
26
  def online?
21
27
  status == 'online'
22
28
  end
29
+
30
+ def setup_failed?
31
+ status == 'setup_failed'
32
+ end
33
+
34
+ def fatal?
35
+ FATAL_STATUSES.include?(status)
36
+ end
37
+
38
+ def settled?
39
+ SETTLED_STATUSES.include?(status)
40
+ end
23
41
  end
24
42
  end
@@ -1,6 +1,3 @@
1
- require 'opsworks/resource'
2
- require 'thor'
3
-
4
1
  module OpsWorks
5
2
  class Layer < Resource
6
3
  attr_accessor :id, :name, :shortname, :custom_recipes
@@ -1,5 +1,3 @@
1
- require 'opsworks/resource'
2
-
3
1
  module OpsWorks
4
2
  class Permission < Resource
5
3
  attr_accessor :id, :stack_id, :iam_user_arn, :ssh, :sudo
@@ -1,13 +1,3 @@
1
- require 'jsonpath'
2
- require 'aws-sdk'
3
- require 'active_support/core_ext/hash/slice'
4
-
5
- require 'opsworks/resource'
6
- require 'opsworks/app'
7
- require 'opsworks/instance'
8
- require 'opsworks/permission'
9
- require 'opsworks/layer'
10
-
11
1
  module OpsWorks
12
2
  class Stack < Resource
13
3
  attr_accessor :id, :name, :custom_json
@@ -142,6 +132,16 @@ module OpsWorks
142
132
  create_deployment(**deploy_args)
143
133
  end
144
134
 
135
+ def create_deployment(options = {})
136
+ response = client.create_deployment(
137
+ options.merge(stack_id: id)
138
+ )
139
+ rescue Aws::OpsWorks::Errors::ValidationException => e
140
+ raise unless e.message == DEPLOY_NO_INSTANCES_ERROR
141
+ else
142
+ Deployment.from_response(client, response)
143
+ end
144
+
145
145
  def active?
146
146
  instances.any?(&:online?)
147
147
  end
@@ -164,6 +164,13 @@ module OpsWorks
164
164
  client.create_app(options)
165
165
  end
166
166
 
167
+ def settled?
168
+ instances = initialize_instances
169
+ fatal = instances.select(&:fatal?)
170
+ raise Errors::StackInFatalState.new(self, fatal) if fatal.any?
171
+ instances.all?(&:settled?)
172
+ end
173
+
167
174
  private
168
175
 
169
176
  # rubocop:disable Eval
@@ -215,15 +222,5 @@ module OpsWorks
215
222
  response = client.describe_deployments(stack_id: id)
216
223
  Deployment.from_collection_response(client, response)
217
224
  end
218
-
219
- def create_deployment(options = {})
220
- response = client.create_deployment(
221
- options.merge(stack_id: id)
222
- )
223
- rescue Aws::OpsWorks::Errors::ValidationException => e
224
- raise unless e.message == DEPLOY_NO_INSTANCES_ERROR
225
- else
226
- Deployment.from_response(client, response)
227
- end
228
225
  end
229
226
  end
@@ -31,4 +31,5 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency 'rspec', '~> 3.0'
32
32
  spec.add_development_dependency 'fabrication', '~> 2.16.0'
33
33
  spec.add_development_dependency 'pry'
34
+ spec.add_development_dependency 'timecop', '~> 0.9'
34
35
  end
@@ -0,0 +1,6 @@
1
+ Fabricator(:instance, from: OpsWorks::Instance) do
2
+ initialize_with { @_klass.new(opsworks_stub) }
3
+ id { SecureRandom.uuid }
4
+ hostname { Fabricate.sequence { |i| "test-instance#{i}" } }
5
+ status { 'online' }
6
+ end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+ describe OpsWorks::CLI::Agent do
4
+ let(:stacks) do
5
+ Array.new(3) { |i| Fabricate(:stack, name: "stack-#{i}") }
6
+ end
7
+ before { allow(OpsWorks::Stack).to receive(:all) { stacks } }
8
+
9
+ describe 'instances:status' do
10
+ it 'returns the status of instances on all stacks' do
11
+ statuses = %w(starting online setup_failed)
12
+
13
+ stacks.zip(statuses).each do |stack, status|
14
+ i = Fabricate(:instance, hostname: "instance-#{status}", status: status)
15
+ expect(stack).to receive(:instances).and_return([i])
16
+ end
17
+
18
+ messages = [
19
+ "stack-0\tinstance-starting\tstarting",
20
+ "stack-1\tinstance-online\tonline",
21
+ "stack-2\tinstance-setup_failed\tsetup_failed"
22
+ ]
23
+
24
+ messages.each do |m|
25
+ expect(subject).to receive(:say).with(m).once.ordered
26
+ end
27
+
28
+ subject.send('instances:status')
29
+ end
30
+
31
+ it 'returns the status of instances on the selected stacks' do
32
+ i = Fabricate(:instance, hostname: 'instance', status: 'online')
33
+ expect(stacks[1]).to receive(:instances).and_return([i])
34
+ [0, 2].each { |n| expect(stacks[n]).not_to receive(:instances) }
35
+
36
+ expect(subject).to receive(:say).with("stack-1\tinstance\tonline")
37
+ subject.options = { stack: [stacks[1].name] }
38
+
39
+ subject.send('instances:status')
40
+ end
41
+ end
42
+
43
+ describe 'instances:wait' do
44
+ before do
45
+ subject.options = { timeout: 100 }
46
+ end
47
+
48
+ it 'waits until all stacks settle' do
49
+ stacks.each { |s| expect(s).to receive(:settled?).and_return(false) }
50
+ expect(subject).to receive(:sleep) do
51
+ stacks.each { |s| expect(s).to receive(:settled?).and_return(true) }
52
+ end
53
+
54
+ subject.send('instances:wait')
55
+ end
56
+
57
+ it 'waits until selected stacks settle' do
58
+ expect(stacks[0]).to receive(:settled?).and_return(false)
59
+ expect(subject).to receive(:sleep) do
60
+ expect(stacks[0]).to receive(:settled?).and_return(true)
61
+ end
62
+
63
+ expect(stacks[1]).not_to receive(:settled?)
64
+ expect(stacks[2]).not_to receive(:settled?)
65
+
66
+ subject.options[:stack] = [stacks[0].name]
67
+
68
+ subject.send('instances:wait')
69
+ end
70
+
71
+ it 'fails if the stacks never settle' do
72
+ t = 0
73
+ allow(subject).to receive(:sleep) do |i|
74
+ t += i
75
+ Timecop.freeze(t)
76
+ end
77
+
78
+ stacks.each { |s| allow(s).to receive(:settled?).and_return(false) }
79
+ allow(stacks[0]).to receive(:settled?).and_return(true)
80
+
81
+ expect { Timecop.freeze(t) { subject.send('instances:wait') } }
82
+ .to raise_error(/did not settle: stack-1 stack-2$/i)
83
+ end
84
+ end
85
+
86
+ describe 'instances:setup' do
87
+ let(:i0) { Fabricate(:instance, hostname: 'i0', status: 'setup_failed') }
88
+ let(:i1) { Fabricate(:instance, hostname: 'i1', status: 'online') }
89
+ let(:i2) { Fabricate(:instance, hostname: 'i2', status: 'setup_failed') }
90
+
91
+ before do
92
+ allow(stacks[0]).to receive(:instances).and_return([i0])
93
+ allow(stacks[1]).to receive(:instances).and_return([i1])
94
+ allow(stacks[2]).to receive(:instances).and_return([i2])
95
+ end
96
+
97
+ it 're-runs setup on setup_failed instances across all stacks' do
98
+ expect(stacks[0]).to receive(:create_deployment)
99
+ .with(command: { name: 'setup' }, instance_ids: [i0.id])
100
+
101
+ expect(stacks[1]).not_to receive(:create_deployment)
102
+
103
+ expect(stacks[2]).to receive(:create_deployment)
104
+ .with(command: { name: 'setup' }, instance_ids: [i2.id])
105
+
106
+ expect(subject).to receive(:say)
107
+ .with('Running setup on stack-0 i0')
108
+ .once.ordered
109
+
110
+ expect(subject).to receive(:say)
111
+ .with('Running setup on stack-2 i2')
112
+ .once.ordered
113
+
114
+ subject.send('instances:setup')
115
+ end
116
+
117
+ it 're-runs setup on setup_failed instances across selected stacks' do
118
+ expect(stacks[0]).not_to receive(:create_deployment)
119
+ expect(stacks[1]).not_to receive(:create_deployment)
120
+ expect(stacks[2]).to receive(:create_deployment)
121
+ .with(command: { name: 'setup' }, instance_ids: [i2.id])
122
+
123
+ expect(subject).to receive(:say)
124
+ .with('Running setup on stack-2 i2')
125
+ .once.ordered
126
+
127
+ subject.options = { stack: [stacks[2].name] }
128
+
129
+ subject.send('instances:setup')
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe OpsWorks::Instance do
4
+ context 'status' do
5
+ STATUSES = [
6
+ ['booting', false, false],
7
+ ['connection_lost', true, true],
8
+ ['online', true, false],
9
+ ['pending', false, false],
10
+ ['rebooting', false, false],
11
+ ['requested', false, false],
12
+ ['running_setup', false, false],
13
+ ['setup_failed', true, true],
14
+ ['shutting_down', false, false],
15
+ ['start_failed', true, true],
16
+ ['stop_failed', true, true],
17
+ ['stopped', true, false],
18
+ ['stopping', false, false],
19
+ ['terminated', true, false],
20
+ ['terminating', false, false]
21
+ ].freeze
22
+
23
+ STATUSES.each do |status, settled_expected, fatal_expected|
24
+ context status do
25
+ it "#settled? is #{settled_expected}" do
26
+ i = described_class.new(nil, status: status)
27
+ expect(i.settled?).to be(settled_expected)
28
+ end
29
+
30
+ it "#fatal? is #{fatal_expected}" do
31
+ i = described_class.new(nil, status: status)
32
+ expect(i.fatal?).to be(fatal_expected)
33
+ end
34
+ end
35
+ end
36
+
37
+ it 'has only a few defined non-fatal settled states' do
38
+ # We use this to make sure that our test cases above are coherent.
39
+ expect(STATUSES.select { |_, s, f| s && !f }.map(&:first))
40
+ .to match_array(%w(online stopped terminated))
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe OpsWorks::Stack do
4
+ describe '#settled?' do
5
+ it 'makes a new API call' do
6
+ client = Aws::OpsWorks::Client.new(
7
+ stub_responses: {
8
+ describe_instances: [
9
+ { instances: [{ instance_id: 'a', status: 'starting' }] },
10
+ { instances: [{ instance_id: 'a', status: 'online' }] },
11
+ { instances: [{ instance_id: 'b', status: 'stopping' }] }
12
+ ]
13
+ }
14
+ )
15
+
16
+ subject = described_class.new(client, id: '123')
17
+
18
+ expect(client).to receive(:describe_instances)
19
+ .with(stack_id: '123')
20
+ .exactly(3).times
21
+ .and_call_original
22
+
23
+ expect(subject).not_to be_settled
24
+ expect(subject).to be_settled
25
+ expect(subject).not_to be_settled
26
+ end
27
+
28
+ it 'returns true if all instances have settled' do
29
+ client = Aws::OpsWorks::Client.new(
30
+ stub_responses: {
31
+ describe_instances: {
32
+ instances: [
33
+ { instance_id: 'a', status: 'online' },
34
+ { instance_id: 'b', status: 'stopped' }
35
+ ]
36
+ }
37
+ }
38
+ )
39
+
40
+ expect(described_class.new(client, id: '123')).to be_settled
41
+ end
42
+
43
+ it 'returns false if any instances has not settled' do
44
+ client = Aws::OpsWorks::Client.new(
45
+ stub_responses: {
46
+ describe_instances: {
47
+ instances: [
48
+ { instance_id: 'a', status: 'online' },
49
+ { instance_id: 'b', status: 'stopping' }
50
+ ]
51
+ }
52
+ }
53
+ )
54
+
55
+ expect(described_class.new(client, id: '123')).not_to be_settled
56
+ end
57
+
58
+ it 'fails if any instance will not settle' do
59
+ client = Aws::OpsWorks::Client.new(
60
+ stub_responses: {
61
+ describe_instances: {
62
+ instances: [
63
+ { instance_id: 'a', status: 'online' },
64
+ { instance_id: 'b', status: 'setup_failed', hostname: 'bar' }
65
+ ]
66
+ }
67
+ }
68
+ )
69
+
70
+ e = OpsWorks::Errors::StackInFatalState
71
+
72
+ expect { described_class.new(client, id: '123', name: 'foo').settled? }
73
+ .to raise_error(e, /fatal.*foo.*bar/i)
74
+ end
75
+ end
76
+ end
@@ -6,6 +6,7 @@ require 'opsworks/cli'
6
6
 
7
7
  require 'securerandom'
8
8
  require 'fabrication'
9
+ require 'timecop'
9
10
 
10
11
  def opsworks_stub
11
12
  Aws::OpsWorks::Client.new(stub_responses: true)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opsworks-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Macreery
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-23 00:00:00.000000000 Z
11
+ date: 2018-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: timecop
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0.9'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '0.9'
153
167
  description: OpsWorks CLI
154
168
  email:
155
169
  - frank@macreery.com
@@ -166,6 +180,7 @@ files:
166
180
  - README.md
167
181
  - Rakefile
168
182
  - bin/opsworks
183
+ - lib/opsworks.rb
169
184
  - lib/opsworks/app.rb
170
185
  - lib/opsworks/cli.rb
171
186
  - lib/opsworks/cli/agent.rb
@@ -176,9 +191,11 @@ files:
176
191
  - lib/opsworks/cli/subcommands/config.rb
177
192
  - lib/opsworks/cli/subcommands/deployments.rb
178
193
  - lib/opsworks/cli/subcommands/iam.rb
194
+ - lib/opsworks/cli/subcommands/instances.rb
179
195
  - lib/opsworks/cli/subcommands/recipes.rb
180
196
  - lib/opsworks/cli/version.rb
181
197
  - lib/opsworks/deployment.rb
198
+ - lib/opsworks/errors.rb
182
199
  - lib/opsworks/instance.rb
183
200
  - lib/opsworks/layer.rb
184
201
  - lib/opsworks/permission.rb
@@ -187,6 +204,7 @@ files:
187
204
  - opsworks-cli.gemspec
188
205
  - spec/fabricators/opsworks/app_fabricator.rb
189
206
  - spec/fabricators/opsworks/deployment_fabricator.rb
207
+ - spec/fabricators/opsworks/instance_fabricator.rb
190
208
  - spec/fabricators/opsworks/permission_fabricator.rb
191
209
  - spec/fabricators/opsworks/stack_fabricator.rb
192
210
  - spec/opsworks/cli/agent_spec.rb
@@ -194,7 +212,10 @@ files:
194
212
  - spec/opsworks/cli/subcommands/chef_spec.rb
195
213
  - spec/opsworks/cli/subcommands/config_spec.rb
196
214
  - spec/opsworks/cli/subcommands/iam_spec.rb
215
+ - spec/opsworks/cli/subcommands/instances_spec.rb
197
216
  - spec/opsworks/cli/subcommands/recipes_spec.rb
217
+ - spec/opsworks/instance_spec.rb
218
+ - spec/opsworks/stack_spec.rb
198
219
  - spec/spec_helper.rb
199
220
  homepage: https://github.com/aptible/opsworks-cli
200
221
  licenses:
@@ -216,13 +237,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
216
237
  version: '0'
217
238
  requirements: []
218
239
  rubyforge_project:
219
- rubygems_version: 2.4.5.1
240
+ rubygems_version: 2.7.6
220
241
  signing_key:
221
242
  specification_version: 4
222
243
  summary: Alternative CLI for Amazon OpsWorks
223
244
  test_files:
224
245
  - spec/fabricators/opsworks/app_fabricator.rb
225
246
  - spec/fabricators/opsworks/deployment_fabricator.rb
247
+ - spec/fabricators/opsworks/instance_fabricator.rb
226
248
  - spec/fabricators/opsworks/permission_fabricator.rb
227
249
  - spec/fabricators/opsworks/stack_fabricator.rb
228
250
  - spec/opsworks/cli/agent_spec.rb
@@ -230,5 +252,8 @@ test_files:
230
252
  - spec/opsworks/cli/subcommands/chef_spec.rb
231
253
  - spec/opsworks/cli/subcommands/config_spec.rb
232
254
  - spec/opsworks/cli/subcommands/iam_spec.rb
255
+ - spec/opsworks/cli/subcommands/instances_spec.rb
233
256
  - spec/opsworks/cli/subcommands/recipes_spec.rb
257
+ - spec/opsworks/instance_spec.rb
258
+ - spec/opsworks/stack_spec.rb
234
259
  - spec/spec_helper.rb