rezept 0.0.2 → 0.1.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/CHANGELOG.md +13 -0
- data/Docfile +8 -23
- data/README.md +35 -6
- data/lib/rezept/actions.rb +79 -0
- data/lib/rezept/cli.rb +13 -2
- data/lib/rezept/client.rb +35 -1
- data/lib/rezept/logger.rb +2 -2
- data/lib/rezept/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a084f39244aeebaf00fd8d2307de6c7dd189a4e5
|
4
|
+
data.tar.gz: f6b24452efdbdf3798883f4be75515d6b57ee779
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce615a416a985a938879af31ca0f6d6628c3b86f446a94bd5a0379066c6cad75506387b50ee54438a6f75b7a638515c6b6a40b80aa19ab549f24190fec4e570b
|
7
|
+
data.tar.gz: 796d1a2eab98ee9ca2bf847126a67b416f5f4ca778f3e4c1ba589083555f07c82cb055109cbceff53023a877f312828d05e6b8b112c672901984b4aeadfba116
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
## 0.1.0
|
2
|
+
|
3
|
+
- Add `run_command` command [#1][]
|
4
|
+
- Some small fixes
|
5
|
+
|
6
|
+
## 0.0.2
|
7
|
+
|
8
|
+
- Initial release
|
9
|
+
|
10
|
+
## 0.0.1 (yunked)
|
11
|
+
|
12
|
+
<!--- The following link definition list is generated by PimpMyChangelog --->
|
13
|
+
[#1]: https://github.com/serverworks/rezept/issues/1
|
data/Docfile
CHANGED
@@ -9,7 +9,8 @@ template "runShellScriptTemplate" do
|
|
9
9
|
action "aws:runShellScript"
|
10
10
|
name "runShellScript"
|
11
11
|
inputs do
|
12
|
-
|
12
|
+
runCommand __script(context.commands)
|
13
|
+
TimeoutSeconds 10
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
@@ -18,7 +19,7 @@ end
|
|
18
19
|
|
19
20
|
Command "My-RunShellScript" do
|
20
21
|
account_ids []
|
21
|
-
include_template "runShellScriptTemplate", commands: "echo 1"
|
22
|
+
include_template "runShellScriptTemplate", commands: "echo 1 >> /tmp/result.txt"
|
22
23
|
end
|
23
24
|
|
24
25
|
Command "My-RunShellScript-2" do
|
@@ -31,29 +32,13 @@ Command "My-RunShellScript-2" do
|
|
31
32
|
action "aws:runShellScript"
|
32
33
|
name "runShellScript"
|
33
34
|
inputs do
|
34
|
-
|
35
|
+
runCommand __script(<<-'EOS')
|
35
36
|
#! /bin/bash
|
36
|
-
echo 1
|
37
|
-
echo 2
|
38
|
-
|
37
|
+
echo 1 >> /tmp/results.txt
|
38
|
+
echo 2 >> /tmp/results.txt
|
39
|
+
exit 1
|
39
40
|
EOS
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
Command "My-RunShellScript-3" do
|
47
|
-
account_ids []
|
48
|
-
content do
|
49
|
-
__dsl do
|
50
|
-
schemaVersion "2.0"
|
51
|
-
description "Run a shell script"
|
52
|
-
mainSteps do |*|
|
53
|
-
action "aws:runShellScript"
|
54
|
-
name "runShellScript"
|
55
|
-
inputs do
|
56
|
-
commands __script_file("script.sh")
|
41
|
+
TimeoutSeconds 10
|
57
42
|
end
|
58
43
|
end
|
59
44
|
end
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Rezept
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/rezept)
|
4
|
+
|
3
5
|
A tool to manage EC2 Systems Manager (SSM) Documents with programmable DSL.
|
4
6
|
|
5
7
|
## Installation
|
@@ -101,6 +103,33 @@ Options:
|
|
101
103
|
# Default: true
|
102
104
|
```
|
103
105
|
|
106
|
+
#### run_command
|
107
|
+
Run the commands
|
108
|
+
|
109
|
+
```
|
110
|
+
$ rezept help run_command
|
111
|
+
Usage:
|
112
|
+
rezept run_command -n, --name=NAME
|
113
|
+
|
114
|
+
Options:
|
115
|
+
-n, --name=NAME # Name of the document
|
116
|
+
-i, [--instance-ids=one two three] # EC2 Instance IDs
|
117
|
+
-t, [--tags=key:value] # EC2 Instance tags
|
118
|
+
-p, [--parameters=key:value] # Parameters for the document
|
119
|
+
[--dry-run], [--no-dry-run] # Dry run (Only output the targets)
|
120
|
+
[--wait], [--no-wait] # Wait and check for all results
|
121
|
+
-f, [--file=FILE] # Configuration file
|
122
|
+
# Default: Docfile
|
123
|
+
[--color], [--no-color] # Disable colorize
|
124
|
+
# Default: true
|
125
|
+
[--amazon-docs], [--no-amazon-docs] # Include Amazon owned documents
|
126
|
+
[--dsl-content], [--no-dsl-content] # Convert JSON contents to DSL
|
127
|
+
# Default: true
|
128
|
+
```
|
129
|
+
|
130
|
+
- If you specify multiple values to `tags` and `parameters`, separate them with commas(`,`).
|
131
|
+
- When you use the `wait` option, the exit code will be `0` if the commands succeed on the all instances, else it will be `1`.
|
132
|
+
|
104
133
|
## Advanced methods
|
105
134
|
|
106
135
|
#### Script styled commands (__script)
|
@@ -118,7 +147,7 @@ Command "My-RunShellScript" do
|
|
118
147
|
action "aws:runShellScript"
|
119
148
|
name "runShellScript"
|
120
149
|
inputs do
|
121
|
-
|
150
|
+
runCommand __script(<<-'EOS')
|
122
151
|
#! /bin/bash
|
123
152
|
echo 1
|
124
153
|
echo 2
|
@@ -145,7 +174,7 @@ Document Type: 'Command'
|
|
145
174
|
"action": "aws:runShellScript",
|
146
175
|
"name": "runShellScript",
|
147
176
|
"inputs": {
|
148
|
-
"
|
177
|
+
"runCommand": [
|
149
178
|
"#! /bin/bash",
|
150
179
|
"echo 1",
|
151
180
|
"echo 2",
|
@@ -172,7 +201,7 @@ Command "My-RunShellScript" do
|
|
172
201
|
action "aws:runShellScript"
|
173
202
|
name "runShellScript"
|
174
203
|
inputs do
|
175
|
-
|
204
|
+
runCommand __script_file("script.sh")
|
176
205
|
end
|
177
206
|
end
|
178
207
|
end
|
@@ -203,7 +232,7 @@ Document Type: 'Command'
|
|
203
232
|
"action": "aws:runShellScript",
|
204
233
|
"name": "runShellScript",
|
205
234
|
"inputs": {
|
206
|
-
"
|
235
|
+
"runCommand": [
|
207
236
|
"#! /bin/bash",
|
208
237
|
"echo 1",
|
209
238
|
"echo 2",
|
@@ -229,7 +258,7 @@ template "runShellScriptTemplate" do
|
|
229
258
|
action "aws:runShellScript"
|
230
259
|
name "runShellScript"
|
231
260
|
inputs do
|
232
|
-
|
261
|
+
runCommand __script(context.commands)
|
233
262
|
end
|
234
263
|
end
|
235
264
|
end
|
@@ -256,7 +285,7 @@ Document Type: 'Command'
|
|
256
285
|
"action": "aws:runShellScript",
|
257
286
|
"name": "runShellScript",
|
258
287
|
"inputs": {
|
259
|
-
"
|
288
|
+
"runCommand": [
|
260
289
|
"echo 1"
|
261
290
|
]
|
262
291
|
}
|
data/lib/rezept/actions.rb
CHANGED
@@ -72,6 +72,85 @@ module Rezept
|
|
72
72
|
_export_file(ret, options['output']) unless options['output'].nil?
|
73
73
|
end
|
74
74
|
|
75
|
+
def run_command(options)
|
76
|
+
dry_run = options['dry_run'] ? '[Dry run] ' : ''
|
77
|
+
|
78
|
+
if options['instance_ids'].nil? and options['tags'].nil?
|
79
|
+
raise "Please specify the targets (--instance-ids/-i' or '--target-tags/-t')"
|
80
|
+
end
|
81
|
+
|
82
|
+
instances = @client.get_target_instances(
|
83
|
+
options['instance_ids'],
|
84
|
+
_tags_to_criteria(options['tags'], 'name')
|
85
|
+
)
|
86
|
+
info("#{dry_run}Target instances...")
|
87
|
+
instances.each do |instance|
|
88
|
+
name_tag = instance.tags.select {|i| i.key == 'Name'}
|
89
|
+
if name_tag.empty?
|
90
|
+
info("- #{instance.instance_id}")
|
91
|
+
else
|
92
|
+
info("- #{name_tag[0].value} (#{instance.instance_id})")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
if dry_run.empty?
|
97
|
+
command = @client.run_command(
|
98
|
+
options['name'],
|
99
|
+
options['instance_ids'],
|
100
|
+
_tags_to_criteria(options['tags'], 'key'),
|
101
|
+
_convert_paraeters(options['parameters'])
|
102
|
+
)
|
103
|
+
_wait_all_results(command.command_id) if options['wait']
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def _tags_to_criteria(targets, key_name)
|
108
|
+
return nil if targets.nil?
|
109
|
+
ret = []
|
110
|
+
targets.each {|k,v| ret << {key_name => "tag:#{k}", 'values' => v.split(',')} }
|
111
|
+
ret
|
112
|
+
end
|
113
|
+
|
114
|
+
def _convert_paraeters(parameters)
|
115
|
+
return nil if parameters.nil?
|
116
|
+
ret = {}
|
117
|
+
parameters.each do |k,v|
|
118
|
+
ret[k] = v.split(',')
|
119
|
+
end
|
120
|
+
ret
|
121
|
+
end
|
122
|
+
|
123
|
+
def _wait_all_results(command_id)
|
124
|
+
info("Wait for all results...")
|
125
|
+
|
126
|
+
done = false
|
127
|
+
failure = false
|
128
|
+
done_instances = []
|
129
|
+
|
130
|
+
until done do
|
131
|
+
sleep 1
|
132
|
+
invocations = @client.list_command_invocations(command_id)
|
133
|
+
invocations.each do |invocation|
|
134
|
+
break if done_instances.include?(invocation.instance_id)
|
135
|
+
unless ['Pending', 'InProgress'].include?(invocation.status)
|
136
|
+
case invocation.status
|
137
|
+
when 'Success'
|
138
|
+
info("- #{invocation.instance_id} => #{invocation.status}")
|
139
|
+
when 'Delayed'
|
140
|
+
warn("- #{invocation.instance_id} => #{invocation.status}")
|
141
|
+
else
|
142
|
+
fatal("- #{invocation.instance_id} => #{invocation.status}")
|
143
|
+
failure = true
|
144
|
+
end
|
145
|
+
done_instances << invocation.instance_id
|
146
|
+
done = true if done_instances.length == invocations.length
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
exit(1) if failure
|
152
|
+
end
|
153
|
+
|
75
154
|
def _apply_docs(local, remote, dry_run)
|
76
155
|
local.each do |l|
|
77
156
|
l_ids = l.delete('account_ids')
|
data/lib/rezept/cli.rb
CHANGED
@@ -29,12 +29,23 @@ module Rezept
|
|
29
29
|
end
|
30
30
|
|
31
31
|
desc "convert", "Convert the documents to the other format"
|
32
|
-
option :name, aliases: '-n', desc: 'Name of document', type: :string, required: true
|
33
|
-
option :type, aliases: '-t', desc: 'Type of document (Command|Automation)', type: :string, required: true
|
32
|
+
option :name, aliases: '-n', desc: 'Name of the document', type: :string, required: true
|
33
|
+
option :type, aliases: '-t', desc: 'Type of the document (Command|Automation)', type: :string, required: true
|
34
34
|
option :format, desc: 'Output format (json|ruby)', type: :string
|
35
35
|
option :output, aliases: '-o', desc: 'Output filename (path)', type: :string
|
36
36
|
def convert
|
37
37
|
@actions.convert(options)
|
38
38
|
end
|
39
|
+
|
40
|
+
desc "run_command", "Run the commands"
|
41
|
+
option :name, aliases: '-n', desc: 'Name of the document', type: :string, required: true
|
42
|
+
option :instance_ids, aliases: '-i', desc: 'EC2 Instance IDs', type: :array
|
43
|
+
option :tags, aliases: '-t', desc: 'EC2 Instance tags', type: :hash
|
44
|
+
option :parameters, aliases: '-p', desc: 'Parameters for the document', type: :hash
|
45
|
+
option :dry_run, desc: 'Dry run (Only output the targets)', type: :boolean, default: false
|
46
|
+
option :wait, desc: 'Wait and check for all results', type: :boolean, default: false
|
47
|
+
def run_command
|
48
|
+
@actions.run_command(options)
|
49
|
+
end
|
39
50
|
end
|
40
51
|
end
|
data/lib/rezept/client.rb
CHANGED
@@ -5,6 +5,7 @@ module Rezept
|
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
@ssm = Aws::SSM::Client.new
|
8
|
+
@ec2 = Aws::EC2::Client.new
|
8
9
|
end
|
9
10
|
|
10
11
|
def set_options(options)
|
@@ -57,7 +58,40 @@ module Rezept
|
|
57
58
|
name: doc['name'],
|
58
59
|
permission_type: 'Share',
|
59
60
|
account_ids_to_add: add_ids,
|
60
|
-
account_ids_to_remove: rm_ids
|
61
|
+
account_ids_to_remove: rm_ids
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_target_instances(instance_ids, filters, next_token=nil)
|
66
|
+
instances = []
|
67
|
+
|
68
|
+
ret = @ec2.describe_instances(
|
69
|
+
instance_ids: instance_ids,
|
70
|
+
filters: filters,
|
71
|
+
next_token: next_token
|
72
|
+
)
|
73
|
+
ret.reservations.each do |reservation|
|
74
|
+
instances.concat(reservation.instances)
|
75
|
+
end
|
76
|
+
|
77
|
+
instances.concat(get_target_instances(instance_ids, filters, ret.next_token)) unless ret.next_token.nil?
|
78
|
+
instances
|
79
|
+
end
|
80
|
+
|
81
|
+
def run_command(name, instance_ids, targets, parameters)
|
82
|
+
@ssm.send_command(
|
83
|
+
document_name: name,
|
84
|
+
instance_ids: instance_ids,
|
85
|
+
targets: targets,
|
86
|
+
parameters: parameters
|
87
|
+
).command
|
88
|
+
end
|
89
|
+
|
90
|
+
def list_command_invocations(command_id, next_token=nil)
|
91
|
+
ret = @ssm.list_command_invocations(command_id: command_id)
|
92
|
+
invocations = ret.command_invocations
|
93
|
+
invocations.concat(list_command_invocations(command_id, ret.next_token)) unless ret.next_token.nil?
|
94
|
+
invocations
|
61
95
|
end
|
62
96
|
|
63
97
|
end
|
data/lib/rezept/logger.rb
CHANGED
@@ -53,8 +53,8 @@ module Rezept
|
|
53
53
|
super { Rezept::TermColor.red(msg) }
|
54
54
|
end
|
55
55
|
|
56
|
-
def error(
|
57
|
-
super
|
56
|
+
def error(msg)
|
57
|
+
super { Rezept::TermColor.red(msg) }
|
58
58
|
end
|
59
59
|
|
60
60
|
module Helper
|
data/lib/rezept/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rezept
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Serverworks Co.,Ltd.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -148,6 +148,7 @@ files:
|
|
148
148
|
- ".gitignore"
|
149
149
|
- ".rspec"
|
150
150
|
- ".travis.yml"
|
151
|
+
- CHANGELOG.md
|
151
152
|
- Docfile
|
152
153
|
- Gemfile
|
153
154
|
- LICENSE.txt
|