esp_sdk 2.0.0 → 2.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.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +6 -1
  4. data/Gemfile.lock +11 -1
  5. data/README.md +287 -28
  6. data/bin/esp +15 -0
  7. data/esp_sdk.gemspec +2 -0
  8. data/lib/esp/aws_clients.rb +60 -0
  9. data/lib/esp/commands/add_external_account.rb +57 -0
  10. data/lib/esp/commands/commands_tasks.rb +106 -0
  11. data/lib/esp/commands/console.rb +68 -0
  12. data/lib/esp/extensions/active_resource/formats/json_api_format.rb +12 -4
  13. data/lib/esp/extensions/active_resource/paginated_collection.rb +5 -5
  14. data/lib/esp/extensions/active_resource/validations.rb +1 -1
  15. data/lib/esp/external_account_creator.rb +77 -0
  16. data/lib/esp/resources/alert.rb +30 -34
  17. data/lib/esp/resources/cloud_trail_event.rb +5 -0
  18. data/lib/esp/resources/contact_request.rb +6 -5
  19. data/lib/esp/resources/custom_signature.rb +32 -56
  20. data/lib/esp/resources/dashboard.rb +8 -1
  21. data/lib/esp/resources/external_account.rb +27 -19
  22. data/lib/esp/resources/organization.rb +27 -3
  23. data/lib/esp/resources/region.rb +15 -3
  24. data/lib/esp/resources/report.rb +28 -24
  25. data/lib/esp/resources/resource.rb +26 -10
  26. data/lib/esp/resources/service.rb +5 -0
  27. data/lib/esp/resources/signature.rb +28 -12
  28. data/lib/esp/resources/stat.rb +21 -2
  29. data/lib/esp/resources/stat_custom_signature.rb +30 -4
  30. data/lib/esp/resources/stat_region.rb +29 -3
  31. data/lib/esp/resources/stat_service.rb +29 -3
  32. data/lib/esp/resources/stat_signature.rb +29 -3
  33. data/lib/esp/resources/sub_organization.rb +27 -3
  34. data/lib/esp/resources/suppression/region.rb +14 -32
  35. data/lib/esp/resources/suppression/signature.rb +14 -40
  36. data/lib/esp/resources/suppression/unique_identifier.rb +8 -6
  37. data/lib/esp/resources/suppression.rb +43 -5
  38. data/lib/esp/resources/tag.rb +5 -0
  39. data/lib/esp/resources/team.rb +33 -9
  40. data/lib/esp/resources/user.rb +29 -3
  41. data/lib/esp/version.rb +1 -1
  42. data/lib/esp.rb +25 -5
  43. data/test/esp/aws_clients_test.rb +101 -0
  44. data/test/esp/extensions/active_resource/formats/json_api_format_test.rb +26 -12
  45. data/test/esp/extensions/active_resource/paginated_collection_test.rb +93 -72
  46. data/test/esp/extensions/active_resource/validations_test.rb +2 -12
  47. data/test/esp/external_account_creator_test.rb +153 -0
  48. data/test/esp/resources/alert_test.rb +71 -33
  49. data/test/esp/resources/cloud_trail_event_test.rb +9 -1
  50. data/test/esp/resources/contact_request_test.rb +8 -0
  51. data/test/esp/resources/custom_signature_test.rb +8 -0
  52. data/test/esp/resources/dashboard_test.rb +8 -0
  53. data/test/esp/resources/external_account_test.rb +8 -0
  54. data/test/esp/resources/metadata_test.rb +1 -1
  55. data/test/esp/resources/organization_test.rb +8 -0
  56. data/test/esp/resources/region_test.rb +12 -4
  57. data/test/esp/resources/report_test.rb +13 -4
  58. data/test/esp/resources/resource_test.rb +208 -64
  59. data/test/esp/resources/service_test.rb +8 -0
  60. data/test/esp/resources/signature_test.rb +15 -9
  61. data/test/esp/resources/stat_custom_signature_test.rb +9 -1
  62. data/test/esp/resources/stat_region_test.rb +23 -1
  63. data/test/esp/resources/stat_service_test.rb +23 -1
  64. data/test/esp/resources/stat_signature_test.rb +23 -1
  65. data/test/esp/resources/stat_test.rb +52 -8
  66. data/test/esp/resources/sub_organization_test.rb +8 -0
  67. data/test/esp/resources/suppression/region_test.rb +10 -2
  68. data/test/esp/resources/suppression/signature_test.rb +10 -2
  69. data/test/esp/resources/suppression/unique_identifier_test.rb +10 -2
  70. data/test/esp/resources/suppression_test.rb +74 -14
  71. data/test/esp/resources/tag_test.rb +9 -1
  72. data/test/esp/resources/team_test.rb +8 -0
  73. data/test/esp/resources/user_test.rb +49 -19
  74. data/test/esp_test.rb +19 -1
  75. data/test/factories/alerts.rb +70 -0
  76. data/test/factories/organizations.rb +2 -2
  77. data/test/factories/regions.rb +1 -1
  78. data/test/factories/sub_organizations.rb +1 -1
  79. data/test/factories/suppressions.rb +109 -3
  80. data/test/factories/users.rb +65 -2
  81. data/test/test_helper.rb +9 -8
  82. metadata +41 -69
  83. data/bin/esp_console +0 -67
  84. data/rdoc/ActiveResource/Formats.html +0 -178
  85. data/rdoc/ActiveResource/PaginatedCollection.html +0 -912
  86. data/rdoc/ActiveResource.html +0 -182
  87. data/rdoc/ESP/Alert.html +0 -808
  88. data/rdoc/ESP/CloudTrailEvent.html +0 -377
  89. data/rdoc/ESP/ContactRequest.html +0 -368
  90. data/rdoc/ESP/CustomSignature.html +0 -748
  91. data/rdoc/ESP/Dashboard.html +0 -357
  92. data/rdoc/ESP/ExternalAccount.html +0 -567
  93. data/rdoc/ESP/Metadata.html +0 -411
  94. data/rdoc/ESP/Organization.html +0 -592
  95. data/rdoc/ESP/Region.html +0 -401
  96. data/rdoc/ESP/Report.html +0 -624
  97. data/rdoc/ESP/Service.html +0 -382
  98. data/rdoc/ESP/Signature.html +0 -557
  99. data/rdoc/ESP/Stat.html +0 -1780
  100. data/rdoc/ESP/StatCustomSignature.html +0 -1601
  101. data/rdoc/ESP/StatRegion.html +0 -1600
  102. data/rdoc/ESP/StatService.html +0 -1600
  103. data/rdoc/ESP/StatSignature.html +0 -1600
  104. data/rdoc/ESP/SubOrganization.html +0 -542
  105. data/rdoc/ESP/Suppression/Region.html +0 -456
  106. data/rdoc/ESP/Suppression/Signature.html +0 -472
  107. data/rdoc/ESP/Suppression/UniqueIdentifier.html +0 -419
  108. data/rdoc/ESP/Suppression.html +0 -651
  109. data/rdoc/ESP/Tag.html +0 -373
  110. data/rdoc/ESP/Team.html +0 -586
  111. data/rdoc/ESP/User.html +0 -485
  112. data/rdoc/ESP.html +0 -549
  113. data/rdoc/README_md.html +0 -503
  114. data/rdoc/created.rid +0 -31
  115. data/rdoc/images/add.png +0 -0
  116. data/rdoc/images/arrow_up.png +0 -0
  117. data/rdoc/images/brick.png +0 -0
  118. data/rdoc/images/brick_link.png +0 -0
  119. data/rdoc/images/bug.png +0 -0
  120. data/rdoc/images/bullet_black.png +0 -0
  121. data/rdoc/images/bullet_toggle_minus.png +0 -0
  122. data/rdoc/images/bullet_toggle_plus.png +0 -0
  123. data/rdoc/images/date.png +0 -0
  124. data/rdoc/images/delete.png +0 -0
  125. data/rdoc/images/find.png +0 -0
  126. data/rdoc/images/loadingAnimation.gif +0 -0
  127. data/rdoc/images/macFFBgHack.png +0 -0
  128. data/rdoc/images/package.png +0 -0
  129. data/rdoc/images/page_green.png +0 -0
  130. data/rdoc/images/page_white_text.png +0 -0
  131. data/rdoc/images/page_white_width.png +0 -0
  132. data/rdoc/images/plugin.png +0 -0
  133. data/rdoc/images/ruby.png +0 -0
  134. data/rdoc/images/tag_blue.png +0 -0
  135. data/rdoc/images/tag_green.png +0 -0
  136. data/rdoc/images/transparent.png +0 -0
  137. data/rdoc/images/wrench.png +0 -0
  138. data/rdoc/images/wrench_orange.png +0 -0
  139. data/rdoc/images/zoom.png +0 -0
  140. data/rdoc/index.html +0 -136
  141. data/rdoc/js/darkfish.js +0 -155
  142. data/rdoc/js/jquery.js +0 -4
  143. data/rdoc/js/navigation.js +0 -142
  144. data/rdoc/js/search.js +0 -94
  145. data/rdoc/js/search_index.js +0 -1
  146. data/rdoc/js/searcher.js +0 -228
  147. data/rdoc/rdoc.css +0 -595
  148. data/rdoc/table_of_contents.html +0 -942
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 346fea31e490e4806a446f57683828c302ef3289
4
- data.tar.gz: 8c429d99558d3b111eb4eabb7d7a35419391ab23
3
+ metadata.gz: eec3d492b1abf2d98d6bbf35c1f88a90c5e2b602
4
+ data.tar.gz: f51d254cdef908e29b311ac812cf2654e14e1b8a
5
5
  SHA512:
6
- metadata.gz: 6ad3f1c191a879a5c17b3042941b7a590918f48a34e597beaf1c06d293d653cb49ac958f4e539ee717d24cac092861fbfce903e870e8ec0be09557542e3e0d82
7
- data.tar.gz: d68c27b4c8fd22fe0dd65a2c4d702b4f8d2a19376e5e826514f1f6d9c8a40f2f316dbf6d6549cccbc164418a463c73e35a2a9e05433bb11f11888526a1a5e246
6
+ metadata.gz: 7edfbd88ee1b306daba55f035da060d5b63eb22c4a3d37d7bc09f6d95b20c510df7756edb8b74f5f18ba1325bbc62929052e4486fb3db26304c3aceba0633981
7
+ data.tar.gz: 1ba56c34e806fe32835db2dc32339d3802f3b830ea3dd9021e470ceab3a223a063107fa8566ec1658883d4d4dd2759be3be3f902982f91d7148c55aea797b69c
data/.travis.yml CHANGED
@@ -5,6 +5,7 @@ rvm:
5
5
  - 2.0.0
6
6
  - 2.1
7
7
  - 2.2
8
+ - 2.3.0
8
9
  script:
9
10
  - bundle exec rake test
10
11
  - bundle exec rake coveralls:push
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
- ## [Unreleased]
1
+ ## 2.1.0 - 2015-01-15
2
2
  ### Added
