REST

Jon Schneider edited this page Jan 23, 2015 · 15 revisions

Table of Contents

Overview

Resources can be fetched using HTTP GET requests. The output will always be JSON (or JSONP if _callback is used). In many cases the results of the GET's will be identical to an equivalent API call to the AWS service, however Edda will preserve cached copies of the API calls so users can query what the resource looked like at a specific time, or can quickly scan through all changes to a resource. Using Matrix Arguments you can find specific resources and with Field Selectors you can extract just the data elements you are interested.

General

  • All APIs might return an error. There will be a non 200 HTTP status code returned with content formatted as:
 {
   "code": INT,
   "message": "STRING"
 }

Select Matrix Arguments

You can use matrix arguments to query for specifc resources. The argument name should map to the location in the document with a '.' character seperating heirarchy levels.

Given this AWS AutoScalingGroup document structure:

 {
   "launchConfigurationName" : "edda-201106231306",
   "instances" : [
     {
     "launchConfigurationName" : "edda-201106231306",
     "instanceId" : "i-0123456789",
     "lifecycleState" : "InService",
     "availabilityZone" : "us-east-1d",
     "healthStatus" : "Healthy"
     } 
   ],
   "availabilityZones" : [
     "us-east-1c",
     "us-east-1d",
     "us-east-1e"
   ],
   "autoScalingGroupName" : "edda"
 }

You could match it with these any of these:

 # find all asgs configured for a zone:
 curl 'http://localhost:8080/edda/api/v2/aws/autoScalingGroups;availabilityZones=us-east-1e'
 
 # find all asgs with at least one instance in a zone:
 curl 'http://localhost:8080/edda/api/v2/aws/autoScalingGroups;instances.availabilityZone=us-east-1e'

Given this AWS Instance document structure:

 {
   "instanceId" : "i-0123456789",
   "publicIpAddress" : "1.2.3.4",
   "tags" : [
     { 
     "key" : "aws:autoscaling:groupName",
     "value" : "edda-v107"
     }
   ],
   "state" : {
     "name" : "terminated",
     "code" : 16
   },
   "securityGroups" : [
     { 
     "groupId" : "sg-0123456789",
     "groupName" : "corp"
     },
   ],
   "instanceType" : "m2.2xlarge",
   "privateIpAddress" : "10.10.10.1",
   "publicDnsName" : "ec2-1-2-3-4.compute-1.amazonaws.com",
   "privateDnsName" : "ip-10-10-10-1.ec2.internal",
   "imageId" : "ami-0123456789",
   "placement" : {
     "tenancy" : "default",
     "availabilityZone" : "us-east-1e",
     "groupName" : ""
   }
 }

You could match it with any of these:

 # find instances in a given state
 curl 'http://localhost:8080/edda/api/v2/view/instances;state.name=terminated'
 
 # find instances given a security group name:
 curl 'http://localhost:8080/edda/api/v2/view/instances;securityGroups.groupName=corp'
 
 # find instances for a zone:
 curl 'http://localhost:8080/edda/api/v2/view/instances;placement.availabilityZone=us-east-1e'

Modifier Matrix Arguments

All Modifier Matrix Arguments begin with a "_" to try to avoid conflicts with the Select Matrix Arguments as described above.

_all

By default the APIs only return the most recent document(s) (or most recent given a timeframe). If you need to see every document revision then then you can set _all.

Typically this Modifier would be used with _diff or _meta. _all implies _expand.

For example you can use Field Selectors and _all to see all the state changes of a given instance, and use _meta to see when those changes happened:

 $ curl 'http://localhost:8080/edda/api/v2/view/instances/i-0123456789;_all;_pp;_meta:(stime,ltime,data:(state:(name)))'
 [
   {
     "ltime" : "2012-06-27T23:45:53.961Z",
     "stime" : "2012-06-27T22:46:53.797Z",
     "data" : {
       "state" : {
         "name" : "terminated"
       } 
     } 
   },
   {
     "ltime" : "2012-06-27T22:46:53.797Z",
     "stime" : "2012-06-27T22:45:53.799Z",
     "data" : {
       "state" : {
         "name" : "shutting-down"
       } 
     } 
   },
   {
     "ltime" : "2012-06-27T22:45:53.799Z",
     "stime" : "2012-06-27T22:42:45.896Z",
     "data" : {
       "state" : {
         "name" : "shutting-down"
       } 
     } 
   },
   {
     "ltime" : "2012-06-27T22:42:45.896Z",
     "stime" : "2012-06-24T20:21:00.283Z",
     "data" : {
       "state" : {
         "name" : "running"
       }
     }
   },
   ...
 ]

_at=<ms timestamp>

You can use _at to view a document as it appeared in the past. If a document has changed (asg has new instances, instance has had eip attached) or is no longer valid (instance was terminated) then you can use _at to see the document as it was in the past. If you query for a document that is no longer valid you will get a 410 GONE error when fetched, and you can use _at to find the last seen copy:

 $ curl 'http://localhost:8080/edda/api/v2/view/instances/i-0123456789;_pp;_at=1340837213797'
 {
   "launchTime" : "2012-06-21T01:42:49.0Z",
   "architecture" : "x86_64",
   "hypervisor" : "xen",
   "instanceId" : "i-0123456789",
   ...
 }

_callback=<name>

