opsworks-cli 0.2.1 → 0.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24ea648dce531f41a4ff17b6d4cb9ab1991f708a
4
- data.tar.gz: 4b897b4a05110a1de06a9196da2ac84d8a9fc62a
3
+ metadata.gz: 85301da60371b32e479e3b0c3abd91386e876ead
4
+ data.tar.gz: 0a07cd8ab46d60e96a647173d3020532d66fd17b
5
5
  SHA512:
6
- metadata.gz: 899b768a457184a2e69014c9de72e385fa35601a7c4229c6df828793624532d8002967a7c3a9a0386fe9aa1fc5bf6f6f0c3db011180b53da6613692a1c7faa75
7
- data.tar.gz: fbbe850475cfa8625531a78ce76df586255f85fa41cebab7ee94cccda743da2ae074e0794dcdc57abe7b7e82838becbda8f72d2f9e64fc6bf3d564f72dd3e367
6
+ metadata.gz: 8c07bc9aa8f89556fae70ba033e52bb43fd72fd7ec9f171c584c96a2c3a09115a791b5e00f7f31539b415610aac2cd802ba4b2f8519289980d861a7bf8c7e7b6
7
+ data.tar.gz: 97e160e494f5a2ecc9a5045a0f76097bf6cb83eab694ca05e3a6e7a6eb7203e8de4ffdde8f6410f95102977fd04ebf855e809344f25991d85bbd984c7fca76cc
data/README.md CHANGED
@@ -50,4 +50,6 @@ Commands:
50
50
 
51
51
  MIT License, see [LICENSE](LICENSE.md) for details.
52
52
 
