boto/boto — pull request #1439 by jamesls (2013-04-13 00:23:51+00:00)
Title: Use only 2 calls for IAM role credentials from metadata service

We're making a total of 8 calls to the metadata service to retrieve credentials for an IAM role:

```
$ tcpdump -i eth0 -s0 -w - | grep -a -o -E "Host\: .*|GET \/.*" &
$ python -c "import boto; c = boto.connect_ec2()"
GET /latest/meta-data/ HTTP/1.1
Host: 169.254.169.254
GET /latest/meta-data/ HTTP/1.1
Host: 169.254.169.254
GET /latest/meta-data/iam/ HTTP/1.1
Host: 169.254.169.254
GET /latest/meta-data/iam/ HTTP/1.1
Host: 169.254.169.254
GET /latest/meta-data/iam/security-credentials/ HTTP/1.1
Host: 169.254.169.254
GET /latest/meta-data/iam/security-credentials/ HTTP/1.1
Host: 169.254.169.254
GET /latest/meta-data/iam/security-credentials/foobar HTTP/1.1
Host: 169.254.169.254
GET /latest/meta-data/iam/security-credentials/foobar HTTP/1.1
Host: 169.254.169.254
```

We really only need two, one to get the role name, one to get credentials. The reason we're making so many calls is two fold:

* The code in `provider.py` is using `metadata['iam']['security-credentials'].values()[0]` to get at credentials. Because of the lazy loading dict that's returned each key access generates a new call to the metadata service.
* A bug fix for #1146 inadvertently doubled the number of calls made to the metadata service.

Verified that we're only making two calls to the metadata service with this fix:

```
$ tcpdump -i eth0 -s0 -w - | grep -a -o -E "Host\: .*|GET \/.*" &
$ python -c "import boto; c = boto.connect_ec2()"
GET /latest/meta-data/iam/security-credentials/ HTTP/1.1
Host: 169.254.169.254
GET /latest/meta-data/iam/security-credentials/foobar HTTP/1.1
Host: 169.254.169.254
```

More info in the commit messages.