_callback is used to provide a jsonp callback. The response content-type will be set to application/javascript and content will be wrapped with the provide callback name:

 $ curl 'http://localhost:8080/edda/api/v2/view/instances/i-0123456789;_pp;_at=1340837213797;_callback=mycallback'
 mycallback({
   "launchTime" : "2012-06-21T01:42:49.0Z",
   "architecture" : "x86_64",
   "hypervisor" : "xen",
   "instanceId" : "i-0123456789",
   ...
 })

_diff[=<context>]

_diff can be used to get a unified diff when several revisions of a document are found. This is typically used with _all and/or _since and maybe with _until and/or _limit.

You can pass a value with the _diff argument as the number of lines of context. If you want the full document, leave a blank value for _diff.

For example, to see the changes of a securityGroup over a given time range:

 $ curl "http://localhost:8080/edda/api/v2/aws/securityGroups/sg-0123456789;_since=1340398800000;_until=1340402400000;_all;_diff=0"
 --- /edda/api/v2/aws/securityGroups/sg-0123456789;_pp;_at=1340387030822
 +++ /edda/api/v2/aws/securityGroups/sg-0123456789;_pp;_at=1340402244685
 @@ -23,0 +23,1 @@
 +        "1.2.3.4/32",

To see the diffs in the last 4 revisions of an instance:

 $ curl 'http://localhost:8080/edda/api/v2/view/instances/i-0123456789;_diff=0;_all;_limit=4'
 --- /edda/api/v2/view/instances/i-0123456789;_pp;_at=1340837153799
 +++ /edda/api/v2/view/instances/i-0123456789;_pp;_at=1340837213797
 @@ -23,2 +23,2 @@
 -    "name" : "shutting-down",
 -    "code" : 32
 +    "name" : "terminated",
 +    "code" : 48
 @@ -27,11 +27,1 @@
 -  "blockDeviceMappings" : [
 -    {
 -      "deviceName" : "/dev/sda1",
 -      "ebs" : {
 -        "volumeId" : "vol-0123456789",
 -        "deleteOnTermination" : true,
 -        "attachTime" : "2012-06-21T01:43:25.0Z",
 -        "status" : "attached"
 -      }
 -    }
 -  ],
 +  "blockDeviceMappings" : [ ],
 @@ -62,1 +52,0 @@
 -  "privateIpAddress" : "10.10.10.1",
 @@ -64,1 +53,1 @@
 -  "privateDnsName" : "ip-10-10-10-1.ec2.internal",
 +  "privateDnsName" : "",
 --- /edda/api/v2/view/instances/i-0123456789;_pp;_at=1340836965896
 +++ /edda/api/v2/view/instances/i-0123456789;_pp;_at=1340837153799
 @@ -9,1 +9,0 @@
 -  "publicIpAddress" : "1.2.3.4",
 @@ -64,1 +63,1 @@
 -  "publicDnsName" : "ec2-1-2-3-4.compute-1.amazonaws.com",
 +  "publicDnsName" : "",
 --- /edda/api/v2/view/instances/i-0123456789;_pp;_at=1340569260283
 +++ /edda/api/v2/view/instances/i-0123456789;_pp;_at=1340836965896
 @@ -8,1 +8,1 @@
 -  "stateTransitionReason" : "",
 +  "stateTransitionReason" : "User initiated (2012-06-27 22:42:44 GMT)",
 @@ -24,2 +24,2 @@
 -    "name" : "running",
 -    "code" : 16
 +    "name" : "shutting-down",
 +    "code" : 32
 @@ -39,0 +39,4 @@
 +  "stateReason" : {
 +    "message" : "Client.UserInitiatedShutdown: User initiated shutdown",
 +    "code" : "Client.UserInitiatedShutdown"
 +  },

_expand

By default when you do an INDEX GET (ie a GET on a resource group without a resource id) you only get the resource names. If you want to see the entire resource specify the _expand Modifier:

 # expanded ...
 $ curl 'http://localhost:8080/edda/api/v2/view/instances;_limit=2;_pp;_expand'
 [
   {
     "launchTime" : "2012-07-04T01:12:29.0Z",
     "architecture" : "x86_64",
     "hypervisor" : "xen",
     "instanceId" : "i-0123456789",
     ...
   }
   ...
 ]

_limit=<num>

Any time a list is returned, you can restrict the quantity returned with _limit=<num>. It is frequently used with _all to see the last <num> revisions of a document. See the usage in _diff to see and effective use case.

_live

This option should rarely be used. Edda is built on top of a MongoDB datastore, but there is some in memory caching in the application servers. There is a possibility for the caches to be out of sync for brief period of time (cache is refreshed every 60s). If variation in the GET responses cannot be tollerated, then you can use _live to direct the queries directly to the MongoDB datastore.

_meta

Edda collects some metadata for the documents it stores. If you use the _meta Modifier then the related metadata will be returned along the document. Here are the keys you will see:

  • stime: this is the timestamp that Edda detected the document modification.
  • ltime: this is the timestamp for when the document was last valid.
  • mtime: this is a timestamp if meta data was modified, it is typically the same as the stime
  • ctime: this is either the create time of the document, or the the document has no documented create/start time it will be the first time Edda saw the document.
  • tags: This is map of key/value pairs that are used for internal Edda mappings.
  • id: the primary identifier for the document (instance ID, asg name, etc)
  • data: This will be the document as stored.
  • _id: this is an internal primary key used by mongo to track the revisions. The format is "id|stime"