53
- Copyright (c) 2014 [Aptible](https://www.aptible.com), Frank Macreery, and contributors.
53
+ Copyright (c) 2014 [Aptible](https://www.aptible.com) and contributors.
54
+
55
+ [<img src="https://s.gravatar.com/avatar/f7790b867ae619ae0496460aa28c5861?s=60" style="border-radius: 50%;" alt="@fancyremarker" />](https://github.com/fancyremarker)
@@ -8,6 +8,8 @@ require_relative 'subcommands/update'
8
8
  require_relative 'subcommands/exec'
9
9
  require_relative 'subcommands/deploy'
10
10
  require_relative 'subcommands/status'
11
+ require_relative 'subcommands/allow'
12
+ require_relative 'subcommands/lockdown'
11
13
 
12
14
  module OpsWorks
13
15
  module CLI
@@ -18,6 +20,8 @@ module OpsWorks
18
20
  include Subcommands::Exec
19
21
  include Subcommands::Deploy
20
22
  include Subcommands::Status
23
+ include Subcommands::Allow
24
+ include Subcommands::Lockdown
21
25
 
22
26
  desc 'version', 'Print OpsWorks CLI version'
23
27
  def version
@@ -0,0 +1,32 @@
1
+ require 'opsworks/permission'
2
+
3
+ module OpsWorks
4
+ module CLI
5
+ module Subcommands
6
+ module Allow
7
+ # rubocop:disable MethodLength
8
+ # rubocop:disable CyclomaticComplexity
9
+ def self.included(thor)
10
+ thor.class_eval do
11
+ desc 'allow USER [--stack STACK]', 'Allow an IAM user on a stack'
12
+ option :stack, type: :array
13
+ option :ssh, type: :boolean, default: true
14
+ option :sudo, type: :boolean, default: true
15
+ def allow(user)
16
+ fetch_keychain_credentials unless env_credentials?
17
+ stacks = parse_stacks(options.merge(active: true))
18
+ stacks.each do |stack|
19
+ permission = stack.find_permission_by_user(user)
20
+ next unless permission
21
+ say "Updating permissions on #{stack.name}..."
22
+ permission.update(ssh: options[:ssh], sudo: options[:sudo])
23
+ end
24
+ end
25
+ end
26
+ end
27
+ # rubocop:enable CyclomaticComplexity
28
+ # rubocop:enable MethodLength
29
+ end
30
+ end
31
+ end
32
+ end
@@ -8,7 +8,7 @@ module OpsWorks
8
8
  # rubocop:disable CyclomaticComplexity
9
9
  def self.included(thor)
10
10
  thor.class_eval do
11
- desc 'deploy [--stack STACK] APP', 'Deploy an OpsWorks app'
11
+ desc 'deploy APP [--stack STACK]', 'Deploy an OpsWorks app'
12
12
  option :stack, type: :array
13
13
  def deploy(name)
14
14
  fetch_keychain_credentials unless env_credentials?
@@ -8,7 +8,7 @@ module OpsWorks
8
8
  # rubocop:disable CyclomaticComplexity
9
9
  def self.included(thor)
10
10
  thor.class_eval do
11
- desc 'exec [--stack STACK] RECIPE', 'Execute a Chef recipe'
11
+ desc 'exec RECIPE [--stack STACK]', 'Execute a Chef recipe'
12
12
  option :stack, type: :array
13
13
  def exec(recipe)
14
14
  fetch_keychain_credentials unless env_credentials?
@@ -0,0 +1,30 @@
1
+ require 'opsworks/permission'
2
+
3
+ module OpsWorks
4
+ module CLI
5
+ module Subcommands
6
+ module Lockdown
7
+ # rubocop:disable MethodLength
8
+ # rubocop:disable CyclomaticComplexity
9
+ def self.included(thor)
10
+ thor.class_eval do
11
+ desc 'lockdown [--stack STACK]', 'Remove all stack permissions'
12
+ option :stack, type: :array
13
+ def lockdown
14
+ fetch_keychain_credentials unless env_credentials?
15
+ stacks = parse_stacks(options.merge(active: true))
16
+ stacks.each do |stack|
17
+ say "Locking down #{stack.name}..."
18
+ stack.permissions.each do |permission|
19
+ permission.update(ssh: false, sudo: false)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ # rubocop:enable CyclomaticComplexity
26
+ # rubocop:enable MethodLength
27
+ end
28
+ end
29
+ end
30
+ end
@@ -9,7 +9,7 @@ module OpsWorks
9
9
  include Helpers::Keychain
10
10
  include Helpers::Options
11
11
 
12
- desc 'status [--stack STACK] APP',
12
+ desc 'status APP [--stack STACK]',
13
13
  'Display the most recent deployment of an app'
14
14
  option :stack, type: :array
15
15
  def status(name)
@@ -1,5 +1,5 @@
1
1
  module OpsWorks
2
2
  module CLI
3
- VERSION = '0.2.1'
3
+ VERSION = '0.2.2'
4
4
  end
5
5
  end
@@ -0,0 +1,45 @@
1
+ require 'opsworks/resource'
2
+
3
+ module OpsWorks
4
+ class Permission < Resource
5
+ attr_accessor :id, :stack_id, :iam_user_arn, :ssh, :sudo
6
+
7
+ def self.from_collection_response(response)
8
+ response.data[:permissions].map do |hash|
9
+ new(
10
+ id: hash[:permission_id],
11
+ stack_id: hash[:stack_id],
12
+ iam_user_arn: hash[:iam_user_arn],
13
+ sudo: hash[:allow_sudo],
14
+ ssh: hash[:allow_ssh]
15
+ )
16
+ end
17
+ end
18
+
19
+ def user
20
+ iam_user_arn.gsub(/^.*user\//, '')
21
+ end
22
+
23
+ def ssh?
24
+ ssh
25
+ end
26
+
27
+ def sudo?
28
+ sudo
29
+ end
30
+
31
+ def update(options = {})
32
+ options[:ssh] = ssh if options[:ssh].nil?
33
+ options[:sudo] = sudo if options[:sudo].nil?
34
+
35
+ self.class.client.set_permission(
36
+ stack_id: stack_id,
37
+ iam_user_arn: iam_user_arn,
38
+ allow_ssh: options[:ssh],
39
+ allow_sudo: options[:sudo]
40
+ )
41
+ self.ssh = options[:ssh]
42
+ self.sudo = options[:sudo]
43
+ end
44
+ end
45
+ end
@@ -1,6 +1,7 @@
1
1
  require 'opsworks/resource'
2
2
  require 'opsworks/app'
3
3
  require 'opsworks/instance'
4
+ require 'opsworks/permission'
4
5
 
5
6
  module OpsWorks
6
7
  class Stack < Resource
@@ -24,6 +25,14 @@ module OpsWorks
24
25
  @apps ||= initialize_apps
25
26
  end
26
27
 
28
+ def permissions
29
+ @permissions ||= initialize_permissions
30
+ end
31
+
32
+ def find_permission_by_user(name)
33
+ permissions.find { |permission| permission.user == name }
34
+ end
35
+
27
36
  def find_app_by_name(name)
28
37
  apps.find { |app| app.name == name }
29
38
  end
@@ -62,6 +71,12 @@ module OpsWorks
62
71
  App.from_collection_response(response)
63
72
  end
64
73
 
74
+ def initialize_permissions
75
+ return [] unless id
76
+ response = self.class.client.describe_permissions(stack_id: id)
77
+ Permission.from_collection_response(response)
78
+ end
79
+
65
80
  def initialize_instances
66
81
  return [] unless id
67
82
  response = self.class.client.describe_instances(stack_id: id)
@@ -0,0 +1,7 @@
1
+ Fabricator(:permission, from: OpsWorks::Permission) do
2
+ id { SecureRandom.uuid }
3
+ stack_id { SecureRandom.uuid }
4
+ iam_user_arn { Fabricate.sequence(:iam) { |i| "iam::#{i}:user/bob" } }
5
+ ssh true
6
+ sudo true
7
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe OpsWorks::CLI::Agent do
4
+ describe '#allow' do
5
+ let(:permissions) { 2.times.map { Fabricate(:permission) } }
6
+ let(:user) { permissions[0].user }
7
+ let(:stacks) do
8
+ 2.times.map do |i|
9
+ Fabricate(:stack).tap do |stack|
10
+ allow(stack).to receive(:find_permission_by_user) { permissions[i] }
11
+ end
12
+ end
13
+ end
14
+
15
+ before { allow(subject).to receive(:say) }
16
+ before { allow(OpsWorks::Stack).to receive(:all) { stacks } }
17
+ before { allow(OpsWorks::Stack).to receive(:active) { stacks } }
18
+
19
+ it 'should update all matching permissions' do
20
+ expect(permissions[0]).to receive(:update)
21
+ expect(permissions[1]).to receive(:update)
22
+ subject.allow(user)
23
+ end
24
+
25
+ it 'should optionally run on a subset of stacks' do
26
+ expect(permissions[0]).to receive(:update)
27
+ expect(permissions[1]).not_to receive(:update)
28
+
29
+ allow(subject).to receive(:options) { { stack: [stacks[0].name] } }
30
+ subject.allow(user)
31
+ end
32
+
33
+ it 'should accept :ssh and :sudo options' do
34
+ expect(permissions[0]).to receive(:update).with(ssh: true, sudo: false)
35
+
36
+ allow(subject).to receive(:options) do
37
+ { stack: [stacks[0].name], ssh: true, sudo: false }
38
+ end
39
+ subject.allow(user)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe OpsWorks::CLI::Agent do
4
+ describe '#lockdown' do
5
+ let(:permissions) { 2.times.map { Fabricate(:permission) } }
6
+ let(:user) { permissions[0].user }
7
+ let(:stack) do
8
+ Fabricate(:stack).tap do |stack|
9
+ allow(stack).to receive(:permissions) { permissions }
10
+ end
11
+ end
12
+
13
+ before { allow(subject).to receive(:say) }
14
+ before { allow(OpsWorks::Stack).to receive(:all) { [stack] } }
15
+ before { allow(OpsWorks::Stack).to receive(:active) { [stack] } }
16
+
17
+ it 'should lock down all stacks' do
18
+ expect(permissions[0]).to receive(:update).with(ssh: false, sudo: false)
19
+ expect(permissions[1]).to receive(:update).with(ssh: false, sudo: false)
20
+ subject.lockdown
21
+ end
22
+
23
+ it 'should optionally run on a subset of stacks' do
24
+ expect(permissions[0]).to receive(:update).with(ssh: false, sudo: false)
25
+ expect(permissions[1]).to receive(:update).with(ssh: false, sudo: false)
26
+
27
+ allow(subject).to receive(:options) { { stacks: [stack.name] } }
28
+ subject.lockdown
29
+ end
30
+ end
31
+ end
metadata CHANGED
@@ -1,139 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opsworks-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Macreery
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-08 00:00:00.000000000 Z
11
+ date: 2014-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: aws-sdk
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: aws-keychain-util
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.5'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.5'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: aptible-tasks
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ~>
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
103
  version: '3.0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ~>
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '3.0'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: fabrication
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '>='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '>='
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: pry
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - '>='
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - '>='
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  description: OpsWorks CLI
@@ -144,9 +144,9 @@ executables:
144
144
  extensions: []
145
145
  extra_rdoc_files: []
146
146
  files:
147
- - .gitignore
148
- - .rspec
149
- - .travis.yml
147
+ - ".gitignore"
148
+ - ".rspec"
149
+ - ".travis.yml"
150
150
  - Gemfile
151
151
  - LICENSE.md
152
152
  - README.md
@@ -157,22 +157,28 @@ files:
157
157
  - lib/opsworks/cli/agent.rb
158
158
  - lib/opsworks/cli/helpers/keychain.rb
159
159
  - lib/opsworks/cli/helpers/options.rb
160
+ - lib/opsworks/cli/subcommands/allow.rb
160
161
  - lib/opsworks/cli/subcommands/deploy.rb
161
162
  - lib/opsworks/cli/subcommands/exec.rb
163
+ - lib/opsworks/cli/subcommands/lockdown.rb
162
164
  - lib/opsworks/cli/subcommands/status.rb
163
165
  - lib/opsworks/cli/subcommands/update.rb
164
166
  - lib/opsworks/cli/version.rb
165
167
  - lib/opsworks/deployment.rb
166
168
  - lib/opsworks/instance.rb
169
+ - lib/opsworks/permission.rb
167
170
  - lib/opsworks/resource.rb
168
171
  - lib/opsworks/stack.rb
169
172
  - opsworks-cli.gemspec
170
173
  - spec/fabricators/opsworks/app_fabricator.rb
171
174
  - spec/fabricators/opsworks/deployment_fabricator.rb
175
+ - spec/fabricators/opsworks/permission_fabricator.rb
172
176
  - spec/fabricators/opsworks/stack_fabricator.rb
173
177
  - spec/opsworks/cli/agent_spec.rb
178
+ - spec/opsworks/cli/subcommands/allow_spec.rb
174
179
  - spec/opsworks/cli/subcommands/deploy_spec.rb
175
180
  - spec/opsworks/cli/subcommands/exec_spec.rb
181
+ - spec/opsworks/cli/subcommands/lockdown_spec.rb
176
182
  - spec/opsworks/cli/subcommands/update_spec.rb
177
183
  - spec/spec_helper.rb
178
184
  homepage: https://github.com/aptible/opsworks-cli
@@ -185,12 +191,12 @@ require_paths:
185
191
  - lib
186
192
  required_ruby_version: !ruby/object:Gem::Requirement
187
193
  requirements:
188
- - - '>='
194
+ - - ">="
189
195
  - !ruby/object:Gem::Version
190
196
  version: '0'
191
197
  required_rubygems_version: !ruby/object:Gem::Requirement
192
198
  requirements:
193
- - - '>='
199
+ - - ">="
194
200
  - !ruby/object:Gem::Version
195
201
  version: '0'
196
202
  requirements: []
@@ -202,9 +208,12 @@ summary: Alternative CLI for Amazon OpsWorks
202
208
  test_files:
203
209
  - spec/fabricators/opsworks/app_fabricator.rb
204
210
  - spec/fabricators/opsworks/deployment_fabricator.rb
211
+ - spec/fabricators/opsworks/permission_fabricator.rb
205
212
  - spec/fabricators/opsworks/stack_fabricator.rb
206
213
  - spec/opsworks/cli/agent_spec.rb
214
+ - spec/opsworks/cli/subcommands/allow_spec.rb
207
215
  - spec/opsworks/cli/subcommands/deploy_spec.rb
208
216
  - spec/opsworks/cli/subcommands/exec_spec.rb
217
+ - spec/opsworks/cli/subcommands/lockdown_spec.rb
209
218
  - spec/opsworks/cli/subcommands/update_spec.rb
210
219
  - spec/spec_helper.rb