vayacondios-client 0.2.11 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.gitignore +64 -0
  2. data/.travis.yml +13 -0
  3. data/CHANGELOG.md +0 -0
  4. data/Gemfile +21 -0
  5. data/LICENSE.md +95 -0
  6. data/Procfile +2 -0
  7. data/README.md +734 -0
  8. data/Rakefile +93 -0
  9. data/bin/vcd +10 -0
  10. data/config/database.yml +6 -0
  11. data/config/spec.example.yml +18 -0
  12. data/config/vayacondios.example.yml +15 -0
  13. data/examples/configuration.rb +56 -0
  14. data/examples/event_stream.rb +19 -0
  15. data/examples/simple.rb +61 -0
  16. data/features/event.feature +319 -0
  17. data/features/events.feature +208 -0
  18. data/features/stash.feature +840 -0
  19. data/features/stashes.feature +492 -0
  20. data/features/step_definitions/stash_steps.rb +113 -0
  21. data/features/stream.feature +30 -0
  22. data/features/support/em.rb +14 -0
  23. data/features/support/env.rb +13 -0
  24. data/lib/vayacondios/client/cli.rb +456 -0
  25. data/lib/vayacondios/client/configuration.rb +13 -0
  26. data/lib/vayacondios/client/connection.rb +39 -0
  27. data/lib/vayacondios/client/http_client.rb +6 -42
  28. data/lib/vayacondios/client/http_methods.rb +85 -0
  29. data/lib/vayacondios/client.rb +21 -0
  30. data/lib/vayacondios/configuration.rb +63 -0
  31. data/lib/vayacondios-client.rb +16 -17
  32. data/lib/vayacondios.rb +22 -0
  33. data/pom.xml +168 -0
  34. data/spec/client/cli_spec.rb +283 -0
  35. data/spec/client/configuration_spec.rb +11 -0
  36. data/spec/client/http_client_spec.rb +150 -0
  37. data/spec/configuration_spec.rb +41 -0
  38. data/spec/spec_helper.rb +27 -0
  39. data/spec/support/database_helper.rb +42 -0
  40. data/spec/support/log_helper.rb +19 -0
  41. data/spec/support/shared_context_for_events.rb +22 -0
  42. data/spec/support/shared_context_for_stashes.rb +24 -0
  43. data/spec/support/shared_examples_for_handlers.rb +32 -0
  44. data/src/main/java/com/infochimps/vayacondios/BaseClient.java +342 -0
  45. data/src/main/java/com/infochimps/vayacondios/HTTPClient.java +426 -0
  46. data/src/main/java/com/infochimps/vayacondios/VayacondiosClient.java +500 -0
  47. data/src/main/java/com/infochimps/vayacondios/test/IntegrationTest.java +3 -0
  48. data/src/test/java/com/infochimps/vayacondios/BaseClientTest.java +50 -0
  49. data/src/test/java/com/infochimps/vayacondios/HTTPClientIT.java +267 -0
  50. data/vayacondios-client.gemspec +25 -0
  51. metadata +96 -60
  52. checksums.yaml +0 -15
  53. data/lib/vayacondios/client/config.rb +0 -7
  54. data/lib/vayacondios/client/configliere.rb +0 -38
  55. data/lib/vayacondios/client/cube_client.rb +0 -39
  56. data/lib/vayacondios/client/itemset.rb +0 -130
  57. data/lib/vayacondios/client/legacy_switch.rb +0 -43
  58. data/lib/vayacondios/client/notifier.rb +0 -123
  59. data/lib/vayacondios/client/zabbix_client.rb +0 -148
  60. data/spec/client/itemset_legacy_spec.rb +0 -55
  61. data/spec/client/itemset_spec.rb +0 -60
  62. data/spec/client/notifier_spec.rb +0 -120