Note when using _meta with Select Matrix Arguments or Field Selectors the document root changes and you will need to modify paramaters names to match (ie add "data." prefix when you want to filter results with _meta and Select Matrix Arguments). Here are some examples using _meta:
 # find all instances that have ever had an IP and print the instance ids and the tags:
 $ curl 'http://localhost:8080/edda/api/v2/view/instances;publicIpAddress=1.2.3.4;_pp;_since=0;_expand:(instanceId,tags)';
 [
   {
     "instanceId" : "i-0123456789",
     "tags" : [
       {
         "key" : "aws:autoscaling:groupName",
         "value" : "app1-v123"
       }
     ]
   },
   {
     "instanceId" : "i-012345678a",
     "tags" : [
       {
         "key" : "aws:autoscaling:groupName",
         "value" : "app2-v123"
       }
     ]
   },
   {
     "instanceId" : "i-012345678b",
     "tags" : [
       {
         "key" : "aws:autoscaling:groupName",
         "value" : "app3-v123"
       }
     ]
   }
 ]
 # now make the same request with _meta and select the ltime and stime
 # use data.publicIpAddress and sub field selectors data:(instanceId,tags):
 $ curl 'http://localhost:8080/edda/api/v2/view/instances;data.publicIpAddress=1.2.3.4;_pp;_since=0;_expand;_meta:(stime,ltime,data:(instanceId,tags))';
 [
   {
     "ltime" : "2012-06-12T18:50:57.348Z",
     "stime" : "2012-06-12T18:48:50.931Z",
     "data" : {
       "instanceId" : "i-0123456789",
       "tags" : [
         {
           "key" : "aws:autoscaling:groupName",
           "value" : "app1-v123"
         }
       ]
     }
   },
   {
     "ltime" : "2012-05-05T15:29:51.0Z",
     "stime" : "2012-05-05T15:27:17.104Z",
     "data" : {
       "instanceId" : "i-012345678a",
       "tags" : [
         {
           "key" : "aws:autoscaling:groupName",
           "value" : "app2-v123"
         }
       ]
     }
   },
   {
     "ltime" : "2012-04-24T07:31:35.493Z",
     "stime" : "2012-04-24T07:29:35.489Z",
     "data" : {
       "instanceId" : "i-012345678b",
       "tags" : [
         {
           "key" : "aws:autoscaling:groupName",
           "value" : "app3-v123"
         }
       ]
     }
   }
 ]

_pp

This will "pretty print" the response. Along with beautifying the format to make it readable it will also translate all the timestamps to more readable YYYY-MM-DDTHH:mm:ss.SSSZ time format.

Example:

 # no pretty-print:
 $ curl "http://localhost:8080/edda/api/v2/aws/volumes/vol-0123456789"
 {"attachments":[],"volumeId":"vol-0123456789","size":4,"tags":[{"key":"owner","value":"cbennett"}],"state":"available","availabilityZone":"us-east-1d","snapshotId":"snap-0123456789","createTime":1324427568000}
 # pretty-print:
 $ curl "http://localhost:8080/edda/api/v2/aws/volumes/vol-0123456789;_pp"
 {
   "attachments" : [ ],
   "volumeId" : "vol-0123456789",
   "size" : 4,
   "tags" : [
     {
       "key" : "owner",
       "value" : "cbennett"
     }
   ],
   "state" : "available",
   "availabilityZone" : "us-east-1d",
   "snapshotId" : "snap-0123456789",
   "createTime" : "2011-12-21T00:32:48.0Z"
 }

_since=<ms timestamp>

