sonic-screwdriver 2.1.1 → 2.2.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
  SHA256:
3
- metadata.gz: '04708ff866e88a9752050a4928b3109948086ee0fe24594fffbc6ee04de03b8a'
4
- data.tar.gz: 4f09a1cce6b42c121205b002da04dbe9d56292514ae597ed5ba2921e38ecba86
3
+ metadata.gz: 95e79b9c9806e506eb5630a849af60ce17517059460e98949c54a75f741b4639
4
+ data.tar.gz: 8723c524148eb771d887fb79bc5aca90b3aaa322c71ba14de11cd4c69c6d1c98
5
5
  SHA512:
6
- metadata.gz: 33433f9fa8025cff559255beb2ec9f107ca7dc1a11643fd3d145f5cc96d2dcc1c7dadbef74d3c4ca689590f3300d200f6c480e75b48dab271c046f751aaa2d19
7
- data.tar.gz: 1d58617e51a1383af495d763270a79fddaa25f2c28fceb97940bdff5fae3f22cfe94e0eac6cf2ec6cbc25c3af3d0f9a5e16dd5738b91a5d28700000569098515
6
+ metadata.gz: 977d962d7ef3e133d055ecf252a8d93b33403daa7f09b0d21c31ddc7720a5a0eb4ea9ff418c3c3705eca0be4f1035efcae06c3f7fb15e7da0e42cdb82f6bcc2c
7
+ data.tar.gz: 23c9dfa55f8a04cbffcd0c2997bb89cc52f465d0af27d4cbeb5b93bd52c9d4ec801150e4593abda76428591ef53049c2937cdaee87a38484955907969b05c997
@@ -7,7 +7,7 @@ jobs:
7
7
  build:
8
8
  docker:
9
9
  # specify the version you desire here
10
- - image: circleci/ruby:2.5.1-node-browsers
10
+ - image: circleci/ruby:2.6.5-node-browsers
11
11
 
12
12
  # Specify service dependencies here if necessary
13
13
  # CircleCI maintains a library of pre-built images
@@ -35,6 +35,8 @@ jobs:
35
35
  - run:
36
36
  name: install dependencies
37
37
  command: |
38
+ gem install bundler
39
+ gem update --system
38
40
  bundle install --jobs=4 --retry=3 --path vendor/bundle
39
41
 
40
42
  - save_cache:
data/.gitignore CHANGED
@@ -14,3 +14,4 @@ spec/reports
14
14
  test/tmp
15
15
  test/version_tmp
16
16
  tmp
