sonic-screwdriver 2.1.1 → 2.2.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 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