_since is the start of a time range. If _until is not also specified, then the time range ends at "now". When _since is added to a request it will show you the most recent revision of all resources have were valid at some point in that time range. Note that _since does not show you documents "modified since", it will show any document that was valid during the timeframe, even it that document had no revisions during the timeframe. If you want to see only documents that were modified, use _updated along with _since. If you want to see all the documents alive in a timeframe, then use _all with _since, otherwise it will only show you the most recent document found for each resource.

 # show the instance that has an EIP:
 $ curl "$EDDA/view/instances;publicIpAddress=1.2.3.4"
 ["i-0123456789"]
 
 # show all instances that have ever had an EIP:
 $ curl "$EDDA/view/instances;publicIpAddress=1.2.3.4;_since=0"
 ["i-0123456789","i-012345678a","i-012345678b","i-012345678c","i-012345678d","i-012345678e","i-012345678f"]
 
 # show all instances that have had an EIP since June 10th:
 $ curl "$EDDA/view/instances;publicIpAddress=1.2.3.4;_since=1339286400000"
 ["i-0123456789","i-012345678a","i-012345678b","i-012345678c"]
 
 # show all instances that had an EIP from June 10th to June 15th:
 $ curl "$EDDA/view/instances;publicIpAddress=1.2.3.4;_since=1339286400000;_until=1339718400000"
 ["i-0123456789","i-012345678a"]
 
 # see all revisions that had an EIP from June 10th to June 15th (and select only id, and stime):
 $ curl "$EDDA/view/instances;data.publicIpAddress=1.2.3.4;_since=1339286400000;_until=1339718400000;_all;_meta:(stime,id)"
 [{"id":"i-0123456789","stime":1339369368409},{"id":"i-012345678a","stime":1339369097371}]
 
 # see list of all instances that changed on Jun 11th between 10:00 and 10:01 am:
 $ curl "$EDDA/view/instances;_since=1339408800000;_until=1339408860000;_updated"
 ["i-0123456789","i-012345678a"]
 
 # you can use jshon to turn that list into something processable by the shell:
 $ curl "$EDDA/view/instances;_since=1339408800000;_until=1339408860000;_updated" | jshon -a -u
 i-0123456789
 i-012345678a
 
 # and a quick loop will show you all the changes:
 $ curl "$EDDA/view/instances;_since=1339408800000;_until=1339408860000;_updated" | jshon -a -u | while read instance; do \
        curl "$EDDA/view/instances/$instance;_since=1339408800000;_until=1339408860000;_all;_diff=2"; \
   done
 --- /edda/api/v2/view/instances/i-0123456789;_pp;_at=1339408680879
 +++ /edda/api/v2/view/instances/i-0123456789;_pp;_at=1339408800881
 @@ -7,5 +7,4 @@
    "amiLaunchIndex" : 0,
    "stateTransitionReason" : "User initiated (2012-06-11 09:57:02 GMT)",
 -  "publicIpAddress" : "1.2.3.4",
    "rootDeviceType" : "ebs",
    "networkInterfaces" : [ ],
 @@ -22,19 +21,9 @@
    "keyName" : "keypair",
    "state" : {
 -    "name" : "shutting-down",
 -    "code" : 32
 +    "name" : "terminated",
 +    "code" : 48
    },
    "kernelId" : "aki-0123456789",
 -  "blockDeviceMappings" : [
 -    {
 -      "deviceName" : "/dev/sda1",
 -      "ebs" : {
 -        "volumeId" : "vol-0123456789",
 -        "deleteOnTermination" : true,
 -        "attachTime" : "2012-06-11T09:46:00.0Z",
 -        "status" : "attached"
 -      }
 -    }
 -  ],
 +  "blockDeviceMappings" : [ ],
    "stateReason" : {
      "message" : "Client.UserInitiatedShutdown: User initiated shutdown",
 @@ -57,7 +46,6 @@
    "instanceType" : "m2.2xlarge",
    "ramdiskId" : "ari-0123456789",
 -  "privateIpAddress" : "10.10.10.1",
 -  "publicDnsName" : "ec2-1-2-3-4.compute-1.amazonaws.com",
 -  "privateDnsName" : "domU-AA-BB-CC-DD-EE-FF.compute-1.internal",
 +  "publicDnsName" : "",
 +  "privateDnsName" : "",
    "clientToken" : "",
    "imageId" : "ami-0123456789",
 --- /edda/api/v2/view/instances/i-012345678a;_pp;_at=1339408740881
 +++ /edda/api/v2/view/instances/i-012345678a;_pp;_at=1339408800881
 @@ -14,5 +14,10 @@
      "state" : "enabled"
    },
 -  "tags" : [ ],
 +  "tags" : [
 +    {
 +      "key" : "aws:autoscaling:groupName",
 +      "value" : "app2-v123"
 +    }
 +  ],
    "keyName" : "keypair",
    "state" : {

_until=<ms timestamp>

This is the end of a time range started by _since. See the above documentation of _since for examples.

_updated

This will change the behavior from showing any valid documents in a time range to only showing documents that have been modified in a time range. You can implement "if modified since" logic with this to see only changed resources since the last time you polled (useful for periodic local cache updates). See an example in _since.

Field Selectors

Field-Select can be used to restrict the data returned, and use matrix arguments to filter the data returned in cases where the resource id is not available or desired.

Field Selectors syntax must always go at the end of the URI, it follows the form of: :(key,key:(subkey,subkey))

Here is an example that filters an AutoScalingGroup to only show the ASG name, instanceIds, and health status:

curl 'http://localhost:8080/edda/api/v2/aws/autoScalingGroups/edda-v123;_pp:(autoScalingGroupName,instances:(instanceId,lifecycleState))'
 { 
   "autoScalingGroupName" : "edda-v123",
   "instances" : [
     { 
       "instanceId" : "i-0123456789",
       "lifecycleState" : "InService"
     },
     { 
       "instanceId" : "i-012345678a",
       "lifecycleState" : "InService"
     },
     { 
       "instanceId" : "i-012345678b",
       "lifecycleState" : "InService"
     }
   ]
 }



Collection APIs

/aws

All APIs under /aws return the raw (JSON serialized) resources as the Amazon AWS APIs return.

/aws/addresses

GET index
 GET /edda/api/v2/aws/addresses
 
 HTTP/1.1 200 OK
 Content-Type: application/json
  
 [
   "1.2.3.4",
   "1.2.3.5",
     ...
 ]
GET single resource
 GET /edda/api/v2/aws/addresses/1.2.3.4
  
 HTTP/1.1 200 OK
 Content-Type: application/json
  
 {
     "instanceId": "i-0123456789",
     "publicIp": "1.2.3.4"
 }



/aws/alarms

GET index
List all know CloudWatch alarms
 GET /edda/api/v2/aws/alarms
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "alarm1-123",
   "alarm2-123",
   ...
 ]