17
+ Gemfile.lock
@@ -1,7 +1,13 @@
1
1
  # Change Log
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
- This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
4
+ This project *loosely* adheres to [Semantic Versioning](http://semver.org/), even before v1.0.
5
+
6
+ ## [2.2.0]
7
+ - #7 sonic execute command: `--tags` and `--instance-id` options instead of polymorphic list. Breaking behavior.
8
+ - display output even if tags used
9
+ - configure default log group
10
+ - correct exit status
5
11
 
6
12
  ## [2.1.1]
7
13
  - use rainbow gem for terminal colors
@@ -16,47 +16,49 @@ PATH
16
16
  GEM
17
17
  remote: https://rubygems.org/
18
18
  specs:
19
- activesupport (5.2.2)
19
+ activesupport (6.0.2.1)
20
20
  concurrent-ruby (~> 1.0, >= 1.0.2)
21
21
  i18n (>= 0.7, < 2)
22
22
  minitest (~> 5.1)
23
23
  tzinfo (~> 1.1)
24
- aws-eventstream (1.0.1)
25
- aws-partitions (1.135.0)
26
- aws-sdk-core (3.46.0)
27
- aws-eventstream (~> 1.0)
28
- aws-partitions (~> 1.0)
29
- aws-sigv4 (~> 1.0)
24
+ zeitwerk (~> 2.2)
25
+ aws-eventstream (1.0.3)
26
+ aws-partitions (1.275.0)
27
+ aws-sdk-core (3.90.1)
28
+ aws-eventstream (~> 1.0, >= 1.0.2)
29
+ aws-partitions (~> 1, >= 1.239.0)
30
+ aws-sigv4 (~> 1.1)
30
31
  jmespath (~> 1.0)
31
- aws-sdk-ec2 (1.67.0)
32
- aws-sdk-core (~> 3, >= 3.39.0)
33
- aws-sigv4 (~> 1.0)
34
- aws-sdk-ecs (1.28.0)
35
- aws-sdk-core (~> 3, >= 3.39.0)
36
- aws-sigv4 (~> 1.0)
37
- aws-sdk-kms (1.13.0)
38
- aws-sdk-core (~> 3, >= 3.39.0)
39
- aws-sigv4 (~> 1.0)
40
- aws-sdk-s3 (1.30.1)
41
- aws-sdk-core (~> 3, >= 3.39.0)
32
+ aws-sdk-ec2 (1.144.0)
33
+ aws-sdk-core (~> 3, >= 3.71.0)
34
+ aws-sigv4 (~> 1.1)
35
+ aws-sdk-ecs (1.57.0)
36
+ aws-sdk-core (~> 3, >= 3.71.0)
37
+ aws-sigv4 (~> 1.1)
38
+ aws-sdk-kms (1.29.0)
39
+ aws-sdk-core (~> 3, >= 3.71.0)
40
+ aws-sigv4 (~> 1.1)
41
+ aws-sdk-s3 (1.60.2)
42
+ aws-sdk-core (~> 3, >= 3.83.0)
42
43
  aws-sdk-kms (~> 1)
43
- aws-sigv4 (~> 1.0)
44
- aws-sdk-ssm (1.35.0)
45
- aws-sdk-core (~> 3, >= 3.39.0)
46
- aws-sigv4 (~> 1.0)
47
- aws-sigv4 (1.0.3)
48
- byebug (10.0.2)
44
+ aws-sigv4 (~> 1.1)
45
+ aws-sdk-ssm (1.71.0)
46
+ aws-sdk-core (~> 3, >= 3.71.0)
47
+ aws-sigv4 (~> 1.1)
48
+ aws-sigv4 (1.1.0)
49
+ aws-eventstream (~> 1.0, >= 1.0.2)
50
+ byebug (11.1.1)
49
51
  cli_markdown (0.1.0)
50
52
  codeclimate-test-reporter (1.0.9)
51
53
  simplecov (<= 0.13)
52
54
  coderay (1.1.2)
53
- concurrent-ruby (1.1.4)
55
+ concurrent-ruby (1.1.6)
54
56
  diff-lcs (1.3)
55
57
  docile (1.1.5)
56
- equatable (0.5.0)
57
- ffi (1.10.0)
58
+ equatable (0.6.1)
59
+ ffi (1.12.2)
58
60
  formatador (0.2.5)
59
- guard (2.15.0)
61
+ guard (2.16.1)
60
62
  formatador (>= 0.2.4)
61
63
  listen (>= 2.7, < 4.0)
62
64
  lumberjack (>= 1.0.12, < 2.0)
@@ -65,8 +67,8 @@ GEM
65
67
  pry (>= 0.9.12)
66
68
  shellany (~> 0.0)
67
69
  thor (>= 0.18.1)
68
- guard-bundler (2.2.1)
69
- bundler (>= 1.3.0, < 3)
70
+ guard-bundler (3.0.0)
71
+ bundler (>= 2.1, < 3)
70
72
  guard (~> 2.2)
71
73
  guard-compat (~> 1.1)
72
74
  guard-compat (1.2.1)
@@ -74,74 +76,70 @@ GEM
74
76
  guard (~> 2.1)
75
77
  guard-compat (~> 1.1)
76
78
  rspec (>= 2.99.0, < 4.0)
77
- hashie (3.6.0)
78
- i18n (1.5.3)
79
+ hashie (4.1.0)
80
+ i18n (1.8.2)
79
81
  concurrent-ruby (~> 1.0)
80
82
  jmespath (1.4.0)
81
- json (2.1.0)
82
- listen (3.1.5)
83
- rb-fsevent (~> 0.9, >= 0.9.4)
84
- rb-inotify (~> 0.9, >= 0.9.7)
85
- ruby_dep (~> 1.2)
86
- lumberjack (1.0.13)
87
- memoist (0.16.0)
83
+ json (2.3.0)
84
+ listen (3.2.1)
85
+ rb-fsevent (~> 0.10, >= 0.10.3)
86
+ rb-inotify (~> 0.9, >= 0.9.10)
87
+ lumberjack (1.2.4)
88
+ memoist (0.16.2)
88
89
  method_source (0.9.2)
89
- minitest (5.11.3)
90
- necromancer (0.4.0)
90
+ minitest (5.14.0)
91
+ necromancer (0.5.1)
91
92
  nenv (0.3.0)
92
- notiffany (0.1.1)
93
+ notiffany (0.1.3)
93
94
  nenv (~> 0.1)
94
95
  shellany (~> 0.0)
95
- pastel (0.7.2)
96
- equatable (~> 0.5.0)
97
- tty-color (~> 0.4.0)
96
+ pastel (0.7.3)
97
+ equatable (~> 0.6)
98
+ tty-color (~> 0.5)
98
99
  pry (0.12.2)
99
100
  coderay (~> 1.1.0)
100
101
  method_source (~> 0.9.0)
101
102
  rainbow (3.0.0)
102
- rake (12.3.2)
103
+ rake (13.0.1)
103
104
  rb-fsevent (0.10.3)
104
- rb-inotify (0.10.0)
105
+ rb-inotify (0.10.1)
105
106
  ffi (~> 1.0)
106
- rspec (3.8.0)
107
- rspec-core (~> 3.8.0)
108
- rspec-expectations (~> 3.8.0)
109
- rspec-mocks (~> 3.8.0)
110
- rspec-core (3.8.0)
111
- rspec-support (~> 3.8.0)
112
- rspec-expectations (3.8.2)
107
+ rspec (3.9.0)
108
+ rspec-core (~> 3.9.0)
109
+ rspec-expectations (~> 3.9.0)
110
+ rspec-mocks (~> 3.9.0)
111
+ rspec-core (3.9.1)
112
+ rspec-support (~> 3.9.1)
113
+ rspec-expectations (3.9.0)
113
114
  diff-lcs (>= 1.2.0, < 2.0)
114
- rspec-support (~> 3.8.0)
115
- rspec-mocks (3.8.0)
115
+ rspec-support (~> 3.9.0)
116
+ rspec-mocks (3.9.1)
116
117
  diff-lcs (>= 1.2.0, < 2.0)
117
- rspec-support (~> 3.8.0)
118
- rspec-support (3.8.0)
119
- ruby_dep (1.5.0)
118
+ rspec-support (~> 3.9.0)
119
+ rspec-support (3.9.2)
120
120
  shellany (0.0.1)
121
121
  simplecov (0.13.0)
122
122
  docile (~> 1.1.0)
123
123
  json (>= 1.8, < 3)
124
124
  simplecov-html (~> 0.10.0)
125
125
  simplecov-html (0.10.2)
126
- thor (0.20.3)
126
+ thor (1.0.1)
127
127
  thread_safe (0.3.6)
128
- timers (4.3.0)
129
- tty-color (0.4.3)
130
- tty-cursor (0.6.0)
131
- tty-prompt (0.18.1)
132
- necromancer (~> 0.4.0)
128
+ tty-color (0.5.1)
129
+ tty-cursor (0.7.1)
130
+ tty-prompt (0.20.0)
131
+ necromancer (~> 0.5.0)
133
132
  pastel (~> 0.7.0)
134
- timers (~> 4.0)
135
- tty-cursor (~> 0.6.0)
136
- tty-reader (~> 0.5.0)
137
- tty-reader (0.5.0)
138
- tty-cursor (~> 0.6.0)
139
- tty-screen (~> 0.6.4)
133
+ tty-reader (~> 0.7.0)
134
+ tty-reader (0.7.0)
135
+ tty-cursor (~> 0.7)
136
+ tty-screen (~> 0.7)
140
137
  wisper (~> 2.0.0)
141
- tty-screen (0.6.5)
142
- tzinfo (1.2.5)
138
+ tty-screen (0.7.1)
139
+ tzinfo (1.2.6)
143
140
  thread_safe (~> 0.1)
144
- wisper (2.0.0)
141
+ wisper (2.0.1)
142
+ zeitwerk (2.2.2)
145
143
 
146
144
  PLATFORMS
147
145
  ruby
@@ -158,4 +156,4 @@ DEPENDENCIES
158
156
  sonic-screwdriver!
159
157
 
160
158
  BUNDLED WITH
161
- 1.17.1
159
+ 2.1.4
data/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
  [![Gitter](https://badges.gitter.im/boltopslabs/sonic.svg)](https://gitter.im/boltopslabs/sonic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
5
5
  [![Support](https://img.shields.io/badge/get-support-blue.svg)](https://boltops.com?utm_source=badge&utm_medium=badge&utm_campaign=sonic)
6
6
 
7
+ [![BoltOps Badge](https://img.boltops.com/boltops/badges/boltops-badge.png)](https://www.boltops.com)
8
+
7
9
  Sonic is a multi-functional tool that helps you manage AWS resources. Sonic contains a group of commands that help debug EC2 instances and ECS containers quickly.
8
10
 
9
11
  See [sonic-screwdriver.cloud](http://sonic-screwdriver.cloud) for full documentation.
@@ -32,15 +34,7 @@ By the time I get into the container, I need to remind my brain of what the orig
32
34
 
33
35
  You can install sonic with RubyGems
34
36
 
35
- ```sh
36
- gem install sonic
37
- ```
38
-
39
- If you want to quickly install sonic without having to worry about sonic's dependencies you can also install the Bolts Toolbelt which has sonic included.
40
-
41
- ```sh
42
- brew cask install boltopslabs/software/bolts
43
- ```
37
+ gem install sonic
44
38
 
45
39
  Full installation instructions are at [Install Sonic Screwdriver](http://sonic-screwdriver.cloud/docs/install/). There are some server side dependencies for some of the sonic commands, so it is important to read through the full installation guide.
46
40
 
@@ -48,30 +42,33 @@ Full installation instructions are at [Install Sonic Screwdriver](http://sonic-s
48
42
 
49
43
  Here is a quick overview of sonic abilities:
50
44
 
51
- ```sh
52
- # ssh into an instance
53
- sonic ssh i-0f7f833131a51ce35
54
- sonic ssh hi-web # ec2 tag
55
- sonic ssh hi-web --cluster staging # ecs service name
56
- sonic ssh hi-web --cluster staging # ecs service name
57
- sonic ssh 7fbc8c75-4675-4d39-a5a4-0395ff8cd474 --cluster staging # ECS container id
58
- sonic ssh 1ed12abd-645c-4a05-9acf-739b9d790170 --cluster staging # ECS task id
45
+ # ssh into an instance
46
+ sonic ssh i-0f7f833131a51ce35
47
+ sonic ssh demo-web # ec2 tag
48
+ sonic ssh demo-web --cluster staging # ecs service name
49
+ sonic ssh demo-web --cluster staging # ecs service name
50
+ sonic ssh 7fbc8c75-4675-4d39-a5a4-0395ff8cd474 --cluster staging # ECS container id
51
+ sonic ssh 1ed12abd-645c-4a05-9acf-739b9d790170 --cluster staging # ECS task id
52
+
53
+ # docker exec to a running ECS docker container
54
+ sonic ecs exec demo-web
59
55
 
60
- # docker exec to a running ECS docker container
61
- sonic ecs exec hi-web
56
+ # docker run with the same environment as the ECS docker running containers
57
+ sonic ecs sh demo-web
62
58
 
63
- # docker run with the same environment as the ECS docker running containers
64
- sonic ecs sh hi-web
59
+ # run command with instance ids
60
+ sonic execute --instance-ids i-111 uptime
61
+ sonic execute --instance-ids i-111,i-222 uptime
65
62
 
66
- # run command on 1 instance
67
- sonic execute i-0f7f833131a51ce35 uptime
63
+ # run command on all instances tagged with Name demo-web and worker
64
+ sonic execute --tags Name=demo-web,demo-worker uptime
68
65
 
69
- # run command on all instances tagged with hi-web and worker
70
- sonic execute hi-web,hi-worker uptime
66
+ # run command on all instances with multiple tags
67
+ # Quotes are important due to semi-colon
68
+ sonic execute --tags "Name=demo-web,demo-worker;Owner=test" uptime
71
69
 
72
- # list ec2 instances
73
- sonic list hi-web
74
- ```
70
+ # list ec2 instances
71
+ sonic list demo-web
75
72
 
76
73
  ## Contributing
77
74
 
@@ -16,16 +16,6 @@ You can also add sonic to your Gemfile in your project if you are working with a
16
16
  gem "sonic-screwdriver"
17
17
  ```
18
18
 
19
- ### Install with Bolts Toolbelt
20
-
21
- If you want to install sonic without having to worry about sonic's ruby dependency you can simply install the Bolts Toolbelt which has sonic included.
22
-
23
- ```sh
24
- brew cask install boltopslabs/software/bolts
25
- ```
26
-
27
- For more information about the Bolts Toolbelt or to get an installer for another operating system visit: [https://boltops.com/toolbelt](https://boltops.com/toolbelt)
28
-
29
19
  ### Server Side Dependencies
30
20
 
31
21
  For a small set of the commands there are server side dependencies.
@@ -6,56 +6,50 @@ title: Sonic Execute
6
6
 
7
7
  Sonic provides a way to execute commands remotely and securely across a list of AWS servers. It does this by leveraging [Amazon EC2 Run Command](https://aws.amazon.com/ec2/execute/). Sonic a simple interface and some conveniences for you. The command is called `sonic execute`:
8
8
 
9
- ```sh
10
- sonic execute [FILTER] [COMMAND]
11
- ```
9
+ sonic execute [FILTER] [COMMAND]
12
10
 
13
11
  ## Examples Summary
14
12
 
15
- ```sh
16
- sonic execute hi-web uptime
17
- sonic execute hi-web-prod uptime
18
- sonic execute i-030033c20c54bf149,i-030033c20c54bf150 uname -a
19
- sonic execute i-030033c20c54bf149 file://hello.sh
20
- ```
13
+ sonic execute --tags Name=demo-web uptime
14
+ sonic execute --tags Name=demo-web,demo-worker uptime # multiple tag values
15
+ sonic execute --instance-ids i-030033c20c54bf149,i-030033c20c54bf150 uname -a
16
+ sonic execute --instance-ids i-030033c20c54bf149 file://hello.sh
21
17
 
22
18
  ## Example Detailed
23
19
 
24
20
  Here's a command example output in detailed:
25
21
 
26
- ```sh
27
- $ sonic execute i-0bf51a000ab4e73a8 uptime
28
- Sending command to SSM with options:
29
- ---
30
- instance_ids:
31
- - i-0bf51a000ab4e73a8
32
- document_name: AWS-RunShellScript
33
- comment: sonic execute i-0bf51a000ab4e73a8 uptime
34
- parameters:
35
- commands:
36
- - uptime
37
- output_s3_region: us-east-1
38
- output_s3_bucket_name: [reacted]
39
- output_s3_key_prefix: ssm/commands/sonic
40
-
41
- Command sent to AWS SSM. To check the details of the command:
42
- aws ssm list-commands --command-id 0bb18d58-6436-49fd-9bfd-0c4b6c51c7a2
43
- aws ssm get-command-invocation --command-id 0bb18d58-6436-49fd-9bfd-0c4b6c51c7a2 --instance-id i-0bf51a000ab4e73a8
44
-
45
- Waiting for ssm command to finish.....
46
- Command finished.
47
-
48
- Displaying output for i-0bf51a000ab4e73a8.
49
- Command status: Success
50
- Command standard output:
51
- 01:08:10 up 8 days, 6:41, 0 users, load average: 0.00, 0.00, 0.00
52
-
53
- To see the more output details visit:
54
- https://us-west-2.console.aws.amazon.com/systems-manager/run-command/0bb18d58-6436-49fd-9bfd-0c4b6c51c7a2
55
-
56
- Pro tip: the console url is already in your copy/paste clipboard.
57
- $
58
- ```
22
+ $ sonic execute --instance-ids i-0bf51a000ab4e73a8 uptime
23
+ Sending command to SSM with options:
24
+ ---
25
+ instance_ids:
26
+ - i-0bf51a000ab4e73a8
27
+ document_name: AWS-RunShellScript
28
+ comment: sonic execute --instance-ids i-0bf51a000ab4e73a8 uptime
29
+ parameters:
30
+ commands:
31
+ - uptime
32
+ output_s3_region: us-east-1
33
+ output_s3_bucket_name: [reacted]
34
+ output_s3_key_prefix: ssm/commands/sonic
35
+
36
+ Command sent to AWS SSM. To check the details of the command:
37
+ aws ssm list-commands --command-id 0bb18d58-6436-49fd-9bfd-0c4b6c51c7a2
38
+ aws ssm get-command-invocation --command-id 0bb18d58-6436-49fd-9bfd-0c4b6c51c7a2 --instance-id i-0bf51a000ab4e73a8
39
+
40
+ Waiting for ssm command to finish.....
41
+ Command finished.
42
+
43
+ Displaying output for i-0bf51a000ab4e73a8.
44
+ Command status: Success
45
+ Command standard output:
46
+ 01:08:10 up 8 days, 6:41, 0 users, load average: 0.00, 0.00, 0.00
47
+
48
+ To see the more output details visit:
49
+ https://us-west-2.console.aws.amazon.com/systems-manager/run-command/0bb18d58-6436-49fd-9bfd-0c4b6c51c7a2
50
+
51
+ Pro tip: the console url is already in your copy/paste clipboard.
52
+ $
59
53
 
60
54
  Notice the conveniences of `sonic execute`, it:
61
55
 
@@ -69,28 +63,30 @@ The AWS SSM console looks like this:
69
63
 
70
64
  <img src="/img/tutorials/ec2-console-run-command.png" class="doc-photo" />
71
65
 
72
- ### Polymorphic Filter
66
+ ### Filter Options
73
67
 
74
- The `sonic execute` command can understand a variety of different filters. The filters can be a list of instances ids or one EC2 tag value. Note, ECS service names are *not* supported for the filter.
68
+ The `sonic execute` command can understand a variety of different filters: `--tags` and `--instance-ids`. Note, ECS service names are *not* supported for the filter.
75
69
 
76
70
  Here is an example, where the uptime command will run on both `i-030033c20c54bf149` and `i-030033c20c54bf150` instances.
77
71
 
78
- ```sh
79
- sonic execute i-066b140d9479e9681,i-09482b1a6e330fbf7 uptime
80
- ```
72
+ sonic execute --instance-ids i-066b140d9479e9681,i-09482b1a6e330fbf7 uptime
73
+
74
+ Here is an example, where the uptime command will run on instances tagged with `Name=demo-web`
75
+
76
+ sonic execute --tags Name=demo-web uptime
81
77
 
82
78
  ## Windows Support
83
79
 
84
80
  Windows is also supported. When running a command sonic will first attempt to use the `AWS-RunShellScript` run command, and if it detects that the instance's platform does not support `AWS-RunShellScript`, it will run the command with the `AWS-RunPowerShellScript` run command. Here's an example:
85
81
 
86
82
  ```
87
- $ sonic execute i-0917ad61b10fa1059 pwd
83
+ $ sonic execute --instance-ids i-0917ad61b10fa1059 pwd
88
84
  Sending command to SSM with options:
89
85
  ---
90
86
  instance_ids:
91
87
  - i-0917ad61b10fa1059
92
88
  document_name: AWS-RunShellScript
93
- comment: sonic execute i-0917ad61b10fa1059 pwd
89
+ comment: sonic execute --instance-ids i-0917ad61b10fa1059 pwd
94
90
  parameters:
95
91
  commands:
96
92
  - pwd
@@ -129,16 +125,12 @@ $
129
125
 
130
126
  Sometimes you might want to run more than just a one-liner command. If you need to run a full script, you can provide the file path to the script by designating it with `file://`. For example, here's a file called `hi.sh`:
131
127
 
132
- ```bash
133
- #!/bin/bash
134
- echo "hello world"
135
- ```
128
+ #!/bin/bash
129
+ echo "hello world"
136
130
 
137
131
  Here's how you run that file:
138
132
 
139
- ```sh
140
- sonic execute hi-web file://hi.sh
141
- ```
133
+ sonic execute demo-web file://hi.sh
142
134
 
143
135
  The file gets read by `sonic execute` and sent to EC2 Run Command to be executed.
144
136
 
@@ -16,10 +16,10 @@ Runs command across fleet of servers via AWS Run Command.
16
16
 
17
17
  ## Examples Summary
18
18
 
19
- $ sonic execute hi-web-prod uptime
20
- $ sonic execute hi-web-prod,hi-worker-prod,hi-clock-prod uptime
21
- $ sonic execute i-030033c20c54bf149,i-030033c20c54bf150 uname -a
22
- $ sonic execute i-030033c20c54bf149 file://hello.sh
19
+ sonic execute --tags Name=demo-web uptime
20
+ sonic execute --tags Name=demo-web,demo-worker uptime # multiple values
21
+ sonic execute --instance-ids i-030033c20c54bf149,i-030033c20c54bf150 uname -a
22
+ sonic execute --instance-ids i-030033c20c54bf149 file://hello.sh # script from file
23
23
 
24
24
  You cannot mix instance ids and tag names in the filter.
25
25
 
@@ -27,13 +27,13 @@ You cannot mix instance ids and tag names in the filter.
27
27
 
28
28
  Here's a command example output in detailed:
29
29
 
30
- $ sonic execute i-0bf51a000ab4e73a8 uptime
30
+ $ sonic execute --instance-ids i-0bf51a000ab4e73a8 uptime
31
31
  Sending command to SSM with options:
32
32
  ---
33
33
  instance_ids:
34
34
  - i-0bf51a000ab4e73a8
35
35
  document_name: AWS-RunShellScript
36
- comment: sonic execute i-0bf51a000ab4e73a8 uptime
36
+ comment: sonic execute --instance-ids i-0bf51a000ab4e73a8 uptime
37
37
  parameters:
38
38
  commands:
39
39
  - uptime
@@ -77,6 +77,8 @@ The AWS SSM console looks like this:
77
77
  ```
78
78
  [--zero-warn], [--no-zero-warn] # Warns user when no instances found
79
79
  # Default: true
80
+ [--instance-ids=INSTANCE_IDS] # Instance ids to execute command on. Format: --instance-ids "i-111,i-222"
81
+ [--tags=TAGS] # Tags used to determine what instances to execute command on. Format: --tags "Key1=v1,v2;Key2=v3"
80
82
  [--verbose], [--no-verbose]
81
83
  [--noop], [--no-noop]
82
84
  ```
@@ -1,4 +1,4 @@
1
1
  #!/bin/bash -ex
2
2
 
3
3
  bundle exec jekyll clean
4
- exec bundle exec jekyll serve
4
+ exec bundle exec jekyll serve --host 0.0.0.0 "$@"
@@ -6,35 +6,31 @@ In a hurry? No sweat! Here's a quick overview of how to use sonic.
6
6
 
7
7
  ### Install
8
8
 
9
- ```sh
10
- gem install sonic-screwdriver
11
- ```
9
+ gem install sonic-screwdriver
12
10
 
13
11
  ### Usage
14
12
 
15
- ```sh
16
- # ssh into an instance
17
- sonic ssh i-0f7f833131a51ce35
18
- sonic ssh hi-web # ec2 tag
19
- sonic ssh hi-web --cluster staging # ecs service name
20
- sonic ssh 7fbc8c75-4675-4d39-a5a4-0395ff8cd474 --cluster staging # ECS container id
21
- sonic ssh 1ed12abd-645c-4a05-9acf-739b9d790170 --cluster staging # ECS task id
13
+ # ssh into an instance
14
+ sonic ssh i-0f7f833131a51ce35
15
+ sonic ssh demo-web # ec2 tag
16
+ sonic ssh demo-web --cluster staging # ecs service name
17
+ sonic ssh 7fbc8c75-4675-4d39-a5a4-0395ff8cd474 --cluster staging # ECS container id
18
+ sonic ssh 1ed12abd-645c-4a05-9acf-739b9d790170 --cluster staging # ECS task id
22
19
 
23
- # docker exec to a running ECS docker container
24
- sonic ecs exec hi-web
20
+ # docker exec to a running ECS docker container
21
+ sonic ecs exec demo-web
25
22
 
26
- # docker run with same environment as the ECS docker running containers
27
- sonic ecs sh hi-web
23
+ # docker run with same environment as the ECS docker running containers
24
+ sonic ecs sh demo-web
28
25
 
29
- # run command on 1 instance
30
- sonic execute i-0f7f833131a51ce35 uptime
26
+ # run command on 1 instance
27
+ sonic execute --instance-ids i-0f7f833131a51ce35 uptime
31
28
 
32
- # run command on all instances tagged with hi-web and worker
33
- sonic execute hi-web,hi-worker uptime
29
+ # run command on all instances tagged with demo-web and worker
30
+ sonic execute --tags Name=demo-web,demo-worker uptime
34
31
 
35
- # list ec2 instances
36
- sonic list hi-web
37
- ```
32
+ # list ec2 instances
33
+ sonic list demo-web
38
34
 
39
35
  Congratulations! You now know the basic sonic screwdriver commands now.
40
36
 
@@ -3,7 +3,7 @@ module Sonic
3
3
  def check_cluster_exists!
4
4
  cluster = ecs.describe_clusters(clusters: [@cluster]).clusters.first
5
5
  unless cluster
6
- UI.error "The #{@cluster.green} cluster does not exist. Are you sure you specified the right cluster?"
6
+ UI.error "The #{@cluster.color(:green)} cluster does not exist. Are you sure you specified the right cluster?"
7
7
  exit 1
8
8
  end
9
9
  end
@@ -20,7 +20,7 @@ module Sonic
20
20
 
21
21
  service = resp.services.first
22
22
  unless service
23
- UI.error "The #{@service.green} service does not exist in #{@cluster.green} cluster. Are you sure you specified the right service and cluster?"
23
+ UI.error "The #{@service.color(:green)} service does not exist in #{@cluster.color(:green)} cluster. Are you sure you specified the right service and cluster?"
24
24
  exit 1
25
25
  end
26
26
  end
@@ -27,8 +27,10 @@ module Sonic
27
27
  long_desc Help.text("execute")
28
28
  option :zero_warn, type: :boolean, default: true, desc: "Warns user when no instances found"
29
29
  # filter - Filter ec2 instances by tag name or instance_ids separated by commas
30
- def execute(filter, *command)
31
- Execute.new(command, options.merge(filter: filter)).execute
30
+ option :instance_ids, desc: %Q|Instance ids to execute command on. Format: --instance-ids "i-111,i-222"|
31
+ option :tags, desc: %Q|Tags used to determine what instances to execute command on. Format: --tags "Key1=v1,v2;Key2=v3"|
32
+ def execute(*command)
33
+ Execute.new(command, options).execute
32
34
  end
33
35
 
34
36
  desc "list [FILTER]", "Lists ec2 instances."
@@ -8,7 +8,8 @@ module Sonic
8
8
  def initialize(command, options)
9
9
  @command = command
10
10
  @options = options
11
- @filter = @options[:filter].split(',').map{|s| s.strip}
11
+ @tags = @options[:tags]
12
+ @instance_ids = @options[:instance_ids]
12
13
  end
13
14
 
14
15
  # aws ssm send-command \
@@ -18,6 +19,7 @@ module Sonic
18
19
  # --parameters '{"commands":["#!/usr/bin/python","print \"Hello world from python\""]}' \
19
20
  # --query "Command.CommandId"
20
21
  def execute
22
+ check_filter_options!
21
23
  ssm_options = build_ssm_options
22
24
  if @options[:noop]
23
25
  UI.noop = true
@@ -33,6 +35,7 @@ module Sonic
33
35
  puts
34
36
  begin
35
37
  resp = send_command(ssm_options)
38
+
36
39
  command_id = resp.command.command_id
37
40
  success = true
38
41
  rescue Aws::SSM::Errors::InvalidInstanceId => e
@@ -49,9 +52,17 @@ module Sonic
49
52
  display_ssm_commands(command_id, ssm_options)
50
53
  puts
51
54
  return if @options[:noop]
52
- wait(command_id)
53
- display_ssm_output(command_id, ssm_options)
55
+ status = wait(command_id)
56
+ instances_found = display_ssm_output(command_id)
54
57
  display_console_url(command_id)
58
+
59
+ if status == "Success"
60
+ puts "Command successful: #{status}".color(:green)
61
+ exit(0)
62
+ else
63
+ puts "Command unsuccessful: #{status}".color(:red)
64
+ exit(1)
65
+ end
55
66
  end
56
67
 
57
68
  def wait(command_id)
@@ -68,15 +79,21 @@ module Sonic
68
79
  end
69
80
  puts "\nCommand finished."
70
81
  puts
82
+ status
71
83
  end
72
84
 
73
- def display_ssm_output(command_id, ssm_options)
74
- instance_ids = ssm_options[:instance_ids]
75
- return unless instance_ids && instance_ids.size > 0
85
+ def display_ssm_output(command_id)
86
+ resp = ssm.list_command_invocations(command_id: command_id)
87
+ command_invocations = resp.command_invocations
88
+ command_invocation = command_invocations.first
89
+ unless command_invocation
90
+ puts "WARN: No instances found that matches the --tags or --instance-ids option".color(:yellow)
91
+ return false # instances_found
92
+ end
93
+ instance_id = command_invocation.instance_id
76
94
 
77
- instance_id = instance_ids.first
78
- if ssm_options[:instance_ids].size > 1
79
- puts "Multiple instance targets. Only displaying output for #{instance_id}."
95
+ if command_invocations.size > 1
96
+ puts "Multiple instance targets. Total targets: #{command_invocations.size}. Only displaying output for #{instance_id}."
80
97
  else
81
98
  puts "Displaying output for #{instance_id}."
82
99
  end
@@ -88,6 +105,7 @@ module Sonic
88
105
  ssm_output(resp, "output")
89
106
  ssm_output(resp, "error")
90
107
  puts
108
+ true # instances_found
91
109
  end
92
110
 
93
111
  def display_console_url(command_id)
@@ -96,8 +114,7 @@ module Sonic
96
114
  puts "To see the more output details visit:"
97
115
  puts " #{console_url}"
98
116
  puts
99
- copy_paste_clipboard(console_url)
100
- UI.say "Pro tip: the console url is already in your copy/paste clipboard."
117
+ copy_paste_clipboard(console_url, "Pro tip: the console url is already in your copy/paste clipboard.")
101
118
  end
102
119
 
103
120
  def colorized_status(status)
@@ -120,7 +137,7 @@ module Sonic
120
137
  return if content.empty?
121
138
 
122
139
  puts "Command standard #{type}:"
123
- # "https://s3.amazonaws.com/lr-infrastructure-prod/ssm/commands/sonic/0a4f4bef-8f63-4235-8b30-ae296477261a/i-0b2e6e187a3f9ada9/awsrunPowerShellScript/0.awsrunPowerShellScript/stderr">
140
+ # "https://s3.amazonaws.com/infra-prod/ssm/commands/sonic/0a4f4bef-8f63-4235-8b30-ae296477261a/i-0b2e6e187a3f9ada9/awsrunPowerShellScript/0.awsrunPowerShellScript/stderr">
124
141
  if content.include?("--output truncated--") && !resp[s3_key].empty?
125
142
  s3_url = resp[s3_key]
126
143
  info = s3_url.sub('https://s3.amazonaws.com/', '').split('/')
@@ -146,7 +163,6 @@ module Sonic
146
163
 
147
164
  begin
148
165
  resp = ssm.send_command(options)
149
- # puts "NOOP FOR NOW"
150
166
  rescue Aws::SSM::Errors::UnsupportedPlatformType
151
167
  retries += 1
152
168
  # toggle AWS-RunShellScript / AWS-RunPowerShellScript
@@ -165,12 +181,18 @@ module Sonic
165
181
  end
166
182
 
167
183
  def build_ssm_options
168
- criteria = transform_filter(@filter)
184
+ criteria = transform_filter_option
169
185
  command = build_command(@command)
170
186
  options = criteria.merge(
171
187
  document_name: "AWS-RunShellScript", # default
172
188
  comment: "sonic #{ARGV.join(' ')}"[0..99], # comment has a max of 100 chars
173
- parameters: { "commands" => command }
189
+ parameters: { "commands" => command },
190
+ # Default CloudWatchLog settings. Can be overwritten with settings.yml send_command
191
+ # IMPORTANT: make sure the EC2 instance the command runs on has access to write to CloudWatch Logs.
192
+ cloud_watch_output_config: {
193
+ # cloud_watch_log_group_name: "ssm", # Defaults to /aws/ssm/AWS-RunShellScript (aws/ssm/SystemsManagerDocumentName https://amzn.to/38TKVse)
194
+ cloud_watch_output_enabled: true,
195
+ },
174
196
  )
175
197
  settings_options = settings["send_command"] || {}
176
198
  options.merge(settings_options.deep_symbolize_keys)
@@ -180,6 +202,12 @@ module Sonic
180
202
  @settings ||= Setting.new.data
181
203
  end
182
204
 
205
+ def check_filter_options!
206
+ return if @tags || @instance_ids
207
+ puts "ERROR: Please provide --tags or --instance-ids option".color(:red)
208
+ exit 1
209
+ end
210
+
183
211
  #
184
212
  # Public: Transform the filter to the ssm send_command equivalent options
185
213
  #
@@ -187,41 +215,31 @@ module Sonic
187
215
  #
188
216
  # Examples
189
217
  #
190
- # transform_filter(["hi-web-prod", "hi-worker-prod", "i-006a097bb10643e20"])
218
+ # transform_filter_option
191
219
  # # => {
192
220
  # instance_ids: ["i-006a097bb10643e20"],
193
221
  # targets: [{key: "Name", values: "hi-web-prod,hi-worker-prod"}]
194
222
  # }
195
223
  #
196
224
  # Returns the duplicated String.
197
- def transform_filter(filter)
198
- valid = validate_filter(filter)
199
- unless valid
200
- UI.error("The filter you provided '#{filter.join(',')}' is not valid.")
201
- UI.say("The filter must either be all instance ids or just a list of tag names.")
202
- exit 1
203
- end
204
-
205
- if filter.detect { |i| instance_id?(i) }
206
- instance_ids = filter
207
- {instance_ids: instance_ids}
208
- else
209
- tags = filter
210
- targets = [{
211
- key: "tag:#{tag_name}",
212
- values: tags
213
- }]
225
+ def transform_filter_option
226
+ if @tags
227
+ list = @tags.split(';')
228
+ targets = list.inject([]) do |final,item|
229
+ tag_name,value_list = item.split('=')
230
+ values = value_list.split(',').map(&:strip)
231
+ # structure expected by ssm send_command
232
+ option = {
233
+ key: "tag:#{tag_name}",
234
+ values: values
235
+ }
236
+ final << option
237
+ final
238
+ end
214
239
  {targets: targets}
215
- end
216
- end
217
-
218
- # Either all instance ids are no instance ids is a valid filter
219
- def validate_filter(filter)
220
- if filter.detect { |i| instance_id?(i) }
221
- instance_ids = filter.select { |i| instance_id?(i) }
222
- instance_ids.size == filter.size
223
- else
224
- true
240
+ else # @instance_ids
241
+ instance_ids = @instance_ids.split(',')
242
+ {instance_ids: instance_ids}
225
243
  end
226
244
  end
227
245
 
@@ -253,8 +271,7 @@ You can use the following command to check registered instances to SSM.
253
271
  #{ssm_describe_command}
254
272
  EOS
255
273
  UI.warn(message)
256
- copy_paste_clipboard(ssm_describe_command)
257
- UI.say "Pro tip: ssm describe-instance-information already in your copy/paste clipboard."
274
+ copy_paste_clipboard(ssm_describe_command, "Pro tip: ssm describe-instance-information already in your copy/paste clipboard.")
258
275
  end
259
276
 
260
277
  def file_path?(command)
@@ -311,9 +328,10 @@ EOL
311
328
  end
312
329
  end
313
330
 
314
- def copy_paste_clipboard(command)
331
+ def copy_paste_clipboard(command, text)
315
332
  return unless RUBY_PLATFORM =~ /darwin/
316
333
  system("echo '#{command}' | pbcopy")
334
+ UI.say text
317
335
  end
318
336
  end
319
337
  end
@@ -3,10 +3,10 @@
3
3
 
4
4
  ## Examples Summary
5
5
 
6
- $ sonic execute hi-web-prod uptime
7
- $ sonic execute hi-web-prod,hi-worker-prod,hi-clock-prod uptime
8
- $ sonic execute i-030033c20c54bf149,i-030033c20c54bf150 uname -a
9
- $ sonic execute i-030033c20c54bf149 file://hello.sh
6
+ sonic execute --tags Name=demo-web uptime
7
+ sonic execute --tags Name=demo-web,demo-worker uptime # multiple values
8
+ sonic execute --instance-ids i-030033c20c54bf149,i-030033c20c54bf150 uname -a
9
+ sonic execute --instance-ids i-030033c20c54bf149 file://hello.sh # script from file
10
10
 
11
11
  You cannot mix instance ids and tag names in the filter.
12
12
 
@@ -14,13 +14,13 @@ You cannot mix instance ids and tag names in the filter.
14
14
 
15
15
  Here's a command example output in detailed:
16
16
 
17
- $ sonic execute i-0bf51a000ab4e73a8 uptime
17
+ $ sonic execute --instance-ids i-0bf51a000ab4e73a8 uptime
18
18
  Sending command to SSM with options:
19
19
  ---
20
20
  instance_ids:
21
21
  - i-0bf51a000ab4e73a8
22
22
  document_name: AWS-RunShellScript
23
- comment: sonic execute i-0bf51a000ab4e73a8 uptime
23
+ comment: sonic execute --instance-ids i-0bf51a000ab4e73a8 uptime
24
24
  parameters:
25
25
  commands:
26
26
  - uptime
@@ -73,7 +73,7 @@ class Ssh
73
73
 
74
74
  task = response.tasks.first
75
75
  unless task
76
- puts "Unable to find a #{task_arn.green} container instance or task in the #{@cluster.green} cluster."
76
+ puts "Unable to find a #{task_arn.color(:green)} container instance or task in the #{@cluster.color(:green)} cluster."
77
77
  exit 1
78
78
  end
79
79
 
@@ -1,3 +1,3 @@
1
1
  module Sonic
2
- VERSION = "2.1.1"
2
+ VERSION = "2.2.0"
3
3
  end
@@ -11,8 +11,13 @@ describe Sonic::CLI do
11
11
  expect(out).to include("=> ssh")
12
12
  end
13
13
 
14
- it "execute should print that command has been sent" do
15
- out = execute("exe/sonic execute #{@args} 1,2,3 uptime")
14
+ it "execute should print that command has been sent --instance-ids" do
15
+ out = execute("exe/sonic execute #{@args} --instance-ids i-1,i-2,i-3 uptime")
16
+ expect(out).to include("Command sent")
17
+ end
18
+
19
+ it "execute should print that command has been sent --tags" do
20
+ out = execute("exe/sonic execute #{@args} --tags Name=value uptime")
16
21
  expect(out).to include("Command sent")
17
22
  end
18
23
 
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Sonic::Execute do
4
4
  before(:each) do
5
5
  @options = {
6
- filter: "i-066b140d9479e9681,i-09482b1a6e330fbf7"
6
+ instance_ids: "i-066b140d9479e9681,i-09482b1a6e330fbf7"
7
7
  }
8
8
  end
9
9
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sonic-screwdriver
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-25 00:00:00.000000000 Z
11
+ date: 2020-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -260,7 +260,6 @@ files:
260
260
  - ".circleci/config.yml"
261
261
  - ".gitignore"
262
262
  - ".rspec"
263
- - ".ruby-version"
264
263
  - CHANGELOG.md
265
264
  - CONTRIBUTING.md
266
265
  - Gemfile
@@ -421,8 +420,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
421
420
  - !ruby/object:Gem::Version
422
421
  version: '0'
423
422
  requirements: []
424
- rubyforge_project:
425
- rubygems_version: 2.7.6
423
+ rubygems_version: 3.1.2
426
424
  signing_key:
427
425
  specification_version: 4
428
426
  summary: Multi-functional tool to manage AWS infrastructure
@@ -1 +0,0 @@
1
- 2.5.1