3
3
  - Implemented searching using `where` on many object.
4
+ - Add external account script. Run with `esp a`
5
+ - Added ability to set a proxy using either the `http_proxy` environment variable, or setting it manually wiht `ESP.http_proxy = <proxy>`
6
+
7
+ ### Changed
8
+ - Changed the `esp_console` executable to just be `esp`. Now start the console with `esp c`
4
9
 
5
10
  ## [2.0.0] - 2015-12-16
6
11
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- esp_sdk (2.0.0)
4
+ esp_sdk (2.1.0)
5
5
  activeresource (~> 4.0.0)
6
6
  api-auth
7
7
  rack
@@ -28,6 +28,13 @@ GEM
28
28
  ast (2.0.0)
29
29
  astrolabe (1.3.1)
30
30
  parser (~> 2.2)
31
+ awesome_print (1.6.1)
32
+ aws-sdk (2.1.36)
33
+ aws-sdk-resources (= 2.1.36)
34
+ aws-sdk-core (2.1.36)
35
+ jmespath (~> 1.0)
36
+ aws-sdk-resources (2.1.36)
37
+ aws-sdk-core (= 2.1.36)
31
38
  bourne (1.6.0)
32
39
  mocha (~> 1.1)
33
40
  builder (3.2.2)
@@ -62,6 +69,7 @@ GEM
62
69
  guard (~> 2.0)
63
70
  rubocop (~> 0.20)
64
71
  i18n (0.7.0)
72
+ jmespath (1.1.3)
65
73
  json (1.8.2)
66
74
  listen (3.0.3)
67
75
  rb-fsevent (>= 0.9.3)
@@ -139,6 +147,8 @@ PLATFORMS
139
147
  ruby
140
148
 
141
149
  DEPENDENCIES
150
+ awesome_print
151
+ aws-sdk
142
152
  bourne
143
153
  bundler
144
154
  coveralls