GET single resource
 GET /edda/api/v2/aws/alarms/alarm1-123
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "OKActions" : [ ],
   "actionsEnabled" : true,
   "alarmActions" : [
     "arn:aws:autoscaling:us-east-1:149510111645:scalingPolicy:a64c80de-f984-4525-ac28-aee7c76d80f4:autoScalingGroupName/app1-v001:policyName/alarm1-123"
   ],
   "alarmArn" : "arn:aws:cloudwatch:us-east-1:149510111645:alarm:alarm1-123",
   "alarmConfigurationUpdatedTimestamp" : 1355784782532,
   "alarmDescription" : null,
   "alarmName" : "alarm1-123",
   "class" : "com.amazonaws.services.cloudwatch.model.MetricAlarm",
   "comparisonOperator" : "GreaterThanOrEqualToThreshold",
   "dimensions" : [
     {
       "class" : "com.amazonaws.services.cloudwatch.model.Dimension",
       "name" : "AutoScalingGroupName",
       "value" : "app1-v001"
     }
   ],
   "evaluationPeriods" : 5,
   "insufficientDataActions" : [ ],
   "metricName" : "RequestStats_-all-requests-_NumCompleted",
   "namespace" : NS",
   "period" : 60,
   "stateReason" : "Threshold Crossed: 1 datapoint (238.35) was not greater than or equal to the threshold (715.0).",
   "stateReasonData" : "{\"version\":\"1.0\",\"queryDate\":\"2012-12-25T02:45:51.395+0000\",\"startDate\":\"2012-12-25T02:44:00.000+0000\",\"statistic\":\"Average\",\"period\":60,\"recentDatapoints\":[238.35],\"threshold\":715.0}",
   "stateUpdatedTimestamp" : "2012-12-25T02:45:51.4Z",
   "stateValue" : "OK",
   "statistic" : "Average",
   "threshold" : 715.0,
   "unit" : null
 }

/aws/autoScalingGroups

GET index
List all known ASG names
 GET /edda/api/v2/aws/autoScalingGroups
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "app1-v123",
   "app2-v345",
   ...
 ]



GET single resource
 GET /edda/api/v2/aws/autoScalingGroups/app1-v123
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "autoScalingGroupARN": "arn:aws:autoscaling:us-east-1:179727101194:autoScalingGroup:a64c80de-f984-4525-ac28-aee7c76d80f4:autoScalingGroupName/app1-v123",
   "autoScalingGroupName": "app1-v123",
   "availabilityZones": [
     "us-east-1a",
     "us-east-1b",
     "us-east-1c",
     "us-east-1d"
   ],
   "createdTime": 1306536735318,
   "defaultCooldown": 10,
   "desiredCapacity": 1,
   "enabledMetrics": [],
   "healthCheckGracePeriod": 600,
   "healthCheckType": "EC2",
   "instances": [{
     "availabilityZone": "us-east-1c",
     "healthStatus": "Healthy",
     "instanceId": "i-0123456789",
     "launchConfigurationName": "app1-20110713095458",
     "lifecycleState": "InService"
   }],
   "launchConfigurationName": "app1-20110713095458",
   "loadBalancerNames": [
     "app1"
   ],
   "maxSize": 1,
   "minSize": 1,
   "placementGroup": null,
   "suspendedProcesses": [],
   "vpczoneIdentifier": null
 }

/aws/buckets

GET index
 GET /edda/api/v2/aws/buckets
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "BUCKET1",
   "BUCKET2",
   ...
 ]



GET single resource
 GET /edda/api/v2/aws/buckets/BUCKET1
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "creationDate": 1305332820000,
   "name": "BUCKET1",
   "owner": {
     "displayName": "buk1",
     "id": "373f1efb6fbc413399015915fae2691417ff3558ed674b5fb73363899b29447a"
   }
 }



/aws/databases

/aws/iamGroups

/aws/iamRoles

/aws/iamUsers

/aws/iamVirtualMFADevices

/aws/images

GET index
 GET /edda/api/v2/aws/images
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "aki-0123456789",
   "aki-012345678a",
   ...
 ]
GET single resource
 GET /edda/api/v2/aws/images/aki-0123456789
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "architecture": "i386",
   "blockDeviceMappings": [],
   "description": null,
   "imageId": "aki-0123456789",
   "imageLocation": "karmic-kernel-zul/ubuntu-kernel-2.6.31-300-ec2-i386-20091001-test-04.manifest.xml",
   "imageOwnerAlias": null,
   "imageType": "kernel",
   "kernelId": null,
   "name": null,
   "ownerId": "099720109477",
   "platform": null,
   "productCodes": [],
   "public": true,
   "ramdiskId": null,
   "rootDeviceName": null,
   "rootDeviceType": "instance-store",
   "state": "available",
   "stateReason": null,
   "tags": [],
   "virtualizationType": "paravirtual"
 }

/aws/instances

NOTE this api is really about Instance Reservations, if you want to work with a specific instance you probably want the /view/instances api.

GET index
 GET /edda/api/v2/aws/instances
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "r-0123456789",
   "r-012345678a",
   ...
 ]
