esp_sdk 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,748 +0,0 @@
1
- <!DOCTYPE html>
2
-
3
- <html>
4
- <head>
5
- <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
6
-
7
- <title>class ESP::CustomSignature - ESPSDK</title>
8
-
9
- <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet">
10
-
11
- <script type="text/javascript">
12
- var rdoc_rel_prefix = "../";
13
- </script>
14
-
15
- <script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
16
- <script type="text/javascript" charset="utf-8" src="../js/navigation.js"></script>
17
- <script type="text/javascript" charset="utf-8" src="../js/search_index.js"></script>
18
- <script type="text/javascript" charset="utf-8" src="../js/search.js"></script>
19
- <script type="text/javascript" charset="utf-8" src="../js/searcher.js"></script>
20
- <script type="text/javascript" charset="utf-8" src="../js/darkfish.js"></script>
21
-
22
-
23
- <body id="top" class="class">
24
- <nav id="metadata">
25
- <nav id="home-section" class="section">
26
- <h3 class="section-header">
27
- <a href="../index.html">Home</a>
28
- <a href="../table_of_contents.html#classes">Classes</a>
29
- <a href="../table_of_contents.html#methods">Methods</a>
30
- </h3>
31
- </nav>
32
-
33
-
34
- <nav id="search-section" class="section project-section" class="initially-hidden">
35
- <form action="#" method="get" accept-charset="utf-8">
36
- <h3 class="section-header">
37
- <input type="text" name="search" placeholder="Search" id="search-field"
38
- title="Type to search, Up and Down to navigate, Enter to load">
39
- </h3>
40
- </form>
41
-
42
- <ul id="search-results" class="initially-hidden"></ul>
43
- </nav>
44
-
45
-
46
-
47
-
48
- <div id="file-metadata">
49
- <nav id="file-list-section" class="section">
50
- <h3 class="section-header">Defined In</h3>
51
- <ul>
52
- <li>lib/esp/resources/custom_signature.rb
53
- </ul>
54
- </nav>
55
-
56
-
57
- </div>
58
-
59
- <div id="class-metadata">
60
-
61
- <nav id="parent-class-section" class="section">
62
- <h3 class="section-header">Parent</h3>
63
-
64
- <p class="link">ESP::Resource
65
-
66
- </nav>
67
-
68
-
69
-
70
- <!-- Method Quickref -->
71
- <nav id="method-list-section" class="section">
72
- <h3 class="section-header">Methods</h3>
73
-
74
- <ul class="link-list">
75
-
76
- <li ><a href="#method-c-all">::all</a>
77
-
78
- <li ><a href="#method-c-create">::create</a>
79
-
80
- <li ><a href="#method-c-find">::find</a>
81
-
82
- <li ><a href="#method-c-run">::run</a>
83
-
84
- <li ><a href="#method-c-run-21">::run!</a>
85
-
86
- <li ><a href="#method-i-organization">#organization</a>
87
-
88
- <li ><a href="#method-i-run">#run</a>
89
-
90
- <li ><a href="#method-i-run-21">#run!</a>
91
-
92
- <li ><a href="#method-i-save">#save</a>
93
-
94
- <li ><a href="#method-i-suppress">#suppress</a>
95
-
96
- </ul>
97
- </nav>
98
-
99
- </div>
100
-
101
- <div id="project-metadata">
102
- <nav id="fileindex-section" class="section project-section">
103
- <h3 class="section-header">Pages</h3>
104
-
105
- <ul>
106
-
107
- <li class="file"><a href="../README_md.html">README</a>
108
-
109
- </ul>
110
- </nav>
111
-
112
- <nav id="classindex-section" class="section project-section">
113
- <h3 class="section-header">Class and Module Index</h3>
114
-
115
- <ul class="link-list">
116
-
117
- <li><a href="../ActiveResource.html">ActiveResource</a>
118
-
119
- <li><a href="../ActiveResource/Formats.html">ActiveResource::Formats</a>
120
-
121
- <li><a href="../ActiveResource/PaginatedCollection.html">ActiveResource::PaginatedCollection</a>
122
-
123
- <li><a href="../ESP.html">ESP</a>
124
-
125
- <li><a href="../ESP/Alert.html">ESP::Alert</a>
126
-
127
- <li><a href="../ESP/CloudTrailEvent.html">ESP::CloudTrailEvent</a>
128
-
129
- <li><a href="../ESP/ContactRequest.html">ESP::ContactRequest</a>
130
-
131
- <li><a href="../ESP/CustomSignature.html">ESP::CustomSignature</a>
132
-
133
- <li><a href="../ESP/Dashboard.html">ESP::Dashboard</a>
134
-
135
- <li><a href="../ESP/ExternalAccount.html">ESP::ExternalAccount</a>
136
-
137
- <li><a href="../ESP/Metadata.html">ESP::Metadata</a>
138
-
139
- <li><a href="../ESP/Organization.html">ESP::Organization</a>
140
-
141
- <li><a href="../ESP/Region.html">ESP::Region</a>
142
-
143
- <li><a href="../ESP/Report.html">ESP::Report</a>
144
-
145
- <li><a href="../ESP/Service.html">ESP::Service</a>
146
-
147
- <li><a href="../ESP/Signature.html">ESP::Signature</a>
148
-
149
- <li><a href="../ESP/Stat.html">ESP::Stat</a>
150
-
151
- <li><a href="../ESP/StatCustomSignature.html">ESP::StatCustomSignature</a>
152
-
153
- <li><a href="../ESP/StatRegion.html">ESP::StatRegion</a>
154
-
155
- <li><a href="../ESP/StatService.html">ESP::StatService</a>
156
-
157
- <li><a href="../ESP/StatSignature.html">ESP::StatSignature</a>
158
-
159
- <li><a href="../ESP/SubOrganization.html">ESP::SubOrganization</a>
160
-
161
- <li><a href="../ESP/Suppression.html">ESP::Suppression</a>
162
-
163
- <li><a href="../ESP/Suppression/Region.html">ESP::Suppression::Region</a>
164
-
165
- <li><a href="../ESP/Suppression/Signature.html">ESP::Suppression::Signature</a>
166
-
167
- <li><a href="../ESP/Suppression/UniqueIdentifier.html">ESP::Suppression::UniqueIdentifier</a>
168
-
169
- <li><a href="../ESP/Tag.html">ESP::Tag</a>
170
-
171
- <li><a href="../ESP/Team.html">ESP::Team</a>
172
-
173
- <li><a href="../ESP/User.html">ESP::User</a>
174
-
175
- </ul>
176
- </nav>
177
-
178
- </div>
179
- </nav>
180
-
181
- <div id="documentation">
182
- <h1 class="class">class ESP::CustomSignature</h1>
183
-
184
- <div id="description" class="description">
185
-
186
- </div><!-- description -->
187
-
188
-
189
-
190
-
191
- <section id="5Buntitled-5D" class="documentation-section">
192
-
193
-
194
-
195
-
196
-
197
-
198
-
199
-
200
- <!-- Methods -->
201
-
202
- <section id="public-class-5Buntitled-5D-method-details" class="method-section section">
203
- <h3 class="section-header">Public Class Methods</h3>
204
-
205
-
206
- <div id="method-c-all" class="method-detail ">
207
-
208
- <div class="method-heading">
209
- <span class="method-name">all</span><span
210
- class="method-args">()</span>
211
-
212
- <span class="method-click-advice">click to toggle source</span>
213
-
214
- </div>
215
-
216
-
217
- <div class="method-description">
218
-
219
- <p>Return a paginated <a href="CustomSignature.html">CustomSignature</a> list</p>
220
-
221
-
222
-
223
-
224
- <div class="method-source-code" id="all-source">
225
- <pre><span class="ruby-comment"># File lib/esp/resources/custom_signature.rb, line 152</span>
226
- </pre>
227
- </div><!-- all-source -->
228
-
229
- </div>
230
-
231
-
232
-
233
-
234
- </div><!-- all-method -->
235
-
236
-
237
- <div id="method-c-create" class="method-detail ">
238
-
239
-
240
- <div class="method-heading">
241
- <span class="method-callseq">
242
- create(attributes={})
243
- </span>
244
-
245
- <span class="method-click-advice">click to toggle source</span>
246
-
247
- </div>
248
-
249
-
250
-
251
- <div class="method-description">
252
-
253
- <p>Create a <a href="CustomSignature.html">CustomSignature</a></p>
254
-
255
- <h4 id="method-c-create-label-Parameter">Parameter<span><a href="#method-c-create-label-Parameter">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
256
-
257
- <p><code>attributes</code> | Required | A hash of custom signature attributes</p>
258
-
259
- <h5 id="method-c-create-label-Valid+Attributes">Valid Attributes<span><a href="#method-c-create-label-Valid+Attributes">&para;</a> <a href="#documentation">&uarr;</a></span></h5>
260
-
261
- <p><code>active</code> | Not Required | Flag that determines if this custom
262
- signature should run on reports</p>
263
-
264
- <p><code>description</code> | Not Required | The description of the custom
265
- signature that is displayed on alerts</p>
266
-
267
- <p><code>identifier</code> | Required | The identifier to use for the custom
268
- signature. Common format is AWS:&lt;Service&gt;-&lt;Number&gt; such as
269
- AWS:IAM-001</p>
270
-
271
- <p><code>language</code> | Required | The language of the custom signature.
272
- Possible values are `ruby` or `javascript`</p>
273
-
274
- <p><code>name</code> | Required | The name of the custom signature</p>
275
-
276
- <p><code>resolution</code> | Not Required | Details for how to resolve this
277
- custom signature that is displayed on alerts</p>
278
-
279
- <p><code>risk_level</code> | Required | The risk-level of the problem
280
- identified by the custom signature</p>
281
-
282
- <p><code>signature</code> | Required | The code for this custom signature</p>
283
-
284
- <h4 id="method-c-create-label-Example">Example<span><a href="#method-c-create-label-Example">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
285
-
286
- <pre class="ruby"><span class="ruby-identifier">signature</span> = <span class="ruby-node">&quot;# Demo Ruby Signature\r\nconfigure do |c|\r\n # Set regions to run in. Remove this line to run in all regions.\r\n c.valid_regions = [:us_east_1]\r\n # Override region to display as global. Useful when checking resources\r\n # like IAM that do not have a specific region.\r\n c.display_as = :global\r\n # deep_inspection works with set_data to automically collect\r\n # data fields for each alert. Not required.\r\n c.deep_inspection = [:users]\r\nend\r\n\r\n# Required perform method\r\ndef perform(aws)\r\n list_users = aws.iam.list_users\r\n count = list_users[:users].count\r\n\r\n # Set data for deep_inspection to use\r\n set_data(list_users)\r\n\r\n if count == 0\r\n fail(user_count: count, condition: &#39;count == 0&#39;)\r\n else\r\n pass(user_count: count, condition: &#39;count &gt;= 1&#39;)\r\n end\r\nend\r\n&quot;</span>
287
- <span class="ruby-identifier">custom_signature</span> = <span class="ruby-constant">ESP</span><span class="ruby-operator">::</span><span class="ruby-constant">CustomSignature</span>.<span class="ruby-identifier">create</span>(<span class="ruby-identifier">signature</span><span class="ruby-operator">:</span> <span class="ruby-identifier">signature</span>, <span class="ruby-identifier">description</span><span class="ruby-operator">:</span> <span class="ruby-string">&quot;A test custom signature.&quot;</span>, <span class="ruby-identifier">identifier</span><span class="ruby-operator">:</span> <span class="ruby-string">&quot;AWS::IAM::001&quot;</span>, <span class="ruby-identifier">language</span><span class="ruby-operator">:</span> <span class="ruby-string">&quot;ruby&quot;</span>, <span class="ruby-identifier">name</span><span class="ruby-operator">:</span> <span class="ruby-string">&quot;Test Signature&quot;</span>, <span class="ruby-identifier">risk_level</span><span class="ruby-operator">:</span> <span class="ruby-string">&quot;Medium&quot;</span>)
288
- </pre>
289
-
290
-
291
-
292
-
293
- <div class="method-source-code" id="create-source">
294
- <pre><span class="ruby-comment"># File lib/esp/resources/custom_signature.rb, line 184</span>
295
- </pre>
296
- </div><!-- create-source -->
297
-
298
- </div>
299
-
300
-
301
-
302
-
303
- </div><!-- create-method -->
304
-
305
-
306
- <div id="method-c-find" class="method-detail ">
307
-
308
-
309
- <div class="method-heading">
310
- <span class="method-callseq">
311
- find(id)
312
- </span>
313
-
314
- <span class="method-click-advice">click to toggle source</span>
315
-
316
- </div>
317
-
318
-
319
-
320
- <div class="method-description">
321
-
322
- <p>Find a <a href="CustomSignature.html">CustomSignature</a> by id</p>
323
-
324
- <h4 id="method-c-find-label-Parameter">Parameter<span><a href="#method-c-find-label-Parameter">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
325
-
326
- <p><code>id</code> | Required | The ID of the custom signature to retrieve</p>
327
-
328
-
329
-
330
-
331
- <div class="method-source-code" id="find-source">
332
- <pre><span class="ruby-comment"># File lib/esp/resources/custom_signature.rb, line 149</span>
333
- </pre>
334
- </div><!-- find-source -->
335
-
336
- </div>
337
-
338
-
339
-
340
-
341
- </div><!-- find-method -->
342
-
343
-
344
- <div id="method-c-run" class="method-detail ">
345
-
346
- <div class="method-heading">
347
- <span class="method-name">run</span><span
348
- class="method-args">(arguments = {})</span>
349
-
350
- <span class="method-click-advice">click to toggle source</span>
351
-
352
- </div>
353
-
354
-
355
- <div class="method-description">
356
-
357
- <p>Run a custom signature that has not been saved. Useful for debugging a
358
- custom signature. Returns a collection of alerts. If not successful,
359
- returns a <a href="CustomSignature.html">CustomSignature</a> object with
360
- the errors object populated.</p>
361
-
362
- <h4 id="method-c-run-label-Parameters">Parameters<span><a href="#method-c-run-label-Parameters">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
363
-
364
- <p><code>arguments</code> | Required | A hash of run arguments</p>
365
-
366
- <h5 id="method-c-run-label-Valid+Arguments">Valid Arguments<span><a href="#method-c-run-label-Valid+Arguments">&para;</a> <a href="#documentation">&uarr;</a></span></h5>
367
-
368
- <p><code>external_account_id</code> | Required | The ID of the external
369
- account to run this custom signature against</p>
370
-
371
- <p><code>signature</code> | Required | The code for this custom signature</p>
372
-
373
- <p><code>language</code> | Required | The language of the custom signature.
374
- Possible values are `ruby` or `javascript`</p>
375
-
376
- <p><code>regions</code> | Required | Array of region names to run this custom
377
- signature against</p>
378
-
379
- <h4 id="method-c-run-label-Example">Example<span><a href="#method-c-run-label-Example">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
380
-
381
- <pre class="ruby"><span class="ruby-identifier">signature</span> = <span class="ruby-node">&quot;# Demo Ruby Signature\r\nconfigure do |c|\r\n # Set regions to run in. Remove this line to run in all regions.\r\n c.valid_regions = [:us_east_1]\r\n # Override region to display as global. Useful when checking resources\r\n # like IAM that do not have a specific region.\r\n c.display_as = :global\r\n # deep_inspection works with set_data to automically collect\r\n # data fields for each alert. Not required.\r\n c.deep_inspection = [:users]\r\nend\r\n\r\n# Required perform method\r\ndef perform(aws)\r\n list_users = aws.iam.list_users\r\n count = list_users[:users].count\r\n\r\n # Set data for deep_inspection to use\r\n set_data(list_users)\r\n\r\n if count == 0\r\n fail(user_count: count, condition: &#39;count == 0&#39;)\r\n else\r\n pass(user_count: count, condition: &#39;count &gt;= 1&#39;)\r\n end\r\nend\r\n&quot;</span>
382
- <span class="ruby-identifier">alerts</span> = <span class="ruby-constant">ESP</span><span class="ruby-operator">::</span><span class="ruby-constant">CustomSignature</span>.<span class="ruby-identifier">run</span>(<span class="ruby-identifier">external_account_id</span><span class="ruby-operator">:</span> <span class="ruby-value">3</span>, <span class="ruby-identifier">regions</span><span class="ruby-operator">:</span> [<span class="ruby-string">&#39;us_east_1&#39;</span>], <span class="ruby-identifier">language</span><span class="ruby-operator">:</span> <span class="ruby-string">&#39;ruby&#39;</span>, <span class="ruby-identifier">signature</span><span class="ruby-operator">:</span> <span class="ruby-identifier">signature</span>)
383
- </pre>
384
-
385
-
386
-
387
-
388
- <div class="method-source-code" id="run-source">
389
- <pre><span class="ruby-comment"># File lib/esp/resources/custom_signature.rb, line 56</span>
390
- <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">run</span>(<span class="ruby-identifier">arguments</span> = {})
391
- <span class="ruby-identifier">arguments</span> = <span class="ruby-identifier">arguments</span>.<span class="ruby-identifier">with_indifferent_access</span>
392
- <span class="ruby-identifier">arguments</span>[<span class="ruby-value">:regions</span>] = <span class="ruby-constant">Array</span>(<span class="ruby-identifier">arguments</span>[<span class="ruby-value">:regions</span>])
393
- <span class="ruby-identifier">new</span>(<span class="ruby-identifier">arguments</span>).<span class="ruby-identifier">run</span>
394
- <span class="ruby-keyword">end</span></pre>
395
- </div><!-- run-source -->
396
-
397
- </div>
398
-
399
-
400
-
401
-
402
- </div><!-- run-method -->
403
-
404
-
405
- <div id="method-c-run-21" class="method-detail ">
406
-
407
- <div class="method-heading">
408
- <span class="method-name">run!</span><span
409
- class="method-args">(arguments = {})</span>
410
-
411
- <span class="method-click-advice">click to toggle source</span>
412
-
413
- </div>
414
-
415
-
416
- <div class="method-description">
417
-
418
- <p>Run a custom signature that has not been saved. Useful for debugging a
419
- custom signature. Returns a collection of alerts. Throws an error if not
420
- successful.</p>
421
-
422
- <h4 id="method-c-run-21-label-Parameters">Parameters<span><a href="#method-c-run-21-label-Parameters">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
423
-
424
- <p><code>arguments</code> | Required | A hash of run arguments</p>
425
-
426
- <h5 id="method-c-run-21-label-Valid+Arguments">Valid Arguments<span><a href="#method-c-run-21-label-Valid+Arguments">&para;</a> <a href="#documentation">&uarr;</a></span></h5>
427
-
428
- <p><code>external_account_id</code> | Required | The ID of the external
429
- account to run this custom signature against</p>
430
-
431
- <p><code>signature</code> | Required | The code for this custom signature</p>
432
-
433
- <p><code>language</code> | Required | The language of the custom signature.
434
- Possible values are `ruby` or `javascript`</p>
435
-
436
- <p><code>regions</code> | Required | Array of region names to run this custom
437
- signature against</p>
438
-
439
- <h4 id="method-c-run-21-label-Example">Example<span><a href="#method-c-run-21-label-Example">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
440
-
441
- <pre class="ruby"><span class="ruby-identifier">signature</span> = <span class="ruby-node">&quot;# Demo Ruby Signature\r\nconfigure do |c|\r\n # Set regions to run in. Remove this line to run in all regions.\r\n c.valid_regions = [:us_east_1]\r\n # Override region to display as global. Useful when checking resources\r\n # like IAM that do not have a specific region.\r\n c.display_as = :global\r\n # deep_inspection works with set_data to automically collect\r\n # data fields for each alert. Not required.\r\n c.deep_inspection = [:users]\r\nend\r\n\r\n# Required perform method\r\ndef perform(aws)\r\n list_users = aws.iam.list_users\r\n count = list_users[:users].count\r\n\r\n # Set data for deep_inspection to use\r\n set_data(list_users)\r\n\r\n if count == 0\r\n fail(user_count: count, condition: &#39;count == 0&#39;)\r\n else\r\n pass(user_count: count, condition: &#39;count &gt;= 1&#39;)\r\n end\r\nend\r\n&quot;</span>
442
- <span class="ruby-identifier">alerts</span> = <span class="ruby-constant">ESP</span><span class="ruby-operator">::</span><span class="ruby-constant">CustomSignature</span>.<span class="ruby-identifier">run!</span>(<span class="ruby-identifier">external_account_id</span><span class="ruby-operator">:</span> <span class="ruby-value">3</span>, <span class="ruby-identifier">regions</span><span class="ruby-operator">:</span> [<span class="ruby-string">&#39;us_east_1&#39;</span>], <span class="ruby-identifier">language</span><span class="ruby-operator">:</span> <span class="ruby-string">&#39;ruby&#39;</span>, <span class="ruby-identifier">signature</span><span class="ruby-operator">:</span> <span class="ruby-identifier">signature</span>)
443
- </pre>
444
-
445
-
446
-
447
-
448
- <div class="method-source-code" id="run-21-source">
449
- <pre><span class="ruby-comment"># File lib/esp/resources/custom_signature.rb, line 28</span>
450
- <span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">run!</span>(<span class="ruby-identifier">arguments</span> = {})
451
- <span class="ruby-identifier">result</span> = <span class="ruby-identifier">run</span>(<span class="ruby-identifier">arguments</span>)
452
- <span class="ruby-keyword">return</span> <span class="ruby-identifier">result</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">ActiveResource</span><span class="ruby-operator">::</span><span class="ruby-constant">Collection</span>)
453
- <span class="ruby-identifier">result</span>.<span class="ruby-identifier">message</span> = <span class="ruby-identifier">result</span>.<span class="ruby-identifier">errors</span>.<span class="ruby-identifier">full_messages</span>.<span class="ruby-identifier">join</span>(<span class="ruby-string">&#39; &#39;</span>)
454
- <span class="ruby-identifier">fail</span>(<span class="ruby-constant">ActiveResource</span><span class="ruby-operator">::</span><span class="ruby-constant">ResourceInvalid</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">result</span>)) <span class="ruby-comment"># rubocop:disable Style/RaiseArgs</span>
455
- <span class="ruby-keyword">end</span></pre>
456
- </div><!-- run-21-source -->
457
-
458
- </div>
459
-
460
-
461
-
462
-
463
- </div><!-- run-21-method -->
464
-
465
-
466
- </section><!-- public-class-method-details -->
467
-
468
- <section id="public-instance-5Buntitled-5D-method-details" class="method-section section">
469
- <h3 class="section-header">Public Instance Methods</h3>
470
-
471
-
472
- <div id="method-i-organization" class="method-detail ">
473
-
474
- <div class="method-heading">
475
- <span class="method-name">organization</span><span
476
- class="method-args">()</span>
477
-
478
- <span class="method-click-advice">click to toggle source</span>
479
-
480
- </div>
481
-
482
-
483
- <div class="method-description">
484
-
485
- <p>The organization this custom signature belongs to.</p>
486
-
487
-
488
-
489
-
490
- <div class="method-source-code" id="organization-source">
491
- <pre><span class="ruby-comment"># File lib/esp/resources/custom_signature.rb, line 5</span>
492
- <span class="ruby-identifier">belongs_to</span> <span class="ruby-value">:organization</span>, <span class="ruby-identifier">class_name</span><span class="ruby-operator">:</span> <span class="ruby-string">&#39;ESP::Organization&#39;</span>
493
- </pre>
494
- </div><!-- organization-source -->
495
-
496
- </div>
497
-
498
-
499
-
500
-
501
- </div><!-- organization-method -->
502
-
503
-
504
- <div id="method-i-run" class="method-detail ">
505
-
506
- <div class="method-heading">
507
- <span class="method-name">run</span><span
508
- class="method-args">(arguments = {})</span>
509
-
510
- <span class="method-click-advice">click to toggle source</span>
511
-
512
- </div>
513
-
514
-
515
- <div class="method-description">
516
-
517
- <p>Run this custom signature instance. Returns a collection of alerts. If not
518
- successful, returns a <a href="CustomSignature.html">CustomSignature</a>
519
- object with the errors object populated.</p>
520
-
521
- <h4 id="method-i-run-label-Parameters">Parameters<span><a href="#method-i-run-label-Parameters">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
522
-
523
- <p><code>arguments</code> | Required | A hash of run arguments</p>
524
-
525
- <h5 id="method-i-run-label-Valid+Arguments">Valid Arguments<span><a href="#method-i-run-label-Valid+Arguments">&para;</a> <a href="#documentation">&uarr;</a></span></h5>
526
-
527
- <p><code>external_account_id</code> | Required | The ID of the external
528
- account to run this custom signature against</p>
529
-
530
- <p><code>regions</code> | Required | Array of region names to run this custom
531
- signature against</p>
532
-
533
- <h4 id="method-i-run-label-Example">Example<span><a href="#method-i-run-label-Example">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
534
-
535
- <pre>custom_signature = ESP::CustomSignature.find(365)
536
- alerts = custom_signature.run(external_account_id: 3, regions: [&#39;us_east_1&#39;])</pre>
537
-
538
-
539
-
540
-
541
- <div class="method-source-code" id="run-source">
542
- <pre><span class="ruby-comment"># File lib/esp/resources/custom_signature.rb, line 103</span>
543
- <span class="ruby-keyword">def</span> <span class="ruby-identifier">run</span>(<span class="ruby-identifier">arguments</span> = {})
544
- <span class="ruby-identifier">arguments</span> = <span class="ruby-identifier">arguments</span>.<span class="ruby-identifier">with_indifferent_access</span>
545
-
546
- <span class="ruby-identifier">attributes</span>[<span class="ruby-string">&#39;external_account_id&#39;</span>] <span class="ruby-operator">||=</span> <span class="ruby-identifier">arguments</span>[<span class="ruby-value">:external_account_id</span>]
547
- <span class="ruby-identifier">attributes</span>[<span class="ruby-string">&#39;regions&#39;</span>] <span class="ruby-operator">||=</span> <span class="ruby-constant">Array</span>(<span class="ruby-identifier">arguments</span>[<span class="ruby-value">:regions</span>])
548
-
549
- <span class="ruby-identifier">response</span> = <span class="ruby-identifier">connection</span>.<span class="ruby-identifier">post</span> <span class="ruby-identifier">endpoint</span>, <span class="ruby-identifier">to_json</span>
550
- <span class="ruby-constant">ESP</span><span class="ruby-operator">::</span><span class="ruby-constant">Alert</span>.<span class="ruby-identifier">send</span>(<span class="ruby-value">:instantiate_collection</span>, <span class="ruby-keyword">self</span>.<span class="ruby-identifier">class</span>.<span class="ruby-identifier">format</span>.<span class="ruby-identifier">decode</span>(<span class="ruby-identifier">response</span>.<span class="ruby-identifier">body</span>))
551
- <span class="ruby-keyword">rescue</span> <span class="ruby-constant">ActiveResource</span><span class="ruby-operator">::</span><span class="ruby-constant">BadRequest</span>, <span class="ruby-constant">ActiveResource</span><span class="ruby-operator">::</span><span class="ruby-constant">ResourceInvalid</span>, <span class="ruby-constant">ActiveResource</span><span class="ruby-operator">::</span><span class="ruby-constant">ResourceNotFound</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">error</span>
552
- <span class="ruby-identifier">load_remote_errors</span>(<span class="ruby-identifier">error</span>, <span class="ruby-keyword">true</span>)
553
- <span class="ruby-keyword">self</span>.<span class="ruby-identifier">code</span> = <span class="ruby-identifier">error</span>.<span class="ruby-identifier">response</span>.<span class="ruby-identifier">code</span>
554
- <span class="ruby-keyword">self</span>
555
- <span class="ruby-keyword">end</span></pre>
556
- </div><!-- run-source -->
557
-
558
- </div>
559
-
560
-
561
-
562
-
563
- </div><!-- run-method -->
564
-
565
-
566
- <div id="method-i-run-21" class="method-detail ">
567
-
568
- <div class="method-heading">
569
- <span class="method-name">run!</span><span
570
- class="method-args">(arguments = {})</span>
571
-
572
- <span class="method-click-advice">click to toggle source</span>
573
-
574
- </div>
575
-
576
-
577
- <div class="method-description">
578
-
579
- <p>Run this custom signature instance. Returns a collection of alerts. Throws
580
- an error if not successful.</p>
581
-
582
- <h4 id="method-i-run-21-label-Parameters">Parameters<span><a href="#method-i-run-21-label-Parameters">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
583
-
584
- <p><code>arguments</code> | Required | A hash of run arguments</p>
585
-
586
- <h5 id="method-i-run-21-label-Valid+Arguments">Valid Arguments<span><a href="#method-i-run-21-label-Valid+Arguments">&para;</a> <a href="#documentation">&uarr;</a></span></h5>
587
-
588
- <p><code>external_account_id</code> | Required | The ID of the external
589
- account to run this custom signature against</p>
590
-
591
- <p><code>regions</code> | Required | Array of region names to run this custom
592
- signature against</p>
593
-
594
- <h4 id="method-i-run-21-label-Example">Example<span><a href="#method-i-run-21-label-Example">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
595
-
596
- <pre>custom_signature = ESP::CustomSignature.find(365)
597
- alerts = custom_signature.run!(external_account_id: 3, regions: [&#39;us_east_1&#39;])</pre>
598
-
599
-
600
-
601
-
602
- <div class="method-source-code" id="run-21-source">
603
- <pre><span class="ruby-comment"># File lib/esp/resources/custom_signature.rb, line 79</span>
604
- <span class="ruby-keyword">def</span> <span class="ruby-identifier">run!</span>(<span class="ruby-identifier">arguments</span> = {})
605
- <span class="ruby-identifier">result</span> = <span class="ruby-identifier">run</span>(<span class="ruby-identifier">arguments</span>)
606
- <span class="ruby-keyword">return</span> <span class="ruby-identifier">result</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">result</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">ActiveResource</span><span class="ruby-operator">::</span><span class="ruby-constant">Collection</span>)
607
- <span class="ruby-keyword">self</span>.<span class="ruby-identifier">message</span> = <span class="ruby-identifier">errors</span>.<span class="ruby-identifier">full_messages</span>.<span class="ruby-identifier">join</span>(<span class="ruby-string">&#39; &#39;</span>)
608
- <span class="ruby-identifier">fail</span>(<span class="ruby-constant">ActiveResource</span><span class="ruby-operator">::</span><span class="ruby-constant">ResourceInvalid</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword">self</span>)) <span class="ruby-comment"># rubocop:disable Style/RaiseArgs</span>
609
- <span class="ruby-keyword">end</span></pre>
610
- </div><!-- run-21-source -->
611
-
612
- </div>
613
-
614
-
615
-
616
-
617
- </div><!-- run-21-method -->
618
-
619
-
620
- <div id="method-i-save" class="method-detail ">
621
-
622
- <div class="method-heading">
623
- <span class="method-name">save</span><span
624
- class="method-args">()</span>
625
-
626
- <span class="method-click-advice">click to toggle source</span>
627
-
628
- </div>
629
-
630
-
631
- <div class="method-description">
632
-
633
- <p>Create or update a <a href="CustomSignature.html">CustomSignature</a></p>
634
-
635
- <h5 id="method-i-save-label-Valid+Attributes">Valid Attributes<span><a href="#method-i-save-label-Valid+Attributes">&para;</a> <a href="#documentation">&uarr;</a></span></h5>
636
-
637
- <p><code>active</code> | Not Required | Flag that determines if this custom
638
- signature should run on reports</p>
639
-
640
- <p><code>description</code> | Not Required | The description of the custom
641
- signature that is displayed on alerts</p>
642
-
643
- <p><code>identifier</code> | Required | The identifier to use for the custom
644
- signature. Common format is AWS:&lt;Service&gt;-&lt;Number&gt; such as
645
- AWS:IAM-001</p>
646
-
647
- <p><code>language</code> | Required | The language of the custom signature.
648
- Possible values are `ruby` or `javascript`</p>
649
-
650
- <p><code>name</code> | Required | The name of the custom signature</p>
651
-
652
- <p><code>resolution</code> | Not Required | Details for how to resolve this
653
- custom signature that is displayed on alerts</p>
654
-
655
- <p><code>risk_level</code> | Required | The risk-level of the problem
656
- identified by the custom signature</p>
657
-
658
- <p><code>signature</code> | Required | The code for this custom signature</p>
659
-
660
- <h4 id="method-i-save-label-Example">Example<span><a href="#method-i-save-label-Example">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
661
-
662
- <pre class="ruby"><span class="ruby-identifier">signature</span> = <span class="ruby-node">&quot;# Demo Ruby Signature\r\nconfigure do |c|\r\n # Set regions to run in. Remove this line to run in all regions.\r\n c.valid_regions = [:us_east_1]\r\n # Override region to display as global. Useful when checking resources\r\n # like IAM that do not have a specific region.\r\n c.display_as = :global\r\n # deep_inspection works with set_data to automically collect\r\n # data fields for each alert. Not required.\r\n c.deep_inspection = [:users]\r\nend\r\n\r\n# Required perform method\r\ndef perform(aws)\r\n list_users = aws.iam.list_users\r\n count = list_users[:users].count\r\n\r\n # Set data for deep_inspection to use\r\n set_data(list_users)\r\n\r\n if count == 0\r\n fail(user_count: count, condition: &#39;count == 0&#39;)\r\n else\r\n pass(user_count: count, condition: &#39;count &gt;= 1&#39;)\r\n end\r\nend\r\n&quot;</span>
663
- <span class="ruby-identifier">custom_signature</span> = <span class="ruby-constant">ESP</span><span class="ruby-operator">::</span><span class="ruby-constant">CustomSignature</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">signature</span><span class="ruby-operator">:</span> <span class="ruby-identifier">signature</span>, <span class="ruby-identifier">description</span><span class="ruby-operator">:</span> <span class="ruby-string">&quot;A test custom signature.&quot;</span>, <span class="ruby-identifier">identifier</span><span class="ruby-operator">:</span> <span class="ruby-string">&quot;AWS::IAM::001&quot;</span>, <span class="ruby-identifier">language</span><span class="ruby-operator">:</span> <span class="ruby-string">&quot;ruby&quot;</span>, <span class="ruby-identifier">name</span><span class="ruby-operator">:</span> <span class="ruby-string">&quot;Test Signature&quot;</span>, <span class="ruby-identifier">risk_level</span><span class="ruby-operator">:</span> <span class="ruby-string">&quot;Medium&quot;</span>)
664
- <span class="ruby-identifier">custom_signature</span>.<span class="ruby-identifier">save</span>
665
- </pre>
666
-
667
-
668
-
669
-
670
- <div class="method-source-code" id="save-source">
671
- <pre><span class="ruby-comment"># File lib/esp/resources/custom_signature.rb, line 211</span>
672
- </pre>
673
- </div><!-- save-source -->
674
-
675
- </div>
676
-
677
-
678
-
679
-
680
- </div><!-- save-method -->
681
-
682
-
683
- <div id="method-i-suppress" class="method-detail ">
684
-
685
- <div class="method-heading">
686
- <span class="method-name">suppress</span><span
687
- class="method-args">(arguments = {})</span>
688
-
689
- <span class="method-click-advice">click to toggle source</span>
690
-
691
- </div>
692
-
693
-
694
- <div class="method-description">
695
-
696
- <p>Create a suppression for this custom signature.</p>
697
-
698
- <h4 id="method-i-suppress-label-Parameter">Parameter<span><a href="#method-i-suppress-label-Parameter">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
699
-
700
- <p><code>arguments</code> | Required | A hash of signature suppression
701
- attributes</p>
702
-
703
- <h5 id="method-i-suppress-label-Valid+Arguments">Valid Arguments<span><a href="#method-i-suppress-label-Valid+Arguments">&para;</a> <a href="#documentation">&uarr;</a></span></h5>
704
-
705
- <p><code>regions</code> | Required | An array of region names to suppress.</p>
706
-
707
- <p><code>external_account_ids</code> | Required | An Array of the external
708
- accounts identified by <code>external_account_id</code> to suppress the
709
- signature or custom signature on.</p>
710
-
711
- <p><code>reason</code> | Required | The reason for creating the suppression.</p>
712
-
713
- <h4 id="method-i-suppress-label-Example">Example<span><a href="#method-i-suppress-label-Example">&para;</a> <a href="#documentation">&uarr;</a></span></h4>
714
-
715
- <pre>suppress(regions: [&#39;us_east_1&#39;], external_account_ids: [5], reason: &#39;My very good reason for creating this suppression&#39;)</pre>
716
-
717
-
718
-
719
-
720
- <div class="method-source-code" id="suppress-source">
721
- <pre><span class="ruby-comment"># File lib/esp/resources/custom_signature.rb, line 133</span>
722
- <span class="ruby-keyword">def</span> <span class="ruby-identifier">suppress</span>(<span class="ruby-identifier">arguments</span> = {})
723
- <span class="ruby-identifier">arguments</span> = <span class="ruby-identifier">arguments</span>.<span class="ruby-identifier">with_indifferent_access</span>
724
- <span class="ruby-constant">ESP</span><span class="ruby-operator">::</span><span class="ruby-constant">Suppression</span><span class="ruby-operator">::</span><span class="ruby-constant">Signature</span>.<span class="ruby-identifier">create</span>(<span class="ruby-identifier">custom_signature_ids</span><span class="ruby-operator">:</span> [<span class="ruby-identifier">id</span>], <span class="ruby-identifier">regions</span><span class="ruby-operator">:</span> <span class="ruby-constant">Array</span>(<span class="ruby-identifier">arguments</span>[<span class="ruby-value">:regions</span>]), <span class="ruby-identifier">external_account_ids</span><span class="ruby-operator">:</span> <span class="ruby-constant">Array</span>(<span class="ruby-identifier">arguments</span>[<span class="ruby-value">:external_account_ids</span>]), <span class="ruby-identifier">reason</span><span class="ruby-operator">:</span> <span class="ruby-identifier">arguments</span>[<span class="ruby-value">:reason</span>])
725
- <span class="ruby-keyword">end</span></pre>
726
- </div><!-- suppress-source -->
727
-
728
- </div>
729
-
730
-
731
-
732
-
733
- </div><!-- suppress-method -->
734
-
735
-
736
- </section><!-- public-instance-method-details -->
737
-
738
- </section><!-- 5Buntitled-5D -->
739
-
740
- </div><!-- documentation -->
741
-
742
-
743
- <footer id="validator-badges">
744
- <p><a href="http://validator.w3.org/check/referer">[Validate]</a>
745
- <p>Generated by <a href="https://github.com/rdoc/rdoc">RDoc</a> 4.0.0.
746
- <p>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish Rdoc Generator</a> 3.
747
- </footer>
748
-