data/README.md ADDED
@@ -0,0 +1,734 @@
1
+ # Vayacondios
2
+
3
+ Vayacondios is a server-client program designed to make it simple to
4
+ collect and centralize information and metrics from a large number of
5
+ disparate sources from multiple application domains.
6
+
7
+ Vayacondios has the following design goals:
8
+
9
+ The client is simple enough to use in a shell script and the server is
10
+ performant enough to support ubiquitous use across a large
11
+ installation with many clients.
12
+
13
+ * *Decentralized* -- Any client can dispatch stashes or events from anywhere
14
+ * *Dynamic* -- No data types or schemas need to be created in advance
15
+ * *Ubiquitous* -- Clients require minimal dependencies because the API is simple to use and access
16
+ * *Simple* -- Clients can write data in whatever way is natural for them
17
+ * *Scalable* -- Server and storage can be scaled horizontally to allow for ever-increasing loads
18
+ * *Fast* -- No client should have to worry that sending data to Vayacondios will affect its performance
19
+
20
+ The basic objects of Vayacondios are **stash** and the **event**:
21
+
22
+ * a **stash** is an "object", a "configuration", or "setting" designed to be shared among many services
23
+ * an **event** is a "fact", "measurement", or "metric" announced by an arbitrary service, possibly related to some stash
24
+
25
+ Stashes and events are each documents which can contain arbitrary
26
+ JSON-serializable data: hashes/maps/dictionarys, arrays/lists,
27
+ strings, numbers, floats, null, &c.
28
+
29
+ The client and server communicate over a RESTful, HTTP-based API which
30
+ speaks JSON.
31
+
32
+ See also [Coda Hale's metrics](https://github.com/codahale/metrics/).
33
+
34
+ <a name="architecture" />
35
+ ## Architecture
36
+
37
+ <a name="architecture-database" />
38
+ ### Database
39
+
40
+ Vayacondios stores all its data in a database. Access to the database
41
+ within Vayacondios is strictly contained within model classes within
42
+ `lib/vayacondios/server/models`. This is so that the backend database
43
+ can one day be changed easily without affecting the rest of the
44
+ application.
45
+
46
+ [MongoDB](http://www.mongodb.org/) is currently the only supported
47
+ database. MongoDB is a natural choice because it exposes atomic query
48
+ primitives which map very closely to the operations exposed by the
49
+ Vayacondios API.
50
+
51
+ <a name="architecture-server" />
52
+ ### Server
53
+
54
+ The Vayacondios server process is a
55
+ [Goliath](https://github.com/postrank-labs/goliath) web server which
56
+ implements the Vayacondios API over HTTP using JSON.
57
+
58
+ A single server process can easily handle hundreds of client requests
59
+ per second. Multiple Vayacondios servers can easily be deployed
60
+ behind a load-balancer.
61
+
62
+ Each running server process reads and writes all its data in a single
63
+ MongoDB database specified at runtime.
64
+
65
+ <a name="architecture-client" />
66
+ ### Client
67
+
68
+ Clients communicate with the Vayacondios server via the HTTP API it
69
+ exposes. This makes it extremely simply for applications in any
70
+ language to communicate with the server.
71
+
72
+ Vayacondios comes with several clients:
73
+
74
+ * a Ruby-language client (`Vayacondios::HttpClient`)
75
+ * a Java-language client (`com.infochimps.vayacondios.HTTPClient`)
76
+ * a command-line client (the `vcd` program)
77
+
78
+ The Ruby-language client and the command-line client are bundled with
79
+ the `vayacondios-client` Ruby gem. The Java-language client is part
80
+ of the `com.infochimps.vayacondios` package.
81
+
82
+ <a name="datamodel" />
83
+ ## Data Model
84
+
85
+ Vayacondios uses a two-level hierarchical data model to organize
86
+ events and stashes.
87
+
88
+ The top-level is the **organization**. Data from multiple
89
+ organizations is stored together but accessed separately by a running
90
+ Vayacondios server. An organization could be the name of a user,
91
+ workgroup, application, or service using Vayacondios.
92
+
93
+ The next level is the **topic**. Each topic within Vayacondios has a
94
+ single stash and can have multiple events. An "object" like a server,
95
+ a database, an application, a service, or a user maps to the concept
96
+ of "topic".
97
+
98
+ Topics and organizations are strings which can only contain letters,
99
+ digits, underscores, periods, and hypens, though periods cannot be the
100
+ first or last character. Organizations cannot begin with the string
101
+ `system.`.
102
+
103
+ <a name="datamodel-events" />
104
+ ### Events
105
+
106
+ Events belong to a topic within an organization. Each event
107
+ additionally has
108
+
109
+ * an ID which is automatically set by the server to a random, unique value if none is provided when the event is announced. Provided IDs cannot contain periods or dollar signs.
110
+ * a timestamp which is automatically set by the server to the current UTC time if none is provided when the event is announced. Provided timestamps will attempt to be parsed either from a string or from an integer UNIX timestamp.
111
+ * arbitrary key/value data. Keys cannot contain periods or dollar signs.
112
+
113
+ Events are used for storing facts, measurements, metrics, errors,
114
+ occurrences, &c. If you anticipate wanting to see a time series or a
115
+ histogram of a certain kind of data then you should consider writing
116
+ that data into Vayacondios as events on some topic.
117
+
118
+ Events are stored in MongoDB in a collection named after their
119
+ organization and topic: an event on the `ci` topic for the `example`
120
+ organization would be stored in the MongoDB collection
121
+ `example.ci.events`. The ID of the event, whether auto-generated by
122
+ the server or specified by the client, will be used as the `_id` field
123
+ of the resulting document within this collection.
124
+
125
+ Here are some examples of data that it would make sense to store as
126
+ events (in JSON format):
127
+
128
+ * the output of a build from a CI system might be written to topic `ci`
129
+ ```
130
+ {
131
+ "environment": "Jenkins CI v. 1.519",
132
+ "project": {
133
+ "name": "website",
134
+ "version": "0b4d99ded50a19e495d2472477bbb0784d8a18d8",
135
+ "url": "https://github.com/mycompany/website.git",
136
+ },
137
+ "build": {
138
+ "time": 182,
139
+ "status": "success"
140
+ },
141
+ "test": {
142
+ "time": 97,
143
+ "ran": 102,
144
+ "passed": 102,
145
+ "failed": 0
146
+ }
147
+ }
148
+ ```
149
+ * an intrusion event picked up by the firewall might be written to topic `firewall.intrusions`
150
+ ```
151
+ {
152
+ "ip": "74.210.29.117",
153
+ "port": 22,
154
+ "type": "ssh",
155
+ "reason": "blacklisted"
156
+ }
157
+ ```
158
+ * some performance statistics for a running server might be written topic `phoenix.servers.webserver-16`
159
+ ```
160
+ {
161
+ "data_center": "Phoenix",
162
+ "rack": "14",
163
+ "server": "webserver-16",
164
+ "cpu": {
165
+ user: 3.17,
166
+ nice: 0.01,
167
+ system: 0.27,
168
+ iowait: 0.18,
169
+ steal: 0.00,
170
+ idle: 96.38
171
+ },
172
+ "mem": {
173
+ "total": 12304632,
174
+ "used": 10335900,
175
+ "free": 1968732
176
+ },
177
+ "net": {
178
+ "out": 2.25,
179
+ "in": 10.28,
180
+ },
181
+ "disk": {
182
+ "write": 16.182,
183
+ "read": 0.11
184
+ }
185
+ ```
186
+
187
+ <a name="datamodel-stashes" />
188
+ ### Stashes
189
+
190
+ Stashes belong to a topic within an organization. Each stash
191
+ additionally has arbitrary key/value data that it can store. Keys
192
+ cannot contain dollar signs or periods.
193
+
194
+ Stashes are used for storing objects, configuration, settings, &c. If
195
+ you anticipate wanting to lookup a value by name then you should
196
+ consider writing that data into Vayacondios as (or within) a stash on
197
+ some topic.
198
+
199
+ The names of top-level keys within a stash can be used as the "ID"
200
+ when retrieving/setting/deleting values via the API.
201
+
202
+ Stashes are stored in MongoDB in a collection named after their
203
+ organization: a stash for the `example` organization would be stored
204
+ in the MongoDB collection `example.stash`. The topic of the stash
205
+ will be used as the `_id` field of the resulting document within this
206
+ collection.
207
+
208
+ Here are some examples of data that it would make sense to store as
209
+ stashes (in JSON format):
210
+
211
+ * a collection of projects to run through a CI system might be stored on topic `ci`
212
+ ```
213
+ {
214
+ "projects": {
215
+ {
216
+ "name": "website",
217
+ "url": "https://github.com/mycompany/website.git",
218
+ },
219
+ {
220
+ "name": "client_tool",
221
+ "url": "https://github.com/mycompany/client_tool.git",
222
+ },
223
+ ...
224
+ }
225
+ }
226
+ ```
227
+ * firewall settings might be stored on topic `firewall`
228
+ ```
229
+ {
230
+ "firewall": {
231
+ "rules": [
232
+ {
233
+ "range": "0.0.0.0",
234
+ "port": 80,
235
+ "protocol": "tcp"
236
+ },
237
+ {
238
+ "range": "10.0.0.0",
239
+ "port"; 22,
240
+ "protocol": "ssh"
241
+ }
242
+ ]
243
+ }
244
+ }
245
+ ```
246
+ * a mapping of servers within some data center might be stored on topic `data_centers.phoenix`
247
+ ```
248
+ {
249
+ "name": "PHX",
250
+ "location": "Phoenix, AZ",
251
+ "servers": [
252
+ "webserver-0",
253
+ "webserver-1",
254
+ "webserver-2",
255
+ ...
256
+ ]
257
+ }
258
+ ```
259
+
260
+ <a name="installation" />
261
+ ## Installation & Configuration
262
+
263
+ <a name="installation-database" />
264
+ ### Database
265
+
266
+ Vayacondios server depends on a database to store all its data.
267
+ Currently, only MongoDB is supported: here are some
268
+ [installation instructions](http://docs.mongodb.org/manual/installation/).
269
+
270
+ <a name="installation-server" />
271
+ ### Server
272
+
273
+ Vayacondios server is distributed via Rubygems:
274
+
275
+ ```
276
+ $ sudo gem install vayacondios-server
277
+ ```
278
+
279
+ Once installed, you can launch a copy of the server from the
280
+ command-line running locally on port 9000:
281
+ ```
282
+ $ vcd-server --verbose --stdout
283
+ ```
284
+
285
+ Ports, logging, the location of MongoDB, and much more can be
286
+ configured via command-line options. Try `vcd-server --help` for more
287
+ details.
288
+
289
+ <a name="installation-client" />
290
+ ### Client
291
+
292
+ The server exposes its API via HTTP so all sorts of clients can talk
293
+ to Vayacondios server. Most simply, a command like
294
+
295
+ ```
296
+ $ curl -X POST http://localhost:9000/v2/my_organization/event/some_topic -d '{"event": "data"}'
297
+ ```
298
+
299
+ will work "right out of the box".
300
+
301
+ You can also install some pre-written clients that are aware of the
302
+ Vayacondios API.
303
+
304
+ <a name="installation-client-cli" />
305
+ #### Command-Line
306
+
307
+ The `vcd` command-line client is installed via Rubygems:
308
+
309
+ ```
310
+ $ sudo gem install vayacondios-client
311
+ ```
312
+
313
+ You can now run the `vcd` program. The equivalent to the above `curl`
314
+ command would be
315
+
316
+ ```
317
+ $ vcd announce 'some_topic' '{"event": "data"}'
318
+ ```
319
+
320
+ The `vcd` program looks for its configuration (where is the
321
+ Vayacondios server? what organization am I in?) in the files
322
+ `/etc/vayacondios/vayacondios.yml` and `~/.vayacondios.yml`. The
323
+ following can be put in either location to customize the behavior of
324
+ `vcd` for a given server or user.
325
+
326
+ ```yml
327
+ ---
328
+ host: vcd.example.com
329
+ port: 9000
330
+ organization: my_company
331
+ ```
332
+
333
+ <a name="installation-client-ruby" />
334
+ #### Ruby Client
335
+
336
+ A Ruby client is also avialable via Rubygems:
337
+
338
+ ```
339
+ $ sudo gem install vayacondios-client
340
+ ```
341
+
342
+ You can now use the `Vayacondios::HttpClient` class in your code:
343
+
344
+ ```ruby
345
+ require 'vayacondios-client'
346
+ client = Vayacondios::HttpClient.new(organization: 'my_company')
347
+ client.announce('some_topic', foo: 'bar')
348
+ ```
349
+
350
+ The Ruby client exposes several API requests as named methods (like
351
+ `announce` above, which maps to a <a
352
+ href="#api-events-announce">announce event</a> API endpoint).
353
+
354
+ <a name="installation-client-java" />
355
+ #### Java Client
356
+
357
+ A Java client is also available. Put the following into your
358
+ `pom.xml`:
359
+
360
+ ```xml
361
+ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
362
+ ...
363
+ <repositories>
364
+ ...
365
+ <repository>
366
+ <id>infochimps.releases</id>
367
+ <name>Infochimps Internal Repository</name>
368
+ <url>https://s3.amazonaws.com/artifacts.chimpy.us/maven-s3p/releases</url>
369
+ </repository>
370
+ ...
371
+ </repositories>
372
+ ...
373
+ <dependencies>
374
+ ...
375
+ <dependency>
376
+ <groupId>com.infochimps</groupId>
377
+ <artifactId>vayacondios</artifactId>
378
+ <version>2.0.0</version>
379
+ </dependency>
380
+ ...
381
+ </dependencies>
382
+ ...
383
+ </project>
384
+ ```
385
+
386
+ You can now use the `com.infochimps.vayacondios.HTTPClient` class in
387
+ your code:
388
+
389
+ ```java
390
+ import com.infochimps.vayacondios.VayacondiosClient;
391
+ import com.infochimps.vayacondios.HTTPClient;
392
+
393
+ class public HelloVayacondios {
394
+ public static void main(String[] args) throws Exception {
395
+ VayacondiosClient client = new HTTPClient("my_organization");
396
+ Map event = new HashMap();
397
+ event.put("foo", "bar");
398
+ client.announce("my_topic", event);
399
+ Thread.sleep(50) // ensures async HTTP request finishes
400
+ client.close();
401
+ }
402
+ }
403
+ ```
404
+
405
+ The Java client exposes several API requests as named methods (like
406
+ `announce` above, which maps to a <a
407
+ href="#api-events-announce">announce event</a> API endpoint).
408
+
409
+ <a name="api" />
410
+ ## API (v2)
411
+
412
+ All HTTP endpoints defined by the Vayacondios server API share a
413
+ common structure: `/:version/:organization/:type/[:topic]/[:id]/...`
414
+
415
+ | Parameter | Required | Definition | Examples |
416
+ | ------------ | -------- | ------------------------------------- | ------------------------------------- |
417
+ | version | required | Vayacondios API version | v1, v2 (current) |
418
+ | organization | required | Name of organization, service, or app | `security`, `accounting`, `customerX` |
419
+ | type | required | Request type | `event`, `stash`, `events`, `stashes` |
420
+ | topic | varies | Topic for event or stash | `firewall`, `servers.webserver-3` |
421
+ | id | varies | ID of event or field within stash | `cpu`, `liua38923u2389f` |
422
+
423
+ The `version`, `organization`, and `type` parameters are always
424
+ required. Other parameters are required depending on the endpoint.
425
+
426
+ Vayacondios server only listens for a single value of the top-level
427
+ `version` parameter (curently: `v2`). A frontend webserver (Apache,
428
+ nginx, &c.) can be used to split traffic to backend Vayacondios
429
+ servers running different versions of the Vayacondios API by routing
430
+ based on this parameter.
431
+
432
+ The `type` parameter is fixed and defines the type of a Vayacondios
433
+ request: `event`, `stash`, `events`, or `stashes`.
434
+
435
+ All other parameters are completely free for clients to specify under
436
+ the following constraints:
437
+
438
+ * the `organization` parameter can only contain letters, digits,
439
+ hyphens, and underscores and it must begin with a letter
440
+
441
+ * the `topic` parameter can only contain letters, digits, hyphens,
442
+ underscores, and periods and it cannot start or end with a period
443
+
444
+ * the `id` parameter cannot contain the dollar sign or period
445
+
446
+ The `type`, `organization`, `topic`, and `id` parameter together
447
+ constitue the *vayacondios route*.
448
+
449
+ The *document* is the request body sent to the server with a given
450
+ request. Requests to Vayacondios should have JSON-encoded bodies but
451
+ the body can be any JSON datatype: Hash, Array, String, Integer,
452
+ Float, Boolean, or `null`.
453
+
454
+ The *response* is the JSON-encoded response body sent back to the
455
+ client from the server. If an error occurred, in addition to the
456
+ appropriate HTTP response code, the response will be a Hash containing
457
+ the key `error` with a message detailing the error.
458
+
459
+ In the case of a record which is not found, the response may be empty
460
+ but the HTTP response code will be 404.
461
+
462
+ In the case of a successful request, the response code will be 200 and
463
+ the response body will the requested/written object.
464
+
465
+ <a name="api-events" />
466
+ ### Events
467
+
468
+ A topic within an organization can have many events.
469
+
470
+ Events are Hash-like data structures which have an associated
471
+ timestamp and ID.
472
+
473
+ Events can be announced, retrieved, and searched. Events cannot be
474
+ updated or deleted, though announcing an event with the same ID as an
475
+ existing event overwrites the existing event.
476
+
477
+ <a name="api-events-announce" />
478
+ #### Announce a new event
479
+
480
+ An event can be created without an ID. The server will generate a
481
+ random, unique ID and include it with the event in the response. This
482
+ is the most common way to write an event. If you don't intend to ever
483
+ retrieve this specific event (as opposed to searching across events)
484
+ then this is the right choice.
485
+
486
+ Events can also be created with an explicit ID. This is less common
487
+ but can be useful if your events naturally contain a unique
488
+ identifier.
489
+
490
+ | Method | Path | Request | Response | Action |
491
+ | ------ | ---------------------------------- | ------- | -------- | ----------------------------------------------- |
492
+ | POST | /v2/:organization/event/:topic | Hash | Hash | Stores a new event with an auto-generated ID |
493
+ | POST | /v2/:organization/event/:topic/:id | Hash | Hash | Stores/overwrites a new event with the given ID |
494
+
495
+ All requests to announce a new event accept a Hash-like request body.
496
+ Key/value pairs in this request body constitute the body of the event.
497
+ The following parameters have special meaning:
498
+
499
+ | Parameter | Description | Default | Example Values |
500
+ | --------- | ------------------------------ | ------------ | ---------------------------------------- |
501
+ | time | Set the timestamp of the event | current time |`2013-06-20 16:20:48 -0500`, `1371763237` |
502
+
503
+ The response body will contain a Hash that is the original request
504
+ Hash but with the (possibly auto-generated) ID and timestamp included.
505
+
506
+ <a name="api-events-get" />
507
+ #### Get an existing event
508
+
509
+ Events can be retrieved if their ID is known.
510
+
511
+ | Method | Path | Request | Response | Action |
512
+ | ------ | ---------------------------------- | ------- | -------- | ----------------------------------------------- |
513
+ | GET | /v2/:organization/event/:topic/:id | N/A | Hash | Retrieve an existing event given its ID |
514
+
515
+ The response will contain the event Hash if found or will be empty if
516
+ not.
517
+
518
+ <a name="api-events-search" />
519
+ #### Search for events
520
+
521
+ You can search for events matching a query.
522
+
523
+ | Method | Path | Request | Response | Action |
524
+ | ------ | ------------------------------- | ------- | ----------- | ----------------------------------------------- |
525
+ | GET | /v2/:organization/events/:topic | Hash | Array<Hash> | Search for events on the given topic. |
526
+
527
+ The default behavior (which will occur with an empty request body) is
528
+ to return the most recent 50 events on the given `topic` sorted in
529
+ descending order by their timestamps.
530
+
531
+ Each key in the query body will be interpeted as a condition that the
532
+ data of each event must match in order to be returned. Keys with
533
+ periods are interpreted as nested fields. The following parameters
534
+ have special meaning and can be used to adjust the time window, number
535
+ of returned events, the sort behavior, and the fields within each
536
+ event to return:
537
+
538
+ | Parameter | Description | Default | Example Values |
539
+ | --------- | -------------------------------------------- | -------------------- | ------------------------------------------------------ |
540
+ | from | Occurred after this time | 1 hour ago | `2013-06-20 Thu 00:00:00 -0500`, 1371704400 |
541
+ | upto | Occurred before this time | current time | `2013-06-20 Thu 23:59:59 -0500`, 1371790799 |
542
+ | limit | Return up to this many events | 50 | 100, 200 |
543
+ | fields | Return only these fields from the event body | all fields | `["account_id", "ip_address"]` |
544
+ | sort | Sort returned events by this field | descending by time | `["time", "ascending"]`, `["ip_address", "ascending"]` |
545
+ | id | Regular expression search on event ID | N/A | `sensor-data-.*`, `2013-06-20-.*` |
546
+
547
+ The response will be an Array of the matching events, possibly an
548
+ empty Array if no events were found.
549
+
550
+ <a name="api-stashes" />
551
+ ### Stashes
552
+
553
+ A topic within an organization can have a stash.
554
+
555
+ Stashes are Hash-like data structures. Each key/value pair with the
556
+ stash can be accessed directly by using the name of its key as the ID
557
+ in requests.
558
+
559
+ Stashes can be set, merged, retrieved, searched, and destroyed.
560
+
561
+ <a name="api-stashes-set" />
562
+ #### Set a value
563
+
564
+ You can set a value for a stash or one of the fields within a stash.
565
+ Your value will override whatever value is currently stored for that
566
+ stash or for that ID within the stash.
567
+
568
+ | Method | Path | Request | Response | Action |
569
+ | ------ | ---------------------------------- | ------- | -------- | ---------------------------------------------------------- |
570
+ | POST | /v2/:organization/stash/:topic | Hash | Hash | Overwrites the stash with the given topic. |
571
+ | POST | /v2/:organization/stash/:topic/:id | varies | varies | Overwrites the ID field of the stash with the given topic. |
572
+
573
+ When setting the stash itself, your value must be Hash-like. When
574
+ setting an ID within a stash, your value can have any datatype.
575
+
576
+ The response for setting a stash will be the (Hash-like) stash you
577
+ just set. When setting an ID within a stash, the response will be of
578
+ the same datatype as the request.
579
+
580
+ #### Merge a value
581
+
582
+ You can merge a value for a stash or one of the fields within a stash.
583
+
584
+ | Method | Path | Request | Response | Action |
585
+ | ------ | ---------------------------------- | ------- | -------- | ----------------------------------------------------------- |
586
+ | PUT | /v2/:organization/stash/:topic | Hash | Hash | Merges into the stash with the given topic. |
587
+ | PUT | /v2/:organization/stash/:topic/:id | varies | varies | Merges into the ID field of the stash with the given topic. |
588
+
589
+ When merging the stash itself, your value must be Hash-like and will
590
+ be merged on top of the existing (Hash-like) stash's value.
591
+
592
+ When merging one of the ID fields within the stash, your value can
593
+ have any datatype and it will be intelligently merged:
594
+
595
+ * if your value is Hash-like and the existing value is Hash-like , your new value will be merged on top of the existing value
596
+ * if your value is Array-like and the existing value is Array-like , your new value will be concatenated to the end of the existing value
597
+ * if your value is String-like and the existing value is String-like , your new value will be concatenated to the end of the existing value
598
+ * if your value is Numeric-like and the existing value is Numeric-like , your new value will be added to the existing value
599
+
600
+ The response for merging a stash will be the Hash-like combination of
601
+ your old and new value. The response for merging an ID within a stash
602
+ will be of the same type as the request.
603
+
604
+ <a name="api-stashes-get" />
605
+ #### Get a value
606
+
607
+ You can get the value of an existing stash or one of the fields within
608
+ that stash.
609
+
610
+ | Method | Path | Request | Response | Action |
611
+ | ------ | ---------------------------------- | ------- | -------- | ------------------------------------------------------ |
612
+ | GET | /v2/:organization/stash/:topic | N/A | Hash | Return the stash with the given topic. |
613
+ | GET | /v2/:organization/stash/:topic/:id | N/A | varies | Return the ID field of the stash with the given topic. |
614
+
615
+ The response for retreiving a stash will be the Hash-like stash while
616
+ the response for retreving an ID field within a stash will vary based
617
+ on the datatype of that value.
618
+
619
+ <a name="api-stashes-delete" />
620
+ #### Delete a value
621
+
622
+ You can get delete a stash or one of the fields within a stash.
623
+
624
+ | Method | Path | Request | Response | Action |
625
+ | ------ | ---------------------------------- | ------- | -------- | ------------------------------------------------------- |
626
+ | DELETE | /v2/:organization/stash/:topic | N/A | Hash | Deletes the stash with the given topic. |
627
+ | DELETE | /v2/:organization/stash/:topic/:id | N/A | Hash | Deletes the ID field of the stash with the given topic. |
628
+
629
+ The response for deleting a stash or an ID within a stash will be a
630
+ Hash naming the topic (and ID if given in the request) deleted.
631
+
632
+ <a name="api-stashes-search" />
633
+ #### Search for stashes
634
+
635
+ You can search for stashes.
636
+
637
+ | Method | Path | Request | Response | Action |
638
+ | ------ | --------------------------- | ------- | -------- | ------------------------------------------------------- |
639
+ | GET | /v2/:organization/stashes | Hash | Array<Hash> | Search for stashes matching the given query. |
640
+
641
+ The default behavior (which will occur with an empty request body) is
642
+ to return 50 stashes in sorted in ascending order by their topic.
643
+
644
+ Each key in the query body will be interpreted as a condition that the
645
+ data of each stash must match in order to be returned. Keys with
646
+ periods are interpreted as nested fields. The following parameters
647
+ have special meaning and can be used to adjust the number of returned
648
+ stashes, the fields within each stash, and the the sort behavior.
649
+
650
+ | Parameter | Description | Default | Example Values |
651
+ | ------------- | ---------------------------------------------- | -------------------- | ---------------------------------- |
652
+ | limit | Return up to this many stashes | 50 | 100, 200 |
653
+ | sort | Sort returned stashes by this field | ascending by topic | `["ip_address", "ascending"]` |
654
+ | fields | Array of fields to include in the response | all fields | `["name", "address", "phone"]` |
655
+ | topic | Regular expression search on the stash's topic | N/A | `servers-.*`, `firewall\..*\.rule` |
656
+ | topic_in | List of explicit topics to match | N/A | `["servers.bob", "servers.alan"]` |
657
+ | topic_not_in | List of explicit topics to **not** match | N/A | `["servers.bob", "servers.alan"]` |
658
+
659
+ The response will be an Array of the matching stashes, possibly an
660
+ empty Array if no events were found.
661
+
662
+ #### Update Multiple Stashes
663
+
664
+ There are two related methods that let you update multiple stashes in
665
+ place according to the same rule.
666
+
667
+ | Method | Path | Request | Response | Action |
668
+ | ------ | ------------------------- | ------- | -------- | --------------------------------------------------- |
669
+ | PUT | /v2/:organization/stashes | Hash | Hash | Apply an update to all stashes matching a query |
670
+ | POST | /v2/:organization/stashes | Hash | Hash | Apply a replacement to all stashes matching a query |
671
+
672
+ Each of these methods accepts a Hash request body that is supposed to have the following parameters:
673
+
674
+ | Parameter | Description | Default | Example Values |
675
+ | --------- | -------------------------------------------------- | ------- | ----------------------------------------------- |
676
+ | query | A Hash of matching criteria the stash must satisfy | N/A | `{"region": "dakota"}` |
677
+ | update | An update to apply to each matched stash | N/A | `{"status": "disabled", "service.ftp": "down"}` |
678
+
679
+ The methods differ in the way they process the `update`. The `POST`
680
+ method will always replace the existing values of the named fields
681
+ (top-level or nested) in the update Hash with their new, updated
682
+ values. This is useful when you want to explicitly set a property to
683
+ some fixed value for all stashes which match some criteria.
684
+
685
+ The `PUT` method (like the `PUT /v2/:organization/stash/:topic`
686
+ method) tries to be more clever and attempts to *merge* the update
687
+ into the record according to the following rules
688
+
689
+ * if your value is Numeric-like, your new value will be added to the existing value
690
+ * if your value is Array-like, your new value will be concatenated to the end of the existing value
691
+ * if your value is Hash-like, it will replace the existing value (**Note::** this is different than the behavior of `PUT /v2:organization/stash/:stopic`.)
692
+ * if your value is String-like, it will replace the existing value (**Note::** this is different than the behavior of `PUT /v2:organization/stash/:stopic`.)
693
+
694
+ Notice that the behavior for Hashes and Strings isn't as nice as it is
695
+ for `PUT /v2:organization/stash/:stopic`. Still, this method is
696
+ useful for when you want to increment some value across all stashes
697
+ which match some criteria.
698
+
699
+ For both of these methods, the query Hash also contains parameters
700
+ that are very similar to when searching for a stash:
701
+
702
+ | Parameter | Description | Default | Example Values |
703
+ | ------------- | ---------------------------------------------- | -------------------- | ---------------------------------- |
704
+ | topic | Regular expression search on the stash's topic | N/A | `servers-.*`, `firewall\..*\.rule` |
705
+ | topic_in | List of explicit topics to match | N/A | `["servers.bob", "servers.alan"]` |
706
+ | topic_not_in | List of explicit topics to **not** match | N/A | `["servers.bob", "servers.alan"]` |
707
+
708
+ Other fields in the query Hash are interpreted as requirements on the
709
+ data in the stash itself.
710
+
711
+ #### Deleting Multiple Stashes
712
+
713
+ The following method can be used to delete multiple stashes which all
714
+ match some criteria:
715
+
716
+ | Method | Path | Request | Response | Action |
717
+ | ------ | ------------------------- | ------- | -------- | ----------------------------------- |
718
+ | DELETE | /v2/:organization/stashes | Hash | Hash | Delete all stashes matching a query |
719
+
720
+ The following request parameters define the query which is used to
721
+ match stashes to be deleted:
722
+
723
+ | Parameter | Description | Default | Example Values |
724
+ | ------------- | ---------------------------------------------- | -------------------- | ---------------------------------- |
725
+ | topic | Regular expression search on the stash's topic | N/A | `servers-.*`, `firewall\..*\.rule` |
726
+ | topic_in | List of explicit topics to match | N/A | `["servers.bob", "servers.alan"]` |
727
+ | topic_not_in | List of explicit topics to **not** match | N/A | `["servers.bob", "servers.alan"]` |
728
+
729
+ Other fields in the query Hash are interpreted as requirements on the
730
+ data in the stash itself in order for it to match and be deleted.
731
+
732
+ ### Copyright
733
+
734
+ Copyright (c) 2011 - 2013 Infochimps. See [LICENSE.md](LICENSE.md) for further details.