GET single resource
GET /edda/api/v2/aws/instances/r-0123456789

 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "groupNames": [
     "corp"
   ],
   "groups": [{
     "groupId": "sg-0123456789",
     "groupName": "corp"
   }],
   "instances": [{
     "amiLaunchIndex": 0,
     "architecture": "x86_64",
     "blockDeviceMappings": [],
     "clientToken": "",
     "imageId": "ami-0123456789",
     "instanceId": "i-0123456789",
     "instanceLifecycle": null,
     "instanceType": "m1.xlarge",
     "kernelId": "aki-0123456789",
     "keyName": "keypair",
     "launchTime": 1276882740000,
     "license": null,
     "monitoring": {
       "state": "enabled"
     },
     "placement": {
       "availabilityZone": "us-east-1a",
       "groupName": "",
       "tenancy": "default"
     },
     "platform": null,
     "privateDnsName": "domU-AA-BB-CC-DD-EE-FF.compute-1.internal",
     "privateIpAddress": "10.10.10.1",
     "productCodes": [],
     "publicDnsName": "ec2-1-2-3-4.compute-1.amazonaws.com",
     "publicIpAddress": "1.2.3.4",
     "ramdiskId": "ari-0123456789",
     "rootDeviceName": null,
     "rootDeviceType": "instance-store",
     "securityGroups": [{
       "groupId": "sg-0123456789",
       "groupName": "corp"
     }],
     "sourceDestCheck": null,
     "spotInstanceRequestId": null,
     "state": {
       "code": 16,
       "name": "running"
     },
     "stateReason": null,
     "stateTransitionReason": "",
     "subnetId": null,
     "tags": [],
     "virtualizationType": "paravirtual",
     "vpcId": null
   }],
   "ownerId": "1234567892345",
   "requesterId": "2345678923456",
   "reservationId": "r-0123456789"
 }

/aws/launchConfigurations

GET index
 GET /edda/api/v2/aws/launchConfigurations
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "app1-20110712112559",
   "app1-20110713095458",
   ...
 ]
GET single resource
 GET /edda/api/v2/aws/launchConfigurations/app1-20110712112559
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "blockDeviceMappings": [],
   "createdTime": 1310495162317,
   "imageId": "ami-0123456789",
   "instanceMonitoring": {
     "enabled": true
   },
   "instanceType": "m1.large",
   "kernelId": "",
   "keyName": "keypair",
   "launchConfigurationARN": "arn:aws:autoscaling:us-east-1:1234567892345:launchConfiguration:a8d548d5-d8e0-4b7f-a9bc-7f25200cbb72:launchConfigurationName/app1-20110712112559",
   "launchConfigurationName": "app1-20110712112559",
   "ramdiskId": "",
   "securityGroups": [
     "edda",
     "corp"
   ],
   "userData": "&lt;base 64 encoded blob&gt;"
 }

/aws/loadBalancers

NOTE to find information about instances behind a load balancer, please see the [#/view/loadBalancerInstances] api

GET index
 GET /edda/api/v2/aws/loadBalancers
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "app1",
   "app2",
   ...
 ]
GET single resource
 GET /edda/api/v2/aws/loadBalancers/app1
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "availabilityZones": [
     "us-east-1a",
     "us-east-1c",
     "us-east-1d"
   ],
   "canonicalHostedZoneName": "app1-83167460.us-east-1.elb.amazonaws.com",
   "canonicalHostedZoneNameID": "ZH893JKQ9W0",
   "createdTime": 1254170158140,
   "dnsname": "app1-83167460.us-east-1.elb.amazonaws.com",
   "healthCheck": {
     "healthyThreshold": 2,
     "interval": 5,
     "target": "HTTP:80/healthcheck",
     "timeout": 3,
     "unhealthyThreshold": 2
   },
   "instances": [],
   "listenerDescriptions": [{
     "listener": {
       "instancePort": 80,
       "loadBalancerPort": 80,
       "protocol": "HTTP",
       "sslcertificateId": null
     },
     "policyNames": []
   }],
   "loadBalancerName": "app1",
   "policies": {
     "appCookieStickinessPolicies": [],
     "lbcookieStickinessPolicies": []
   },
   "sourceSecurityGroup": {
     "groupName": "amazon-elb-sg",
     "ownerAlias": "amazon-elb"
   }
 }

/aws/reservedInstances

GET index
 GET /edda/api/v2/aws/reservedInstances
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "7f531792-07a5-45c4-ab51-c2f465a2d49d",
   "98a01ae6-9ac4-45de-80b5-b107f6800568",
   ...
 ]
GET single resource
 GET /edda/api/v2/aws/reservedInstances/7f531792-07a5-45c4-ab51-c2f465a2d49d
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
  {
   "availabilityZone" : "us-east-1e",
   "class" : "com.amazonaws.services.ec2.model.ReservedInstances",
   "currencyCode" : "USD",
   "duration" : 30672000,
   "fixedPrice" : 0.0,
   "instanceCount" : 79,
   "instanceTenancy" : "default",
   "instanceType" : "m1.xlarge",
   "offeringType" : "Heavy Utilization",
   "productDescription" : "Linux/UNIX",
   "recurringCharges" : [
     {
       "amount" : 0.061,
       "class" : "com.amazonaws.services.ec2.model.RecurringCharge",
       "frequency" : "Hourly"
     }
   ],
   "reservedInstancesId" : "7f531792-07a5-45c4-ab51-c2f465a2d49d",
   "start" : 1354320000000,
   "state" : "active",
   "tags" : [ ],
   "usagePrice" : 0.0
 }



/aws/scalingPolicies

GET index
 GET /edda/api/v2/aws/scalingPolicies
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "policy1-123",
   "policy2-123",
   ...
 ]