data/README.md CHANGED
@@ -13,7 +13,7 @@ This Readme is for the V2 version of the ESP SDK. For V1 information, see the [
13
13
 
14
14
  Add this line to your application's Gemfile:
15
15
 
16
- gem 'esp_sdk'
16
+ gem 'esp_sdk'
17
17
 
18
18
  And then execute:
19
19
 
@@ -53,6 +53,29 @@ end
53
53
 
54
54
  Get your HMAC keys from the Evident.io website, [esp.evident.io](https://esp.evident.io/settings/api_keys)
55
55
 
56
+ ## Set a Proxy URI
57
+
58
+ If you need to go through a proxy server, you can set the proxy URI.
59
+ You can set this directly:
60
+
61
+ ```ruby
62
+ ESP.http_proxy = <proxy uri>
63
+ ```
64
+
65
+ or, if in a Rails application, you can use the configure block in an initializer:
66
+
67
+ ```ruby
68
+ ESP.configure do |config|
69
+ config.http_proxy = <proxy uri>
70
+ end
71
+ ```
72
+
73
+ Alternatively, the proxy can also be set with an environment variable.
74
+
75
+ ```
76
+ export http_proxy=<proxy uri>
77
+ ```
78
+
56
79
  ## Appliance Users
57
80
 
58
81
  Users of Evident.io's AWS marketplace appliance will need to set the host for their appliance instance.
@@ -72,7 +95,6 @@ end
72
95
 
73
96
  Alternatively, the site can also be set with an environment variable.
74
97
 
75
-
76
98
  ```
77
99
  export ESP_HOST=<host for appliance instance>
78
100
  ```
@@ -197,7 +219,9 @@ espsdk:004:0> page4 = alerts.page(4)
197
219
  espsdk:004:0> alerts.current_page_number # => "25"
198
220
  espsdk:004:0> page4.current_page_number # => "4"
199
221
  ```
200
-
222
+
223
+ See ActiveResource::PaginatedCollection for all the pagination methods available.
224
+
201
225
  ## Associated Objects
202
226
  Most of the objects in the Evident.io SDK have a corresponding API call associated with it. That means if you call an object's
203
227
  association, then that will make another API call. For example:
@@ -218,37 +242,272 @@ of the relations wanted in an +include+ option.
218
242
  espsdk:004:0> external_account = ESP::ExternalAccount.find(3, include: 'organization,sub_orgnanization,team')
219
243
  ```
220
244
 
245
+ ```ruby
246
+ espsdk:004:0> external_account = ESP::ExternalAccount.where(id_eq: 3, include: 'organization,sub_organization,team')
247
+ ```
248
+
221
249
  With that call, organization, sub_organization and team will all come back in the response, and calling, `external_account.organization`,
222
- `external_account.sub_organization` and `external_account.team`, will not make another API call. Most objects' find method accepts the
223
- +include+ option.
224
-
225
- See the [**Documentation**](http://www.rubydoc.info/gems/esp_sdk/ESP/ActiveResource/PaginatedCollection.html) for all the pagination methods available.
250
+ `external_account.sub_organization` and `external_account.team`, will not make another API call.
251
+
252
+ You can nest include requests with the dot property. For example, requesting `external_account.team` on an alert will expand the `external_account` property into a full `External Account` object, and will then expand the `team` property on that external account into a full `Team` object.
253
+ Deep nesting is available as well. `external_account.team.organization`
254
+
255
+ ```ruby
256
+ alert = ESP::Alert.find(1, include: 'tags,external_account.team')
257
+ #=> <ESP::Alert:0x007fb82acd3298 @attributes={"id"=>"1", "type"=>"alerts"...}>
258
+
259
+ alerts = ESP::Alert.where(report_id: 4, include: 'tags,external_account.team')
260
+ #=> #<ActiveResource::PaginatedCollection:0x007fb82b0b54b0 @elements=[#<ESP::Alert:0x007fb82b0b1fb8 @attributes={"id"=>"1", "type"=>"alerts"...>
261
+ ```
262
+
263
+ Most objects' find and where methods accept the +include+ option. Those methods that accept the +include+ option are documented with the available associations that are includable.
264
+
265
+ ## Filtering/Searching
266
+ For objects that implement `where`, parameters can be passed that will filter the results based on the search criteria specified.
267
+ The criteria that can be specified depends on the object. Each object is documented whether it implements `where` or not,
268
+ and if so, which attributes can be included in the search criteria.
269
+
270
+ ### Searching
271
+
272
+ The primary method of searching is by using what is known as *predicates*.
273
+
274
+ Predicates are used within Evident.io API search queries to determine what information to
275
+ match. For instance, the `cont` predicate, when added to the `name` attribute, will check to see if `name`` contains a value using a wildcard query.
276
+
277
+ ```ruby
278
+ ESP::Signature.where(name_cont: 'dns')
279
+ #=> will return signatures `where name LIKE '%dns%'`
280
+ ```
281
+
282
+ ### OR Conditions
283
+
284
+ You can also combine predicates for OR queries:
285
+
286
+ ```ruby
287
+ ESP::Signature.where(name_or_description_cont: 'dns')
288
+ #=> will return signatures `where name LIKE '%dns%' or description LIKE '%dns%'`
289
+ ```
290
+
291
+ ### Conditions on Relationships
292
+
293
+ The syntax for queries on an associated relationship is to just append the association name to the attribute:
294
+
295
+ ```ruby
296
+ ESP::Suppression.where(regions_code_eq: 'us_east_1')
297
+ #=> will return suppressions that have a region relationship `where code = 'us_east_1'`
298
+ ```
299
+
300
+ ### Complex Filtering
301
+
302
+ Add multiple attributes and predicates to form complex queries:
303
+
304
+ ```ruby
305
+ ESP::Suppression.where(regions_code_start: 'us', created_by_email_eq: 'bob@mycompany.com', resource_not_null: '1')
306
+ #=> will return suppressions that have a region relationship `where code LIKE 'us%'` and created_by relationship `where email = 'bob@mycompany.com'` and `resource IS NOT NULL`
307
+ ```
308
+
309
+ You can also change the `combinator` for complex queries from the default `AND` to `OR` by adding the `m: 'or'` parameter
310
+
311
+ ```ruby
312
+ ESP::Suppression.where(regions_code_start: 'us', created_by_email_eq: 'bob@mycompany.com', resource_not_null: '1', m: 'or')
313
+ #=> will return suppressions that have a region relationship `where code LIKE 'us%'` **OR** created_by relationship `where email = 'bob@mycompany.com'` **OR** `resource IS NOT NULL`
314
+ ```
315
+
316
+ ### Bad Attributes
317
+
318
+ **Please note:** any attempt to use a predicate for an attribute that does not exist will return a
319
+ *422 (Unprocessable Entity)* response. For instance, this will not work:
320
+
321
+ ```ruby
322
+ ESP::Suppression.where(bad_attribute_eq: 'something')
323
+ #=> ActiveResource::ResourceInvalid: Failed. Response code = 422. Response message = Invalid search term bad_attribute_eq.
324
+ ```
325
+
326
+ **Also note:** any attempt to use a predicate for an attribute that exists on the object, but is not a documented searchable attribute will _silently fail_
327
+ and will be excluded from the search criteria.
328
+
329
+ ## Available Predicates
330
+
331
+ Below is a list of the available predicates and their opposites.
332
+
333
+ ### eq (equals)
334
+
335
+ The `eq` predicate returns all records where a field is *exactly* equal to a given value:
336
+
337
+ ```ruby
338
+ ESP::Suppression.where(regions_code_eq: 'us_east_1')
339
+ #=> will return suppressions that have a region relationship `where code = 'us_east_1'`
340
+ ```
341
+
342
+ **Opposite: `not_eq`**
343
+
344
+ ### lt (less than)
345
+
346
+ The `lt` predicate returns all records where a field is less than a given value:
347
+
348
+ ```ruby
349
+ ESP::Report.where(created_at_lt: 1.hour.ago)
350
+ #=> will return reports `where created_at < '2015-11-11 16:25:30'`
351
+ ```
352
+
353
+ **Opposite: `gt` (greater than)**
354
+
355
+ ### lteq (less than or equal to)
356
+
357
+ The `lteq` predicate returns all records where a field is less than *or equal to* a given value:
358
+
359
+ ```ruby
360
+ ESP::Report.where(created_at_lteq: 1.hour.ago)
361
+ #=> will return reports `where created_at <= '2015-11-11 16:25:30'`
362
+ ```
363
+
364
+ **Opposite: `gteq` (greater than or equal to)**
365
+
366
+ ### in
367
+
368
+ The `in` predicate returns all records where a field is within a specified list:
369
+
370
+ ```ruby
371
+ ESP::Signature.where(risk_level_in: ['Low', 'Medium'])
372
+ #=> will return signatures `where risk_level IN ('Low', 'Medium')`
373
+ ```
374
+
375
+ **Opposite: `not_in`**
376
+
377
+ ### cont (contains)
378
+
379
+ The `cont` predicate returns all records where a field contains a given value:
380
+
381
+ ```ruby
382
+ ESP::Signature.where(name_cont: 'dns')
383
+ #=> will return signatures `where name LIKE '%dns%'`
384
+ ```
385
+
386
+ **Opposite: `not_cont`**
387
+
388
+ **Please note:** This predicate is only available on attributes listed in the "Valid Matching Searchable Attributes"" section
389
+ for each implemented `where` method.
390
+
391
+ ### cont_any (contains any)
392
+
393
+ The `cont_any` predicate returns all records where a field contains any of given values:
394
+
395
+ ```ruby
396
+ ESP::Signature.where(name_cont_any: ['dns', 'EC2'])
397
+ #=> will return signatures `where name LIKE '%dns%' or name LIKE '%EC2%'`
398
+ ```
399
+
400
+ **Opposite: `not_cont_any`**
401
+
402
+ **Please note:** This predicate is only available on attributes listed in the "Valid Matching Searchable Attributes"" section
403
+ for each implemented `where` method.
404
+
405
+
406
+ ### start (starts with)
407
+
408
+ The `start` predicate returns all records where a field begins with a given value:
409
+
410
+ ```ruby
411
+ ESP::Signature.where(name_start: 'dns')
412
+ #=> will return signatures `where name LIKE 'dns%'`
413
+ ```
414
+
415
+ **Opposite: `not_start`**
416
+
417
+ **Please note:** This predicate is only available on attributes listed in the "Valid Matching Searchable Attributes"" section
418
+ for each implemented `where` method.
419
+
420
+ ### end (ends with)
421
+
422
+ The `end` predicate returns all records where a field ends with a given value:
423
+
424
+ ```ruby
425
+ ESP::Signature.where(name_end: 'dns')
426
+ #=> will return signatures `where name LIKE '%dns'`
427
+ ```
428
+
429
+ **Opposite: `not_end`**
430
+
431
+ **Please note:** This predicate is only available on attributes listed in the "Valid Matching Searchable Attributes"" section
432
+ for each implemented `where` method.
433
+
434
+ ### present
435
+
436
+ The `present` predicate returns all records where a field is present (not null and not a
437
+ blank string).
438
+
439
+ ```ruby
440
+ ESP::Signature.where(identifier_present: '1')
441
+ #=> will return signatures `where identifier IS NOT NULL AND identifier != ''`
442
+ ```
443
+
444
+ **Opposite: `blank`**
445
+
446
+ ### null
447
+
448
+ The `null` predicate returns all records where a field is null:
449
+
450
+ ```ruby
451
+ ESP::Signature.where(identifier_null: 1)
452
+ #=> will return signatures `where identifier IS NULL`
453
+ ```
454
+
455
+ **Opposite: `not_null`**
456
+
457
+ ## Sorting
458
+
459
+ Lists can also be sorted by adding the `sorts` parameter with the field to sort by to the `filter` parameter.
460
+
461
+ ```ruby
462
+ ESP::Signature.where(name_cont: 'dns', sort: 'risk_level desc')
463
+ #=> will return signatures `where name LIKE '%dns%'` sorted by `risk_level` in descending order.
464
+ ```
465
+
466
+ Lists can be sorted by multiple fields by specifying an ordered array.
467
+
468
+ ```ruby
469
+ ESP::Signature.where(name_cont: 'dns', sorts: ['risk_level desc', 'created_at'])
470
+ #=> will return signatures `where name LIKE '%dns%'` sorted by `risk_level` in descending order and then by `created_at` in ascending order.
471
+ ```
226
472
 
227
473
  ## Available Objects
228
- * [ESP::Alert](http://www.rubydoc.info/gems/esp_sdk/ESP/Alert.html)
229
- * [ESP::CloudTrailEvent](http://www.rubydoc.info/gems/esp_sdk/ESP/CloudTrailEvent.html)
230
- * [ESP::ContactRequest](http://www.rubydoc.info/gems/esp_sdk/ESP/ContactRequest.html)
231
- * [ESP::CustomSignature](http://www.rubydoc.info/gems/esp_sdk/ESP/CustomSignature.html)
232
- * [ESP::Dashboard](http://www.rubydoc.info/gems/esp_sdk/ESP/Dashboard.html)
233
- * [ESP::ExternalAccount](http://www.rubydoc.info/gems/esp_sdk/ESP/ExternalAccount.html)
234
- * [ESP::Organization](http://www.rubydoc.info/gems/esp_sdk/ESP/Organization.html)
235
- * [ESP::Region](http://www.rubydoc.info/gems/esp_sdk/ESP/Region.html)
236
- * [ESP::Report](http://www.rubydoc.info/gems/esp_sdk/ESP/Report.html)
237
- * [ESP::Service](http://www.rubydoc.info/gems/esp_sdk/ESP/Service.html)
238
- * [ESP::Signature](http://www.rubydoc.info/gems/esp_sdk/ESP/Signature.html)
239
- * [ESP::Stat](http://www.rubydoc.info/gems/esp_sdk/ESP/Stat.html)
240
- * [ESP::SubOrganization](http://www.rubydoc.info/gems/esp_sdk/ESP/SubOrganization.html)
241
- * [ESP::Suppression](http://www.rubydoc.info/gems/esp_sdk/ESP/Suppression.html)
242
- * [ESP::Suppression::Region](http://www.rubydoc.info/gems/esp_sdk/ESP/Suppression::Region.html)
243
- * [ESP::Suppression::Signature](http://www.rubydoc.info/gems/esp_sdk/ESP/Suppression::Signature.html)
244
- * [ESP::Suppression::UniqueIdentifier](http://www.rubydoc.info/gems/esp_sdk/ESP/Suppression::UniqueIdentifier.html)
245
- * [ESP::Tag](http://www.rubydoc.info/gems/esp_sdk/ESP/Tag.html)
246
- * [ESP::Team](http://www.rubydoc.info/gems/esp_sdk/ESP/Team.html)
247
- * [ESP::User](http://www.rubydoc.info/gems/esp_sdk/ESP/User.html)
474
+ * ESP::Alert
475
+ * ESP::CloudTrailEvent
476
+ * ESP::ContactRequest
477
+ * ESP::CustomSignature
478
+ * ESP::Dashboard
479
+ * ESP::ExternalAccount
480
+ * ESP::Organization
481
+ * ESP::Region
482
+ * ESP::Report
483
+ * ESP::Service
484
+ * ESP::Signature
485
+ * ESP::Stat
486
+ * ESP::Stat
487
+ * ESP::Stat
488
+ * ESP::Stat
489
+ * ESP::Stat
490
+ * ESP::SubOrganization
491
+ * ESP::Suppression
492
+ * ESP::Suppression::Region
493
+ * ESP::Suppression::Signature
494
+ * ESP::Suppression::UniqueIdentifier
495
+ * ESP::Tag
496
+ * ESP::Team
497
+ * ESP::User
248
498
 
249
499
  # Console
250
- The Evident.io SDK gem also provides an IRB console you can use if not using it in a Rails app. Run it with `bin/esp_console`
500
+ The Evident.io SDK gem also provides an IRB console you can use if not using it in a Rails app. Run it with `esp console` or use the shortcut `esp c`
501
+
502
+ # Add External Account Script
503
+ The `esp` executable can also run a script that will create an external account and team for an already created sub organization that has the name 'AutoCreate'.
504
+ The script can be run with the command `esp add_external_account` or the shortcut `esp a`.
505
+
506
+ To run this script you will need to install the aws-sdk gem.
507
+
508
+ gem install aws-sdk
251
509
 
510
+ Additional information can be found in the help. `esp add_external_account -h`
252
511
 
253
512
  ## Contributing
254
513
 
data/bin/esp ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ ARGV << '--help' if ARGV.empty?
3
+
4
+ aliases = {
5
+ "c" => "console",
6
+ "a" => "add_external_account"
7
+ }
8
+
9
+ command = ARGV.shift
10
+ command = aliases[command] || command
11
+
12
+ require_relative '../lib/esp/commands/commands_tasks'
13
+
14
+ ESP::CommandsTasks.new(ARGV).run_command!(command)
15
+
data/esp_sdk.gemspec CHANGED
@@ -34,6 +34,8 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency 'coveralls'
35
35
  spec.add_development_dependency 'factory_girl'
36
36
  spec.add_development_dependency 'rdoc'
37
+ spec.add_development_dependency 'awesome_print'
38
+ spec.add_development_dependency 'aws-sdk'
37
39
 
38
40
  spec.add_dependency 'activeresource', '~> 4.0.0'
39
41
  spec.add_dependency 'api-auth'
@@ -0,0 +1,60 @@
1
+ require 'aws-sdk'
2
+
3
+ module ESP # :nodoc: all
4
+ class AWSClients
5
+ include ActiveModel::Validations
6
+
7
+ ESP_OWNER_ID = { "production" => "613698206329".freeze }.freeze
8
+ AWS_ROLE_NAME = "Evident-Service-Role-AutoCreate".freeze
9
+ AWS_ROLE_POLICY_ARN = "arn:aws:iam::aws:policy/SecurityAudit".freeze
10
+
11
+ validates :owner_id, length: { is: 12 }, numericality: true
12
+
13
+ def create_and_attach_role!(external_account_id)
14
+ role = iam.create_role(role_name: AWS_ROLE_NAME, assume_role_policy_document: trust_policy(external_account_id))
15
+ iam.attach_role_policy(role_name: AWS_ROLE_NAME, policy_arn: AWS_ROLE_POLICY_ARN)
16
+ role
17
+ end
18
+
19
+ def owner_id
20
+ @owner_id ||= ec2.describe_security_groups.security_groups[0].owner_id
21
+ end
22
+
23
+ private
24
+
25
+ def ec2
26
+ @ec2 ||= Aws::EC2::Client.new
27
+ end
28
+
29
+ def iam
30
+ @iam ||= Aws::IAM::Client.new
31
+ end
32
+
33
+ def esp_owner_id
34
+ ESP_OWNER_ID.fetch(ESP.env, "762160981991")
35
+ end
36
+
37
+ def trust_policy(external_account_id) # rubocop:disable Metrics/MethodLength
38
+ <<TRUST_POLICY
39
+ {
40
+ "Version": "2012-10-17",
41
+ "Statement": [
42
+ {
43
+ "Sid": "",
44
+ "Effect": "Allow",
45
+ "Principal": {
46
+ "AWS": "arn:aws:iam::#{esp_owner_id}:root"
47
+ },
48
+ "Action": "sts:AssumeRole",
49
+ "Condition": {
50
+ "StringEquals": {
51
+ "sts:ExternalId": "#{external_account_id}"
52
+ }
53
+ }
54
+ }
55
+ ]
56
+ }
57
+ TRUST_POLICY
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,57 @@
1
+ require 'optparse'
2
+
3
+ ARGV.clone.options do |opts|
4
+ opts.banner = "Usage: esp add_external_account"
5
+
6
+ opts.separator ""
7
+
8
+ opts.on("-h", "--help",
9
+ "Show this help message.") do
10
+ puts opts # rubocop:disable Rails/Output
11
+ exit
12
+ end
13
+
14
+ opts.separator ""
15
+ opts.separator "Adds external accounts to ESP"
16
+ opts.separator ""
17
+ opts.separator " NOTE: This program automatically generates new teams for every external account added. Some modifications may"
18
+ opts.separator " be required if you would like to organize accounts into specific teams. Please contact support@evident.io"
19
+ opts.separator " if you have any questions."
20
+ opts.separator ""
21
+ opts.separator " AWS SDK for Ruby v2 required"
22
+ opts.separator " Install it by running `gem install aws-sdk`"
23
+ opts.separator " http://docs.aws.amazon.com/sdkforruby/api/"
24
+ opts.separator ""
25
+ opts.separator " The AWS SDK for Ruby requires credentials to be set via environment variables, configuration file,"
26
+ opts.separator " or within the program. Also, you must set an AWS region for the SDK to communicate with the AWS"
27
+ opts.separator " service endpoints. It is recommended that you set environment variables before proceeding."
28
+ opts.separator ""
29
+ opts.separator " Required variables:"
30
+ opts.separator " ENV['AWS_REGION']"
31
+ opts.separator " ENV['AWS_ACCESS_KEY_ID']"
32
+ opts.separator " ENV['AWS_SECRET_ACCESS_KEY']"
33
+ opts.separator " ENV['AWS_SESSION_TOKEN'] (if generating credentials using STS AssumeRole)"
34
+ opts.separator ""
35
+ opts.separator " The ESP SDK for Ruby requires credentials to be set via environment variables or within the program."
36
+ opts.separator " It is recommended that you set environment variables before proceeding."
37
+ opts.separator " See the documentation for more information. http://www.rubydoc.info/gems/esp_sdk/"
38
+ opts.separator ""
39
+ opts.separator " Required variables:"
40
+ opts.separator " ENV['ESP_ACCESS_KEY_ID']"
41
+ opts.separator " ENV['ESP_SECRET_ACCESS_KEY']"
42
+ opts.separator ""
43
+ opts.separator " Generate ESP keys at:"
44
+ opts.separator " https://esp.evident.io/settings/profile"
45
+ opts.separator ""
46
+
47
+ opts.parse!
48
+ end
49
+
50
+ begin
51
+ external_account = ESP::ExternalAccountCreator.new.create
52
+ puts "done on #{external_account.created_at}" # rubocop:disable Rails/Output
53
+ rescue ESP::AddExternalAccountError => e
54
+ puts e.message.inspect # rubocop:disable Rails/Output
55
+ puts e.backtrace # rubocop:disable Rails/Output
56
+ exit e.exit_code
57
+ end
@@ -0,0 +1,106 @@
1
+ module ESP
2
+ # This is a class which takes in an esp command and initiates the appropriate
3
+ # initiation sequence.
4
+ #
5
+ # Warning: This class mutates ARGV because some commands require manipulating
6
+ # it before they are run.
7
+ class CommandsTasks # :nodoc:
8
+ attr_reader :argv
9
+
10
+ HELP_MESSAGE = <<-EOT
11
+ Usage: esp COMMAND [environment] [ARGS]
12
+
13
+ The ESP commands are:
14
+ console Start the ESP console (short-cut alias: "c")
15
+ add_external_account Adds external accounts to ESP (short-cut alias: "a")
16
+
17
+ All commands can be run with -h (or --help) for more information.
18
+ EOT
19
+
20
+ COMMAND_WHITELIST = %w(console add_external_account version help)
21
+
22
+ def initialize(argv)
23
+ @argv = argv
24
+ end
25
+
26
+ def run_command!(command)
27
+ command = parse_command(command)
28
+ if COMMAND_WHITELIST.include?(command)
29
+ set_env!
30
+ require_relative '../../../lib/esp_sdk'
31
+ send(command)
32
+ else
33
+ write_error_message(command)
34
+ end
35
+ end
36
+
37
+ def console
38
+ require_command!("console")
39
+
40
+ print_banner
41
+ ESP::Console.new.start
42
+ end
43
+
44
+ def add_external_account
45
+ require_command!("add_external_account")
46
+ end
47
+
48
+ def version
49
+ puts "ESP #{ESP::VERSION}" # rubocop:disable Rails/Output
50
+ exit(0)
51
+ end
52
+
53
+ def help
54
+ write_help_message
55
+ end
56
+
57
+ private
58
+
59
+ def shift_argv!
60
+ argv.shift if argv.first && argv.first[0] != '-'
61
+ end
62
+
63
+ def require_command!(command)
64
+ require_relative "./#{command}"
65
+ end
66
+
67
+ def set_env!
68
+ ENV['ESP_ENV'] = argv.first if argv.first && argv.first[0] != '-'
69
+ end
70
+
71
+ def write_help_message
72
+ puts HELP_MESSAGE # rubocop:disable Rails/Output
73
+ end
74
+
75
+ def write_error_message(command)
76
+ puts "Error: Command '#{command}' not recognized" # rubocop:disable Rails/Output
77
+ write_help_message
78
+ exit(1)
79
+ end
80
+
81
+ def parse_command(command)
82
+ case command
83
+ when '--version', '-v'
84
+ 'version'
85
+ when '--help', '-h'
86
+ 'help'
87
+ else
88
+ command
89
+ end
90
+ end
91
+
92
+ def print_banner
93
+ begin
94
+ puts File.read(File.expand_path(File.dirname(__FILE__) + '/../../../assets/esp_logo.ans')) # rubocop:disable Rails/Output
95
+ rescue # rubocop:disable Lint/HandleExceptions
96
+ # swallow the error
97
+ end
98
+ print <<-banner # rubocop:disable Rails/Output
99
+
100
+ Evident Security Platform Console #{ESP::VERSION}
101
+ Copyright (c) 2013-#{Time.current.year} Evident Security, All Rights Reserved.
102
+ http://www.evident.io
103
+ banner
104
+ end
105
+ end
106
+ end