swa 0.8.6 → 1.0.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/.beads/.gitignore +18 -0
- data/.beads/issues.jsonl +5 -0
- data/.rubocop.yml +39 -0
- data/AGENTS.md +541 -0
- data/CLAUDE.md +5 -0
- data/Gemfile +9 -1
- data/README.md +0 -5
- data/Rakefile +2 -0
- data/bin/console +1 -0
- data/exe/swa +2 -1
- data/lib/swa/athena/catalog.rb +4 -0
- data/lib/swa/athena/database.rb +4 -0
- data/lib/swa/athena/query_execution.rb +4 -0
- data/lib/swa/athena/work_group.rb +4 -0
- data/lib/swa/cli/athena_command.rb +93 -42
- data/lib/swa/cli/base_command.rb +22 -14
- data/lib/swa/cli/cloud_formation_command.rb +11 -4
- data/lib/swa/cli/cloudtrail_command.rb +130 -0
- data/lib/swa/cli/collection_behaviour.rb +4 -2
- data/lib/swa/cli/data_output.rb +12 -11
- data/lib/swa/cli/ec2_command.rb +21 -37
- data/lib/swa/cli/elb_command.rb +5 -3
- data/lib/swa/cli/filter_options.rb +6 -1
- data/lib/swa/cli/glue_command.rb +84 -36
- data/lib/swa/cli/iam_command.rb +42 -33
- data/lib/swa/cli/item_behaviour.rb +4 -2
- data/lib/swa/cli/kms_command.rb +26 -5
- data/lib/swa/cli/lake_formation_command.rb +72 -11
- data/lib/swa/cli/main_command.rb +19 -9
- data/lib/swa/cli/s3_command.rb +32 -24
- data/lib/swa/cli/selector.rb +4 -0
- data/lib/swa/cli/tag_filter_options.rb +6 -2
- data/lib/swa/cloud_formation/stack.rb +5 -1
- data/lib/swa/cloud_trail/event.rb +49 -0
- data/lib/swa/data_presentation.rb +23 -22
- data/lib/swa/ec2/image.rb +7 -5
- data/lib/swa/ec2/instance.rb +5 -1
- data/lib/swa/ec2/key_pair.rb +4 -0
- data/lib/swa/ec2/security_group.rb +5 -3
- data/lib/swa/ec2/snapshot.rb +6 -4
- data/lib/swa/ec2/subnet.rb +5 -3
- data/lib/swa/ec2/tagged_resource.rb +4 -0
- data/lib/swa/ec2/volume.rb +7 -5
- data/lib/swa/ec2/vpc.rb +5 -3
- data/lib/swa/elb/load_balancer.rb +4 -0
- data/lib/swa/glue/crawl.rb +5 -1
- data/lib/swa/glue/crawler.rb +5 -1
- data/lib/swa/glue/database.rb +5 -0
- data/lib/swa/glue/job.rb +4 -0
- data/lib/swa/glue/job_bookmark_entry.rb +4 -0
- data/lib/swa/glue/job_run.rb +5 -1
- data/lib/swa/glue/partition.rb +5 -1
- data/lib/swa/glue/table.rb +4 -0
- data/lib/swa/iam/credentials.rb +7 -7
- data/lib/swa/iam/group.rb +5 -3
- data/lib/swa/iam/instance_profile.rb +5 -3
- data/lib/swa/iam/policy.rb +5 -3
- data/lib/swa/iam/role.rb +10 -3
- data/lib/swa/iam/role_policy.rb +5 -3
- data/lib/swa/iam/user.rb +5 -3
- data/lib/swa/kms/alias.rb +4 -0
- data/lib/swa/kms/key.rb +4 -0
- data/lib/swa/lake_formation/data_lake_settings.rb +15 -0
- data/lib/swa/lake_formation/permission.rb +5 -1
- data/lib/swa/lake_formation/resource_info.rb +4 -0
- data/lib/swa/lake_formation/tag.rb +25 -0
- data/lib/swa/polyfill.rb +3 -1
- data/lib/swa/record.rb +5 -3
- data/lib/swa/resource.rb +3 -1
- data/lib/swa/s3/bucket.rb +5 -3
- data/lib/swa/s3/object.rb +7 -5
- data/lib/swa/s3/object_list_entry.rb +4 -0
- data/lib/swa/s3/object_version.rb +13 -7
- data/lib/swa/version.rb +5 -1
- data/lib/swa.rb +2 -0
- data/swa.gemspec +29 -25
- metadata +63 -29
data/lib/swa/cli/iam_command.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "aws-sdk-iam"
|
|
2
4
|
require "swa/cli/base_command"
|
|
3
5
|
require "swa/cli/collection_behaviour"
|
|
@@ -10,6 +12,7 @@ require "swa/iam/role"
|
|
|
10
12
|
require "swa/iam/user"
|
|
11
13
|
|
|
12
14
|
module Swa
|
|
15
|
+
|
|
13
16
|
module CLI
|
|
14
17
|
|
|
15
18
|
class IamCommand < BaseCommand
|
|
@@ -36,8 +39,6 @@ module Swa
|
|
|
36
39
|
|
|
37
40
|
include CollectionBehaviour
|
|
38
41
|
|
|
39
|
-
private
|
|
40
|
-
|
|
41
42
|
def collection
|
|
42
43
|
query_for(:groups, Swa::IAM::Group)
|
|
43
44
|
end
|
|
@@ -50,8 +51,6 @@ module Swa
|
|
|
50
51
|
|
|
51
52
|
include ItemBehaviour
|
|
52
53
|
|
|
53
|
-
private
|
|
54
|
-
|
|
55
54
|
def item
|
|
56
55
|
Swa::IAM::InstanceProfile.new(iam.instance_profile(File.basename(name)))
|
|
57
56
|
end
|
|
@@ -66,8 +65,6 @@ module Swa
|
|
|
66
65
|
|
|
67
66
|
include CollectionBehaviour
|
|
68
67
|
|
|
69
|
-
private
|
|
70
|
-
|
|
71
68
|
def collection
|
|
72
69
|
query_for(:instance_profiles, Swa::IAM::InstanceProfile)
|
|
73
70
|
end
|
|
@@ -80,8 +77,6 @@ module Swa
|
|
|
80
77
|
|
|
81
78
|
include ItemBehaviour
|
|
82
79
|
|
|
83
|
-
private
|
|
84
|
-
|
|
85
80
|
def item
|
|
86
81
|
Swa::IAM::Policy.new(iam.policy(arn))
|
|
87
82
|
end
|
|
@@ -117,14 +112,12 @@ module Swa
|
|
|
117
112
|
|
|
118
113
|
include CollectionBehaviour
|
|
119
114
|
|
|
120
|
-
private
|
|
121
|
-
|
|
122
115
|
def collection
|
|
123
116
|
query_for(:policies, Swa::IAM::Policy, query_options)
|
|
124
117
|
end
|
|
125
118
|
|
|
126
119
|
def query_options
|
|
127
|
-
{ :
|
|
120
|
+
{ scope: scope }.compact
|
|
128
121
|
end
|
|
129
122
|
|
|
130
123
|
end
|
|
@@ -135,8 +128,6 @@ module Swa
|
|
|
135
128
|
|
|
136
129
|
include ItemBehaviour
|
|
137
130
|
|
|
138
|
-
private
|
|
139
|
-
|
|
140
131
|
def role
|
|
141
132
|
Swa::IAM::Role.new(iam.role(File.basename(name)))
|
|
142
133
|
end
|
|
@@ -148,8 +139,8 @@ module Swa
|
|
|
148
139
|
subcommand "assume", "Assume the role" do
|
|
149
140
|
|
|
150
141
|
option "--session-name", "NAME", "STS session-name",
|
|
151
|
-
:
|
|
152
|
-
:
|
|
142
|
+
environment_variable: "USER",
|
|
143
|
+
default: "swa"
|
|
153
144
|
|
|
154
145
|
parameter "[COMMAND] ...", "command to execute"
|
|
155
146
|
|
|
@@ -162,29 +153,35 @@ module Swa
|
|
|
162
153
|
end
|
|
163
154
|
end
|
|
164
155
|
|
|
165
|
-
private
|
|
166
|
-
|
|
167
156
|
def assume
|
|
168
157
|
response = sts_client.assume_role(
|
|
169
|
-
:
|
|
170
|
-
:
|
|
158
|
+
role_arn: item.arn,
|
|
159
|
+
role_session_name: session_name
|
|
171
160
|
)
|
|
172
161
|
Swa::IAM::Credentials.new(response.credentials.to_h)
|
|
173
162
|
end
|
|
174
163
|
|
|
175
164
|
def dump_env(env)
|
|
176
|
-
env.each do |k,v|
|
|
165
|
+
env.each do |k, v|
|
|
177
166
|
puts "#{k}=#{v}"
|
|
178
167
|
end
|
|
179
168
|
end
|
|
180
169
|
|
|
181
170
|
end
|
|
182
171
|
|
|
183
|
-
subcommand ["policies"], "Show
|
|
172
|
+
subcommand ["attached-policies"], "Show attached managed policies." do
|
|
184
173
|
|
|
185
174
|
include CollectionBehaviour
|
|
186
175
|
|
|
187
|
-
|
|
176
|
+
def collection
|
|
177
|
+
role.attached_policies
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
subcommand ["policies"], "Show role policies." do
|
|
183
|
+
|
|
184
|
+
include CollectionBehaviour
|
|
188
185
|
|
|
189
186
|
def collection
|
|
190
187
|
role.policies
|
|
@@ -206,14 +203,33 @@ module Swa
|
|
|
206
203
|
|
|
207
204
|
end
|
|
208
205
|
|
|
209
|
-
private
|
|
210
|
-
|
|
211
206
|
def item
|
|
212
207
|
role.policy(policy_name)
|
|
213
208
|
end
|
|
214
209
|
|
|
215
210
|
end
|
|
216
211
|
|
|
212
|
+
subcommand ["simulate"], "Simulate an action" do
|
|
213
|
+
|
|
214
|
+
parameter "ACTION ...", "action to simulate"
|
|
215
|
+
|
|
216
|
+
option %w[--resource -R], "RESOURCE", "resource ARN", multivalued: true do |arg|
|
|
217
|
+
arg.sub(%r{\As3://}, "arn:aws:s3:::")
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def execute
|
|
221
|
+
evaluation_results = iam.client.simulate_principal_policy(
|
|
222
|
+
policy_source_arn: role.arn,
|
|
223
|
+
action_names: action_list,
|
|
224
|
+
resource_arns: resource_list
|
|
225
|
+
).each.flat_map(&:evaluation_results).map { |result| stringify_keys(result.to_h) }
|
|
226
|
+
display_data(evaluation_results)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
include DataPresentation
|
|
230
|
+
|
|
231
|
+
end
|
|
232
|
+
|
|
217
233
|
subcommand "trust-policy", "print AssumeRolePolicyDocument" do
|
|
218
234
|
|
|
219
235
|
self.default_subcommand = "data"
|
|
@@ -226,8 +242,6 @@ module Swa
|
|
|
226
242
|
display_data(trust_policy_data, query)
|
|
227
243
|
end
|
|
228
244
|
|
|
229
|
-
private
|
|
230
|
-
|
|
231
245
|
def trust_policy_data
|
|
232
246
|
JSON.parse(role.assume_role_policy_document)
|
|
233
247
|
end
|
|
@@ -254,8 +268,6 @@ module Swa
|
|
|
254
268
|
|
|
255
269
|
include CollectionBehaviour
|
|
256
270
|
|
|
257
|
-
private
|
|
258
|
-
|
|
259
271
|
def collection
|
|
260
272
|
query_for(:roles, Swa::IAM::Role)
|
|
261
273
|
end
|
|
@@ -268,8 +280,6 @@ module Swa
|
|
|
268
280
|
|
|
269
281
|
include ItemBehaviour
|
|
270
282
|
|
|
271
|
-
private
|
|
272
|
-
|
|
273
283
|
def item
|
|
274
284
|
Swa::IAM::User.new(iam.user(File.basename(name)))
|
|
275
285
|
end
|
|
@@ -284,8 +294,6 @@ module Swa
|
|
|
284
294
|
|
|
285
295
|
include CollectionBehaviour
|
|
286
296
|
|
|
287
|
-
private
|
|
288
|
-
|
|
289
297
|
def collection
|
|
290
298
|
query_for(:users, Swa::IAM::User)
|
|
291
299
|
end
|
|
@@ -300,7 +308,7 @@ module Swa
|
|
|
300
308
|
|
|
301
309
|
def query_for(query_method, resource_model, *query_args)
|
|
302
310
|
aws_resources = iam.public_send(query_method, *query_args)
|
|
303
|
-
|
|
311
|
+
resource_model.list(aws_resources)
|
|
304
312
|
end
|
|
305
313
|
|
|
306
314
|
def sts_client
|
|
@@ -310,4 +318,5 @@ module Swa
|
|
|
310
318
|
end
|
|
311
319
|
|
|
312
320
|
end
|
|
321
|
+
|
|
313
322
|
end
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Swa
|
|
4
|
+
|
|
2
5
|
module CLI
|
|
3
6
|
|
|
4
7
|
module ItemBehaviour
|
|
5
8
|
|
|
6
9
|
def self.included(target)
|
|
7
|
-
|
|
8
10
|
target.subcommand ["summary", "s"], "One-line summary" do
|
|
9
11
|
def execute
|
|
10
12
|
puts item.summary
|
|
@@ -20,10 +22,10 @@ module Swa
|
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
end
|
|
23
|
-
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
end
|
|
30
|
+
|
|
29
31
|
end
|
data/lib/swa/cli/kms_command.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "aws-sdk-kms"
|
|
2
4
|
require "swa/cli/base_command"
|
|
3
5
|
require "swa/cli/collection_behaviour"
|
|
@@ -6,6 +8,7 @@ require "swa/kms/alias"
|
|
|
6
8
|
require "swa/kms/key"
|
|
7
9
|
|
|
8
10
|
module Swa
|
|
11
|
+
|
|
9
12
|
module CLI
|
|
10
13
|
|
|
11
14
|
class KmsCommand < BaseCommand
|
|
@@ -28,10 +31,29 @@ module Swa
|
|
|
28
31
|
|
|
29
32
|
include ItemBehaviour
|
|
30
33
|
|
|
31
|
-
private
|
|
32
|
-
|
|
33
34
|
def item
|
|
34
|
-
Swa::KMS::Key.new(kms_client.describe_key(:
|
|
35
|
+
Swa::KMS::Key.new(kms_client.describe_key(key_id: id).key_metadata)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
subcommand ["policies"], "Show key policies" do
|
|
39
|
+
|
|
40
|
+
def execute
|
|
41
|
+
policy_names = kms_client.list_key_policies(key_id: id).lazy.flat_map(&:policy_names)
|
|
42
|
+
puts(*policy_names)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
subcommand ["policy"], "Show named key policy" do
|
|
48
|
+
|
|
49
|
+
parameter "NAME", "policy name"
|
|
50
|
+
|
|
51
|
+
def execute
|
|
52
|
+
policy = kms_client.get_key_policy(key_id: id, policy_name: name)
|
|
53
|
+
policy_data = MultiJson.load(policy.policy)
|
|
54
|
+
display_data(policy_data)
|
|
55
|
+
end
|
|
56
|
+
|
|
35
57
|
end
|
|
36
58
|
|
|
37
59
|
end
|
|
@@ -40,8 +62,6 @@ module Swa
|
|
|
40
62
|
|
|
41
63
|
include CollectionBehaviour
|
|
42
64
|
|
|
43
|
-
private
|
|
44
|
-
|
|
45
65
|
def collection
|
|
46
66
|
query_for(:list_keys, :keys, Swa::KMS::Key)
|
|
47
67
|
end
|
|
@@ -61,4 +81,5 @@ module Swa
|
|
|
61
81
|
end
|
|
62
82
|
|
|
63
83
|
end
|
|
84
|
+
|
|
64
85
|
end
|
|
@@ -1,39 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "aws-sdk-lakeformation"
|
|
2
4
|
require "swa/cli/base_command"
|
|
3
5
|
require "swa/cli/collection_behaviour"
|
|
4
6
|
require "swa/cli/item_behaviour"
|
|
7
|
+
require "swa/lake_formation/data_lake_settings"
|
|
5
8
|
require "swa/lake_formation/permission"
|
|
6
9
|
require "swa/lake_formation/resource_info"
|
|
10
|
+
require "swa/lake_formation/tag"
|
|
7
11
|
|
|
8
12
|
module Swa
|
|
13
|
+
|
|
9
14
|
module CLI
|
|
10
15
|
|
|
11
16
|
class LakeFormationCommand < BaseCommand
|
|
12
17
|
|
|
18
|
+
subcommand ["data-lake-settings", "settings"], "Show Data Lake Settings" do
|
|
19
|
+
|
|
20
|
+
self.default_subcommand = "data"
|
|
21
|
+
|
|
22
|
+
include ItemBehaviour
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def item
|
|
27
|
+
Swa::LakeFormation::DataLakeSettings.new(lf_client.get_data_lake_settings.data_lake_settings)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def execute
|
|
31
|
+
display_data(stringify_keys(response.data_lake_settings.to_h))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
subcommand ["lf-tags", "tags"], "Show LF-Tags" do
|
|
37
|
+
|
|
38
|
+
self.description = <<-EOF
|
|
39
|
+
List LF-Tags.
|
|
40
|
+
EOF
|
|
41
|
+
|
|
42
|
+
include CollectionBehaviour
|
|
43
|
+
|
|
44
|
+
def collection
|
|
45
|
+
query_for(:list_lf_tags, :lf_tags, Swa::LakeFormation::Tag)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
13
49
|
subcommand ["permissions"], "Show permissions" do
|
|
14
50
|
|
|
15
51
|
self.description = <<-EOF
|
|
16
52
|
List permissions.
|
|
17
53
|
EOF
|
|
18
54
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
option ["--type", "-T"], "TYPE", "Resource type" do |value|
|
|
22
|
-
value = value.upcase
|
|
23
|
-
raise ArgumentError, "Invalid resource type: #{value}" unless ALLOWED_RESOURCE_TYPES.include?(value)
|
|
24
|
-
value
|
|
55
|
+
option ["--resource", "-R"], "DATABASE[.TABLE]", "Resource", attribute_name: :resource_filter do |value|
|
|
56
|
+
parse_resource_filter(value)
|
|
25
57
|
end
|
|
26
58
|
|
|
27
|
-
|
|
59
|
+
option ["--principal", "-P"], "ARN", "Principal ARN"
|
|
28
60
|
|
|
29
|
-
|
|
61
|
+
include CollectionBehaviour
|
|
30
62
|
|
|
31
63
|
def collection
|
|
32
64
|
query_args = {}
|
|
33
|
-
query_args[:
|
|
65
|
+
query_args[:resource] = resource_filter if resource_filter
|
|
66
|
+
if principal
|
|
67
|
+
query_args[:principal] = {
|
|
68
|
+
data_lake_principal_identifier: principal
|
|
69
|
+
}
|
|
70
|
+
end
|
|
34
71
|
query_for(:list_permissions, :principal_resource_permissions, Swa::LakeFormation::Permission, **query_args)
|
|
35
72
|
end
|
|
36
73
|
|
|
74
|
+
def parse_resource_filter(value)
|
|
75
|
+
case value
|
|
76
|
+
when /\A(\w+)\z/
|
|
77
|
+
{
|
|
78
|
+
database: {
|
|
79
|
+
name: value
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
when /\A(\w+)\.(\w+|\*)\z/
|
|
83
|
+
{
|
|
84
|
+
table: {
|
|
85
|
+
database_name: ::Regexp.last_match(1),
|
|
86
|
+
name: ::Regexp.last_match(2)
|
|
87
|
+
}
|
|
88
|
+
}.tap do |filter|
|
|
89
|
+
if ::Regexp.last_match(2) == "*"
|
|
90
|
+
filter[:table].delete(:name)
|
|
91
|
+
filter[:table][:table_wildcard] = {}
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
raise ArgumentError, "Invalid resource filter: #{value.inspect}"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
37
99
|
end
|
|
38
100
|
|
|
39
101
|
subcommand ["resources"], "Show resources" do
|
|
@@ -44,8 +106,6 @@ module Swa
|
|
|
44
106
|
|
|
45
107
|
include CollectionBehaviour
|
|
46
108
|
|
|
47
|
-
private
|
|
48
|
-
|
|
49
109
|
def collection
|
|
50
110
|
query_for(:list_resources, :resource_info_list, Swa::LakeFormation::ResourceInfo)
|
|
51
111
|
end
|
|
@@ -65,4 +125,5 @@ module Swa
|
|
|
65
125
|
end
|
|
66
126
|
|
|
67
127
|
end
|
|
128
|
+
|
|
68
129
|
end
|
data/lib/swa/cli/main_command.rb
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "swa/cli/base_command"
|
|
2
4
|
require "swa/cli/athena_command"
|
|
3
5
|
require "swa/cli/cloud_formation_command"
|
|
6
|
+
require "swa/cli/cloudtrail_command"
|
|
4
7
|
require "swa/cli/ec2_command"
|
|
5
8
|
require "swa/cli/elb_command"
|
|
6
9
|
require "swa/cli/glue_command"
|
|
@@ -10,25 +13,27 @@ require "swa/cli/lake_formation_command"
|
|
|
10
13
|
require "swa/cli/s3_command"
|
|
11
14
|
|
|
12
15
|
module Swa
|
|
16
|
+
|
|
13
17
|
module CLI
|
|
14
18
|
|
|
15
19
|
class MainCommand < BaseCommand
|
|
16
20
|
|
|
17
21
|
subcommand "athena", "Athena stuff", AthenaCommand
|
|
18
|
-
subcommand [
|
|
22
|
+
subcommand %w[cf cloudformation], "CloudFormation stuff", CloudFormationCommand
|
|
23
|
+
subcommand "cloudtrail", "CloudTrail stuff", CloudtrailCommand
|
|
19
24
|
subcommand "ec2", "EC2 stuff", Ec2Command
|
|
20
25
|
subcommand "elb", "elb stuff", ElbCommand
|
|
21
26
|
subcommand "glue", "Glue stuff", GlueCommand
|
|
22
27
|
subcommand "iam", "IAM stuff", IamCommand
|
|
23
28
|
subcommand "kms", "KMS stuff", KmsCommand
|
|
24
|
-
subcommand [
|
|
29
|
+
subcommand %w[lf lakeformation], "LakeFormation stuff", LakeFormationCommand
|
|
25
30
|
subcommand "s3", "S3 stuff", S3Command
|
|
26
31
|
|
|
27
32
|
protected
|
|
28
33
|
|
|
29
34
|
RESOURCE_PREFIXES_BY_SERVICE = {
|
|
30
|
-
"ec2" => %w
|
|
31
|
-
}
|
|
35
|
+
"ec2" => %w[ami i sg subnet vpc]
|
|
36
|
+
}.freeze
|
|
32
37
|
|
|
33
38
|
def subcommand_for_prefix(prefix)
|
|
34
39
|
RESOURCE_PREFIXES_BY_SERVICE.each do |subcommand, prefixes|
|
|
@@ -39,16 +44,20 @@ module Swa
|
|
|
39
44
|
def parse_parameters
|
|
40
45
|
case remaining_arguments.first
|
|
41
46
|
when /^(\w+)-/
|
|
42
|
-
subcommand = subcommand_for_prefix(
|
|
47
|
+
subcommand = subcommand_for_prefix(::Regexp.last_match(1))
|
|
43
48
|
remaining_arguments.unshift(subcommand) if subcommand
|
|
44
49
|
when %r{^s3://([^/]+)/(.+/)?$}
|
|
45
|
-
remaining_arguments[0, 1] =
|
|
50
|
+
remaining_arguments[0, 1] =
|
|
51
|
+
["s3", "bucket", ::Regexp.last_match(1), "objects", "--prefix", ::Regexp.last_match(2)]
|
|
46
52
|
when %r{^s3://([^/]+)/(.+)\*$}
|
|
47
|
-
remaining_arguments[0, 1] =
|
|
53
|
+
remaining_arguments[0, 1] =
|
|
54
|
+
["s3", "bucket", ::Regexp.last_match(1), "objects", "--prefix", ::Regexp.last_match(2)]
|
|
48
55
|
when %r{^s3://([^/]+)/(.+)$}
|
|
49
|
-
remaining_arguments[0, 1] = ["s3", "bucket",
|
|
56
|
+
remaining_arguments[0, 1] = ["s3", "bucket", ::Regexp.last_match(1), "object", ::Regexp.last_match(2)]
|
|
50
57
|
when %r{^s3://([^/]+)$}
|
|
51
|
-
remaining_arguments[0, 1] = ["s3", "bucket",
|
|
58
|
+
remaining_arguments[0, 1] = ["s3", "bucket", ::Regexp.last_match(1)]
|
|
59
|
+
when %r{^arn:aws:iam::.*:policy/}
|
|
60
|
+
remaining_arguments.unshift("iam", "policy")
|
|
52
61
|
end
|
|
53
62
|
super
|
|
54
63
|
end
|
|
@@ -56,4 +65,5 @@ module Swa
|
|
|
56
65
|
end
|
|
57
66
|
|
|
58
67
|
end
|
|
68
|
+
|
|
59
69
|
end
|
data/lib/swa/cli/s3_command.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "aws-sdk-s3"
|
|
2
4
|
require "swa/cli/base_command"
|
|
3
5
|
require "swa/cli/collection_behaviour"
|
|
@@ -7,13 +9,14 @@ require "swa/s3/bucket"
|
|
|
7
9
|
require "swa/s3/object"
|
|
8
10
|
|
|
9
11
|
module Swa
|
|
12
|
+
|
|
10
13
|
module CLI
|
|
11
14
|
|
|
12
15
|
class S3Command < BaseCommand
|
|
13
16
|
|
|
14
17
|
subcommand "bucket", "Show bucket" do
|
|
15
18
|
|
|
16
|
-
parameter "NAME", "bucket name", :
|
|
19
|
+
parameter "NAME", "bucket name", attribute_name: :bucket_name
|
|
17
20
|
|
|
18
21
|
include ItemBehaviour
|
|
19
22
|
|
|
@@ -33,23 +36,39 @@ module Swa
|
|
|
33
36
|
|
|
34
37
|
alias_method :item, :bucket
|
|
35
38
|
|
|
39
|
+
subcommand "arn", "Display ARN" do
|
|
40
|
+
|
|
41
|
+
def execute
|
|
42
|
+
puts "arn:aws:s3:::#{bucket_name}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
36
47
|
subcommand "object", "Show object" do
|
|
37
48
|
|
|
38
|
-
parameter "KEY", "object key", :
|
|
49
|
+
parameter "KEY", "object key", attribute_name: :object_key
|
|
39
50
|
|
|
40
51
|
include ItemBehaviour
|
|
41
52
|
|
|
53
|
+
subcommand "arn", "Display ARN" do
|
|
54
|
+
|
|
55
|
+
def execute
|
|
56
|
+
puts "arn:aws:s3:::#{bucket_name}/#{object_key}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
42
61
|
subcommand "get", "GET object" do
|
|
43
62
|
|
|
44
63
|
def execute
|
|
45
|
-
IO.copy_stream(object.
|
|
64
|
+
IO.copy_stream(object.body, $stdout)
|
|
46
65
|
end
|
|
47
66
|
|
|
48
67
|
end
|
|
49
68
|
|
|
50
69
|
subcommand "put", "PUT object" do
|
|
51
70
|
|
|
52
|
-
parameter "[PAYLOAD]", "data", :
|
|
71
|
+
parameter "[PAYLOAD]", "data", default: "STDIN"
|
|
53
72
|
|
|
54
73
|
def execute
|
|
55
74
|
object.put(payload)
|
|
@@ -65,7 +84,7 @@ module Swa
|
|
|
65
84
|
|
|
66
85
|
subcommand "upload", "Upload file" do
|
|
67
86
|
|
|
68
|
-
parameter "FILE", "file name", :
|
|
87
|
+
parameter "FILE", "file name", attribute_name: :file_name
|
|
69
88
|
|
|
70
89
|
def execute
|
|
71
90
|
object.upload_from(file_name)
|
|
@@ -75,15 +94,13 @@ module Swa
|
|
|
75
94
|
|
|
76
95
|
subcommand "download", "download object to local file" do
|
|
77
96
|
|
|
78
|
-
option %w
|
|
97
|
+
option %w[-T --to], "TARGET", "file or directory to download into", default: ".", attribute_name: :target
|
|
79
98
|
|
|
80
99
|
def execute
|
|
81
100
|
object.download_into(target_file_path, &method(:log_download_progress))
|
|
82
101
|
logger.info "Downloaded to #{target_file_path}"
|
|
83
102
|
end
|
|
84
103
|
|
|
85
|
-
private
|
|
86
|
-
|
|
87
104
|
def target_file_path
|
|
88
105
|
if File.directory?(target)
|
|
89
106
|
File.join(target, File.basename(object_key))
|
|
@@ -105,29 +122,27 @@ module Swa
|
|
|
105
122
|
|
|
106
123
|
subcommand ["version", "v"], "Show version" do
|
|
107
124
|
|
|
108
|
-
parameter "ID", "object version ID", :
|
|
125
|
+
parameter "ID", "object version ID", attribute_name: :version_id
|
|
109
126
|
|
|
110
127
|
include ItemBehaviour
|
|
111
128
|
|
|
112
129
|
subcommand "get", "GET object" do
|
|
113
130
|
|
|
114
131
|
def execute
|
|
115
|
-
IO.copy_stream(version.
|
|
132
|
+
IO.copy_stream(version.body, $stdout)
|
|
116
133
|
end
|
|
117
134
|
|
|
118
135
|
end
|
|
119
136
|
|
|
120
137
|
subcommand "download", "download version to local file" do
|
|
121
138
|
|
|
122
|
-
option %w
|
|
139
|
+
option %w[-T --to], "TARGET", "file or directory to download into", default: ".", attribute_name: :target
|
|
123
140
|
|
|
124
141
|
def execute
|
|
125
142
|
version.download_into(target_file_path)
|
|
126
143
|
logger.info "Downloaded to #{target_file_path}"
|
|
127
144
|
end
|
|
128
145
|
|
|
129
|
-
private
|
|
130
|
-
|
|
131
146
|
def target_file_path
|
|
132
147
|
if File.directory?(target)
|
|
133
148
|
File.join(target, File.basename(object_key))
|
|
@@ -152,16 +167,12 @@ module Swa
|
|
|
152
167
|
|
|
153
168
|
include CollectionBehaviour
|
|
154
169
|
|
|
155
|
-
protected
|
|
156
|
-
|
|
157
170
|
def collection
|
|
158
|
-
bucket.object_versions(:
|
|
171
|
+
bucket.object_versions(prefix: object_key)
|
|
159
172
|
end
|
|
160
173
|
|
|
161
174
|
end
|
|
162
175
|
|
|
163
|
-
protected
|
|
164
|
-
|
|
165
176
|
def object
|
|
166
177
|
Swa::S3::Object.new(aws_bucket.object(object_key))
|
|
167
178
|
end
|
|
@@ -178,7 +189,7 @@ module Swa
|
|
|
178
189
|
|
|
179
190
|
subcommand ["list", "ls"], "One-line summary" do
|
|
180
191
|
|
|
181
|
-
option %w
|
|
192
|
+
option %w[-R --recursive], :flag, "list recursively"
|
|
182
193
|
|
|
183
194
|
def execute
|
|
184
195
|
delimiter = "/" unless recursive?
|
|
@@ -210,8 +221,6 @@ module Swa
|
|
|
210
221
|
|
|
211
222
|
end
|
|
212
223
|
|
|
213
|
-
protected
|
|
214
|
-
|
|
215
224
|
def objects
|
|
216
225
|
bucket.objects(prefix: prefix)
|
|
217
226
|
end
|
|
@@ -255,10 +264,8 @@ module Swa
|
|
|
255
264
|
|
|
256
265
|
end
|
|
257
266
|
|
|
258
|
-
protected
|
|
259
|
-
|
|
260
267
|
def versions
|
|
261
|
-
bucket.object_versions(:
|
|
268
|
+
bucket.object_versions(prefix: prefix)
|
|
262
269
|
end
|
|
263
270
|
|
|
264
271
|
end
|
|
@@ -314,4 +321,5 @@ module Swa
|
|
|
314
321
|
end
|
|
315
322
|
|
|
316
323
|
end
|
|
324
|
+
|
|
317
325
|
end
|