GET single resource
 GET /edda/api/v2/aws/scalingPolicies/policy1-123
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "adjustmentType" : "ChangeInCapacity",
   "alarms" : [
     {
       "alarmARN" : "arn:aws:cloudwatch:us-east-1:149510111645:alarm:alarm1-123",
       "alarmName" : "alarm1-123",
       "class" : "com.amazonaws.services.autoscaling.model.Alarm"
     }
   ],
   "autoScalingGroupName" : "app1-v001",
   "class" : "com.amazonaws.services.autoscaling.model.ScalingPolicy",
   "cooldown" : 600,
   "minAdjustmentStep" : null,
   "policyARN" : "arn:aws:autoscaling:us-east-1:149510111645:scalingPolicy:37b331e1-cf66-45bb-9fda-fffe27401451:autoScalingGroupName/app1-v001:policyName/policy1-123",
   "policyName" : "policy1-123",
   "scalingAdjustment" : 75
 }

/aws/securityGroups

GET index
 GET /edda/api/v2/aws/securityGroups
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "sg-0123456789",
   "sg-012345678a",
   ...
 ]
GET single resource
 GET /edda/api/v2/aws/securityGroups/sg-0123456789
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "description": "frontend access",
   "groupId": "sg-0123456789",
   "groupName": "frontend-0123456789",
   "ipPermissions": [{
     "fromPort": 443,
     "ipProtocol": "tcp",
     "ipRanges": [
       "10.10.10.1/8"
     ],
     "toPort": 443,
     "userIdGroupPairs": []
   }, {
     "fromPort": 7001,
     "ipProtocol": "tcp",
     "ipRanges": [
       "10.10.10.1/8"
     ],
     "toPort": 7001,
     "userIdGroupPairs": [{
       "groupId": "sg-0123456789",
       "groupName": "backend",
       "userId": "1234567892345"
     }]
   }, {
     "fromPort": 7002,
     "ipProtocol": "tcp",
     "ipRanges": [],
     "toPort": 7002,
     "userIdGroupPairs": [{
       "groupId": "sg-0123456789",
       "groupName": "amazon-elb-sg",
       "userId": "amazon-elb"
     }]
   }, {
     "fromPort": 80,
     "ipProtocol": "tcp",
     "ipRanges": [
       "10.10.10.1/8"
     ],
     "toPort": 80,
     "userIdGroupPairs": []
   }],
   "ipPermissionsEgress": [],
   "ownerId": "1234567892345",
   "tags": [],
   "vpcId": null
 }



/aws/snapshots

GET index
 GET /edda/api/v2/aws/snapshots
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "snap-0123456789",
   "snap-012345678a",
   ...
 ]
GET single resource
 GET /edda/api/v2/aws/snapshots/snap-0123456789
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "description": "APP1 on ext3, no LVM",
   "ownerAlias": null,
   "ownerId": "1234567892345",
   "progress": "100%",
   "snapshotId": "snap-0123456789",
   "startTime": 1263329622000,
   "state": "completed",
   "tags": [],
   "volumeId": "vol-0123456789",
   "volumeSize": 500
 }

/aws/tags

Note the tags api is a bit special. There are no primary keys for tags, there is a uniq tuple of the tag name, the resource id and the resource type.

GET all tags for a specific resource using Matrix Arguments
 GET /edda/api/v2/aws/tags;_expand=1;resourceId=snap-0123456789;resourceType=snapshot:(key,value)
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   {
     "key": "device",
     "value": "/dev/sdh9"
   },
   {
     "key": "name",
     "value": "APP1PROD"
   },
   {
     "key": "desc",
     "value": "APP1PROD.30.MASTER.us-east-1d.0"
   },
   {
     "key": "zone",
     "value": "us-east-1c"
   },
   {
     "key": "timestamp",
     "value": "Wed May 11 11:38:04 PDT 2011"
   },
   {
     "key": "index",
     "value": "30"
   },
   {
     "key": "mount point",
     "value": "/DB/APP1PROD/data10"
   },
   {
     "key": "role",
     "value": "MASTER"
   }
 ]

/aws/volumes

GET index
 GET /edda/api/v2/aws/volumes
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "vol-0123456789",
   "vol-012345678a",
   ...
 ]
GET single resource
 GET /edda/api/v2/aws/volumes/vol-0123456789
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "attachments": [],
   "availabilityZone": "us-east-1c",
   "createTime": 1245094932000,
   "size": 250,
   "snapshotId": "",
   "state": "available",
   "tags": [],
   "volumeId": "vol-0123456789"
 }

/group

These collections are special and quite different, they primarly deal with group memberships (ie instances are members of auto scaling groups). There is no corresponding AWS API that contains all details. Also we do not store complete history for these apis. New document revision are generated for history any time the membership changes, not when a particular member changes. If an instance change IP address, it will be captured and stored to the data store, however you cannot find out what the previous IP addres was with this api, for that you would need to use /view/instances. Basic interesting details about each member are caputured and store, but for more information about the members you will need to use the particular member apis.

An additional key added for each member is slot. Slots are arbitrary numbers ranging from 0 to the size of the group. The slot numbers are assigned to members as soon as they appear, and the slot ID will never change for a member. When membership changes (ie old instance dies, new instance becomes member) then the old slot id will be reassigned to the new member. This mechanism is primarly used within Netflix for our Monitoring systems so they can efficient shard the massive amounts of metric data they collect for each instance.

When using time range Modifier Matrix Arguments the historical members will be merged into a single resource and the "end" time will be set to the last time the group saw the member.

/group/autoScalingGroups

GET index
 GET /edda/api/v2/group/autoScalingGroups
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "app1-v123",
   "app2-v345",
   ...
 ]
GET single resource
 GET /edda/api/v2/group/autoScalingGroups/app1-v123
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "desiredCapacity": 1,
   "end": null,
   "instances": [
     {
       "availabilityZone": "us-east-1c",
       "end": null,
       "imageId": "ami-0123456789",
       "instanceId": "i-0123456789",
       "instanceType": "m2.4xlarge",
       "launchTime": 1351968460000,
       "lifecycleState": "InService",
       "platform": null,
       "privateIpAddress": "10.10.10.1",
       "publicDnsName": "ec2-1-2-3-4.compute-1.amazonaws.com",
       "publicIpAddress": "1.2.3.4",
       "slot": 0,
       "start": 1351968460000
     }
   ],
   "launchConfigurationName": "app1-20121103114731",
   "loadBalancerNames": [
     "app1"
   ],
   "maxSize": 1,
   "minSize": 1,
   "name": "app1-v123",
   "start": 1351968453255
 }



/view

The view APIs represent aspects of other APIs, to make the data more usable and accessable. /view/instances is the common one, since /aws/instances really returns the "reservation" concept as from the EC2 APIs. Since the indivitual instance data is generally more useful for us, we pull apart the /aws/instances document and store the instance details seperated in a /view api. The /view/simpleQueues api likewise does not correspond to a single AWS API, it is a merge of multiple API calls to make the data more useful.

/view/instances

The documents from this API are derived from the /aws/instances API, but split out to be individually accessible.

GET index
 GET /edda/api/v2/view/instances
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "i-0123456789",
   "i-012345678a",
   ...
 ]
GET single resource
 GET /edda/api/v2/view/instances/i-0123456789
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "amiLaunchIndex": 0,
   "architecture": "x86_64",
   "blockDeviceMappings": [],
   "clientToken": "",
   "imageId": "ami-0123456789",
   "instanceId": "i-0123456789",
   "instanceLifecycle": null,
   "instanceType": "m1.xlarge",
   "kernelId": "aki-0123456789",
   "keyName": "keypair",
   "launchTime": 1276882740000,
   "license": null,
   "monitoring": {
     "state": "enabled"
   },
   "placement": {
     "availabilityZone": "us-east-1a",
     "groupName": "",
     "tenancy": "default"
   },
   "platform": null,
   "privateDnsName": "domU-AA-BB-CC-DD-EE-FF.compute-1.internal",
   "privateIpAddress": "10.10.10.1",
   "productCodes": [],
   "publicDnsName": "ec2-1-2-3-4.compute-1.amazonaws.com",
   "publicIpAddress": "1.2.3.4",
   "ramdiskId": "ari-0123456789",
   "rootDeviceName": null,
   "rootDeviceType": "instance-store",
   "securityGroups": [{
     "groupId": "sg-0123456789",
     "groupName": "corp"
   }],
   "sourceDestCheck": null,
   "spotInstanceRequestId": null,
   "state": {
     "code": 16,
     "name": "running"
   },
   "stateReason": null,
   "stateTransitionReason": "",
   "subnetId": null,
   "tags": [],
   "virtualizationType": "paravirtual",
   "vpcId": null
 }

/view/loadBalancerInstances

The documents from this API do not directly correspond to any AWS API but is generated based on several AWS API calls.

GET index
 GET /edda/api/v2/view/loadBalancerInstances
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "app1",
   "app2",
   ...
 ]
GET single resource
 GET /edda/api/v2/view/loadBalancerInstances/app1
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "instances": [{
     "description": "N/A",
     "instanceId": "i-0123456789",
     "reasonCode": "N/A",
     "state": "InService"
   }],
   "name": "app1"
 }



/view/simpleQueues

The documents from this API do not directly correspond to any AWS API but is generated based on several AWS API calls.

GET index
 GET /edda/api/v2/view/simpleQueues
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 [
   "app1_queue",
   "app2_queue",
   ...
 ]
GET single resource
Note the Approximate* attributes are changing constantly, so Edda will not generate document revisions every time the values of an Approximate* key changes. However a change to any other attribute will generate a new document revision.
 GET /edda/api/v2/view/simpleQueues/app1_queue
 
 HTTP/1.1 200 OK
 Content-Type: application/json
 
 {
   "attributes" : {
     "ApproximateNumberOfMessages" : "245",
     "ApproximateNumberOfMessagesDelayed" : "0",
     "ApproximateNumberOfMessagesNotVisible" : "8648",
     "CreatedTimestamp" : "1343149082",
     "DelaySeconds" : "0",
     "LastModifiedTimestamp" : "1348348404",
     "MaximumMessageSize" : "65536",
     "MessageRetentionPeriod" : "345600",
     "QueueArn" : "arn:aws:sqs:us-east-1:149510111645:app1_queue",
     "VisibilityTimeout" : "30"
   },
   "name" : "app1_queue",
   "url" : "https://sqs.us-east-1.amazonaws.com/149510111645/app1_queue"
 }