gcloud 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (768) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +4 -0
  3. data/Makefile +4 -0
  4. data/Manifest +760 -1
  5. data/bin/gcloud +7 -0
  6. data/bin/{gcutil → gcutil.symlink} +0 -0
  7. data/bin/gsutil-symlink +377 -0
  8. data/gcloud.gemspec +5 -5
  9. data/packages/gsutil/CHECKSUM +1 -0
  10. data/packages/gsutil/COPYING +202 -0
  11. data/packages/gsutil/LICENSE.third_party +295 -0
  12. data/packages/gsutil/MANIFEST.in +5 -0
  13. data/packages/gsutil/README +38 -0
  14. data/packages/gsutil/README.pkg +49 -0
  15. data/packages/gsutil/ReleaseNotes.txt +780 -0
  16. data/packages/gsutil/VERSION +1 -0
  17. data/packages/gsutil/boto/Changelog.rst +35 -0
  18. data/packages/gsutil/boto/LICENSE +18 -0
  19. data/packages/gsutil/boto/MANIFEST.in +12 -0
  20. data/packages/gsutil/boto/README.rst +163 -0
  21. data/packages/gsutil/boto/bin/asadmin +290 -0
  22. data/packages/gsutil/boto/bin/bundle_image +27 -0
  23. data/packages/gsutil/boto/bin/cfadmin +108 -0
  24. data/packages/gsutil/boto/bin/cq +89 -0
  25. data/packages/gsutil/boto/bin/cwutil +140 -0
  26. data/packages/gsutil/boto/bin/elbadmin +284 -0
  27. data/packages/gsutil/boto/bin/fetch_file +43 -0
  28. data/packages/gsutil/boto/bin/glacier +154 -0
  29. data/packages/gsutil/boto/bin/instance_events +145 -0
  30. data/packages/gsutil/boto/bin/kill_instance +35 -0
  31. data/packages/gsutil/boto/bin/launch_instance +252 -0
  32. data/packages/gsutil/boto/bin/list_instances +90 -0
  33. data/packages/gsutil/boto/bin/lss3 +77 -0
  34. data/packages/gsutil/boto/bin/mturk +465 -0
  35. data/packages/gsutil/boto/bin/pyami_sendmail +52 -0
  36. data/packages/gsutil/boto/bin/route53 +205 -0
  37. data/packages/gsutil/boto/bin/s3put +374 -0
  38. data/packages/gsutil/boto/bin/sdbadmin +194 -0
  39. data/packages/gsutil/boto/bin/taskadmin +116 -0
  40. data/packages/gsutil/boto/boto/__init__.py +793 -0
  41. data/packages/gsutil/boto/boto/__init__.pyc +0 -0
  42. data/packages/gsutil/boto/boto/auth.py +682 -0
  43. data/packages/gsutil/boto/boto/auth.pyc +0 -0
  44. data/packages/gsutil/boto/boto/auth_handler.py +58 -0
  45. data/packages/gsutil/boto/boto/auth_handler.pyc +0 -0
  46. data/packages/gsutil/boto/boto/beanstalk/__init__.py +65 -0
  47. data/packages/gsutil/boto/boto/beanstalk/exception.py +64 -0
  48. data/packages/gsutil/boto/boto/beanstalk/layer1.py +1153 -0
  49. data/packages/gsutil/boto/boto/beanstalk/response.py +703 -0
  50. data/packages/gsutil/boto/boto/beanstalk/wrapper.py +29 -0
  51. data/packages/gsutil/boto/boto/cacerts/__init__.py +22 -0
  52. data/packages/gsutil/boto/boto/cacerts/__init__.pyc +0 -0
  53. data/packages/gsutil/boto/boto/cacerts/cacerts.txt +633 -0
  54. data/packages/gsutil/boto/boto/cloudformation/__init__.py +68 -0
  55. data/packages/gsutil/boto/boto/cloudformation/connection.py +364 -0
  56. data/packages/gsutil/boto/boto/cloudformation/stack.py +360 -0
  57. data/packages/gsutil/boto/boto/cloudformation/template.py +43 -0
  58. data/packages/gsutil/boto/boto/cloudfront/__init__.py +324 -0
  59. data/packages/gsutil/boto/boto/cloudfront/distribution.py +745 -0
  60. data/packages/gsutil/boto/boto/cloudfront/exception.py +26 -0
  61. data/packages/gsutil/boto/boto/cloudfront/identity.py +122 -0
  62. data/packages/gsutil/boto/boto/cloudfront/invalidation.py +216 -0
  63. data/packages/gsutil/boto/boto/cloudfront/logging.py +38 -0
  64. data/packages/gsutil/boto/boto/cloudfront/object.py +48 -0
  65. data/packages/gsutil/boto/boto/cloudfront/origin.py +150 -0
  66. data/packages/gsutil/boto/boto/cloudfront/signers.py +60 -0
  67. data/packages/gsutil/boto/boto/cloudsearch/__init__.py +45 -0
  68. data/packages/gsutil/boto/boto/cloudsearch/document.py +265 -0
  69. data/packages/gsutil/boto/boto/cloudsearch/domain.py +394 -0
  70. data/packages/gsutil/boto/boto/cloudsearch/layer1.py +738 -0
  71. data/packages/gsutil/boto/boto/cloudsearch/layer2.py +67 -0
  72. data/packages/gsutil/boto/boto/cloudsearch/optionstatus.py +248 -0
  73. data/packages/gsutil/boto/boto/cloudsearch/search.py +365 -0
  74. data/packages/gsutil/boto/boto/cloudsearch/sourceattribute.py +75 -0
  75. data/packages/gsutil/boto/boto/compat.py +28 -0
  76. data/packages/gsutil/boto/boto/compat.pyc +0 -0
  77. data/packages/gsutil/boto/boto/connection.py +1081 -0
  78. data/packages/gsutil/boto/boto/connection.pyc +0 -0
  79. data/packages/gsutil/boto/boto/contrib/__init__.py +22 -0
  80. data/packages/gsutil/boto/boto/contrib/ymlmessage.py +52 -0
  81. data/packages/gsutil/boto/boto/core/README +58 -0
  82. data/packages/gsutil/boto/boto/core/__init__.py +23 -0
  83. data/packages/gsutil/boto/boto/core/auth.py +78 -0
  84. data/packages/gsutil/boto/boto/core/credentials.py +154 -0
  85. data/packages/gsutil/boto/boto/core/dictresponse.py +178 -0
  86. data/packages/gsutil/boto/boto/core/service.py +67 -0
  87. data/packages/gsutil/boto/boto/datapipeline/__init__.py +0 -0
  88. data/packages/gsutil/boto/boto/datapipeline/exceptions.py +42 -0
  89. data/packages/gsutil/boto/boto/datapipeline/layer1.py +546 -0
  90. data/packages/gsutil/boto/boto/dynamodb/__init__.py +66 -0
  91. data/packages/gsutil/boto/boto/dynamodb/batch.py +262 -0
  92. data/packages/gsutil/boto/boto/dynamodb/condition.py +170 -0
  93. data/packages/gsutil/boto/boto/dynamodb/exceptions.py +64 -0
  94. data/packages/gsutil/boto/boto/dynamodb/item.py +196 -0
  95. data/packages/gsutil/boto/boto/dynamodb/layer1.py +575 -0
  96. data/packages/gsutil/boto/boto/dynamodb/layer2.py +798 -0
  97. data/packages/gsutil/boto/boto/dynamodb/schema.py +112 -0
  98. data/packages/gsutil/boto/boto/dynamodb/table.py +540 -0
  99. data/packages/gsutil/boto/boto/dynamodb/types.py +326 -0
  100. data/packages/gsutil/boto/boto/ec2/__init__.py +96 -0
  101. data/packages/gsutil/boto/boto/ec2/address.py +103 -0
  102. data/packages/gsutil/boto/boto/ec2/autoscale/__init__.py +781 -0
  103. data/packages/gsutil/boto/boto/ec2/autoscale/activity.py +74 -0
  104. data/packages/gsutil/boto/boto/ec2/autoscale/group.py +337 -0
  105. data/packages/gsutil/boto/boto/ec2/autoscale/instance.py +60 -0
  106. data/packages/gsutil/boto/boto/ec2/autoscale/launchconfig.py +209 -0
  107. data/packages/gsutil/boto/boto/ec2/autoscale/policy.py +166 -0
  108. data/packages/gsutil/boto/boto/ec2/autoscale/request.py +38 -0
  109. data/packages/gsutil/boto/boto/ec2/autoscale/scheduled.py +60 -0
  110. data/packages/gsutil/boto/boto/ec2/autoscale/tag.py +84 -0
  111. data/packages/gsutil/boto/boto/ec2/blockdevicemapping.py +141 -0
  112. data/packages/gsutil/boto/boto/ec2/bundleinstance.py +78 -0
  113. data/packages/gsutil/boto/boto/ec2/buyreservation.py +84 -0
  114. data/packages/gsutil/boto/boto/ec2/cloudwatch/__init__.py +603 -0
  115. data/packages/gsutil/boto/boto/ec2/cloudwatch/alarm.py +316 -0
  116. data/packages/gsutil/boto/boto/ec2/cloudwatch/datapoint.py +40 -0
  117. data/packages/gsutil/boto/boto/ec2/cloudwatch/dimension.py +38 -0
  118. data/packages/gsutil/boto/boto/ec2/cloudwatch/listelement.py +31 -0
  119. data/packages/gsutil/boto/boto/ec2/cloudwatch/metric.py +175 -0
  120. data/packages/gsutil/boto/boto/ec2/connection.py +3409 -0
  121. data/packages/gsutil/boto/boto/ec2/ec2object.py +107 -0
  122. data/packages/gsutil/boto/boto/ec2/elb/__init__.py +553 -0
  123. data/packages/gsutil/boto/boto/ec2/elb/healthcheck.py +89 -0
  124. data/packages/gsutil/boto/boto/ec2/elb/instancestate.py +62 -0
  125. data/packages/gsutil/boto/boto/ec2/elb/listelement.py +36 -0
  126. data/packages/gsutil/boto/boto/ec2/elb/listener.py +75 -0
  127. data/packages/gsutil/boto/boto/ec2/elb/loadbalancer.py +324 -0
  128. data/packages/gsutil/boto/boto/ec2/elb/policies.py +89 -0
  129. data/packages/gsutil/boto/boto/ec2/elb/securitygroup.py +38 -0
  130. data/packages/gsutil/boto/boto/ec2/group.py +39 -0
  131. data/packages/gsutil/boto/boto/ec2/image.py +350 -0
  132. data/packages/gsutil/boto/boto/ec2/instance.py +661 -0
  133. data/packages/gsutil/boto/boto/ec2/instanceinfo.py +51 -0
  134. data/packages/gsutil/boto/boto/ec2/instancestatus.py +207 -0
  135. data/packages/gsutil/boto/boto/ec2/keypair.py +113 -0
  136. data/packages/gsutil/boto/boto/ec2/launchspecification.py +105 -0
  137. data/packages/gsutil/boto/boto/ec2/networkinterface.py +247 -0
  138. data/packages/gsutil/boto/boto/ec2/placementgroup.py +51 -0
  139. data/packages/gsutil/boto/boto/ec2/regioninfo.py +34 -0
  140. data/packages/gsutil/boto/boto/ec2/reservedinstance.py +227 -0
  141. data/packages/gsutil/boto/boto/ec2/securitygroup.py +357 -0
  142. data/packages/gsutil/boto/boto/ec2/snapshot.py +170 -0
  143. data/packages/gsutil/boto/boto/ec2/spotdatafeedsubscription.py +63 -0
  144. data/packages/gsutil/boto/boto/ec2/spotinstancerequest.py +188 -0
  145. data/packages/gsutil/boto/boto/ec2/spotpricehistory.py +55 -0
  146. data/packages/gsutil/boto/boto/ec2/tag.py +87 -0
  147. data/packages/gsutil/boto/boto/ec2/vmtype.py +58 -0
  148. data/packages/gsutil/boto/boto/ec2/volume.py +293 -0
  149. data/packages/gsutil/boto/boto/ec2/volumestatus.py +200 -0
  150. data/packages/gsutil/boto/boto/ec2/zone.py +80 -0
  151. data/packages/gsutil/boto/boto/ecs/__init__.py +90 -0
  152. data/packages/gsutil/boto/boto/ecs/item.py +153 -0
  153. data/packages/gsutil/boto/boto/elasticache/__init__.py +62 -0
  154. data/packages/gsutil/boto/boto/elasticache/layer1.py +1252 -0
  155. data/packages/gsutil/boto/boto/elastictranscoder/__init__.py +62 -0
  156. data/packages/gsutil/boto/boto/elastictranscoder/exceptions.py +46 -0
  157. data/packages/gsutil/boto/boto/elastictranscoder/layer1.py +509 -0
  158. data/packages/gsutil/boto/boto/emr/__init__.py +73 -0
  159. data/packages/gsutil/boto/boto/emr/bootstrap_action.py +44 -0
  160. data/packages/gsutil/boto/boto/emr/connection.py +531 -0
  161. data/packages/gsutil/boto/boto/emr/emrobject.py +176 -0
  162. data/packages/gsutil/boto/boto/emr/instance_group.py +43 -0
  163. data/packages/gsutil/boto/boto/emr/step.py +281 -0
  164. data/packages/gsutil/boto/boto/exception.py +476 -0
  165. data/packages/gsutil/boto/boto/exception.pyc +0 -0
  166. data/packages/gsutil/boto/boto/file/README +49 -0
  167. data/packages/gsutil/boto/boto/file/__init__.py +28 -0
  168. data/packages/gsutil/boto/boto/file/bucket.py +112 -0
  169. data/packages/gsutil/boto/boto/file/connection.py +33 -0
  170. data/packages/gsutil/boto/boto/file/key.py +199 -0
  171. data/packages/gsutil/boto/boto/file/simpleresultset.py +30 -0
  172. data/packages/gsutil/boto/boto/fps/__init__.py +21 -0
  173. data/packages/gsutil/boto/boto/fps/connection.py +369 -0
  174. data/packages/gsutil/boto/boto/fps/exception.py +344 -0
  175. data/packages/gsutil/boto/boto/fps/response.py +175 -0
  176. data/packages/gsutil/boto/boto/glacier/__init__.py +57 -0
  177. data/packages/gsutil/boto/boto/glacier/concurrent.py +409 -0
  178. data/packages/gsutil/boto/boto/glacier/exceptions.py +58 -0
  179. data/packages/gsutil/boto/boto/glacier/job.py +152 -0
  180. data/packages/gsutil/boto/boto/glacier/layer1.py +637 -0
  181. data/packages/gsutil/boto/boto/glacier/layer2.py +93 -0
  182. data/packages/gsutil/boto/boto/glacier/response.py +48 -0
  183. data/packages/gsutil/boto/boto/glacier/utils.py +163 -0
  184. data/packages/gsutil/boto/boto/glacier/vault.py +387 -0
  185. data/packages/gsutil/boto/boto/glacier/writer.py +242 -0
  186. data/packages/gsutil/boto/boto/gs/__init__.py +22 -0
  187. data/packages/gsutil/boto/boto/gs/__init__.pyc +0 -0
  188. data/packages/gsutil/boto/boto/gs/acl.py +304 -0
  189. data/packages/gsutil/boto/boto/gs/acl.pyc +0 -0
  190. data/packages/gsutil/boto/boto/gs/bucket.py +870 -0
  191. data/packages/gsutil/boto/boto/gs/bucket.pyc +0 -0
  192. data/packages/gsutil/boto/boto/gs/bucketlistresultset.py +64 -0
  193. data/packages/gsutil/boto/boto/gs/bucketlistresultset.pyc +0 -0
  194. data/packages/gsutil/boto/boto/gs/connection.py +103 -0
  195. data/packages/gsutil/boto/boto/gs/connection.pyc +0 -0
  196. data/packages/gsutil/boto/boto/gs/cors.py +169 -0
  197. data/packages/gsutil/boto/boto/gs/cors.pyc +0 -0
  198. data/packages/gsutil/boto/boto/gs/key.py +704 -0
  199. data/packages/gsutil/boto/boto/gs/key.pyc +0 -0
  200. data/packages/gsutil/boto/boto/gs/resumable_upload_handler.py +659 -0
  201. data/packages/gsutil/boto/boto/gs/resumable_upload_handler.pyc +0 -0
  202. data/packages/gsutil/boto/boto/gs/user.py +54 -0
  203. data/packages/gsutil/boto/boto/gs/user.pyc +0 -0
  204. data/packages/gsutil/boto/boto/handler.py +44 -0
  205. data/packages/gsutil/boto/boto/handler.pyc +0 -0
  206. data/packages/gsutil/boto/boto/https_connection.py +124 -0
  207. data/packages/gsutil/boto/boto/https_connection.pyc +0 -0
  208. data/packages/gsutil/boto/boto/iam/__init__.py +74 -0
  209. data/packages/gsutil/boto/boto/iam/connection.py +1317 -0
  210. data/packages/gsutil/boto/boto/iam/summarymap.py +42 -0
  211. data/packages/gsutil/boto/boto/jsonresponse.py +163 -0
  212. data/packages/gsutil/boto/boto/jsonresponse.pyc +0 -0
  213. data/packages/gsutil/boto/boto/manage/__init__.py +23 -0
  214. data/packages/gsutil/boto/boto/manage/cmdshell.py +241 -0
  215. data/packages/gsutil/boto/boto/manage/propget.py +64 -0
  216. data/packages/gsutil/boto/boto/manage/server.py +556 -0
  217. data/packages/gsutil/boto/boto/manage/task.py +175 -0
  218. data/packages/gsutil/boto/boto/manage/test_manage.py +34 -0
  219. data/packages/gsutil/boto/boto/manage/volume.py +420 -0
  220. data/packages/gsutil/boto/boto/mashups/__init__.py +23 -0
  221. data/packages/gsutil/boto/boto/mashups/interactive.py +97 -0
  222. data/packages/gsutil/boto/boto/mashups/iobject.py +115 -0
  223. data/packages/gsutil/boto/boto/mashups/order.py +211 -0
  224. data/packages/gsutil/boto/boto/mashups/server.py +395 -0
  225. data/packages/gsutil/boto/boto/mturk/__init__.py +23 -0
  226. data/packages/gsutil/boto/boto/mturk/connection.py +1027 -0
  227. data/packages/gsutil/boto/boto/mturk/layoutparam.py +55 -0
  228. data/packages/gsutil/boto/boto/mturk/notification.py +103 -0
  229. data/packages/gsutil/boto/boto/mturk/price.py +48 -0
  230. data/packages/gsutil/boto/boto/mturk/qualification.py +137 -0
  231. data/packages/gsutil/boto/boto/mturk/question.py +455 -0
  232. data/packages/gsutil/boto/boto/mws/__init__.py +21 -0
  233. data/packages/gsutil/boto/boto/mws/connection.py +813 -0
  234. data/packages/gsutil/boto/boto/mws/exception.py +75 -0
  235. data/packages/gsutil/boto/boto/mws/response.py +655 -0
  236. data/packages/gsutil/boto/boto/plugin.py +90 -0
  237. data/packages/gsutil/boto/boto/plugin.pyc +0 -0
  238. data/packages/gsutil/boto/boto/provider.py +337 -0
  239. data/packages/gsutil/boto/boto/provider.pyc +0 -0
  240. data/packages/gsutil/boto/boto/pyami/__init__.py +22 -0
  241. data/packages/gsutil/boto/boto/pyami/__init__.pyc +0 -0
  242. data/packages/gsutil/boto/boto/pyami/bootstrap.py +134 -0
  243. data/packages/gsutil/boto/boto/pyami/config.py +229 -0
  244. data/packages/gsutil/boto/boto/pyami/config.pyc +0 -0
  245. data/packages/gsutil/boto/boto/pyami/copybot.cfg +60 -0
  246. data/packages/gsutil/boto/boto/pyami/copybot.py +97 -0
  247. data/packages/gsutil/boto/boto/pyami/helloworld.py +28 -0
  248. data/packages/gsutil/boto/boto/pyami/installers/__init__.py +64 -0
  249. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/__init__.py +22 -0
  250. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/apache.py +43 -0
  251. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/ebs.py +238 -0
  252. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/installer.py +96 -0
  253. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/mysql.py +109 -0
  254. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/trac.py +139 -0
  255. data/packages/gsutil/boto/boto/pyami/launch_ami.py +178 -0
  256. data/packages/gsutil/boto/boto/pyami/scriptbase.py +44 -0
  257. data/packages/gsutil/boto/boto/pyami/startup.py +60 -0
  258. data/packages/gsutil/boto/boto/rds/__init__.py +1194 -0
  259. data/packages/gsutil/boto/boto/rds/dbinstance.py +357 -0
  260. data/packages/gsutil/boto/boto/rds/dbsecuritygroup.py +177 -0
  261. data/packages/gsutil/boto/boto/rds/dbsnapshot.py +108 -0
  262. data/packages/gsutil/boto/boto/rds/event.py +49 -0
  263. data/packages/gsutil/boto/boto/rds/parametergroup.py +201 -0
  264. data/packages/gsutil/boto/boto/rds/regioninfo.py +32 -0
  265. data/packages/gsutil/boto/boto/regioninfo.py +63 -0
  266. data/packages/gsutil/boto/boto/regioninfo.pyc +0 -0
  267. data/packages/gsutil/boto/boto/resultset.py +169 -0
  268. data/packages/gsutil/boto/boto/resultset.pyc +0 -0
  269. data/packages/gsutil/boto/boto/roboto/__init__.py +1 -0
  270. data/packages/gsutil/boto/boto/roboto/awsqueryrequest.py +504 -0
  271. data/packages/gsutil/boto/boto/roboto/awsqueryservice.py +121 -0
  272. data/packages/gsutil/boto/boto/roboto/param.py +147 -0
  273. data/packages/gsutil/boto/boto/route53/__init__.py +75 -0
  274. data/packages/gsutil/boto/boto/route53/connection.py +403 -0
  275. data/packages/gsutil/boto/boto/route53/exception.py +27 -0
  276. data/packages/gsutil/boto/boto/route53/hostedzone.py +56 -0
  277. data/packages/gsutil/boto/boto/route53/record.py +306 -0
  278. data/packages/gsutil/boto/boto/route53/status.py +42 -0
  279. data/packages/gsutil/boto/boto/route53/zone.py +412 -0
  280. data/packages/gsutil/boto/boto/s3/__init__.py +84 -0
  281. data/packages/gsutil/boto/boto/s3/__init__.pyc +0 -0
  282. data/packages/gsutil/boto/boto/s3/acl.py +164 -0
  283. data/packages/gsutil/boto/boto/s3/acl.pyc +0 -0
  284. data/packages/gsutil/boto/boto/s3/bucket.py +1634 -0
  285. data/packages/gsutil/boto/boto/s3/bucket.pyc +0 -0
  286. data/packages/gsutil/boto/boto/s3/bucketlistresultset.py +139 -0
  287. data/packages/gsutil/boto/boto/s3/bucketlistresultset.pyc +0 -0
  288. data/packages/gsutil/boto/boto/s3/bucketlogging.py +83 -0
  289. data/packages/gsutil/boto/boto/s3/bucketlogging.pyc +0 -0
  290. data/packages/gsutil/boto/boto/s3/connection.py +540 -0
  291. data/packages/gsutil/boto/boto/s3/connection.pyc +0 -0
  292. data/packages/gsutil/boto/boto/s3/cors.py +210 -0
  293. data/packages/gsutil/boto/boto/s3/cors.pyc +0 -0
  294. data/packages/gsutil/boto/boto/s3/deletemarker.py +55 -0
  295. data/packages/gsutil/boto/boto/s3/deletemarker.pyc +0 -0
  296. data/packages/gsutil/boto/boto/s3/key.py +1712 -0
  297. data/packages/gsutil/boto/boto/s3/key.pyc +0 -0
  298. data/packages/gsutil/boto/boto/s3/keyfile.py +134 -0
  299. data/packages/gsutil/boto/boto/s3/keyfile.pyc +0 -0
  300. data/packages/gsutil/boto/boto/s3/lifecycle.py +231 -0
  301. data/packages/gsutil/boto/boto/s3/lifecycle.pyc +0 -0
  302. data/packages/gsutil/boto/boto/s3/multidelete.py +138 -0
  303. data/packages/gsutil/boto/boto/s3/multidelete.pyc +0 -0
  304. data/packages/gsutil/boto/boto/s3/multipart.py +315 -0
  305. data/packages/gsutil/boto/boto/s3/multipart.pyc +0 -0
  306. data/packages/gsutil/boto/boto/s3/prefix.py +42 -0
  307. data/packages/gsutil/boto/boto/s3/prefix.pyc +0 -0
  308. data/packages/gsutil/boto/boto/s3/resumable_download_handler.py +339 -0
  309. data/packages/gsutil/boto/boto/s3/resumable_download_handler.pyc +0 -0
  310. data/packages/gsutil/boto/boto/s3/tagging.py +71 -0
  311. data/packages/gsutil/boto/boto/s3/tagging.pyc +0 -0
  312. data/packages/gsutil/boto/boto/s3/user.py +49 -0
  313. data/packages/gsutil/boto/boto/s3/user.pyc +0 -0
  314. data/packages/gsutil/boto/boto/s3/website.py +237 -0
  315. data/packages/gsutil/boto/boto/s3/website.pyc +0 -0
  316. data/packages/gsutil/boto/boto/sdb/__init__.py +67 -0
  317. data/packages/gsutil/boto/boto/sdb/connection.py +617 -0
  318. data/packages/gsutil/boto/boto/sdb/db/__init__.py +20 -0
  319. data/packages/gsutil/boto/boto/sdb/db/blob.py +75 -0
  320. data/packages/gsutil/boto/boto/sdb/db/key.py +59 -0
  321. data/packages/gsutil/boto/boto/sdb/db/manager/__init__.py +85 -0
  322. data/packages/gsutil/boto/boto/sdb/db/manager/sdbmanager.py +732 -0
  323. data/packages/gsutil/boto/boto/sdb/db/manager/xmlmanager.py +517 -0
  324. data/packages/gsutil/boto/boto/sdb/db/model.py +294 -0
  325. data/packages/gsutil/boto/boto/sdb/db/property.py +703 -0
  326. data/packages/gsutil/boto/boto/sdb/db/query.py +85 -0
  327. data/packages/gsutil/boto/boto/sdb/db/sequence.py +226 -0
  328. data/packages/gsutil/boto/boto/sdb/db/test_db.py +231 -0
  329. data/packages/gsutil/boto/boto/sdb/domain.py +377 -0
  330. data/packages/gsutil/boto/boto/sdb/item.py +181 -0
  331. data/packages/gsutil/boto/boto/sdb/queryresultset.py +92 -0
  332. data/packages/gsutil/boto/boto/sdb/regioninfo.py +32 -0
  333. data/packages/gsutil/boto/boto/services/__init__.py +23 -0
  334. data/packages/gsutil/boto/boto/services/bs.py +179 -0
  335. data/packages/gsutil/boto/boto/services/message.py +58 -0
  336. data/packages/gsutil/boto/boto/services/result.py +136 -0
  337. data/packages/gsutil/boto/boto/services/service.py +161 -0
  338. data/packages/gsutil/boto/boto/services/servicedef.py +91 -0
  339. data/packages/gsutil/boto/boto/services/sonofmmm.cfg +43 -0
  340. data/packages/gsutil/boto/boto/services/sonofmmm.py +81 -0
  341. data/packages/gsutil/boto/boto/services/submit.py +88 -0
  342. data/packages/gsutil/boto/boto/ses/__init__.py +54 -0
  343. data/packages/gsutil/boto/boto/ses/connection.py +521 -0
  344. data/packages/gsutil/boto/boto/ses/exceptions.py +77 -0
  345. data/packages/gsutil/boto/boto/sns/__init__.py +78 -0
  346. data/packages/gsutil/boto/boto/sns/connection.py +431 -0
  347. data/packages/gsutil/boto/boto/sqs/__init__.py +56 -0
  348. data/packages/gsutil/boto/boto/sqs/attributes.py +46 -0
  349. data/packages/gsutil/boto/boto/sqs/batchresults.py +95 -0
  350. data/packages/gsutil/boto/boto/sqs/connection.py +417 -0
  351. data/packages/gsutil/boto/boto/sqs/jsonmessage.py +43 -0
  352. data/packages/gsutil/boto/boto/sqs/message.py +253 -0
  353. data/packages/gsutil/boto/boto/sqs/queue.py +478 -0
  354. data/packages/gsutil/boto/boto/sqs/regioninfo.py +32 -0
  355. data/packages/gsutil/boto/boto/storage_uri.py +835 -0
  356. data/packages/gsutil/boto/boto/storage_uri.pyc +0 -0
  357. data/packages/gsutil/boto/boto/sts/__init__.py +55 -0
  358. data/packages/gsutil/boto/boto/sts/connection.py +207 -0
  359. data/packages/gsutil/boto/boto/sts/credentials.py +215 -0
  360. data/packages/gsutil/boto/boto/swf/__init__.py +60 -0
  361. data/packages/gsutil/boto/boto/swf/exceptions.py +44 -0
  362. data/packages/gsutil/boto/boto/swf/layer1.py +1512 -0
  363. data/packages/gsutil/boto/boto/swf/layer1_decisions.py +287 -0
  364. data/packages/gsutil/boto/boto/swf/layer2.py +342 -0
  365. data/packages/gsutil/boto/boto/utils.py +927 -0
  366. data/packages/gsutil/boto/boto/utils.pyc +0 -0
  367. data/packages/gsutil/boto/boto/vpc/__init__.py +910 -0
  368. data/packages/gsutil/boto/boto/vpc/customergateway.py +54 -0
  369. data/packages/gsutil/boto/boto/vpc/dhcpoptions.py +72 -0
  370. data/packages/gsutil/boto/boto/vpc/internetgateway.py +72 -0
  371. data/packages/gsutil/boto/boto/vpc/routetable.py +109 -0
  372. data/packages/gsutil/boto/boto/vpc/subnet.py +57 -0
  373. data/packages/gsutil/boto/boto/vpc/vpc.py +54 -0
  374. data/packages/gsutil/boto/boto/vpc/vpnconnection.py +60 -0
  375. data/packages/gsutil/boto/boto/vpc/vpngateway.py +83 -0
  376. data/packages/gsutil/boto/docs/BotoCheatSheet.pdf +0 -0
  377. data/packages/gsutil/boto/docs/Makefile +89 -0
  378. data/packages/gsutil/boto/docs/make.bat +113 -0
  379. data/packages/gsutil/boto/docs/source/_templates/layout.html +3 -0
  380. data/packages/gsutil/boto/docs/source/autoscale_tut.rst +220 -0
  381. data/packages/gsutil/boto/docs/source/boto_config_tut.rst +125 -0
  382. data/packages/gsutil/boto/docs/source/boto_theme/static/boto.css_t +239 -0
  383. data/packages/gsutil/boto/docs/source/boto_theme/static/pygments.css +61 -0
  384. data/packages/gsutil/boto/docs/source/boto_theme/theme.conf +3 -0
  385. data/packages/gsutil/boto/docs/source/cloudfront_tut.rst +196 -0
  386. data/packages/gsutil/boto/docs/source/cloudsearch_tut.rst +411 -0
  387. data/packages/gsutil/boto/docs/source/cloudwatch_tut.rst +116 -0
  388. data/packages/gsutil/boto/docs/source/conf.py +32 -0
  389. data/packages/gsutil/boto/docs/source/contributing.rst +204 -0
  390. data/packages/gsutil/boto/docs/source/documentation.rst +59 -0
  391. data/packages/gsutil/boto/docs/source/dynamodb_tut.rst +339 -0
  392. data/packages/gsutil/boto/docs/source/ec2_tut.rst +86 -0
  393. data/packages/gsutil/boto/docs/source/elb_tut.rst +257 -0
  394. data/packages/gsutil/boto/docs/source/emr_tut.rst +108 -0
  395. data/packages/gsutil/boto/docs/source/index.rst +146 -0
  396. data/packages/gsutil/boto/docs/source/rds_tut.rst +108 -0
  397. data/packages/gsutil/boto/docs/source/ref/autoscale.rst +62 -0
  398. data/packages/gsutil/boto/docs/source/ref/beanstalk.rst +26 -0
  399. data/packages/gsutil/boto/docs/source/ref/boto.rst +47 -0
  400. data/packages/gsutil/boto/docs/source/ref/cloudformation.rst +34 -0
  401. data/packages/gsutil/boto/docs/source/ref/cloudfront.rst +68 -0
  402. data/packages/gsutil/boto/docs/source/ref/cloudsearch.rst +59 -0
  403. data/packages/gsutil/boto/docs/source/ref/cloudwatch.rst +27 -0
  404. data/packages/gsutil/boto/docs/source/ref/contrib.rst +32 -0
  405. data/packages/gsutil/boto/docs/source/ref/datapipeline.rst +26 -0
  406. data/packages/gsutil/boto/docs/source/ref/dynamodb.rst +61 -0
  407. data/packages/gsutil/boto/docs/source/ref/ec2.rst +140 -0
  408. data/packages/gsutil/boto/docs/source/ref/ecs.rst +19 -0
  409. data/packages/gsutil/boto/docs/source/ref/elasticache.rst +19 -0
  410. data/packages/gsutil/boto/docs/source/ref/elastictranscoder.rst +26 -0
  411. data/packages/gsutil/boto/docs/source/ref/elb.rst +47 -0
  412. data/packages/gsutil/boto/docs/source/ref/emr.rst +34 -0
  413. data/packages/gsutil/boto/docs/source/ref/file.rst +34 -0
  414. data/packages/gsutil/boto/docs/source/ref/fps.rst +19 -0
  415. data/packages/gsutil/boto/docs/source/ref/glacier.rst +63 -0
  416. data/packages/gsutil/boto/docs/source/ref/gs.rst +72 -0
  417. data/packages/gsutil/boto/docs/source/ref/iam.rst +27 -0
  418. data/packages/gsutil/boto/docs/source/ref/index.rst +40 -0
  419. data/packages/gsutil/boto/docs/source/ref/manage.rst +47 -0
  420. data/packages/gsutil/boto/docs/source/ref/mturk.rst +54 -0
  421. data/packages/gsutil/boto/docs/source/ref/mws.rst +33 -0
  422. data/packages/gsutil/boto/docs/source/ref/pyami.rst +103 -0
  423. data/packages/gsutil/boto/docs/source/ref/rds.rst +47 -0
  424. data/packages/gsutil/boto/docs/source/ref/route53.rst +34 -0
  425. data/packages/gsutil/boto/docs/source/ref/s3.rst +111 -0
  426. data/packages/gsutil/boto/docs/source/ref/sdb.rst +45 -0
  427. data/packages/gsutil/boto/docs/source/ref/sdb_db.rst +83 -0
  428. data/packages/gsutil/boto/docs/source/ref/services.rst +61 -0
  429. data/packages/gsutil/boto/docs/source/ref/ses.rst +21 -0
  430. data/packages/gsutil/boto/docs/source/ref/sns.rst +17 -0
  431. data/packages/gsutil/boto/docs/source/ref/sqs.rst +61 -0
  432. data/packages/gsutil/boto/docs/source/ref/sts.rst +25 -0
  433. data/packages/gsutil/boto/docs/source/ref/swf.rst +22 -0
  434. data/packages/gsutil/boto/docs/source/ref/vpc.rst +54 -0
  435. data/packages/gsutil/boto/docs/source/s3_tut.rst +450 -0
  436. data/packages/gsutil/boto/docs/source/security_groups.rst +82 -0
  437. data/packages/gsutil/boto/docs/source/ses_tut.rst +171 -0
  438. data/packages/gsutil/boto/docs/source/simpledb_tut.rst +188 -0
  439. data/packages/gsutil/boto/docs/source/sqs_tut.rst +246 -0
  440. data/packages/gsutil/boto/docs/source/vpc_tut.rst +100 -0
  441. data/packages/gsutil/boto/pylintrc +305 -0
  442. data/packages/gsutil/boto/requirements.txt +10 -0
  443. data/packages/gsutil/boto/setup.py +89 -0
  444. data/packages/gsutil/boto/tests/__init__.py +20 -0
  445. data/packages/gsutil/boto/tests/db/test_lists.py +96 -0
  446. data/packages/gsutil/boto/tests/db/test_password.py +128 -0
  447. data/packages/gsutil/boto/tests/db/test_query.py +152 -0
  448. data/packages/gsutil/boto/tests/db/test_sequence.py +109 -0
  449. data/packages/gsutil/boto/tests/devpay/__init__.py +0 -0
  450. data/packages/gsutil/boto/tests/devpay/test_s3.py +181 -0
  451. data/packages/gsutil/boto/tests/fps/__init__.py +0 -0
  452. data/packages/gsutil/boto/tests/fps/test.py +100 -0
  453. data/packages/gsutil/boto/tests/fps/test_verify_signature.py +12 -0
  454. data/packages/gsutil/boto/tests/integration/__init__.py +0 -0
  455. data/packages/gsutil/boto/tests/integration/beanstalk/test_wrapper.py +209 -0
  456. data/packages/gsutil/boto/tests/integration/cloudformation/__init__.py +21 -0
  457. data/packages/gsutil/boto/tests/integration/cloudformation/test_cert_verification.py +40 -0
  458. data/packages/gsutil/boto/tests/integration/cloudformation/test_connection.py +110 -0
  459. data/packages/gsutil/boto/tests/integration/cloudsearch/__init__.py +21 -0
  460. data/packages/gsutil/boto/tests/integration/cloudsearch/test_cert_verification.py +40 -0
  461. data/packages/gsutil/boto/tests/integration/datapipeline/test_layer1.py +122 -0
  462. data/packages/gsutil/boto/tests/integration/dynamodb/__init__.py +20 -0
  463. data/packages/gsutil/boto/tests/integration/dynamodb/test_cert_verification.py +40 -0
  464. data/packages/gsutil/boto/tests/integration/dynamodb/test_layer1.py +266 -0
  465. data/packages/gsutil/boto/tests/integration/dynamodb/test_layer2.py +484 -0
  466. data/packages/gsutil/boto/tests/integration/dynamodb/test_table.py +84 -0
  467. data/packages/gsutil/boto/tests/integration/ec2/__init__.py +20 -0
  468. data/packages/gsutil/boto/tests/integration/ec2/autoscale/__init__.py +21 -0
  469. data/packages/gsutil/boto/tests/integration/ec2/autoscale/test_cert_verification.py +40 -0
  470. data/packages/gsutil/boto/tests/integration/ec2/autoscale/test_connection.py +167 -0
  471. data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/__init__.py +20 -0
  472. data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/test_cert_verification.py +40 -0
  473. data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/test_connection.py +277 -0
  474. data/packages/gsutil/boto/tests/integration/ec2/elb/__init__.py +20 -0
  475. data/packages/gsutil/boto/tests/integration/ec2/elb/test_cert_verification.py +40 -0
  476. data/packages/gsutil/boto/tests/integration/ec2/elb/test_connection.py +130 -0
  477. data/packages/gsutil/boto/tests/integration/ec2/test_cert_verification.py +40 -0
  478. data/packages/gsutil/boto/tests/integration/ec2/test_connection.py +192 -0
  479. data/packages/gsutil/boto/tests/integration/ec2/vpc/__init__.py +0 -0
  480. data/packages/gsutil/boto/tests/integration/ec2/vpc/test_connection.py +95 -0
  481. data/packages/gsutil/boto/tests/integration/elasticache/__init__.py +0 -0
  482. data/packages/gsutil/boto/tests/integration/elasticache/test_layer1.py +67 -0
  483. data/packages/gsutil/boto/tests/integration/elastictranscoder/__init__.py +0 -0
  484. data/packages/gsutil/boto/tests/integration/elastictranscoder/test_cert_verification.py +35 -0
  485. data/packages/gsutil/boto/tests/integration/elastictranscoder/test_layer1.py +115 -0
  486. data/packages/gsutil/boto/tests/integration/emr/__init__.py +20 -0
  487. data/packages/gsutil/boto/tests/integration/emr/test_cert_verification.py +40 -0
  488. data/packages/gsutil/boto/tests/integration/glacier/__init__.py +22 -0
  489. data/packages/gsutil/boto/tests/integration/glacier/test_cert_verification.py +40 -0
  490. data/packages/gsutil/boto/tests/integration/glacier/test_layer1.py +44 -0
  491. data/packages/gsutil/boto/tests/integration/glacier/test_layer2.py +45 -0
  492. data/packages/gsutil/boto/tests/integration/gs/__init__.py +0 -0
  493. data/packages/gsutil/boto/tests/integration/gs/cb_test_harness.py +71 -0
  494. data/packages/gsutil/boto/tests/integration/gs/test_basic.py +379 -0
  495. data/packages/gsutil/boto/tests/integration/gs/test_generation_conditionals.py +399 -0
  496. data/packages/gsutil/boto/tests/integration/gs/test_resumable_downloads.py +358 -0
  497. data/packages/gsutil/boto/tests/integration/gs/test_resumable_uploads.py +525 -0
  498. data/packages/gsutil/boto/tests/integration/gs/test_storage_uri.py +125 -0
  499. data/packages/gsutil/boto/tests/integration/gs/test_versioning.py +268 -0
  500. data/packages/gsutil/boto/tests/integration/gs/testcase.py +116 -0
  501. data/packages/gsutil/boto/tests/integration/gs/util.py +63 -0
  502. data/packages/gsutil/boto/tests/integration/iam/__init__.py +20 -0
  503. data/packages/gsutil/boto/tests/integration/iam/test_cert_verification.py +40 -0
  504. data/packages/gsutil/boto/tests/integration/mws/__init__.py +0 -0
  505. data/packages/gsutil/boto/tests/integration/mws/test.py +100 -0
  506. data/packages/gsutil/boto/tests/integration/rds/__init__.py +21 -0
  507. data/packages/gsutil/boto/tests/integration/rds/test_cert_verification.py +40 -0
  508. data/packages/gsutil/boto/tests/integration/route53/__init__.py +20 -0
  509. data/packages/gsutil/boto/tests/integration/route53/test_cert_verification.py +40 -0
  510. data/packages/gsutil/boto/tests/integration/route53/test_zone.py +132 -0
  511. data/packages/gsutil/boto/tests/integration/s3/__init__.py +20 -0
  512. data/packages/gsutil/boto/tests/integration/s3/mock_storage_service.py +589 -0
  513. data/packages/gsutil/boto/tests/integration/s3/other_cacerts.txt +70 -0
  514. data/packages/gsutil/boto/tests/integration/s3/test_bucket.py +263 -0
  515. data/packages/gsutil/boto/tests/integration/s3/test_cert_verification.py +40 -0
  516. data/packages/gsutil/boto/tests/integration/s3/test_connection.py +245 -0
  517. data/packages/gsutil/boto/tests/integration/s3/test_cors.py +78 -0
  518. data/packages/gsutil/boto/tests/integration/s3/test_encryption.py +115 -0
  519. data/packages/gsutil/boto/tests/integration/s3/test_https_cert_validation.py +141 -0
  520. data/packages/gsutil/boto/tests/integration/s3/test_key.py +375 -0
  521. data/packages/gsutil/boto/tests/integration/s3/test_mfa.py +95 -0
  522. data/packages/gsutil/boto/tests/integration/s3/test_multidelete.py +181 -0
  523. data/packages/gsutil/boto/tests/integration/s3/test_multipart.py +139 -0
  524. data/packages/gsutil/boto/tests/integration/s3/test_pool.py +246 -0
  525. data/packages/gsutil/boto/tests/integration/s3/test_versioning.py +158 -0
  526. data/packages/gsutil/boto/tests/integration/sdb/__init__.py +20 -0
  527. data/packages/gsutil/boto/tests/integration/sdb/test_cert_verification.py +40 -0
  528. data/packages/gsutil/boto/tests/integration/sdb/test_connection.py +119 -0
  529. data/packages/gsutil/boto/tests/integration/ses/__init__.py +0 -0
  530. data/packages/gsutil/boto/tests/integration/ses/test_cert_verification.py +40 -0
  531. data/packages/gsutil/boto/tests/integration/ses/test_connection.py +38 -0
  532. data/packages/gsutil/boto/tests/integration/sns/__init__.py +20 -0
  533. data/packages/gsutil/boto/tests/integration/sns/test_cert_verification.py +40 -0
  534. data/packages/gsutil/boto/tests/integration/sqs/__init__.py +20 -0
  535. data/packages/gsutil/boto/tests/integration/sqs/test_cert_verification.py +40 -0
  536. data/packages/gsutil/boto/tests/integration/sqs/test_connection.py +217 -0
  537. data/packages/gsutil/boto/tests/integration/sts/__init__.py +20 -0
  538. data/packages/gsutil/boto/tests/integration/sts/test_cert_verification.py +40 -0
  539. data/packages/gsutil/boto/tests/integration/sts/test_session_token.py +65 -0
  540. data/packages/gsutil/boto/tests/integration/swf/__init__.py +0 -0
  541. data/packages/gsutil/boto/tests/integration/swf/test_cert_verification.py +40 -0
  542. data/packages/gsutil/boto/tests/integration/swf/test_layer1.py +246 -0
  543. data/packages/gsutil/boto/tests/integration/swf/test_layer1_workflow_execution.py +173 -0
  544. data/packages/gsutil/boto/tests/mturk/__init__.py +0 -0
  545. data/packages/gsutil/boto/tests/mturk/_init_environment.py +28 -0
  546. data/packages/gsutil/boto/tests/mturk/all_tests.py +24 -0
  547. data/packages/gsutil/boto/tests/mturk/cleanup_tests.py +47 -0
  548. data/packages/gsutil/boto/tests/mturk/common.py +45 -0
  549. data/packages/gsutil/boto/tests/mturk/create_free_text_question_regex.doctest +100 -0
  550. data/packages/gsutil/boto/tests/mturk/create_hit.doctest +92 -0
  551. data/packages/gsutil/boto/tests/mturk/create_hit_binary.doctest +94 -0
  552. data/packages/gsutil/boto/tests/mturk/create_hit_external.py +21 -0
  553. data/packages/gsutil/boto/tests/mturk/create_hit_from_hit_type.doctest +103 -0
  554. data/packages/gsutil/boto/tests/mturk/create_hit_test.py +21 -0
  555. data/packages/gsutil/boto/tests/mturk/create_hit_with_qualifications.py +16 -0
  556. data/packages/gsutil/boto/tests/mturk/hit_persistence.py +27 -0
  557. data/packages/gsutil/boto/tests/mturk/mocks.py +11 -0
  558. data/packages/gsutil/boto/tests/mturk/reviewable_hits.doctest +129 -0
  559. data/packages/gsutil/boto/tests/mturk/run-doctest.py +13 -0
  560. data/packages/gsutil/boto/tests/mturk/search_hits.doctest +16 -0
  561. data/packages/gsutil/boto/tests/mturk/selenium_support.py +61 -0
  562. data/packages/gsutil/boto/tests/mturk/support.py +7 -0
  563. data/packages/gsutil/boto/tests/mturk/test_disable_hit.py +11 -0
  564. data/packages/gsutil/boto/tests/test.py +59 -0
  565. data/packages/gsutil/boto/tests/unit/__init__.py +79 -0
  566. data/packages/gsutil/boto/tests/unit/auth/__init__.py +0 -0
  567. data/packages/gsutil/boto/tests/unit/auth/test_sigv4.py +73 -0
  568. data/packages/gsutil/boto/tests/unit/beanstalk/__init__.py +0 -0
  569. data/packages/gsutil/boto/tests/unit/beanstalk/test_layer1.py +128 -0
  570. data/packages/gsutil/boto/tests/unit/cloudformation/__init__.py +0 -0
  571. data/packages/gsutil/boto/tests/unit/cloudformation/test_connection.py +605 -0
  572. data/packages/gsutil/boto/tests/unit/cloudformation/test_stack.py +63 -0
  573. data/packages/gsutil/boto/tests/unit/cloudfront/__init__.py +0 -0
  574. data/packages/gsutil/boto/tests/unit/cloudfront/test_invalidation_list.py +113 -0
  575. data/packages/gsutil/boto/tests/unit/cloudfront/test_signed_urls.py +354 -0
  576. data/packages/gsutil/boto/tests/unit/cloudsearch/__init__.py +1 -0
  577. data/packages/gsutil/boto/tests/unit/cloudsearch/test_connection.py +241 -0
  578. data/packages/gsutil/boto/tests/unit/cloudsearch/test_document.py +324 -0
  579. data/packages/gsutil/boto/tests/unit/cloudsearch/test_search.py +325 -0
  580. data/packages/gsutil/boto/tests/unit/dynamodb/__init__.py +0 -0
  581. data/packages/gsutil/boto/tests/unit/dynamodb/test_batch.py +103 -0
  582. data/packages/gsutil/boto/tests/unit/dynamodb/test_layer2.py +119 -0
  583. data/packages/gsutil/boto/tests/unit/dynamodb/test_types.py +82 -0
  584. data/packages/gsutil/boto/tests/unit/ec2/__init__.py +0 -0
  585. data/packages/gsutil/boto/tests/unit/ec2/autoscale/__init__.py +0 -0
  586. data/packages/gsutil/boto/tests/unit/ec2/autoscale/test_group.py +162 -0
  587. data/packages/gsutil/boto/tests/unit/ec2/test_address.py +39 -0
  588. data/packages/gsutil/boto/tests/unit/ec2/test_blockdevicemapping.py +79 -0
  589. data/packages/gsutil/boto/tests/unit/ec2/test_connection.py +480 -0
  590. data/packages/gsutil/boto/tests/unit/ec2/test_instance.py +243 -0
  591. data/packages/gsutil/boto/tests/unit/ec2/test_networkinterface.py +140 -0
  592. data/packages/gsutil/boto/tests/unit/ec2/test_volume.py +248 -0
  593. data/packages/gsutil/boto/tests/unit/emr/test_emr_responses.py +373 -0
  594. data/packages/gsutil/boto/tests/unit/glacier/__init__.py +0 -0
  595. data/packages/gsutil/boto/tests/unit/glacier/test_concurrent.py +120 -0
  596. data/packages/gsutil/boto/tests/unit/glacier/test_job.py +60 -0
  597. data/packages/gsutil/boto/tests/unit/glacier/test_layer1.py +98 -0
  598. data/packages/gsutil/boto/tests/unit/glacier/test_layer2.py +266 -0
  599. data/packages/gsutil/boto/tests/unit/glacier/test_utils.py +116 -0
  600. data/packages/gsutil/boto/tests/unit/glacier/test_vault.py +100 -0
  601. data/packages/gsutil/boto/tests/unit/glacier/test_writer.py +185 -0
  602. data/packages/gsutil/boto/tests/unit/provider/__init__.py +0 -0
  603. data/packages/gsutil/boto/tests/unit/provider/test_provider.py +176 -0
  604. data/packages/gsutil/boto/tests/unit/rds/__init__.py +0 -0
  605. data/packages/gsutil/boto/tests/unit/rds/test_connection.py +131 -0
  606. data/packages/gsutil/boto/tests/unit/s3/__init__.py +0 -0
  607. data/packages/gsutil/boto/tests/unit/s3/test_cors_configuration.py +77 -0
  608. data/packages/gsutil/boto/tests/unit/s3/test_key.py +75 -0
  609. data/packages/gsutil/boto/tests/unit/s3/test_keyfile.py +101 -0
  610. data/packages/gsutil/boto/tests/unit/s3/test_lifecycle.py +97 -0
  611. data/packages/gsutil/boto/tests/unit/s3/test_tagging.py +47 -0
  612. data/packages/gsutil/boto/tests/unit/s3/test_uri.py +257 -0
  613. data/packages/gsutil/boto/tests/unit/s3/test_website.py +188 -0
  614. data/packages/gsutil/boto/tests/unit/sns/__init__.py +0 -0
  615. data/packages/gsutil/boto/tests/unit/sns/test_connection.py +99 -0
  616. data/packages/gsutil/boto/tests/unit/sqs/__init__.py +0 -0
  617. data/packages/gsutil/boto/tests/unit/sqs/test_connection.py +98 -0
  618. data/packages/gsutil/boto/tests/unit/sqs/test_queue.py +40 -0
  619. data/packages/gsutil/boto/tests/unit/sts/test_connection.py +74 -0
  620. data/packages/gsutil/boto/tests/unit/test_connection.py +60 -0
  621. data/packages/gsutil/boto/tests/unit/utils/test_utils.py +109 -0
  622. data/packages/gsutil/boto/tox.ini +8 -0
  623. data/packages/gsutil/gslib/README +5 -0
  624. data/packages/gsutil/gslib/__init__.py +22 -0
  625. data/packages/gsutil/gslib/__init__.pyc +0 -0
  626. data/packages/gsutil/gslib/addlhelp/__init__.py +15 -0
  627. data/packages/gsutil/gslib/addlhelp/acls.py +234 -0
  628. data/packages/gsutil/gslib/addlhelp/anon.py +57 -0
  629. data/packages/gsutil/gslib/addlhelp/command_opts.py +116 -0
  630. data/packages/gsutil/gslib/addlhelp/dev.py +139 -0
  631. data/packages/gsutil/gslib/addlhelp/metadata.py +186 -0
  632. data/packages/gsutil/gslib/addlhelp/naming.py +173 -0
  633. data/packages/gsutil/gslib/addlhelp/prod.py +160 -0
  634. data/packages/gsutil/gslib/addlhelp/projects.py +130 -0
  635. data/packages/gsutil/gslib/addlhelp/subdirs.py +110 -0
  636. data/packages/gsutil/gslib/addlhelp/support.py +86 -0
  637. data/packages/gsutil/gslib/addlhelp/versioning.py +242 -0
  638. data/packages/gsutil/gslib/addlhelp/wildcards.py +170 -0
  639. data/packages/gsutil/gslib/bucket_listing_ref.py +175 -0
  640. data/packages/gsutil/gslib/bucket_listing_ref.pyc +0 -0
  641. data/packages/gsutil/gslib/command.py +722 -0
  642. data/packages/gsutil/gslib/command.pyc +0 -0
  643. data/packages/gsutil/gslib/command_runner.py +101 -0
  644. data/packages/gsutil/gslib/command_runner.pyc +0 -0
  645. data/packages/gsutil/gslib/commands/__init__.py +15 -0
  646. data/packages/gsutil/gslib/commands/__init__.pyc +0 -0
  647. data/packages/gsutil/gslib/commands/cat.py +131 -0
  648. data/packages/gsutil/gslib/commands/cat.pyc +0 -0
  649. data/packages/gsutil/gslib/commands/chacl.py +532 -0
  650. data/packages/gsutil/gslib/commands/chacl.pyc +0 -0
  651. data/packages/gsutil/gslib/commands/config.py +694 -0
  652. data/packages/gsutil/gslib/commands/config.pyc +0 -0
  653. data/packages/gsutil/gslib/commands/cp.py +1818 -0
  654. data/packages/gsutil/gslib/commands/cp.pyc +0 -0
  655. data/packages/gsutil/gslib/commands/disablelogging.py +101 -0
  656. data/packages/gsutil/gslib/commands/disablelogging.pyc +0 -0
  657. data/packages/gsutil/gslib/commands/enablelogging.py +149 -0
  658. data/packages/gsutil/gslib/commands/enablelogging.pyc +0 -0
  659. data/packages/gsutil/gslib/commands/getacl.py +82 -0
  660. data/packages/gsutil/gslib/commands/getacl.pyc +0 -0
  661. data/packages/gsutil/gslib/commands/getcors.py +121 -0
  662. data/packages/gsutil/gslib/commands/getcors.pyc +0 -0
  663. data/packages/gsutil/gslib/commands/getdefacl.py +86 -0
  664. data/packages/gsutil/gslib/commands/getdefacl.pyc +0 -0
  665. data/packages/gsutil/gslib/commands/getlogging.py +137 -0
  666. data/packages/gsutil/gslib/commands/getlogging.pyc +0 -0
  667. data/packages/gsutil/gslib/commands/getversioning.py +116 -0
  668. data/packages/gsutil/gslib/commands/getversioning.pyc +0 -0
  669. data/packages/gsutil/gslib/commands/getwebcfg.py +122 -0
  670. data/packages/gsutil/gslib/commands/getwebcfg.pyc +0 -0
  671. data/packages/gsutil/gslib/commands/help.py +218 -0
  672. data/packages/gsutil/gslib/commands/help.pyc +0 -0
  673. data/packages/gsutil/gslib/commands/ls.py +578 -0
  674. data/packages/gsutil/gslib/commands/ls.pyc +0 -0
  675. data/packages/gsutil/gslib/commands/mb.py +172 -0
  676. data/packages/gsutil/gslib/commands/mb.pyc +0 -0
  677. data/packages/gsutil/gslib/commands/mv.py +159 -0
  678. data/packages/gsutil/gslib/commands/mv.pyc +0 -0
  679. data/packages/gsutil/gslib/commands/perfdiag.py +903 -0
  680. data/packages/gsutil/gslib/commands/perfdiag.pyc +0 -0
  681. data/packages/gsutil/gslib/commands/rb.py +113 -0
  682. data/packages/gsutil/gslib/commands/rb.pyc +0 -0
  683. data/packages/gsutil/gslib/commands/rm.py +239 -0
  684. data/packages/gsutil/gslib/commands/rm.pyc +0 -0
  685. data/packages/gsutil/gslib/commands/setacl.py +138 -0
  686. data/packages/gsutil/gslib/commands/setacl.pyc +0 -0
  687. data/packages/gsutil/gslib/commands/setcors.py +145 -0
  688. data/packages/gsutil/gslib/commands/setcors.pyc +0 -0
  689. data/packages/gsutil/gslib/commands/setdefacl.py +105 -0
  690. data/packages/gsutil/gslib/commands/setdefacl.pyc +0 -0
  691. data/packages/gsutil/gslib/commands/setmeta.py +428 -0
  692. data/packages/gsutil/gslib/commands/setmeta.pyc +0 -0
  693. data/packages/gsutil/gslib/commands/setversioning.py +114 -0
  694. data/packages/gsutil/gslib/commands/setversioning.pyc +0 -0
  695. data/packages/gsutil/gslib/commands/setwebcfg.py +190 -0
  696. data/packages/gsutil/gslib/commands/setwebcfg.pyc +0 -0
  697. data/packages/gsutil/gslib/commands/test.py +228 -0
  698. data/packages/gsutil/gslib/commands/test.pyc +0 -0
  699. data/packages/gsutil/gslib/commands/update.py +305 -0
  700. data/packages/gsutil/gslib/commands/update.pyc +0 -0
  701. data/packages/gsutil/gslib/commands/version.py +150 -0
  702. data/packages/gsutil/gslib/commands/version.pyc +0 -0
  703. data/packages/gsutil/gslib/exception.py +76 -0
  704. data/packages/gsutil/gslib/exception.pyc +0 -0
  705. data/packages/gsutil/gslib/help_provider.py +81 -0
  706. data/packages/gsutil/gslib/help_provider.pyc +0 -0
  707. data/packages/gsutil/gslib/name_expansion.py +550 -0
  708. data/packages/gsutil/gslib/name_expansion.pyc +0 -0
  709. data/packages/gsutil/gslib/no_op_auth_plugin.py +30 -0
  710. data/packages/gsutil/gslib/plurality_checkable_iterator.py +56 -0
  711. data/packages/gsutil/gslib/plurality_checkable_iterator.pyc +0 -0
  712. data/packages/gsutil/gslib/project_id.py +67 -0
  713. data/packages/gsutil/gslib/project_id.pyc +0 -0
  714. data/packages/gsutil/gslib/storage_uri_builder.py +56 -0
  715. data/packages/gsutil/gslib/storage_uri_builder.pyc +0 -0
  716. data/packages/gsutil/gslib/tests/__init__.py +15 -0
  717. data/packages/gsutil/gslib/tests/__init__.pyc +0 -0
  718. data/packages/gsutil/gslib/tests/test_chacl.py +236 -0
  719. data/packages/gsutil/gslib/tests/test_cp.py +267 -0
  720. data/packages/gsutil/gslib/tests/test_data/test.gif +0 -0
  721. data/packages/gsutil/gslib/tests/test_data/test.mp3 +0 -0
  722. data/packages/gsutil/gslib/tests/test_ls.py +66 -0
  723. data/packages/gsutil/gslib/tests/test_mv.py +69 -0
  724. data/packages/gsutil/gslib/tests/test_naming.py +989 -0
  725. data/packages/gsutil/gslib/tests/test_perfdiag.py +41 -0
  726. data/packages/gsutil/gslib/tests/test_plurality_checkable_iterator.py +67 -0
  727. data/packages/gsutil/gslib/tests/test_rm.py +143 -0
  728. data/packages/gsutil/gslib/tests/test_setacl.py +152 -0
  729. data/packages/gsutil/gslib/tests/test_setcors.py +168 -0
  730. data/packages/gsutil/gslib/tests/test_setmeta.py +91 -0
  731. data/packages/gsutil/gslib/tests/test_setversioning.py +44 -0
  732. data/packages/gsutil/gslib/tests/test_setwebcfg.py +63 -0
  733. data/packages/gsutil/gslib/tests/test_thread_pool.py +92 -0
  734. data/packages/gsutil/gslib/tests/test_wildcard_iterator.py +364 -0
  735. data/packages/gsutil/gslib/tests/testcase/__init__.py +18 -0
  736. data/packages/gsutil/gslib/tests/testcase/base.py +89 -0
  737. data/packages/gsutil/gslib/tests/testcase/integration_testcase.py +197 -0
  738. data/packages/gsutil/gslib/tests/testcase/unit_testcase.py +230 -0
  739. data/packages/gsutil/gslib/tests/util.py +125 -0
  740. data/packages/gsutil/gslib/tests/util.pyc +0 -0
  741. data/packages/gsutil/gslib/thread_pool.py +79 -0
  742. data/packages/gsutil/gslib/thread_pool.pyc +0 -0
  743. data/packages/gsutil/gslib/util.py +151 -0
  744. data/packages/gsutil/gslib/util.pyc +0 -0
  745. data/packages/gsutil/gslib/wildcard_iterator.py +492 -0
  746. data/packages/gsutil/gslib/wildcard_iterator.pyc +0 -0
  747. data/packages/gsutil/gsutil +377 -0
  748. data/packages/gsutil/gsutil.spec.in +75 -0
  749. data/packages/gsutil/oauth2_plugin/__init__.py +22 -0
  750. data/packages/gsutil/oauth2_plugin/__init__.pyc +0 -0
  751. data/packages/gsutil/oauth2_plugin/oauth2_client.py +642 -0
  752. data/packages/gsutil/oauth2_plugin/oauth2_client.pyc +0 -0
  753. data/packages/gsutil/oauth2_plugin/oauth2_client_test.py +374 -0
  754. data/packages/gsutil/oauth2_plugin/oauth2_helper.py +110 -0
  755. data/packages/gsutil/oauth2_plugin/oauth2_helper.pyc +0 -0
  756. data/packages/gsutil/oauth2_plugin/oauth2_plugin.py +24 -0
  757. data/packages/gsutil/oauth2_plugin/oauth2_plugin.pyc +0 -0
  758. data/packages/gsutil/pkg_gen.sh +54 -0
  759. data/packages/gsutil/pkg_util.py +60 -0
  760. data/packages/gsutil/setup.py +141 -0
  761. data/packages/gsutil/third_party/__init__.py +0 -0
  762. data/packages/gsutil/third_party/__init__.pyc +0 -0
  763. data/packages/gsutil/third_party/fancy_urllib/README +21 -0
  764. data/packages/gsutil/third_party/fancy_urllib/__init__.py +398 -0
  765. data/packages/gsutil/third_party/fancy_urllib/__init__.pyc +0 -0
  766. data/tasks/rubygem.rake +3 -1
  767. metadata +770 -7
  768. metadata.gz.sig +0 -0
@@ -0,0 +1,3409 @@
1
+ # Copyright (c) 2006-2012 Mitch Garnaat http://garnaat.org/
2
+ # Copyright (c) 2010, Eucalyptus Systems, Inc.
3
+ # Copyright (c) 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a
6
+ # copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish, dis-
9
+ # tribute, sublicense, and/or sell copies of the Software, and to permit
10
+ # persons to whom the Software is furnished to do so, subject to the fol-
11
+ # lowing conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included
14
+ # in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
+ # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
18
+ # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19
+ # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
+ # IN THE SOFTWARE.
23
+
24
+ """
25
+ Represents a connection to the EC2 service.
26
+ """
27
+
28
+ import base64
29
+ import warnings
30
+ from datetime import datetime
31
+ from datetime import timedelta
32
+
33
+ import boto
34
+ from boto.connection import AWSQueryConnection
35
+ from boto.resultset import ResultSet
36
+ from boto.ec2.image import Image, ImageAttribute
37
+ from boto.ec2.instance import Reservation, Instance
38
+ from boto.ec2.instance import ConsoleOutput, InstanceAttribute
39
+ from boto.ec2.keypair import KeyPair
40
+ from boto.ec2.address import Address
41
+ from boto.ec2.volume import Volume, VolumeAttribute
42
+ from boto.ec2.snapshot import Snapshot
43
+ from boto.ec2.snapshot import SnapshotAttribute
44
+ from boto.ec2.zone import Zone
45
+ from boto.ec2.securitygroup import SecurityGroup
46
+ from boto.ec2.regioninfo import RegionInfo
47
+ from boto.ec2.instanceinfo import InstanceInfo
48
+ from boto.ec2.reservedinstance import ReservedInstancesOffering
49
+ from boto.ec2.reservedinstance import ReservedInstance
50
+ from boto.ec2.reservedinstance import ReservedInstanceListing
51
+ from boto.ec2.spotinstancerequest import SpotInstanceRequest
52
+ from boto.ec2.spotpricehistory import SpotPriceHistory
53
+ from boto.ec2.spotdatafeedsubscription import SpotDatafeedSubscription
54
+ from boto.ec2.bundleinstance import BundleInstanceTask
55
+ from boto.ec2.placementgroup import PlacementGroup
56
+ from boto.ec2.tag import Tag
57
+ from boto.ec2.vmtype import VmType
58
+ from boto.ec2.instancestatus import InstanceStatusSet
59
+ from boto.ec2.volumestatus import VolumeStatusSet
60
+ from boto.ec2.networkinterface import NetworkInterface
61
+ from boto.exception import EC2ResponseError
62
+
63
+ #boto.set_stream_logger('ec2')
64
+
65
+
66
+ class EC2Connection(AWSQueryConnection):
67
+
68
+ APIVersion = boto.config.get('Boto', 'ec2_version', '2012-12-01')
69
+ DefaultRegionName = boto.config.get('Boto', 'ec2_region_name', 'us-east-1')
70
+ DefaultRegionEndpoint = boto.config.get('Boto', 'ec2_region_endpoint',
71
+ 'ec2.us-east-1.amazonaws.com')
72
+ ResponseError = EC2ResponseError
73
+
74
+ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
75
+ is_secure=True, host=None, port=None,
76
+ proxy=None, proxy_port=None,
77
+ proxy_user=None, proxy_pass=None, debug=0,
78
+ https_connection_factory=None, region=None, path='/',
79
+ api_version=None, security_token=None,
80
+ validate_certs=True):
81
+ """
82
+ Init method to create a new connection to EC2.
83
+ """
84
+ if not region:
85
+ region = RegionInfo(self, self.DefaultRegionName,
86
+ self.DefaultRegionEndpoint)
87
+ self.region = region
88
+ AWSQueryConnection.__init__(self, aws_access_key_id,
89
+ aws_secret_access_key,
90
+ is_secure, port, proxy, proxy_port,
91
+ proxy_user, proxy_pass,
92
+ self.region.endpoint, debug,
93
+ https_connection_factory, path,
94
+ security_token,
95
+ validate_certs=validate_certs)
96
+ if api_version:
97
+ self.APIVersion = api_version
98
+
99
+ def _required_auth_capability(self):
100
+ return ['ec2']
101
+
102
+ def get_params(self):
103
+ """
104
+ Returns a dictionary containing the value of of all of the keyword
105
+ arguments passed when constructing this connection.
106
+ """
107
+ param_names = ['aws_access_key_id', 'aws_secret_access_key',
108
+ 'is_secure', 'port', 'proxy', 'proxy_port',
109
+ 'proxy_user', 'proxy_pass',
110
+ 'debug', 'https_connection_factory']
111
+ params = {}
112
+ for name in param_names:
113
+ params[name] = getattr(self, name)
114
+ return params
115
+
116
+ def build_filter_params(self, params, filters):
117
+ i = 1
118
+ for name in filters:
119
+ aws_name = name
120
+ if not aws_name.startswith('tag:'):
121
+ aws_name = name.replace('_', '-')
122
+ params['Filter.%d.Name' % i] = aws_name
123
+ value = filters[name]
124
+ if not isinstance(value, list):
125
+ value = [value]
126
+ j = 1
127
+ for v in value:
128
+ params['Filter.%d.Value.%d' % (i, j)] = v
129
+ j += 1
130
+ i += 1
131
+
132
+ # Image methods
133
+
134
+ def get_all_images(self, image_ids=None, owners=None,
135
+ executable_by=None, filters=None):
136
+ """
137
+ Retrieve all the EC2 images available on your account.
138
+
139
+ :type image_ids: list
140
+ :param image_ids: A list of strings with the image IDs wanted
141
+
142
+ :type owners: list
143
+ :param owners: A list of owner IDs
144
+
145
+ :type executable_by: list
146
+ :param executable_by: Returns AMIs for which the specified
147
+ user ID has explicit launch permissions
148
+
149
+ :type filters: dict
150
+ :param filters: Optional filters that can be used to limit
151
+ the results returned. Filters are provided
152
+ in the form of a dictionary consisting of
153
+ filter names as the key and filter values
154
+ as the value. The set of allowable filter
155
+ names/values is dependent on the request
156
+ being performed. Check the EC2 API guide
157
+ for details.
158
+
159
+ :rtype: list
160
+ :return: A list of :class:`boto.ec2.image.Image`
161
+ """
162
+ params = {}
163
+ if image_ids:
164
+ self.build_list_params(params, image_ids, 'ImageId')
165
+ if owners:
166
+ self.build_list_params(params, owners, 'Owner')
167
+ if executable_by:
168
+ self.build_list_params(params, executable_by, 'ExecutableBy')
169
+ if filters:
170
+ self.build_filter_params(params, filters)
171
+ return self.get_list('DescribeImages', params,
172
+ [('item', Image)], verb='POST')
173
+
174
+ def get_all_kernels(self, kernel_ids=None, owners=None):
175
+ """
176
+ Retrieve all the EC2 kernels available on your account.
177
+ Constructs a filter to allow the processing to happen server side.
178
+
179
+ :type kernel_ids: list
180
+ :param kernel_ids: A list of strings with the image IDs wanted
181
+
182
+ :type owners: list
183
+ :param owners: A list of owner IDs
184
+
185
+ :rtype: list
186
+ :return: A list of :class:`boto.ec2.image.Image`
187
+ """
188
+ params = {}
189
+ if kernel_ids:
190
+ self.build_list_params(params, kernel_ids, 'ImageId')
191
+ if owners:
192
+ self.build_list_params(params, owners, 'Owner')
193
+ filter = {'image-type': 'kernel'}
194
+ self.build_filter_params(params, filter)
195
+ return self.get_list('DescribeImages', params,
196
+ [('item', Image)], verb='POST')
197
+
198
+ def get_all_ramdisks(self, ramdisk_ids=None, owners=None):
199
+ """
200
+ Retrieve all the EC2 ramdisks available on your account.
201
+ Constructs a filter to allow the processing to happen server side.
202
+
203
+ :type ramdisk_ids: list
204
+ :param ramdisk_ids: A list of strings with the image IDs wanted
205
+
206
+ :type owners: list
207
+ :param owners: A list of owner IDs
208
+
209
+ :rtype: list
210
+ :return: A list of :class:`boto.ec2.image.Image`
211
+ """
212
+ params = {}
213
+ if ramdisk_ids:
214
+ self.build_list_params(params, ramdisk_ids, 'ImageId')
215
+ if owners:
216
+ self.build_list_params(params, owners, 'Owner')
217
+ filter = {'image-type': 'ramdisk'}
218
+ self.build_filter_params(params, filter)
219
+ return self.get_list('DescribeImages', params,
220
+ [('item', Image)], verb='POST')
221
+
222
+ def get_image(self, image_id):
223
+ """
224
+ Shortcut method to retrieve a specific image (AMI).
225
+
226
+ :type image_id: string
227
+ :param image_id: the ID of the Image to retrieve
228
+
229
+ :rtype: :class:`boto.ec2.image.Image`
230
+ :return: The EC2 Image specified or None if the image is not found
231
+ """
232
+ try:
233
+ return self.get_all_images(image_ids=[image_id])[0]
234
+ except IndexError: # None of those images available
235
+ return None
236
+
237
+ def register_image(self, name=None, description=None, image_location=None,
238
+ architecture=None, kernel_id=None, ramdisk_id=None,
239
+ root_device_name=None, block_device_map=None):
240
+ """
241
+ Register an image.
242
+
243
+ :type name: string
244
+ :param name: The name of the AMI. Valid only for EBS-based images.
245
+
246
+ :type description: string
247
+ :param description: The description of the AMI.
248
+
249
+ :type image_location: string
250
+ :param image_location: Full path to your AMI manifest in
251
+ Amazon S3 storage. Only used for S3-based AMI's.
252
+
253
+ :type architecture: string
254
+ :param architecture: The architecture of the AMI. Valid choices are:
255
+ * i386
256
+ * x86_64
257
+
258
+ :type kernel_id: string
259
+ :param kernel_id: The ID of the kernel with which to launch
260
+ the instances
261
+
262
+ :type root_device_name: string
263
+ :param root_device_name: The root device name (e.g. /dev/sdh)
264
+
265
+ :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
266
+ :param block_device_map: A BlockDeviceMapping data structure
267
+ describing the EBS volumes associated with the Image.
268
+
269
+ :rtype: string
270
+ :return: The new image id
271
+ """
272
+ params = {}
273
+ if name:
274
+ params['Name'] = name
275
+ if description:
276
+ params['Description'] = description
277
+ if architecture:
278
+ params['Architecture'] = architecture
279
+ if kernel_id:
280
+ params['KernelId'] = kernel_id
281
+ if ramdisk_id:
282
+ params['RamdiskId'] = ramdisk_id
283
+ if image_location:
284
+ params['ImageLocation'] = image_location
285
+ if root_device_name:
286
+ params['RootDeviceName'] = root_device_name
287
+ if block_device_map:
288
+ block_device_map.build_list_params(params)
289
+ rs = self.get_object('RegisterImage', params, ResultSet, verb='POST')
290
+ image_id = getattr(rs, 'imageId', None)
291
+ return image_id
292
+
293
+ def deregister_image(self, image_id, delete_snapshot=False):
294
+ """
295
+ Unregister an AMI.
296
+
297
+ :type image_id: string
298
+ :param image_id: the ID of the Image to unregister
299
+
300
+ :type delete_snapshot: bool
301
+ :param delete_snapshot: Set to True if we should delete the
302
+ snapshot associated with an EBS volume
303
+ mounted at /dev/sda1
304
+
305
+ :rtype: bool
306
+ :return: True if successful
307
+ """
308
+ snapshot_id = None
309
+ if delete_snapshot:
310
+ image = self.get_image(image_id)
311
+ for key in image.block_device_mapping:
312
+ if key == "/dev/sda1":
313
+ snapshot_id = image.block_device_mapping[key].snapshot_id
314
+ break
315
+
316
+ result = self.get_status('DeregisterImage',
317
+ {'ImageId':image_id}, verb='POST')
318
+ if result and snapshot_id:
319
+ return result and self.delete_snapshot(snapshot_id)
320
+ return result
321
+
322
+ def create_image(self, instance_id, name,
323
+ description=None, no_reboot=False):
324
+ """
325
+ Will create an AMI from the instance in the running or stopped
326
+ state.
327
+
328
+ :type instance_id: string
329
+ :param instance_id: the ID of the instance to image.
330
+
331
+ :type name: string
332
+ :param name: The name of the new image
333
+
334
+ :type description: string
335
+ :param description: An optional human-readable string describing
336
+ the contents and purpose of the AMI.
337
+
338
+ :type no_reboot: bool
339
+ :param no_reboot: An optional flag indicating that the bundling process
340
+ should not attempt to shutdown the instance before
341
+ bundling. If this flag is True, the responsibility
342
+ of maintaining file system integrity is left to the
343
+ owner of the instance.
344
+
345
+ :rtype: string
346
+ :return: The new image id
347
+ """
348
+ params = {'InstanceId': instance_id,
349
+ 'Name': name}
350
+ if description:
351
+ params['Description'] = description
352
+ if no_reboot:
353
+ params['NoReboot'] = 'true'
354
+ img = self.get_object('CreateImage', params, Image, verb='POST')
355
+ return img.id
356
+
357
+ # ImageAttribute methods
358
+
359
+ def get_image_attribute(self, image_id, attribute='launchPermission'):
360
+ """
361
+ Gets an attribute from an image.
362
+
363
+ :type image_id: string
364
+ :param image_id: The Amazon image id for which you want info about
365
+
366
+ :type attribute: string
367
+ :param attribute: The attribute you need information about.
368
+ Valid choices are:
369
+ * launchPermission
370
+ * productCodes
371
+ * blockDeviceMapping
372
+
373
+ :rtype: :class:`boto.ec2.image.ImageAttribute`
374
+ :return: An ImageAttribute object representing the value of the
375
+ attribute requested
376
+ """
377
+ params = {'ImageId': image_id,
378
+ 'Attribute': attribute}
379
+ return self.get_object('DescribeImageAttribute', params,
380
+ ImageAttribute, verb='POST')
381
+
382
+ def modify_image_attribute(self, image_id, attribute='launchPermission',
383
+ operation='add', user_ids=None, groups=None,
384
+ product_codes=None):
385
+ """
386
+ Changes an attribute of an image.
387
+
388
+ :type image_id: string
389
+ :param image_id: The image id you wish to change
390
+
391
+ :type attribute: string
392
+ :param attribute: The attribute you wish to change
393
+
394
+ :type operation: string
395
+ :param operation: Either add or remove (this is required for changing
396
+ launchPermissions)
397
+
398
+ :type user_ids: list
399
+ :param user_ids: The Amazon IDs of users to add/remove attributes
400
+
401
+ :type groups: list
402
+ :param groups: The groups to add/remove attributes
403
+
404
+ :type product_codes: list
405
+ :param product_codes: Amazon DevPay product code. Currently only one
406
+ product code can be associated with an AMI. Once
407
+ set, the product code cannot be changed or reset.
408
+ """
409
+ params = {'ImageId': image_id,
410
+ 'Attribute': attribute,
411
+ 'OperationType': operation}
412
+ if user_ids:
413
+ self.build_list_params(params, user_ids, 'UserId')
414
+ if groups:
415
+ self.build_list_params(params, groups, 'UserGroup')
416
+ if product_codes:
417
+ self.build_list_params(params, product_codes, 'ProductCode')
418
+ return self.get_status('ModifyImageAttribute', params, verb='POST')
419
+
420
+ def reset_image_attribute(self, image_id, attribute='launchPermission'):
421
+ """
422
+ Resets an attribute of an AMI to its default value.
423
+
424
+ :type image_id: string
425
+ :param image_id: ID of the AMI for which an attribute will be described
426
+
427
+ :type attribute: string
428
+ :param attribute: The attribute to reset
429
+
430
+ :rtype: bool
431
+ :return: Whether the operation succeeded or not
432
+ """
433
+ params = {'ImageId': image_id,
434
+ 'Attribute': attribute}
435
+ return self.get_status('ResetImageAttribute', params, verb='POST')
436
+
437
+ # Instance methods
438
+
439
+ def get_all_instances(self, instance_ids=None, filters=None):
440
+ """
441
+ Retrieve all the instances associated with your account.
442
+
443
+ :type instance_ids: list
444
+ :param instance_ids: A list of strings of instance IDs
445
+
446
+ :type filters: dict
447
+ :param filters: Optional filters that can be used to limit the
448
+ results returned. Filters are provided in the form of a
449
+ dictionary consisting of filter names as the key and
450
+ filter values as the value. The set of allowable filter
451
+ names/values is dependent on the request being performed.
452
+ Check the EC2 API guide for details.
453
+
454
+ :rtype: list
455
+ :return: A list of :class:`boto.ec2.instance.Reservation`
456
+ """
457
+ params = {}
458
+ if instance_ids:
459
+ self.build_list_params(params, instance_ids, 'InstanceId')
460
+ if filters:
461
+ if 'group-id' in filters:
462
+ gid = filters.get('group-id')
463
+ if not gid.startswith('sg-') or len(gid) != 11:
464
+ warnings.warn(
465
+ "The group-id filter now requires a security group "
466
+ "identifier (sg-*) instead of a group name. To filter "
467
+ "by group name use the 'group-name' filter instead.",
468
+ UserWarning)
469
+ self.build_filter_params(params, filters)
470
+ return self.get_list('DescribeInstances', params,
471
+ [('item', Reservation)], verb='POST')
472
+
473
+ def get_all_instance_status(self, instance_ids=None,
474
+ max_results=None, next_token=None,
475
+ filters=None):
476
+ """
477
+ Retrieve all the instances in your account scheduled for maintenance.
478
+
479
+ :type instance_ids: list
480
+ :param instance_ids: A list of strings of instance IDs
481
+
482
+ :type max_results: int
483
+ :param max_results: The maximum number of paginated instance
484
+ items per response.
485
+
486
+ :type next_token: str
487
+ :param next_token: A string specifying the next paginated set
488
+ of results to return.
489
+
490
+ :type filters: dict
491
+ :param filters: Optional filters that can be used to limit
492
+ the results returned. Filters are provided
493
+ in the form of a dictionary consisting of
494
+ filter names as the key and filter values
495
+ as the value. The set of allowable filter
496
+ names/values is dependent on the request
497
+ being performed. Check the EC2 API guide
498
+ for details.
499
+
500
+ :rtype: list
501
+ :return: A list of instances that have maintenance scheduled.
502
+ """
503
+ params = {}
504
+ if instance_ids:
505
+ self.build_list_params(params, instance_ids, 'InstanceId')
506
+ if max_results:
507
+ params['MaxResults'] = max_results
508
+ if next_token:
509
+ params['NextToken'] = next_token
510
+ if filters:
511
+ self.build_filter_params(params, filters)
512
+ return self.get_object('DescribeInstanceStatus', params,
513
+ InstanceStatusSet, verb='POST')
514
+
515
+ def run_instances(self, image_id, min_count=1, max_count=1,
516
+ key_name=None, security_groups=None,
517
+ user_data=None, addressing_type=None,
518
+ instance_type='m1.small', placement=None,
519
+ kernel_id=None, ramdisk_id=None,
520
+ monitoring_enabled=False, subnet_id=None,
521
+ block_device_map=None,
522
+ disable_api_termination=False,
523
+ instance_initiated_shutdown_behavior=None,
524
+ private_ip_address=None,
525
+ placement_group=None, client_token=None,
526
+ security_group_ids=None,
527
+ additional_info=None, instance_profile_name=None,
528
+ instance_profile_arn=None, tenancy=None,
529
+ ebs_optimized=False, network_interfaces=None):
530
+ """
531
+ Runs an image on EC2.
532
+
533
+ :type image_id: string
534
+ :param image_id: The ID of the image to run.
535
+
536
+ :type min_count: int
537
+ :param min_count: The minimum number of instances to launch.
538
+
539
+ :type max_count: int
540
+ :param max_count: The maximum number of instances to launch.
541
+
542
+ :type key_name: string
543
+ :param key_name: The name of the key pair with which to
544
+ launch instances.
545
+
546
+ :type security_groups: list of strings
547
+ :param security_groups: The names of the security groups with which to
548
+ associate instances
549
+
550
+ :type user_data: string
551
+ :param user_data: The user data passed to the launched instances
552
+
553
+ :type instance_type: string
554
+ :param instance_type: The type of instance to run:
555
+
556
+ * t1.micro
557
+ * m1.small
558
+ * m1.medium
559
+ * m1.large
560
+ * m1.xlarge
561
+ * c1.medium
562
+ * c1.xlarge
563
+ * m2.xlarge
564
+ * m2.2xlarge
565
+ * m2.4xlarge
566
+ * cc1.4xlarge
567
+ * cg1.4xlarge
568
+ * cc2.8xlarge
569
+
570
+ :type placement: string
571
+ :param placement: The availability zone in which to launch
572
+ the instances.
573
+
574
+ :type kernel_id: string
575
+ :param kernel_id: The ID of the kernel with which to launch the
576
+ instances.
577
+
578
+ :type ramdisk_id: string
579
+ :param ramdisk_id: The ID of the RAM disk with which to launch the
580
+ instances.
581
+
582
+ :type monitoring_enabled: bool
583
+ :param monitoring_enabled: Enable CloudWatch monitoring on
584
+ the instance.
585
+
586
+ :type subnet_id: string
587
+ :param subnet_id: The subnet ID within which to launch the instances
588
+ for VPC.
589
+
590
+ :type private_ip_address: string
591
+ :param private_ip_address: If you're using VPC, you can
592
+ optionally use this parameter to assign the instance a
593
+ specific available IP address from the subnet (e.g.,
594
+ 10.0.0.25).
595
+
596
+ :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
597
+ :param block_device_map: A BlockDeviceMapping data structure
598
+ describing the EBS volumes associated with the Image.
599
+
600
+ :type disable_api_termination: bool
601
+ :param disable_api_termination: If True, the instances will be locked
602
+ and will not be able to be terminated via the API.
603
+
604
+ :type instance_initiated_shutdown_behavior: string
605
+ :param instance_initiated_shutdown_behavior: Specifies whether the
606
+ instance stops or terminates on instance-initiated shutdown.
607
+ Valid values are:
608
+
609
+ * stop
610
+ * terminate
611
+
612
+ :type placement_group: string
613
+ :param placement_group: If specified, this is the name of the placement
614
+ group in which the instance(s) will be launched.
615
+
616
+ :type client_token: string
617
+ :param client_token: Unique, case-sensitive identifier you provide
618
+ to ensure idempotency of the request. Maximum 64 ASCII characters.
619
+
620
+ :type security_group_ids: list of strings
621
+ :param security_group_ids: The ID of the VPC security groups with
622
+ which to associate instances.
623
+
624
+ :type additional_info: string
625
+ :param additional_info: Specifies additional information to make
626
+ available to the instance(s).
627
+
628
+ :type tenancy: string
629
+ :param tenancy: The tenancy of the instance you want to
630
+ launch. An instance with a tenancy of 'dedicated' runs on
631
+ single-tenant hardware and can only be launched into a
632
+ VPC. Valid values are:"default" or "dedicated".
633
+ NOTE: To use dedicated tenancy you MUST specify a VPC
634
+ subnet-ID as well.
635
+
636
+ :type instance_profile_arn: string
637
+ :param instance_profile_arn: The Amazon resource name (ARN) of
638
+ the IAM Instance Profile (IIP) to associate with the instances.
639
+
640
+ :type instance_profile_name: string
641
+ :param instance_profile_name: The name of
642
+ the IAM Instance Profile (IIP) to associate with the instances.
643
+
644
+ :type ebs_optimized: bool
645
+ :param ebs_optimized: Whether the instance is optimized for
646
+ EBS I/O. This optimization provides dedicated throughput
647
+ to Amazon EBS and an optimized configuration stack to
648
+ provide optimal EBS I/O performance. This optimization
649
+ isn't available with all instance types.
650
+
651
+ :type network_interfaces: list
652
+ :param network_interfaces: A list of
653
+ :class:`boto.ec2.networkinterface.NetworkInterfaceSpecification`
654
+
655
+ :rtype: Reservation
656
+ :return: The :class:`boto.ec2.instance.Reservation` associated with
657
+ the request for machines
658
+ """
659
+ params = {'ImageId': image_id,
660
+ 'MinCount': min_count,
661
+ 'MaxCount': max_count}
662
+ if key_name:
663
+ params['KeyName'] = key_name
664
+ if security_group_ids:
665
+ l = []
666
+ for group in security_group_ids:
667
+ if isinstance(group, SecurityGroup):
668
+ l.append(group.id)
669
+ else:
670
+ l.append(group)
671
+ self.build_list_params(params, l, 'SecurityGroupId')
672
+ if security_groups:
673
+ l = []
674
+ for group in security_groups:
675
+ if isinstance(group, SecurityGroup):
676
+ l.append(group.name)
677
+ else:
678
+ l.append(group)
679
+ self.build_list_params(params, l, 'SecurityGroup')
680
+ if user_data:
681
+ params['UserData'] = base64.b64encode(user_data)
682
+ if addressing_type:
683
+ params['AddressingType'] = addressing_type
684
+ if instance_type:
685
+ params['InstanceType'] = instance_type
686
+ if placement:
687
+ params['Placement.AvailabilityZone'] = placement
688
+ if placement_group:
689
+ params['Placement.GroupName'] = placement_group
690
+ if tenancy:
691
+ params['Placement.Tenancy'] = tenancy
692
+ if kernel_id:
693
+ params['KernelId'] = kernel_id
694
+ if ramdisk_id:
695
+ params['RamdiskId'] = ramdisk_id
696
+ if monitoring_enabled:
697
+ params['Monitoring.Enabled'] = 'true'
698
+ if subnet_id:
699
+ params['SubnetId'] = subnet_id
700
+ if private_ip_address:
701
+ params['PrivateIpAddress'] = private_ip_address
702
+ if block_device_map:
703
+ block_device_map.build_list_params(params)
704
+ if disable_api_termination:
705
+ params['DisableApiTermination'] = 'true'
706
+ if instance_initiated_shutdown_behavior:
707
+ val = instance_initiated_shutdown_behavior
708
+ params['InstanceInitiatedShutdownBehavior'] = val
709
+ if client_token:
710
+ params['ClientToken'] = client_token
711
+ if additional_info:
712
+ params['AdditionalInfo'] = additional_info
713
+ if instance_profile_name:
714
+ params['IamInstanceProfile.Name'] = instance_profile_name
715
+ if instance_profile_arn:
716
+ params['IamInstanceProfile.Arn'] = instance_profile_arn
717
+ if ebs_optimized:
718
+ params['EbsOptimized'] = 'true'
719
+ if network_interfaces:
720
+ network_interfaces.build_list_params(params)
721
+ return self.get_object('RunInstances', params, Reservation,
722
+ verb='POST')
723
+
724
+ def terminate_instances(self, instance_ids=None):
725
+ """
726
+ Terminate the instances specified
727
+
728
+ :type instance_ids: list
729
+ :param instance_ids: A list of strings of the Instance IDs to terminate
730
+
731
+ :rtype: list
732
+ :return: A list of the instances terminated
733
+ """
734
+ params = {}
735
+ if instance_ids:
736
+ self.build_list_params(params, instance_ids, 'InstanceId')
737
+ return self.get_list('TerminateInstances', params,
738
+ [('item', Instance)], verb='POST')
739
+
740
+ def stop_instances(self, instance_ids=None, force=False):
741
+ """
742
+ Stop the instances specified
743
+
744
+ :type instance_ids: list
745
+ :param instance_ids: A list of strings of the Instance IDs to stop
746
+
747
+ :type force: bool
748
+ :param force: Forces the instance to stop
749
+
750
+ :rtype: list
751
+ :return: A list of the instances stopped
752
+ """
753
+ params = {}
754
+ if force:
755
+ params['Force'] = 'true'
756
+ if instance_ids:
757
+ self.build_list_params(params, instance_ids, 'InstanceId')
758
+ return self.get_list('StopInstances', params,
759
+ [('item', Instance)], verb='POST')
760
+
761
+ def start_instances(self, instance_ids=None):
762
+ """
763
+ Start the instances specified
764
+
765
+ :type instance_ids: list
766
+ :param instance_ids: A list of strings of the Instance IDs to start
767
+
768
+ :rtype: list
769
+ :return: A list of the instances started
770
+ """
771
+ params = {}
772
+ if instance_ids:
773
+ self.build_list_params(params, instance_ids, 'InstanceId')
774
+ return self.get_list('StartInstances', params,
775
+ [('item', Instance)], verb='POST')
776
+
777
+ def get_console_output(self, instance_id):
778
+ """
779
+ Retrieves the console output for the specified instance.
780
+
781
+ :type instance_id: string
782
+ :param instance_id: The instance ID of a running instance on the cloud.
783
+
784
+ :rtype: :class:`boto.ec2.instance.ConsoleOutput`
785
+ :return: The console output as a ConsoleOutput object
786
+ """
787
+ params = {}
788
+ self.build_list_params(params, [instance_id], 'InstanceId')
789
+ return self.get_object('GetConsoleOutput', params,
790
+ ConsoleOutput, verb='POST')
791
+
792
+ def reboot_instances(self, instance_ids=None):
793
+ """
794
+ Reboot the specified instances.
795
+
796
+ :type instance_ids: list
797
+ :param instance_ids: The instances to terminate and reboot
798
+ """
799
+ params = {}
800
+ if instance_ids:
801
+ self.build_list_params(params, instance_ids, 'InstanceId')
802
+ return self.get_status('RebootInstances', params)
803
+
804
+ def confirm_product_instance(self, product_code, instance_id):
805
+ params = {'ProductCode': product_code,
806
+ 'InstanceId': instance_id}
807
+ rs = self.get_object('ConfirmProductInstance', params,
808
+ ResultSet, verb='POST')
809
+ return (rs.status, rs.ownerId)
810
+
811
+ # InstanceAttribute methods
812
+
813
+ def get_instance_attribute(self, instance_id, attribute):
814
+ """
815
+ Gets an attribute from an instance.
816
+
817
+ :type instance_id: string
818
+ :param instance_id: The Amazon id of the instance
819
+
820
+ :type attribute: string
821
+ :param attribute: The attribute you need information about
822
+ Valid choices are:
823
+
824
+ * instanceType
825
+ * kernel
826
+ * ramdisk
827
+ * userData
828
+ * disableApiTermination
829
+ * instanceInitiatedShutdownBehavior
830
+ * rootDeviceName
831
+ * blockDeviceMapping
832
+ * productCodes
833
+ * sourceDestCheck
834
+ * groupSet
835
+ * ebsOptimized
836
+
837
+ :rtype: :class:`boto.ec2.image.InstanceAttribute`
838
+ :return: An InstanceAttribute object representing the value of the
839
+ attribute requested
840
+ """
841
+ params = {'InstanceId': instance_id}
842
+ if attribute:
843
+ params['Attribute'] = attribute
844
+ return self.get_object('DescribeInstanceAttribute', params,
845
+ InstanceAttribute, verb='POST')
846
+
847
+ def modify_instance_attribute(self, instance_id, attribute, value):
848
+ """
849
+ Changes an attribute of an instance
850
+
851
+ :type instance_id: string
852
+ :param instance_id: The instance id you wish to change
853
+
854
+ :type attribute: string
855
+ :param attribute: The attribute you wish to change.
856
+
857
+ * instanceType - A valid instance type (m1.small)
858
+ * kernel - Kernel ID (None)
859
+ * ramdisk - Ramdisk ID (None)
860
+ * userData - Base64 encoded String (None)
861
+ * disableApiTermination - Boolean (true)
862
+ * instanceInitiatedShutdownBehavior - stop|terminate
863
+ * blockDeviceMapping - List of strings - ie: ['/dev/sda=false']
864
+ * sourceDestCheck - Boolean (true)
865
+ * groupSet - Set of Security Groups or IDs
866
+ * ebsOptimized - Boolean (false)
867
+
868
+ :type value: string
869
+ :param value: The new value for the attribute
870
+
871
+ :rtype: bool
872
+ :return: Whether the operation succeeded or not
873
+ """
874
+ # Allow a bool to be passed in for value of disableApiTermination
875
+ bool_reqs = ('disableapitermination',
876
+ 'sourcedestcheck',
877
+ 'ebsoptimized')
878
+ if attribute.lower() in bool_reqs:
879
+ if isinstance(value, bool):
880
+ if value:
881
+ value = 'true'
882
+ else:
883
+ value = 'false'
884
+
885
+ params = {'InstanceId': instance_id}
886
+
887
+ # groupSet is handled differently from other arguments
888
+ if attribute.lower() == 'groupset':
889
+ for idx, sg in enumerate(value):
890
+ if isinstance(sg, SecurityGroup):
891
+ sg = sg.id
892
+ params['GroupId.%s' % (idx + 1)] = sg
893
+ elif attribute.lower() == 'blockdevicemapping':
894
+ for idx, kv in enumerate(value):
895
+ dev_name, _, flag = kv.partition('=')
896
+ pre = 'BlockDeviceMapping.%d' % (idx + 1)
897
+ params['%s.DeviceName' % pre] = dev_name
898
+ params['%s.Ebs.DeleteOnTermination' % pre] = flag or 'true'
899
+ else:
900
+ # for backwards compatibility handle lowercase first letter
901
+ attribute = attribute[0].upper() + attribute[1:]
902
+ params['%s.Value' % attribute] = value
903
+
904
+ return self.get_status('ModifyInstanceAttribute', params, verb='POST')
905
+
906
+ def reset_instance_attribute(self, instance_id, attribute):
907
+ """
908
+ Resets an attribute of an instance to its default value.
909
+
910
+ :type instance_id: string
911
+ :param instance_id: ID of the instance
912
+
913
+ :type attribute: string
914
+ :param attribute: The attribute to reset. Valid values are:
915
+ kernel|ramdisk
916
+
917
+ :rtype: bool
918
+ :return: Whether the operation succeeded or not
919
+ """
920
+ params = {'InstanceId': instance_id,
921
+ 'Attribute': attribute}
922
+ return self.get_status('ResetInstanceAttribute', params, verb='POST')
923
+
924
+ # Spot Instances
925
+
926
+ def get_all_spot_instance_requests(self, request_ids=None,
927
+ filters=None):
928
+ """
929
+ Retrieve all the spot instances requests associated with your account.
930
+
931
+ :type request_ids: list
932
+ :param request_ids: A list of strings of spot instance request IDs
933
+
934
+ :type filters: dict
935
+ :param filters: Optional filters that can be used to limit the
936
+ results returned. Filters are provided in the form of a
937
+ dictionary consisting of filter names as the key and
938
+ filter values as the value. The set of allowable filter
939
+ names/values is dependent on the request being performed.
940
+ Check the EC2 API guide for details.
941
+
942
+ :rtype: list
943
+ :return: A list of
944
+ :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
945
+ """
946
+ params = {}
947
+ if request_ids:
948
+ self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
949
+ if filters:
950
+ if 'launch.group-id' in filters:
951
+ lgid = filters.get('launch.group-id')
952
+ if not lgid.startswith('sg-') or len(lgid) != 11:
953
+ warnings.warn(
954
+ "The 'launch.group-id' filter now requires a security "
955
+ "group id (sg-*) and no longer supports filtering by "
956
+ "group name. Please update your filters accordingly.",
957
+ UserWarning)
958
+ self.build_filter_params(params, filters)
959
+ return self.get_list('DescribeSpotInstanceRequests', params,
960
+ [('item', SpotInstanceRequest)], verb='POST')
961
+
962
+ def get_spot_price_history(self, start_time=None, end_time=None,
963
+ instance_type=None, product_description=None,
964
+ availability_zone=None):
965
+ """
966
+ Retrieve the recent history of spot instances pricing.
967
+
968
+ :type start_time: str
969
+ :param start_time: An indication of how far back to provide price
970
+ changes for. An ISO8601 DateTime string.
971
+
972
+ :type end_time: str
973
+ :param end_time: An indication of how far forward to provide price
974
+ changes for. An ISO8601 DateTime string.
975
+
976
+ :type instance_type: str
977
+ :param instance_type: Filter responses to a particular instance type.
978
+
979
+ :type product_description: str
980
+ :param product_description: Filter responses to a particular platform.
981
+ Valid values are currently:
982
+
983
+ * Linux/UNIX
984
+ * SUSE Linux
985
+ * Windows
986
+ * Linux/UNIX (Amazon VPC)
987
+ * SUSE Linux (Amazon VPC)
988
+ * Windows (Amazon VPC)
989
+
990
+ :type availability_zone: str
991
+ :param availability_zone: The availability zone for which prices
992
+ should be returned. If not specified, data for all
993
+ availability zones will be returned.
994
+
995
+ :rtype: list
996
+ :return: A list tuples containing price and timestamp.
997
+ """
998
+ params = {}
999
+ if start_time:
1000
+ params['StartTime'] = start_time
1001
+ if end_time:
1002
+ params['EndTime'] = end_time
1003
+ if instance_type:
1004
+ params['InstanceType'] = instance_type
1005
+ if product_description:
1006
+ params['ProductDescription'] = product_description
1007
+ if availability_zone:
1008
+ params['AvailabilityZone'] = availability_zone
1009
+ return self.get_list('DescribeSpotPriceHistory', params,
1010
+ [('item', SpotPriceHistory)], verb='POST')
1011
+
1012
+ def request_spot_instances(self, price, image_id, count=1, type='one-time',
1013
+ valid_from=None, valid_until=None,
1014
+ launch_group=None, availability_zone_group=None,
1015
+ key_name=None, security_groups=None,
1016
+ user_data=None, addressing_type=None,
1017
+ instance_type='m1.small', placement=None,
1018
+ kernel_id=None, ramdisk_id=None,
1019
+ monitoring_enabled=False, subnet_id=None,
1020
+ placement_group=None,
1021
+ block_device_map=None,
1022
+ instance_profile_arn=None,
1023
+ instance_profile_name=None,
1024
+ security_group_ids=None,
1025
+ ebs_optimized=False,
1026
+ network_interfaces=None):
1027
+ """
1028
+ Request instances on the spot market at a particular price.
1029
+
1030
+ :type price: str
1031
+ :param price: The maximum price of your bid
1032
+
1033
+ :type image_id: string
1034
+ :param image_id: The ID of the image to run
1035
+
1036
+ :type count: int
1037
+ :param count: The of instances to requested
1038
+
1039
+ :type type: str
1040
+ :param type: Type of request. Can be 'one-time' or 'persistent'.
1041
+ Default is one-time.
1042
+
1043
+ :type valid_from: str
1044
+ :param valid_from: Start date of the request. An ISO8601 time string.
1045
+
1046
+ :type valid_until: str
1047
+ :param valid_until: End date of the request. An ISO8601 time string.
1048
+
1049
+ :type launch_group: str
1050
+ :param launch_group: If supplied, all requests will be fulfilled
1051
+ as a group.
1052
+
1053
+ :type availability_zone_group: str
1054
+ :param availability_zone_group: If supplied, all requests will be
1055
+ fulfilled within a single availability zone.
1056
+
1057
+ :type key_name: string
1058
+ :param key_name: The name of the key pair with which to
1059
+ launch instances
1060
+
1061
+ :type security_groups: list of strings
1062
+ :param security_groups: The names of the security groups with which to
1063
+ associate instances
1064
+
1065
+ :type user_data: string
1066
+ :param user_data: The user data passed to the launched instances
1067
+
1068
+ :type instance_type: string
1069
+ :param instance_type: The type of instance to run:
1070
+
1071
+ * m1.small
1072
+ * m1.large
1073
+ * m1.xlarge
1074
+ * c1.medium
1075
+ * c1.xlarge
1076
+ * m2.xlarge
1077
+ * m2.2xlarge
1078
+ * m2.4xlarge
1079
+ * cc1.4xlarge
1080
+ * t1.micro
1081
+
1082
+ :type placement: string
1083
+ :param placement: The availability zone in which to launch
1084
+ the instances
1085
+
1086
+ :type kernel_id: string
1087
+ :param kernel_id: The ID of the kernel with which to launch the
1088
+ instances
1089
+
1090
+ :type ramdisk_id: string
1091
+ :param ramdisk_id: The ID of the RAM disk with which to launch the
1092
+ instances
1093
+
1094
+ :type monitoring_enabled: bool
1095
+ :param monitoring_enabled: Enable CloudWatch monitoring on
1096
+ the instance.
1097
+
1098
+ :type subnet_id: string
1099
+ :param subnet_id: The subnet ID within which to launch the instances
1100
+ for VPC.
1101
+
1102
+ :type placement_group: string
1103
+ :param placement_group: If specified, this is the name of the placement
1104
+ group in which the instance(s) will be launched.
1105
+
1106
+ :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
1107
+ :param block_device_map: A BlockDeviceMapping data structure
1108
+ describing the EBS volumes associated with the Image.
1109
+
1110
+ :type security_group_ids: list of strings
1111
+ :param security_group_ids: The ID of the VPC security groups with
1112
+ which to associate instances.
1113
+
1114
+ :type instance_profile_arn: string
1115
+ :param instance_profile_arn: The Amazon resource name (ARN) of
1116
+ the IAM Instance Profile (IIP) to associate with the instances.
1117
+
1118
+ :type instance_profile_name: string
1119
+ :param instance_profile_name: The name of
1120
+ the IAM Instance Profile (IIP) to associate with the instances.
1121
+
1122
+ :type ebs_optimized: bool
1123
+ :param ebs_optimized: Whether the instance is optimized for
1124
+ EBS I/O. This optimization provides dedicated throughput
1125
+ to Amazon EBS and an optimized configuration stack to
1126
+ provide optimal EBS I/O performance. This optimization
1127
+ isn't available with all instance types.
1128
+
1129
+ :type network_interfaces: list
1130
+ :param network_interfaces: A list of
1131
+ :class:`boto.ec2.networkinterface.NetworkInterfaceSpecification`
1132
+
1133
+ :rtype: Reservation
1134
+ :return: The :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
1135
+ associated with the request for machines
1136
+ """
1137
+ ls = 'LaunchSpecification'
1138
+ params = {'%s.ImageId' % ls: image_id,
1139
+ 'Type': type,
1140
+ 'SpotPrice': price}
1141
+ if count:
1142
+ params['InstanceCount'] = count
1143
+ if valid_from:
1144
+ params['ValidFrom'] = valid_from
1145
+ if valid_until:
1146
+ params['ValidUntil'] = valid_until
1147
+ if launch_group:
1148
+ params['LaunchGroup'] = launch_group
1149
+ if availability_zone_group:
1150
+ params['AvailabilityZoneGroup'] = availability_zone_group
1151
+ if key_name:
1152
+ params['%s.KeyName' % ls] = key_name
1153
+ if security_group_ids:
1154
+ l = []
1155
+ for group in security_group_ids:
1156
+ if isinstance(group, SecurityGroup):
1157
+ l.append(group.id)
1158
+ else:
1159
+ l.append(group)
1160
+ self.build_list_params(params, l,
1161
+ '%s.SecurityGroupId' % ls)
1162
+ if security_groups:
1163
+ l = []
1164
+ for group in security_groups:
1165
+ if isinstance(group, SecurityGroup):
1166
+ l.append(group.name)
1167
+ else:
1168
+ l.append(group)
1169
+ self.build_list_params(params, l, '%s.SecurityGroup' % ls)
1170
+ if user_data:
1171
+ params['%s.UserData' % ls] = base64.b64encode(user_data)
1172
+ if addressing_type:
1173
+ params['%s.AddressingType' % ls] = addressing_type
1174
+ if instance_type:
1175
+ params['%s.InstanceType' % ls] = instance_type
1176
+ if placement:
1177
+ params['%s.Placement.AvailabilityZone' % ls] = placement
1178
+ if kernel_id:
1179
+ params['%s.KernelId' % ls] = kernel_id
1180
+ if ramdisk_id:
1181
+ params['%s.RamdiskId' % ls] = ramdisk_id
1182
+ if monitoring_enabled:
1183
+ params['%s.Monitoring.Enabled' % ls] = 'true'
1184
+ if subnet_id:
1185
+ params['%s.SubnetId' % ls] = subnet_id
1186
+ if placement_group:
1187
+ params['%s.Placement.GroupName' % ls] = placement_group
1188
+ if block_device_map:
1189
+ block_device_map.build_list_params(params, '%s.' % ls)
1190
+ if instance_profile_name:
1191
+ params['%s.IamInstanceProfile.Name' % ls] = instance_profile_name
1192
+ if instance_profile_arn:
1193
+ params['%s.IamInstanceProfile.Arn' % ls] = instance_profile_arn
1194
+ if ebs_optimized:
1195
+ params['%s.EbsOptimized' % ls] = 'true'
1196
+ if network_interfaces:
1197
+ network_interfaces.build_list_params(params, prefix=ls + '.')
1198
+ return self.get_list('RequestSpotInstances', params,
1199
+ [('item', SpotInstanceRequest)],
1200
+ verb='POST')
1201
+
1202
+ def cancel_spot_instance_requests(self, request_ids):
1203
+ """
1204
+ Cancel the specified Spot Instance Requests.
1205
+
1206
+ :type request_ids: list
1207
+ :param request_ids: A list of strings of the Request IDs to terminate
1208
+
1209
+ :rtype: list
1210
+ :return: A list of the instances terminated
1211
+ """
1212
+ params = {}
1213
+ if request_ids:
1214
+ self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
1215
+ return self.get_list('CancelSpotInstanceRequests', params,
1216
+ [('item', Instance)], verb='POST')
1217
+
1218
+ def get_spot_datafeed_subscription(self):
1219
+ """
1220
+ Return the current spot instance data feed subscription
1221
+ associated with this account, if any.
1222
+
1223
+ :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscription`
1224
+ :return: The datafeed subscription object or None
1225
+ """
1226
+ return self.get_object('DescribeSpotDatafeedSubscription',
1227
+ None, SpotDatafeedSubscription, verb='POST')
1228
+
1229
+ def create_spot_datafeed_subscription(self, bucket, prefix):
1230
+ """
1231
+ Create a spot instance datafeed subscription for this account.
1232
+
1233
+ :type bucket: str or unicode
1234
+ :param bucket: The name of the bucket where spot instance data
1235
+ will be written. The account issuing this request
1236
+ must have FULL_CONTROL access to the bucket
1237
+ specified in the request.
1238
+
1239
+ :type prefix: str or unicode
1240
+ :param prefix: An optional prefix that will be pre-pended to all
1241
+ data files written to the bucket.
1242
+
1243
+ :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscription`
1244
+ :return: The datafeed subscription object or None
1245
+ """
1246
+ params = {'Bucket': bucket}
1247
+ if prefix:
1248
+ params['Prefix'] = prefix
1249
+ return self.get_object('CreateSpotDatafeedSubscription',
1250
+ params, SpotDatafeedSubscription, verb='POST')
1251
+
1252
+ def delete_spot_datafeed_subscription(self):
1253
+ """
1254
+ Delete the current spot instance data feed subscription
1255
+ associated with this account
1256
+
1257
+ :rtype: bool
1258
+ :return: True if successful
1259
+ """
1260
+ return self.get_status('DeleteSpotDatafeedSubscription',
1261
+ None, verb='POST')
1262
+
1263
+ # Zone methods
1264
+
1265
+ def get_all_zones(self, zones=None, filters=None):
1266
+ """
1267
+ Get all Availability Zones associated with the current region.
1268
+
1269
+ :type zones: list
1270
+ :param zones: Optional list of zones. If this list is present,
1271
+ only the Zones associated with these zone names
1272
+ will be returned.
1273
+
1274
+ :type filters: dict
1275
+ :param filters: Optional filters that can be used to limit
1276
+ the results returned. Filters are provided
1277
+ in the form of a dictionary consisting of
1278
+ filter names as the key and filter values
1279
+ as the value. The set of allowable filter
1280
+ names/values is dependent on the request
1281
+ being performed. Check the EC2 API guide
1282
+ for details.
1283
+
1284
+ :rtype: list of :class:`boto.ec2.zone.Zone`
1285
+ :return: The requested Zone objects
1286
+ """
1287
+ params = {}
1288
+ if zones:
1289
+ self.build_list_params(params, zones, 'ZoneName')
1290
+ if filters:
1291
+ self.build_filter_params(params, filters)
1292
+ return self.get_list('DescribeAvailabilityZones', params,
1293
+ [('item', Zone)], verb='POST')
1294
+
1295
+ # Address methods
1296
+
1297
+ def get_all_addresses(self, addresses=None, filters=None, allocation_ids=None):
1298
+ """
1299
+ Get all EIP's associated with the current credentials.
1300
+
1301
+ :type addresses: list
1302
+ :param addresses: Optional list of addresses. If this list is present,
1303
+ only the Addresses associated with these addresses
1304
+ will be returned.
1305
+
1306
+ :type filters: dict
1307
+ :param filters: Optional filters that can be used to limit
1308
+ the results returned. Filters are provided
1309
+ in the form of a dictionary consisting of
1310
+ filter names as the key and filter values
1311
+ as the value. The set of allowable filter
1312
+ names/values is dependent on the request
1313
+ being performed. Check the EC2 API guide
1314
+ for details.
1315
+
1316
+ :type allocation_ids: list
1317
+ :param allocation_ids: Optional list of allocation IDs. If this list is
1318
+ present, only the Addresses associated with the given
1319
+ allocation IDs will be returned.
1320
+
1321
+ :rtype: list of :class:`boto.ec2.address.Address`
1322
+ :return: The requested Address objects
1323
+ """
1324
+ params = {}
1325
+ if addresses:
1326
+ self.build_list_params(params, addresses, 'PublicIp')
1327
+ if allocation_ids:
1328
+ self.build_list_params(params, allocation_ids, 'AllocationId')
1329
+ if filters:
1330
+ self.build_filter_params(params, filters)
1331
+ return self.get_list('DescribeAddresses', params, [('item', Address)], verb='POST')
1332
+
1333
+ def allocate_address(self, domain=None):
1334
+ """
1335
+ Allocate a new Elastic IP address and associate it with your account.
1336
+
1337
+ :type domain: string
1338
+ :param domain: Optional string. If domain is set to "vpc" the address
1339
+ will be allocated to VPC . Will return address
1340
+ object with allocation_id.
1341
+
1342
+ :rtype: :class:`boto.ec2.address.Address`
1343
+ :return: The newly allocated Address
1344
+ """
1345
+ params = {}
1346
+
1347
+ if domain is not None:
1348
+ params['Domain'] = domain
1349
+
1350
+ return self.get_object('AllocateAddress', params, Address, verb='POST')
1351
+
1352
+ def assign_private_ip_addresses(self, network_interface_id=None,
1353
+ private_ip_addresses=None,
1354
+ secondary_private_ip_address_count=None,
1355
+ allow_reassignment=False):
1356
+ """
1357
+ Assigns one or more secondary private IP addresses to a network
1358
+ interface in Amazon VPC.
1359
+
1360
+ :type network_interface_id: string
1361
+ :param network_interface_id: The network interface to which the IP
1362
+ address will be assigned.
1363
+
1364
+ :type private_ip_addresses: list
1365
+ :param private_ip_addresses: Assigns the specified IP addresses as
1366
+ secondary IP addresses to the network interface.
1367
+
1368
+ :type secondary_private_ip_address_count: int
1369
+ :param secondary_private_ip_address_count: The number of secondary IP
1370
+ addresses to assign to the network interface. You cannot specify
1371
+ this parameter when also specifying private_ip_addresses.
1372
+
1373
+ :type allow_reassignment: bool
1374
+ :param allow_reassignment: Specifies whether to allow an IP address
1375
+ that is already assigned to another network interface or instance
1376
+ to be reassigned to the specified network interface.
1377
+
1378
+ :rtype: bool
1379
+ :return: True if successful
1380
+ """
1381
+ params = {}
1382
+
1383
+ if network_interface_id is not None:
1384
+ params['NetworkInterfaceId'] = network_interface_id
1385
+
1386
+ if private_ip_addresses is not None:
1387
+ self.build_list_params(params, private_ip_addresses,
1388
+ 'PrivateIpAddress')
1389
+ elif secondary_private_ip_address_count is not None:
1390
+ params['SecondaryPrivateIpAddressCount'] = \
1391
+ secondary_private_ip_address_count
1392
+
1393
+ if allow_reassignment:
1394
+ params['AllowReassignment'] = 'true'
1395
+
1396
+ return self.get_status('AssignPrivateIpAddresses', params, verb='POST')
1397
+
1398
+ def associate_address(self, instance_id=None, public_ip=None,
1399
+ allocation_id=None, network_interface_id=None,
1400
+ private_ip_address=None, allow_reassociation=False):
1401
+ """
1402
+ Associate an Elastic IP address with a currently running instance.
1403
+ This requires one of ``public_ip`` or ``allocation_id`` depending
1404
+ on if you're associating a VPC address or a plain EC2 address.
1405
+
1406
+ When using an Allocation ID, make sure to pass ``None`` for ``public_ip``
1407
+ as EC2 expects a single parameter and if ``public_ip`` is passed boto
1408
+ will preference that instead of ``allocation_id``.
1409
+
1410
+ :type instance_id: string
1411
+ :param instance_id: The ID of the instance
1412
+
1413
+ :type public_ip: string
1414
+ :param public_ip: The public IP address for EC2 based allocations.
1415
+
1416
+ :type allocation_id: string
1417
+ :param allocation_id: The allocation ID for a VPC-based elastic IP.
1418
+
1419
+ :type network_interface_id: string
1420
+ :param network_interface_id: The network interface ID to which
1421
+ elastic IP is to be assigned to
1422
+
1423
+ :type private_ip_address: string
1424
+ :param private_ip_address: The primary or secondary private IP address
1425
+ to associate with the Elastic IP address.
1426
+
1427
+ :type allow_reassociation: bool
1428
+ :param allow_reassociation: Specify this option to allow an Elastic IP
1429
+ address that is already associated with another network interface
1430
+ or instance to be re-associated with the specified instance or
1431
+ interface.
1432
+
1433
+ :rtype: bool
1434
+ :return: True if successful
1435
+ """
1436
+ params = {}
1437
+ if instance_id is not None:
1438
+ params['InstanceId'] = instance_id
1439
+ elif network_interface_id is not None:
1440
+ params['NetworkInterfaceId'] = network_interface_id
1441
+
1442
+ if public_ip is not None:
1443
+ params['PublicIp'] = public_ip
1444
+ elif allocation_id is not None:
1445
+ params['AllocationId'] = allocation_id
1446
+
1447
+ if private_ip_address is not None:
1448
+ params['PrivateIpAddress'] = private_ip_address
1449
+
1450
+ if allow_reassociation:
1451
+ params['AllowReassociation'] = 'true'
1452
+
1453
+ return self.get_status('AssociateAddress', params, verb='POST')
1454
+
1455
+ def disassociate_address(self, public_ip=None, association_id=None):
1456
+ """
1457
+ Disassociate an Elastic IP address from a currently running instance.
1458
+
1459
+ :type public_ip: string
1460
+ :param public_ip: The public IP address for EC2 elastic IPs.
1461
+
1462
+ :type association_id: string
1463
+ :param association_id: The association ID for a VPC based elastic ip.
1464
+
1465
+ :rtype: bool
1466
+ :return: True if successful
1467
+ """
1468
+ params = {}
1469
+
1470
+ if public_ip is not None:
1471
+ params['PublicIp'] = public_ip
1472
+ elif association_id is not None:
1473
+ params['AssociationId'] = association_id
1474
+
1475
+ return self.get_status('DisassociateAddress', params, verb='POST')
1476
+
1477
+ def release_address(self, public_ip=None, allocation_id=None):
1478
+ """
1479
+ Free up an Elastic IP address. Pass a public IP address to
1480
+ release an EC2 Elastic IP address and an AllocationId to
1481
+ release a VPC Elastic IP address. You should only pass
1482
+ one value.
1483
+
1484
+ This requires one of ``public_ip`` or ``allocation_id`` depending
1485
+ on if you're associating a VPC address or a plain EC2 address.
1486
+
1487
+ When using an Allocation ID, make sure to pass ``None`` for ``public_ip``
1488
+ as EC2 expects a single parameter and if ``public_ip`` is passed boto
1489
+ will preference that instead of ``allocation_id``.
1490
+
1491
+ :type public_ip: string
1492
+ :param public_ip: The public IP address for EC2 elastic IPs.
1493
+
1494
+ :type allocation_id: string
1495
+ :param allocation_id: The Allocation ID for VPC elastic IPs.
1496
+
1497
+ :rtype: bool
1498
+ :return: True if successful
1499
+ """
1500
+ params = {}
1501
+
1502
+ if public_ip is not None:
1503
+ params['PublicIp'] = public_ip
1504
+ elif allocation_id is not None:
1505
+ params['AllocationId'] = allocation_id
1506
+
1507
+ return self.get_status('ReleaseAddress', params, verb='POST')
1508
+
1509
+ def unassign_private_ip_addresses(self, network_interface_id=None,
1510
+ private_ip_addresses=None):
1511
+ """
1512
+ Unassigns one or more secondary private IP addresses from a network
1513
+ interface in Amazon VPC.
1514
+
1515
+ :type network_interface_id: string
1516
+ :param network_interface_id: The network interface from which the
1517
+ secondary private IP address will be unassigned.
1518
+
1519
+ :type private_ip_addresses: list
1520
+ :param private_ip_addresses: Specifies the secondary private IP
1521
+ addresses that you want to unassign from the network interface.
1522
+
1523
+ :rtype: bool
1524
+ :return: True if successful
1525
+ """
1526
+ params = {}
1527
+
1528
+ if network_interface_id is not None:
1529
+ params['NetworkInterfaceId'] = network_interface_id
1530
+
1531
+ if private_ip_addresses is not None:
1532
+ self.build_list_params(params, private_ip_addresses,
1533
+ 'PrivateIpAddress')
1534
+
1535
+ return self.get_status('UnassignPrivateIpAddresses', params,
1536
+ verb='POST')
1537
+
1538
+ # Volume methods
1539
+
1540
+ def get_all_volumes(self, volume_ids=None, filters=None):
1541
+ """
1542
+ Get all Volumes associated with the current credentials.
1543
+
1544
+ :type volume_ids: list
1545
+ :param volume_ids: Optional list of volume ids. If this list
1546
+ is present, only the volumes associated with
1547
+ these volume ids will be returned.
1548
+
1549
+ :type filters: dict
1550
+ :param filters: Optional filters that can be used to limit
1551
+ the results returned. Filters are provided
1552
+ in the form of a dictionary consisting of
1553
+ filter names as the key and filter values
1554
+ as the value. The set of allowable filter
1555
+ names/values is dependent on the request
1556
+ being performed. Check the EC2 API guide
1557
+ for details.
1558
+
1559
+ :rtype: list of :class:`boto.ec2.volume.Volume`
1560
+ :return: The requested Volume objects
1561
+ """
1562
+ params = {}
1563
+ if volume_ids:
1564
+ self.build_list_params(params, volume_ids, 'VolumeId')
1565
+ if filters:
1566
+ self.build_filter_params(params, filters)
1567
+ return self.get_list('DescribeVolumes', params,
1568
+ [('item', Volume)], verb='POST')
1569
+
1570
+ def get_all_volume_status(self, volume_ids=None,
1571
+ max_results=None, next_token=None,
1572
+ filters=None):
1573
+ """
1574
+ Retrieve the status of one or more volumes.
1575
+
1576
+ :type volume_ids: list
1577
+ :param volume_ids: A list of strings of volume IDs
1578
+
1579
+ :type max_results: int
1580
+ :param max_results: The maximum number of paginated instance
1581
+ items per response.
1582
+
1583
+ :type next_token: str
1584
+ :param next_token: A string specifying the next paginated set
1585
+ of results to return.
1586
+
1587
+ :type filters: dict
1588
+ :param filters: Optional filters that can be used to limit
1589
+ the results returned. Filters are provided
1590
+ in the form of a dictionary consisting of
1591
+ filter names as the key and filter values
1592
+ as the value. The set of allowable filter
1593
+ names/values is dependent on the request
1594
+ being performed. Check the EC2 API guide
1595
+ for details.
1596
+
1597
+ :rtype: list
1598
+ :return: A list of volume status.
1599
+ """
1600
+ params = {}
1601
+ if volume_ids:
1602
+ self.build_list_params(params, volume_ids, 'VolumeId')
1603
+ if max_results:
1604
+ params['MaxResults'] = max_results
1605
+ if next_token:
1606
+ params['NextToken'] = next_token
1607
+ if filters:
1608
+ self.build_filter_params(params, filters)
1609
+ return self.get_object('DescribeVolumeStatus', params,
1610
+ VolumeStatusSet, verb='POST')
1611
+
1612
+ def enable_volume_io(self, volume_id):
1613
+ """
1614
+ Enables I/O operations for a volume that had I/O operations
1615
+ disabled because the data on the volume was potentially inconsistent.
1616
+
1617
+ :type volume_id: str
1618
+ :param volume_id: The ID of the volume.
1619
+
1620
+ :rtype: bool
1621
+ :return: True if successful
1622
+ """
1623
+ params = {'VolumeId': volume_id}
1624
+ return self.get_status('EnableVolumeIO', params, verb='POST')
1625
+
1626
+ def get_volume_attribute(self, volume_id,
1627
+ attribute='autoEnableIO'):
1628
+ """
1629
+ Describes attribute of the volume.
1630
+
1631
+ :type volume_id: str
1632
+ :param volume_id: The ID of the volume.
1633
+
1634
+ :type attribute: str
1635
+ :param attribute: The requested attribute. Valid values are:
1636
+
1637
+ * autoEnableIO
1638
+
1639
+ :rtype: list of :class:`boto.ec2.volume.VolumeAttribute`
1640
+ :return: The requested Volume attribute
1641
+ """
1642
+ params = {'VolumeId': volume_id, 'Attribute': attribute}
1643
+ return self.get_object('DescribeVolumeAttribute', params,
1644
+ VolumeAttribute, verb='POST')
1645
+
1646
+ def modify_volume_attribute(self, volume_id, attribute, new_value):
1647
+ """
1648
+ Changes an attribute of an Volume.
1649
+
1650
+ :type volume_id: string
1651
+ :param volume_id: The volume id you wish to change
1652
+
1653
+ :type attribute: string
1654
+ :param attribute: The attribute you wish to change. Valid values are:
1655
+ AutoEnableIO.
1656
+
1657
+ :type new_value: string
1658
+ :param new_value: The new value of the attribute.
1659
+ """
1660
+ params = {'VolumeId': volume_id}
1661
+ if attribute == 'AutoEnableIO':
1662
+ params['AutoEnableIO.Value'] = new_value
1663
+ return self.get_status('ModifyVolumeAttribute', params, verb='POST')
1664
+
1665
+ def create_volume(self, size, zone, snapshot=None,
1666
+ volume_type=None, iops=None):
1667
+ """
1668
+ Create a new EBS Volume.
1669
+
1670
+ :type size: int
1671
+ :param size: The size of the new volume, in GiB
1672
+
1673
+ :type zone: string or :class:`boto.ec2.zone.Zone`
1674
+ :param zone: The availability zone in which the Volume will be created.
1675
+
1676
+ :type snapshot: string or :class:`boto.ec2.snapshot.Snapshot`
1677
+ :param snapshot: The snapshot from which the new Volume will be
1678
+ created.
1679
+
1680
+ :type volume_type: string
1681
+ :param volume_type: The type of the volume. (optional). Valid
1682
+ values are: standard | io1.
1683
+
1684
+ :type iops: int
1685
+ :param iops: The provisioned IOPs you want to associate with
1686
+ this volume. (optional)
1687
+ """
1688
+ if isinstance(zone, Zone):
1689
+ zone = zone.name
1690
+ params = {'AvailabilityZone': zone}
1691
+ if size:
1692
+ params['Size'] = size
1693
+ if snapshot:
1694
+ if isinstance(snapshot, Snapshot):
1695
+ snapshot = snapshot.id
1696
+ params['SnapshotId'] = snapshot
1697
+ if volume_type:
1698
+ params['VolumeType'] = volume_type
1699
+ if iops:
1700
+ params['Iops'] = str(iops)
1701
+ return self.get_object('CreateVolume', params, Volume, verb='POST')
1702
+
1703
+ def delete_volume(self, volume_id):
1704
+ """
1705
+ Delete an EBS volume.
1706
+
1707
+ :type volume_id: str
1708
+ :param volume_id: The ID of the volume to be delete.
1709
+
1710
+ :rtype: bool
1711
+ :return: True if successful
1712
+ """
1713
+ params = {'VolumeId': volume_id}
1714
+ return self.get_status('DeleteVolume', params, verb='POST')
1715
+
1716
+ def attach_volume(self, volume_id, instance_id, device):
1717
+ """
1718
+ Attach an EBS volume to an EC2 instance.
1719
+
1720
+ :type volume_id: str
1721
+ :param volume_id: The ID of the EBS volume to be attached.
1722
+
1723
+ :type instance_id: str
1724
+ :param instance_id: The ID of the EC2 instance to which it will
1725
+ be attached.
1726
+
1727
+ :type device: str
1728
+ :param device: The device on the instance through which the
1729
+ volume will be exposted (e.g. /dev/sdh)
1730
+
1731
+ :rtype: bool
1732
+ :return: True if successful
1733
+ """
1734
+ params = {'InstanceId': instance_id,
1735
+ 'VolumeId': volume_id,
1736
+ 'Device': device}
1737
+ return self.get_status('AttachVolume', params, verb='POST')
1738
+
1739
+ def detach_volume(self, volume_id, instance_id=None,
1740
+ device=None, force=False):
1741
+ """
1742
+ Detach an EBS volume from an EC2 instance.
1743
+
1744
+ :type volume_id: str
1745
+ :param volume_id: The ID of the EBS volume to be attached.
1746
+
1747
+ :type instance_id: str
1748
+ :param instance_id: The ID of the EC2 instance from which it will
1749
+ be detached.
1750
+
1751
+ :type device: str
1752
+ :param device: The device on the instance through which the
1753
+ volume is exposted (e.g. /dev/sdh)
1754
+
1755
+ :type force: bool
1756
+ :param force: Forces detachment if the previous detachment
1757
+ attempt did not occur cleanly. This option can lead to
1758
+ data loss or a corrupted file system. Use this option only
1759
+ as a last resort to detach a volume from a failed
1760
+ instance. The instance will not have an opportunity to
1761
+ flush file system caches nor file system meta data. If you
1762
+ use this option, you must perform file system check and
1763
+ repair procedures.
1764
+
1765
+ :rtype: bool
1766
+ :return: True if successful
1767
+ """
1768
+ params = {'VolumeId': volume_id}
1769
+ if instance_id:
1770
+ params['InstanceId'] = instance_id
1771
+ if device:
1772
+ params['Device'] = device
1773
+ if force:
1774
+ params['Force'] = 'true'
1775
+ return self.get_status('DetachVolume', params, verb='POST')
1776
+
1777
+ # Snapshot methods
1778
+
1779
+ def get_all_snapshots(self, snapshot_ids=None,
1780
+ owner=None, restorable_by=None,
1781
+ filters=None):
1782
+ """
1783
+ Get all EBS Snapshots associated with the current credentials.
1784
+
1785
+ :type snapshot_ids: list
1786
+ :param snapshot_ids: Optional list of snapshot ids. If this list is
1787
+ present, only the Snapshots associated with
1788
+ these snapshot ids will be returned.
1789
+
1790
+ :type owner: str
1791
+ :param owner: If present, only the snapshots owned by the specified user
1792
+ will be returned. Valid values are:
1793
+
1794
+ * self
1795
+ * amazon
1796
+ * AWS Account ID
1797
+
1798
+ :type restorable_by: str
1799
+ :param restorable_by: If present, only the snapshots that are restorable
1800
+ by the specified account id will be returned.
1801
+
1802
+ :type filters: dict
1803
+ :param filters: Optional filters that can be used to limit
1804
+ the results returned. Filters are provided
1805
+ in the form of a dictionary consisting of
1806
+ filter names as the key and filter values
1807
+ as the value. The set of allowable filter
1808
+ names/values is dependent on the request
1809
+ being performed. Check the EC2 API guide
1810
+ for details.
1811
+
1812
+ :rtype: list of :class:`boto.ec2.snapshot.Snapshot`
1813
+ :return: The requested Snapshot objects
1814
+ """
1815
+ params = {}
1816
+ if snapshot_ids:
1817
+ self.build_list_params(params, snapshot_ids, 'SnapshotId')
1818
+ if owner:
1819
+ params['Owner'] = owner
1820
+ if restorable_by:
1821
+ params['RestorableBy'] = restorable_by
1822
+ if filters:
1823
+ self.build_filter_params(params, filters)
1824
+ return self.get_list('DescribeSnapshots', params,
1825
+ [('item', Snapshot)], verb='POST')
1826
+
1827
+ def create_snapshot(self, volume_id, description=None):
1828
+ """
1829
+ Create a snapshot of an existing EBS Volume.
1830
+
1831
+ :type volume_id: str
1832
+ :param volume_id: The ID of the volume to be snapshot'ed
1833
+
1834
+ :type description: str
1835
+ :param description: A description of the snapshot.
1836
+ Limited to 255 characters.
1837
+
1838
+ :rtype: :class:`boto.ec2.snapshot.Snapshot`
1839
+ :return: The created Snapshot object
1840
+ """
1841
+ params = {'VolumeId': volume_id}
1842
+ if description:
1843
+ params['Description'] = description[0:255]
1844
+ snapshot = self.get_object('CreateSnapshot', params,
1845
+ Snapshot, verb='POST')
1846
+ volume = self.get_all_volumes([volume_id])[0]
1847
+ volume_name = volume.tags.get('Name')
1848
+ if volume_name:
1849
+ snapshot.add_tag('Name', volume_name)
1850
+ return snapshot
1851
+
1852
+ def delete_snapshot(self, snapshot_id):
1853
+ params = {'SnapshotId': snapshot_id}
1854
+ return self.get_status('DeleteSnapshot', params, verb='POST')
1855
+
1856
+ def copy_snapshot(self, source_region, source_snapshot_id,
1857
+ description=None):
1858
+ """
1859
+ Copies a point-in-time snapshot of an Amazon Elastic Block Store
1860
+ (Amazon EBS) volume and stores it in Amazon Simple Storage Service
1861
+ (Amazon S3). You can copy the snapshot within the same region or from
1862
+ one region to another. You can use the snapshot to create new Amazon
1863
+ EBS volumes or Amazon Machine Images (AMIs).
1864
+
1865
+
1866
+ :type source_region: str
1867
+ :param source_region: The ID of the AWS region that contains the
1868
+ snapshot to be copied (e.g 'us-east-1', 'us-west-2', etc.).
1869
+
1870
+ :type source_snapshot_id: str
1871
+ :param source_snapshot_id: The ID of the Amazon EBS snapshot to copy
1872
+
1873
+ :type description: str
1874
+ :param description: A description of the new Amazon EBS snapshot.
1875
+
1876
+ :rtype: str
1877
+ :return: The snapshot ID
1878
+
1879
+ """
1880
+ params = {
1881
+ 'SourceRegion': source_region,
1882
+ 'SourceSnapshotId': source_snapshot_id,
1883
+ }
1884
+ if description is not None:
1885
+ params['Description'] = description
1886
+ snapshot = self.get_object('CopySnapshot', params, Snapshot,
1887
+ verb='POST')
1888
+ return snapshot.id
1889
+
1890
+ def trim_snapshots(self, hourly_backups=8, daily_backups=7,
1891
+ weekly_backups=4):
1892
+ """
1893
+ Trim excess snapshots, based on when they were taken. More current
1894
+ snapshots are retained, with the number retained decreasing as you
1895
+ move back in time.
1896
+
1897
+ If ebs volumes have a 'Name' tag with a value, their snapshots
1898
+ will be assigned the same tag when they are created. The values
1899
+ of the 'Name' tags for snapshots are used by this function to
1900
+ group snapshots taken from the same volume (or from a series
1901
+ of like-named volumes over time) for trimming.
1902
+
1903
+ For every group of like-named snapshots, this function retains
1904
+ the newest and oldest snapshots, as well as, by default, the
1905
+ first snapshots taken in each of the last eight hours, the first
1906
+ snapshots taken in each of the last seven days, the first snapshots
1907
+ taken in the last 4 weeks (counting Midnight Sunday morning as
1908
+ the start of the week), and the first snapshot from the first
1909
+ Sunday of each month forever.
1910
+
1911
+ :type hourly_backups: int
1912
+ :param hourly_backups: How many recent hourly backups should be saved.
1913
+
1914
+ :type daily_backups: int
1915
+ :param daily_backups: How many recent daily backups should be saved.
1916
+
1917
+ :type weekly_backups: int
1918
+ :param weekly_backups: How many recent weekly backups should be saved.
1919
+ """
1920
+
1921
+ # This function first builds up an ordered list of target times
1922
+ # that snapshots should be saved for (last 8 hours, last 7 days, etc.).
1923
+ # Then a map of snapshots is constructed, with the keys being
1924
+ # the snapshot / volume names and the values being arrays of
1925
+ # chronologically sorted snapshots.
1926
+ # Finally, for each array in the map, we go through the snapshot
1927
+ # array and the target time array in an interleaved fashion,
1928
+ # deleting snapshots whose start_times don't immediately follow a
1929
+ # target time (we delete a snapshot if there's another snapshot
1930
+ # that was made closer to the preceding target time).
1931
+
1932
+ now = datetime.utcnow()
1933
+ last_hour = datetime(now.year, now.month, now.day, now.hour)
1934
+ last_midnight = datetime(now.year, now.month, now.day)
1935
+ last_sunday = datetime(now.year, now.month, now.day) - timedelta(days = (now.weekday() + 1) % 7)
1936
+ start_of_month = datetime(now.year, now.month, 1)
1937
+
1938
+ target_backup_times = []
1939
+
1940
+ # there are no snapshots older than 1/1/2007
1941
+ oldest_snapshot_date = datetime(2007, 1, 1)
1942
+
1943
+ for hour in range(0, hourly_backups):
1944
+ target_backup_times.append(last_hour - timedelta(hours = hour))
1945
+
1946
+ for day in range(0, daily_backups):
1947
+ target_backup_times.append(last_midnight - timedelta(days = day))
1948
+
1949
+ for week in range(0, weekly_backups):
1950
+ target_backup_times.append(last_sunday - timedelta(weeks = week))
1951
+
1952
+ one_day = timedelta(days = 1)
1953
+ while start_of_month > oldest_snapshot_date:
1954
+ # append the start of the month to the list of
1955
+ # snapshot dates to save:
1956
+ target_backup_times.append(start_of_month)
1957
+ # there's no timedelta setting for one month, so instead:
1958
+ # decrement the day by one, so we go to the final day of
1959
+ # the previous month...
1960
+ start_of_month -= one_day
1961
+ # ... and then go to the first day of that previous month:
1962
+ start_of_month = datetime(start_of_month.year,
1963
+ start_of_month.month, 1)
1964
+
1965
+ temp = []
1966
+
1967
+ for t in target_backup_times:
1968
+ if temp.__contains__(t) == False:
1969
+ temp.append(t)
1970
+
1971
+ # sort to make the oldest dates first, and make sure the month start
1972
+ # and last four week's start are in the proper order
1973
+ target_backup_times = sorted(temp)
1974
+
1975
+ # get all the snapshots, sort them by date and time, and
1976
+ # organize them into one array for each volume:
1977
+ all_snapshots = self.get_all_snapshots(owner = 'self')
1978
+ all_snapshots.sort(cmp = lambda x, y: cmp(x.start_time, y.start_time))
1979
+ snaps_for_each_volume = {}
1980
+ for snap in all_snapshots:
1981
+ # the snapshot name and the volume name are the same.
1982
+ # The snapshot name is set from the volume
1983
+ # name at the time the snapshot is taken
1984
+ volume_name = snap.tags.get('Name')
1985
+ if volume_name:
1986
+ # only examine snapshots that have a volume name
1987
+ snaps_for_volume = snaps_for_each_volume.get(volume_name)
1988
+ if not snaps_for_volume:
1989
+ snaps_for_volume = []
1990
+ snaps_for_each_volume[volume_name] = snaps_for_volume
1991
+ snaps_for_volume.append(snap)
1992
+
1993
+ # Do a running comparison of snapshot dates to desired time
1994
+ #periods, keeping the oldest snapshot in each
1995
+ # time period and deleting the rest:
1996
+ for volume_name in snaps_for_each_volume:
1997
+ snaps = snaps_for_each_volume[volume_name]
1998
+ snaps = snaps[:-1] # never delete the newest snapshot
1999
+ time_period_number = 0
2000
+ snap_found_for_this_time_period = False
2001
+ for snap in snaps:
2002
+ check_this_snap = True
2003
+ while check_this_snap and time_period_number < target_backup_times.__len__():
2004
+ snap_date = datetime.strptime(snap.start_time,
2005
+ '%Y-%m-%dT%H:%M:%S.000Z')
2006
+ if snap_date < target_backup_times[time_period_number]:
2007
+ # the snap date is before the cutoff date.
2008
+ # Figure out if it's the first snap in this
2009
+ # date range and act accordingly (since both
2010
+ #date the date ranges and the snapshots
2011
+ # are sorted chronologically, we know this
2012
+ #snapshot isn't in an earlier date range):
2013
+ if snap_found_for_this_time_period == True:
2014
+ if not snap.tags.get('preserve_snapshot'):
2015
+ # as long as the snapshot wasn't marked
2016
+ # with the 'preserve_snapshot' tag, delete it:
2017
+ try:
2018
+ self.delete_snapshot(snap.id)
2019
+ boto.log.info('Trimmed snapshot %s (%s)' % (snap.tags['Name'], snap.start_time))
2020
+ except EC2ResponseError:
2021
+ boto.log.error('Attempt to trim snapshot %s (%s) failed. Possible result of a race condition with trimming on another server?' % (snap.tags['Name'], snap.start_time))
2022
+ # go on and look at the next snapshot,
2023
+ #leaving the time period alone
2024
+ else:
2025
+ # this was the first snapshot found for this
2026
+ #time period. Leave it alone and look at the
2027
+ # next snapshot:
2028
+ snap_found_for_this_time_period = True
2029
+ check_this_snap = False
2030
+ else:
2031
+ # the snap is after the cutoff date. Check it
2032
+ # against the next cutoff date
2033
+ time_period_number += 1
2034
+ snap_found_for_this_time_period = False
2035
+
2036
+ def get_snapshot_attribute(self, snapshot_id,
2037
+ attribute='createVolumePermission'):
2038
+ """
2039
+ Get information about an attribute of a snapshot. Only one attribute
2040
+ can be specified per call.
2041
+
2042
+ :type snapshot_id: str
2043
+ :param snapshot_id: The ID of the snapshot.
2044
+
2045
+ :type attribute: str
2046
+ :param attribute: The requested attribute. Valid values are:
2047
+
2048
+ * createVolumePermission
2049
+
2050
+ :rtype: list of :class:`boto.ec2.snapshotattribute.SnapshotAttribute`
2051
+ :return: The requested Snapshot attribute
2052
+ """
2053
+ params = {'Attribute': attribute}
2054
+ if snapshot_id:
2055
+ params['SnapshotId'] = snapshot_id
2056
+ return self.get_object('DescribeSnapshotAttribute', params,
2057
+ SnapshotAttribute, verb='POST')
2058
+
2059
+ def modify_snapshot_attribute(self, snapshot_id,
2060
+ attribute='createVolumePermission',
2061
+ operation='add', user_ids=None, groups=None):
2062
+ """
2063
+ Changes an attribute of an image.
2064
+
2065
+ :type snapshot_id: string
2066
+ :param snapshot_id: The snapshot id you wish to change
2067
+
2068
+ :type attribute: string
2069
+ :param attribute: The attribute you wish to change. Valid values are:
2070
+ createVolumePermission
2071
+
2072
+ :type operation: string
2073
+ :param operation: Either add or remove (this is required for changing
2074
+ snapshot ermissions)
2075
+
2076
+ :type user_ids: list
2077
+ :param user_ids: The Amazon IDs of users to add/remove attributes
2078
+
2079
+ :type groups: list
2080
+ :param groups: The groups to add/remove attributes. The only valid
2081
+ value at this time is 'all'.
2082
+
2083
+ """
2084
+ params = {'SnapshotId': snapshot_id,
2085
+ 'Attribute': attribute,
2086
+ 'OperationType': operation}
2087
+ if user_ids:
2088
+ self.build_list_params(params, user_ids, 'UserId')
2089
+ if groups:
2090
+ self.build_list_params(params, groups, 'UserGroup')
2091
+ return self.get_status('ModifySnapshotAttribute', params, verb='POST')
2092
+
2093
+ def reset_snapshot_attribute(self, snapshot_id,
2094
+ attribute='createVolumePermission'):
2095
+ """
2096
+ Resets an attribute of a snapshot to its default value.
2097
+
2098
+ :type snapshot_id: string
2099
+ :param snapshot_id: ID of the snapshot
2100
+
2101
+ :type attribute: string
2102
+ :param attribute: The attribute to reset
2103
+
2104
+ :rtype: bool
2105
+ :return: Whether the operation succeeded or not
2106
+ """
2107
+ params = {'SnapshotId': snapshot_id,
2108
+ 'Attribute': attribute}
2109
+ return self.get_status('ResetSnapshotAttribute', params, verb='POST')
2110
+
2111
+ # Keypair methods
2112
+
2113
+ def get_all_key_pairs(self, keynames=None, filters=None):
2114
+ """
2115
+ Get all key pairs associated with your account.
2116
+
2117
+ :type keynames: list
2118
+ :param keynames: A list of the names of keypairs to retrieve.
2119
+ If not provided, all key pairs will be returned.
2120
+
2121
+ :type filters: dict
2122
+ :param filters: Optional filters that can be used to limit the
2123
+ results returned. Filters are provided in the form of a
2124
+ dictionary consisting of filter names as the key and
2125
+ filter values as the value. The set of allowable filter
2126
+ names/values is dependent on the request being performed.
2127
+ Check the EC2 API guide for details.
2128
+
2129
+ :rtype: list
2130
+ :return: A list of :class:`boto.ec2.keypair.KeyPair`
2131
+ """
2132
+ params = {}
2133
+ if keynames:
2134
+ self.build_list_params(params, keynames, 'KeyName')
2135
+ if filters:
2136
+ self.build_filter_params(params, filters)
2137
+ return self.get_list('DescribeKeyPairs', params,
2138
+ [('item', KeyPair)], verb='POST')
2139
+
2140
+ def get_key_pair(self, keyname):
2141
+ """
2142
+ Convenience method to retrieve a specific keypair (KeyPair).
2143
+
2144
+ :type image_id: string
2145
+ :param image_id: the ID of the Image to retrieve
2146
+
2147
+ :rtype: :class:`boto.ec2.keypair.KeyPair`
2148
+ :return: The KeyPair specified or None if it is not found
2149
+ """
2150
+ try:
2151
+ return self.get_all_key_pairs(keynames=[keyname])[0]
2152
+ except self.ResponseError, e:
2153
+ if e.code == 'InvalidKeyPair.NotFound':
2154
+ return None
2155
+ else:
2156
+ raise
2157
+
2158
+ def create_key_pair(self, key_name):
2159
+ """
2160
+ Create a new key pair for your account.
2161
+ This will create the key pair within the region you
2162
+ are currently connected to.
2163
+
2164
+ :type key_name: string
2165
+ :param key_name: The name of the new keypair
2166
+
2167
+ :rtype: :class:`boto.ec2.keypair.KeyPair`
2168
+ :return: The newly created :class:`boto.ec2.keypair.KeyPair`.
2169
+ The material attribute of the new KeyPair object
2170
+ will contain the the unencrypted PEM encoded RSA private key.
2171
+ """
2172
+ params = {'KeyName': key_name}
2173
+ return self.get_object('CreateKeyPair', params, KeyPair, verb='POST')
2174
+
2175
+ def delete_key_pair(self, key_name):
2176
+ """
2177
+ Delete a key pair from your account.
2178
+
2179
+ :type key_name: string
2180
+ :param key_name: The name of the keypair to delete
2181
+ """
2182
+ params = {'KeyName': key_name}
2183
+ return self.get_status('DeleteKeyPair', params, verb='POST')
2184
+
2185
+ def import_key_pair(self, key_name, public_key_material):
2186
+ """
2187
+ mports the public key from an RSA key pair that you created
2188
+ with a third-party tool.
2189
+
2190
+ Supported formats:
2191
+
2192
+ * OpenSSH public key format (e.g., the format
2193
+ in ~/.ssh/authorized_keys)
2194
+
2195
+ * Base64 encoded DER format
2196
+
2197
+ * SSH public key file format as specified in RFC4716
2198
+
2199
+ DSA keys are not supported. Make sure your key generator is
2200
+ set up to create RSA keys.
2201
+
2202
+ Supported lengths: 1024, 2048, and 4096.
2203
+
2204
+ :type key_name: string
2205
+ :param key_name: The name of the new keypair
2206
+
2207
+ :type public_key_material: string
2208
+ :param public_key_material: The public key. You must base64 encode
2209
+ the public key material before sending
2210
+ it to AWS.
2211
+
2212
+ :rtype: :class:`boto.ec2.keypair.KeyPair`
2213
+ :return: The newly created :class:`boto.ec2.keypair.KeyPair`.
2214
+ The material attribute of the new KeyPair object
2215
+ will contain the the unencrypted PEM encoded RSA private key.
2216
+ """
2217
+ public_key_material = base64.b64encode(public_key_material)
2218
+ params = {'KeyName': key_name,
2219
+ 'PublicKeyMaterial': public_key_material}
2220
+ return self.get_object('ImportKeyPair', params, KeyPair, verb='POST')
2221
+
2222
+ # SecurityGroup methods
2223
+
2224
+ def get_all_security_groups(self, groupnames=None, group_ids=None,
2225
+ filters=None):
2226
+ """
2227
+ Get all security groups associated with your account in a region.
2228
+
2229
+ :type groupnames: list
2230
+ :param groupnames: A list of the names of security groups to retrieve.
2231
+ If not provided, all security groups will be
2232
+ returned.
2233
+
2234
+ :type group_ids: list
2235
+ :param group_ids: A list of IDs of security groups to retrieve for
2236
+ security groups within a VPC.
2237
+
2238
+ :type filters: dict
2239
+ :param filters: Optional filters that can be used to limit
2240
+ the results returned. Filters are provided
2241
+ in the form of a dictionary consisting of
2242
+ filter names as the key and filter values
2243
+ as the value. The set of allowable filter
2244
+ names/values is dependent on the request
2245
+ being performed. Check the EC2 API guide
2246
+ for details.
2247
+
2248
+ :rtype: list
2249
+ :return: A list of :class:`boto.ec2.securitygroup.SecurityGroup`
2250
+ """
2251
+ params = {}
2252
+ if groupnames is not None:
2253
+ self.build_list_params(params, groupnames, 'GroupName')
2254
+ if group_ids is not None:
2255
+ self.build_list_params(params, group_ids, 'GroupId')
2256
+ if filters is not None:
2257
+ self.build_filter_params(params, filters)
2258
+
2259
+ return self.get_list('DescribeSecurityGroups', params,
2260
+ [('item', SecurityGroup)], verb='POST')
2261
+
2262
+ def create_security_group(self, name, description, vpc_id=None):
2263
+ """
2264
+ Create a new security group for your account.
2265
+ This will create the security group within the region you
2266
+ are currently connected to.
2267
+
2268
+ :type name: string
2269
+ :param name: The name of the new security group
2270
+
2271
+ :type description: string
2272
+ :param description: The description of the new security group
2273
+
2274
+ :type vpc_id: string
2275
+ :param vpc_id: The ID of the VPC to create the security group in,
2276
+ if any.
2277
+
2278
+ :rtype: :class:`boto.ec2.securitygroup.SecurityGroup`
2279
+ :return: The newly created :class:`boto.ec2.securitygroup.SecurityGroup`.
2280
+ """
2281
+ params = {'GroupName': name,
2282
+ 'GroupDescription': description}
2283
+
2284
+ if vpc_id is not None:
2285
+ params['VpcId'] = vpc_id
2286
+
2287
+ group = self.get_object('CreateSecurityGroup', params,
2288
+ SecurityGroup, verb='POST')
2289
+ group.name = name
2290
+ group.description = description
2291
+ if vpc_id is not None:
2292
+ group.vpc_id = vpc_id
2293
+ return group
2294
+
2295
+ def delete_security_group(self, name=None, group_id=None):
2296
+ """
2297
+ Delete a security group from your account.
2298
+
2299
+ :type name: string
2300
+ :param name: The name of the security group to delete.
2301
+
2302
+ :type group_id: string
2303
+ :param group_id: The ID of the security group to delete within
2304
+ a VPC.
2305
+
2306
+ :rtype: bool
2307
+ :return: True if successful.
2308
+ """
2309
+ params = {}
2310
+
2311
+ if name is not None:
2312
+ params['GroupName'] = name
2313
+ elif group_id is not None:
2314
+ params['GroupId'] = group_id
2315
+
2316
+ return self.get_status('DeleteSecurityGroup', params, verb='POST')
2317
+
2318
+ def authorize_security_group_deprecated(self, group_name,
2319
+ src_security_group_name=None,
2320
+ src_security_group_owner_id=None,
2321
+ ip_protocol=None,
2322
+ from_port=None, to_port=None,
2323
+ cidr_ip=None):
2324
+ """
2325
+ NOTE: This method uses the old-style request parameters
2326
+ that did not allow a port to be specified when
2327
+ authorizing a group.
2328
+
2329
+ :type group_name: string
2330
+ :param group_name: The name of the security group you are adding
2331
+ the rule to.
2332
+
2333
+ :type src_security_group_name: string
2334
+ :param src_security_group_name: The name of the security group you are
2335
+ granting access to.
2336
+
2337
+ :type src_security_group_owner_id: string
2338
+ :param src_security_group_owner_id: The ID of the owner of the security
2339
+ group you are granting access to.
2340
+
2341
+ :type ip_protocol: string
2342
+ :param ip_protocol: Either tcp | udp | icmp
2343
+
2344
+ :type from_port: int
2345
+ :param from_port: The beginning port number you are enabling
2346
+
2347
+ :type to_port: int
2348
+ :param to_port: The ending port number you are enabling
2349
+
2350
+ :type to_port: string
2351
+ :param to_port: The CIDR block you are providing access to.
2352
+ See http://goo.gl/Yj5QC
2353
+
2354
+ :rtype: bool
2355
+ :return: True if successful.
2356
+ """
2357
+ params = {'GroupName':group_name}
2358
+ if src_security_group_name:
2359
+ params['SourceSecurityGroupName'] = src_security_group_name
2360
+ if src_security_group_owner_id:
2361
+ params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id
2362
+ if ip_protocol:
2363
+ params['IpProtocol'] = ip_protocol
2364
+ if from_port:
2365
+ params['FromPort'] = from_port
2366
+ if to_port:
2367
+ params['ToPort'] = to_port
2368
+ if cidr_ip:
2369
+ params['CidrIp'] = cidr_ip
2370
+ return self.get_status('AuthorizeSecurityGroupIngress', params)
2371
+
2372
+ def authorize_security_group(self, group_name=None,
2373
+ src_security_group_name=None,
2374
+ src_security_group_owner_id=None,
2375
+ ip_protocol=None,
2376
+ from_port=None, to_port=None,
2377
+ cidr_ip=None, group_id=None,
2378
+ src_security_group_group_id=None):
2379
+ """
2380
+ Add a new rule to an existing security group.
2381
+ You need to pass in either src_security_group_name and
2382
+ src_security_group_owner_id OR ip_protocol, from_port, to_port,
2383
+ and cidr_ip. In other words, either you are authorizing another
2384
+ group or you are authorizing some ip-based rule.
2385
+
2386
+ :type group_name: string
2387
+ :param group_name: The name of the security group you are adding
2388
+ the rule to.
2389
+
2390
+ :type src_security_group_name: string
2391
+ :param src_security_group_name: The name of the security group you are
2392
+ granting access to.
2393
+
2394
+ :type src_security_group_owner_id: string
2395
+ :param src_security_group_owner_id: The ID of the owner of the security
2396
+ group you are granting access to.
2397
+
2398
+ :type ip_protocol: string
2399
+ :param ip_protocol: Either tcp | udp | icmp
2400
+
2401
+ :type from_port: int
2402
+ :param from_port: The beginning port number you are enabling
2403
+
2404
+ :type to_port: int
2405
+ :param to_port: The ending port number you are enabling
2406
+
2407
+ :type cidr_ip: string or list of strings
2408
+ :param cidr_ip: The CIDR block you are providing access to.
2409
+ See http://goo.gl/Yj5QC
2410
+
2411
+ :type group_id: string
2412
+ :param group_id: ID of the EC2 or VPC security group to
2413
+ modify. This is required for VPC security groups and can
2414
+ be used instead of group_name for EC2 security groups.
2415
+
2416
+ :type src_security_group_group_id: string
2417
+ :param src_security_group_group_id: The ID of the security
2418
+ group you are granting access to. Can be used instead of
2419
+ src_security_group_name
2420
+
2421
+ :rtype: bool
2422
+ :return: True if successful.
2423
+ """
2424
+ if src_security_group_name:
2425
+ if from_port is None and to_port is None and ip_protocol is None:
2426
+ return self.authorize_security_group_deprecated(
2427
+ group_name, src_security_group_name,
2428
+ src_security_group_owner_id)
2429
+
2430
+ params = {}
2431
+
2432
+ if group_name:
2433
+ params['GroupName'] = group_name
2434
+ if group_id:
2435
+ params['GroupId'] = group_id
2436
+ if src_security_group_name:
2437
+ param_name = 'IpPermissions.1.Groups.1.GroupName'
2438
+ params[param_name] = src_security_group_name
2439
+ if src_security_group_owner_id:
2440
+ param_name = 'IpPermissions.1.Groups.1.UserId'
2441
+ params[param_name] = src_security_group_owner_id
2442
+ if src_security_group_group_id:
2443
+ param_name = 'IpPermissions.1.Groups.1.GroupId'
2444
+ params[param_name] = src_security_group_group_id
2445
+ if ip_protocol:
2446
+ params['IpPermissions.1.IpProtocol'] = ip_protocol
2447
+ if from_port is not None:
2448
+ params['IpPermissions.1.FromPort'] = from_port
2449
+ if to_port is not None:
2450
+ params['IpPermissions.1.ToPort'] = to_port
2451
+ if cidr_ip:
2452
+ if not isinstance(cidr_ip, list):
2453
+ cidr_ip = [cidr_ip]
2454
+ for i, single_cidr_ip in enumerate(cidr_ip):
2455
+ params['IpPermissions.1.IpRanges.%d.CidrIp' % (i+1)] = \
2456
+ single_cidr_ip
2457
+
2458
+ return self.get_status('AuthorizeSecurityGroupIngress',
2459
+ params, verb='POST')
2460
+
2461
+ def authorize_security_group_egress(self,
2462
+ group_id,
2463
+ ip_protocol,
2464
+ from_port=None,
2465
+ to_port=None,
2466
+ src_group_id=None,
2467
+ cidr_ip=None):
2468
+ """
2469
+ The action adds one or more egress rules to a VPC security
2470
+ group. Specifically, this action permits instances in a
2471
+ security group to send traffic to one or more destination
2472
+ CIDR IP address ranges, or to one or more destination
2473
+ security groups in the same VPC.
2474
+ """
2475
+ params = {
2476
+ 'GroupId': group_id,
2477
+ 'IpPermissions.1.IpProtocol': ip_protocol
2478
+ }
2479
+
2480
+ if from_port is not None:
2481
+ params['IpPermissions.1.FromPort'] = from_port
2482
+ if to_port is not None:
2483
+ params['IpPermissions.1.ToPort'] = to_port
2484
+ if src_group_id is not None:
2485
+ params['IpPermissions.1.Groups.1.GroupId'] = src_group_id
2486
+ if cidr_ip is not None:
2487
+ params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
2488
+
2489
+ return self.get_status('AuthorizeSecurityGroupEgress',
2490
+ params, verb='POST')
2491
+
2492
+ def revoke_security_group_deprecated(self, group_name,
2493
+ src_security_group_name=None,
2494
+ src_security_group_owner_id=None,
2495
+ ip_protocol=None,
2496
+ from_port=None, to_port=None,
2497
+ cidr_ip=None):
2498
+ """
2499
+ NOTE: This method uses the old-style request parameters
2500
+ that did not allow a port to be specified when
2501
+ authorizing a group.
2502
+
2503
+ Remove an existing rule from an existing security group.
2504
+ You need to pass in either src_security_group_name and
2505
+ src_security_group_owner_id OR ip_protocol, from_port, to_port,
2506
+ and cidr_ip. In other words, either you are revoking another
2507
+ group or you are revoking some ip-based rule.
2508
+
2509
+ :type group_name: string
2510
+ :param group_name: The name of the security group you are removing
2511
+ the rule from.
2512
+
2513
+ :type src_security_group_name: string
2514
+ :param src_security_group_name: The name of the security group you are
2515
+ revoking access to.
2516
+
2517
+ :type src_security_group_owner_id: string
2518
+ :param src_security_group_owner_id: The ID of the owner of the security
2519
+ group you are revoking access to.
2520
+
2521
+ :type ip_protocol: string
2522
+ :param ip_protocol: Either tcp | udp | icmp
2523
+
2524
+ :type from_port: int
2525
+ :param from_port: The beginning port number you are disabling
2526
+
2527
+ :type to_port: int
2528
+ :param to_port: The ending port number you are disabling
2529
+
2530
+ :type to_port: string
2531
+ :param to_port: The CIDR block you are revoking access to.
2532
+ http://goo.gl/Yj5QC
2533
+
2534
+ :rtype: bool
2535
+ :return: True if successful.
2536
+ """
2537
+ params = {'GroupName':group_name}
2538
+ if src_security_group_name:
2539
+ params['SourceSecurityGroupName'] = src_security_group_name
2540
+ if src_security_group_owner_id:
2541
+ params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id
2542
+ if ip_protocol:
2543
+ params['IpProtocol'] = ip_protocol
2544
+ if from_port:
2545
+ params['FromPort'] = from_port
2546
+ if to_port:
2547
+ params['ToPort'] = to_port
2548
+ if cidr_ip:
2549
+ params['CidrIp'] = cidr_ip
2550
+ return self.get_status('RevokeSecurityGroupIngress', params)
2551
+
2552
+ def revoke_security_group(self, group_name=None,
2553
+ src_security_group_name=None,
2554
+ src_security_group_owner_id=None,
2555
+ ip_protocol=None, from_port=None, to_port=None,
2556
+ cidr_ip=None, group_id=None,
2557
+ src_security_group_group_id=None):
2558
+ """
2559
+ Remove an existing rule from an existing security group.
2560
+ You need to pass in either src_security_group_name and
2561
+ src_security_group_owner_id OR ip_protocol, from_port, to_port,
2562
+ and cidr_ip. In other words, either you are revoking another
2563
+ group or you are revoking some ip-based rule.
2564
+
2565
+ :type group_name: string
2566
+ :param group_name: The name of the security group you are removing
2567
+ the rule from.
2568
+
2569
+ :type src_security_group_name: string
2570
+ :param src_security_group_name: The name of the security group you are
2571
+ revoking access to.
2572
+
2573
+ :type src_security_group_owner_id: string
2574
+ :param src_security_group_owner_id: The ID of the owner of the security
2575
+ group you are revoking access to.
2576
+
2577
+ :type ip_protocol: string
2578
+ :param ip_protocol: Either tcp | udp | icmp
2579
+
2580
+ :type from_port: int
2581
+ :param from_port: The beginning port number you are disabling
2582
+
2583
+ :type to_port: int
2584
+ :param to_port: The ending port number you are disabling
2585
+
2586
+ :type cidr_ip: string
2587
+ :param cidr_ip: The CIDR block you are revoking access to.
2588
+ See http://goo.gl/Yj5QC
2589
+
2590
+ :type group_id: string
2591
+ :param group_id: ID of the EC2 or VPC security group to
2592
+ modify. This is required for VPC security groups and can
2593
+ be used instead of group_name for EC2 security groups.
2594
+
2595
+ :type src_security_group_group_id: string
2596
+ :param src_security_group_group_id: The ID of the security group
2597
+ for which you are revoking access. Can be used instead
2598
+ of src_security_group_name
2599
+
2600
+ :rtype: bool
2601
+ :return: True if successful.
2602
+ """
2603
+ if src_security_group_name:
2604
+ if from_port is None and to_port is None and ip_protocol is None:
2605
+ return self.revoke_security_group_deprecated(
2606
+ group_name, src_security_group_name,
2607
+ src_security_group_owner_id)
2608
+ params = {}
2609
+ if group_name is not None:
2610
+ params['GroupName'] = group_name
2611
+ if group_id is not None:
2612
+ params['GroupId'] = group_id
2613
+ if src_security_group_name:
2614
+ param_name = 'IpPermissions.1.Groups.1.GroupName'
2615
+ params[param_name] = src_security_group_name
2616
+ if src_security_group_group_id:
2617
+ param_name = 'IpPermissions.1.Groups.1.GroupId'
2618
+ params[param_name] = src_security_group_group_id
2619
+ if src_security_group_owner_id:
2620
+ param_name = 'IpPermissions.1.Groups.1.UserId'
2621
+ params[param_name] = src_security_group_owner_id
2622
+ if ip_protocol:
2623
+ params['IpPermissions.1.IpProtocol'] = ip_protocol
2624
+ if from_port is not None:
2625
+ params['IpPermissions.1.FromPort'] = from_port
2626
+ if to_port is not None:
2627
+ params['IpPermissions.1.ToPort'] = to_port
2628
+ if cidr_ip:
2629
+ params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
2630
+ return self.get_status('RevokeSecurityGroupIngress',
2631
+ params, verb='POST')
2632
+
2633
+ def revoke_security_group_egress(self,
2634
+ group_id,
2635
+ ip_protocol,
2636
+ from_port=None,
2637
+ to_port=None,
2638
+ src_group_id=None,
2639
+ cidr_ip=None):
2640
+ """
2641
+ Remove an existing egress rule from an existing VPC security
2642
+ group. You need to pass in an ip_protocol, from_port and
2643
+ to_port range only if the protocol you are using is
2644
+ port-based. You also need to pass in either a src_group_id or
2645
+ cidr_ip.
2646
+
2647
+ :type group_name: string
2648
+ :param group_id: The name of the security group you are removing
2649
+ the rule from.
2650
+
2651
+ :type ip_protocol: string
2652
+ :param ip_protocol: Either tcp | udp | icmp | -1
2653
+
2654
+ :type from_port: int
2655
+ :param from_port: The beginning port number you are disabling
2656
+
2657
+ :type to_port: int
2658
+ :param to_port: The ending port number you are disabling
2659
+
2660
+ :type src_group_id: src_group_id
2661
+ :param src_group_id: The source security group you are
2662
+ revoking access to.
2663
+
2664
+ :type cidr_ip: string
2665
+ :param cidr_ip: The CIDR block you are revoking access to.
2666
+ See http://goo.gl/Yj5QC
2667
+
2668
+ :rtype: bool
2669
+ :return: True if successful.
2670
+ """
2671
+
2672
+ params = {}
2673
+ if group_id:
2674
+ params['GroupId'] = group_id
2675
+ if ip_protocol:
2676
+ params['IpPermissions.1.IpProtocol'] = ip_protocol
2677
+ if from_port is not None:
2678
+ params['IpPermissions.1.FromPort'] = from_port
2679
+ if to_port is not None:
2680
+ params['IpPermissions.1.ToPort'] = to_port
2681
+ if src_group_id is not None:
2682
+ params['IpPermissions.1.Groups.1.GroupId'] = src_group_id
2683
+ if cidr_ip:
2684
+ params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
2685
+ return self.get_status('RevokeSecurityGroupEgress',
2686
+ params, verb='POST')
2687
+
2688
+ #
2689
+ # Regions
2690
+ #
2691
+
2692
+ def get_all_regions(self, region_names=None, filters=None):
2693
+ """
2694
+ Get all available regions for the EC2 service.
2695
+
2696
+ :type region_names: list of str
2697
+ :param region_names: Names of regions to limit output
2698
+
2699
+ :type filters: dict
2700
+ :param filters: Optional filters that can be used to limit
2701
+ the results returned. Filters are provided
2702
+ in the form of a dictionary consisting of
2703
+ filter names as the key and filter values
2704
+ as the value. The set of allowable filter
2705
+ names/values is dependent on the request
2706
+ being performed. Check the EC2 API guide
2707
+ for details.
2708
+
2709
+ :rtype: list
2710
+ :return: A list of :class:`boto.ec2.regioninfo.RegionInfo`
2711
+ """
2712
+ params = {}
2713
+ if region_names:
2714
+ self.build_list_params(params, region_names, 'RegionName')
2715
+ if filters:
2716
+ self.build_filter_params(params, filters)
2717
+ regions = self.get_list('DescribeRegions', params,
2718
+ [('item', RegionInfo)], verb='POST')
2719
+ for region in regions:
2720
+ region.connection_cls = EC2Connection
2721
+ return regions
2722
+
2723
+ #
2724
+ # Reservation methods
2725
+ #
2726
+
2727
+ def get_all_reserved_instances_offerings(self,
2728
+ reserved_instances_offering_ids=None,
2729
+ instance_type=None,
2730
+ availability_zone=None,
2731
+ product_description=None,
2732
+ filters=None,
2733
+ instance_tenancy=None,
2734
+ offering_type=None,
2735
+ include_marketplace=None,
2736
+ min_duration=None,
2737
+ max_duration=None,
2738
+ max_instance_count=None,
2739
+ next_token=None,
2740
+ max_results=None):
2741
+ """
2742
+ Describes Reserved Instance offerings that are available for purchase.
2743
+
2744
+ :type reserved_instances_offering_ids: list
2745
+ :param reserved_instances_id: One or more Reserved Instances
2746
+ offering IDs.
2747
+
2748
+ :type instance_type: str
2749
+ :param instance_type: Displays Reserved Instances of the specified
2750
+ instance type.
2751
+
2752
+ :type availability_zone: str
2753
+ :param availability_zone: Displays Reserved Instances within the
2754
+ specified Availability Zone.
2755
+
2756
+ :type product_description: str
2757
+ :param product_description: Displays Reserved Instances with the
2758
+ specified product description.
2759
+
2760
+ :type filters: dict
2761
+ :param filters: Optional filters that can be used to limit
2762
+ the results returned. Filters are provided
2763
+ in the form of a dictionary consisting of
2764
+ filter names as the key and filter values
2765
+ as the value. The set of allowable filter
2766
+ names/values is dependent on the request
2767
+ being performed. Check the EC2 API guide
2768
+ for details.
2769
+
2770
+ :type instance_tenancy: string
2771
+ :param instance_tenancy: The tenancy of the Reserved Instance offering.
2772
+ A Reserved Instance with tenancy of dedicated will run on
2773
+ single-tenant hardware and can only be launched within a VPC.
2774
+
2775
+ :type offering_type: string
2776
+ :param offering_type: The Reserved Instance offering type. Valid
2777
+ Values: `"Heavy Utilization" | "Medium Utilization" | "Light
2778
+ Utilization"`
2779
+
2780
+ :type include_marketplace: bool
2781
+ :param include_marketplace: Include Marketplace offerings in the
2782
+ response.
2783
+
2784
+ :type min_duration: int :param min_duration: Minimum duration (in
2785
+ seconds) to filter when searching for offerings.
2786
+
2787
+ :type max_duration: int
2788
+ :param max_duration: Maximum duration (in seconds) to filter when
2789
+ searching for offerings.
2790
+
2791
+ :type max_instance_count: int
2792
+ :param max_instance_count: Maximum number of instances to filter when
2793
+ searching for offerings.
2794
+
2795
+ :type next_token: string
2796
+ :param next_token: Token to use when requesting the next paginated set
2797
+ of offerings.
2798
+
2799
+ :type max_results: int
2800
+ :param max_results: Maximum number of offerings to return per call.
2801
+
2802
+ :rtype: list
2803
+ :return: A list of
2804
+ :class:`boto.ec2.reservedinstance.ReservedInstancesOffering`.
2805
+
2806
+ """
2807
+ params = {}
2808
+ if reserved_instances_offering_ids is not None:
2809
+ self.build_list_params(params, reserved_instances_offering_ids,
2810
+ 'ReservedInstancesOfferingId')
2811
+ if instance_type:
2812
+ params['InstanceType'] = instance_type
2813
+ if availability_zone:
2814
+ params['AvailabilityZone'] = availability_zone
2815
+ if product_description:
2816
+ params['ProductDescription'] = product_description
2817
+ if filters:
2818
+ self.build_filter_params(params, filters)
2819
+ if instance_tenancy is not None:
2820
+ params['InstanceTenancy'] = instance_tenancy
2821
+ if offering_type is not None:
2822
+ params['OfferingType'] = offering_type
2823
+ if include_marketplace is not None:
2824
+ if include_marketplace:
2825
+ params['IncludeMarketplace'] = 'true'
2826
+ else:
2827
+ params['IncludeMarketplace'] = 'false'
2828
+ if min_duration is not None:
2829
+ params['MinDuration'] = str(min_duration)
2830
+ if max_duration is not None:
2831
+ params['MaxDuration'] = str(max_duration)
2832
+ if max_instance_count is not None:
2833
+ params['MaxInstanceCount'] = str(max_instance_count)
2834
+ if next_token is not None:
2835
+ params['NextToken'] = next_token
2836
+ if max_results is not None:
2837
+ params['MaxResults'] = str(max_results)
2838
+
2839
+ return self.get_list('DescribeReservedInstancesOfferings',
2840
+ params, [('item', ReservedInstancesOffering)],
2841
+ verb='POST')
2842
+
2843
+ def get_all_reserved_instances(self, reserved_instances_id=None,
2844
+ filters=None):
2845
+ """
2846
+ Describes one or more of the Reserved Instances that you purchased.
2847
+
2848
+ :type reserved_instance_ids: list
2849
+ :param reserved_instance_ids: A list of the reserved instance ids that
2850
+ will be returned. If not provided, all reserved instances
2851
+ will be returned.
2852
+
2853
+ :type filters: dict
2854
+ :param filters: Optional filters that can be used to limit the
2855
+ results returned. Filters are provided in the form of a
2856
+ dictionary consisting of filter names as the key and
2857
+ filter values as the value. The set of allowable filter
2858
+ names/values is dependent on the request being performed.
2859
+ Check the EC2 API guide for details.
2860
+
2861
+ :rtype: list
2862
+ :return: A list of :class:`boto.ec2.reservedinstance.ReservedInstance`
2863
+ """
2864
+ params = {}
2865
+ if reserved_instances_id:
2866
+ self.build_list_params(params, reserved_instances_id,
2867
+ 'ReservedInstancesId')
2868
+ if filters:
2869
+ self.build_filter_params(params, filters)
2870
+ return self.get_list('DescribeReservedInstances',
2871
+ params, [('item', ReservedInstance)], verb='POST')
2872
+
2873
+ def purchase_reserved_instance_offering(self,
2874
+ reserved_instances_offering_id,
2875
+ instance_count=1, limit_price=None):
2876
+ """
2877
+ Purchase a Reserved Instance for use with your account.
2878
+ ** CAUTION **
2879
+ This request can result in large amounts of money being charged to your
2880
+ AWS account. Use with caution!
2881
+
2882
+ :type reserved_instances_offering_id: string
2883
+ :param reserved_instances_offering_id: The offering ID of the Reserved
2884
+ Instance to purchase
2885
+
2886
+ :type instance_count: int
2887
+ :param instance_count: The number of Reserved Instances to purchase.
2888
+ Default value is 1.
2889
+
2890
+ :type limit_price: tuple
2891
+ :param instance_count: Limit the price on the total order.
2892
+ Must be a tuple of (amount, currency_code), for example:
2893
+ (100.0, 'USD').
2894
+
2895
+ :rtype: :class:`boto.ec2.reservedinstance.ReservedInstance`
2896
+ :return: The newly created Reserved Instance
2897
+ """
2898
+ params = {
2899
+ 'ReservedInstancesOfferingId': reserved_instances_offering_id,
2900
+ 'InstanceCount': instance_count}
2901
+ if limit_price is not None:
2902
+ params['LimitPrice.Amount'] = str(limit_price[0])
2903
+ params['LimitPrice.CurrencyCode'] = str(limit_price[1])
2904
+ return self.get_object('PurchaseReservedInstancesOffering', params,
2905
+ ReservedInstance, verb='POST')
2906
+
2907
+ def create_reserved_instances_listing(self, reserved_instances_id, instance_count,
2908
+ price_schedules, client_token):
2909
+ """Creates a new listing for Reserved Instances.
2910
+
2911
+ Creates a new listing for Amazon EC2 Reserved Instances that will be
2912
+ sold in the Reserved Instance Marketplace. You can submit one Reserved
2913
+ Instance listing at a time.
2914
+
2915
+ The Reserved Instance Marketplace matches sellers who want to resell
2916
+ Reserved Instance capacity that they no longer need with buyers who
2917
+ want to purchase additional capacity. Reserved Instances bought and
2918
+ sold through the Reserved Instance Marketplace work like any other
2919
+ Reserved Instances.
2920
+
2921
+ If you want to sell your Reserved Instances, you must first register as
2922
+ a Seller in the Reserved Instance Marketplace. After completing the
2923
+ registration process, you can create a Reserved Instance Marketplace
2924
+ listing of some or all of your Reserved Instances, and specify the
2925
+ upfront price you want to receive for them. Your Reserved Instance
2926
+ listings then become available for purchase.
2927
+
2928
+ :type reserved_instances_id: string
2929
+ :param reserved_instances_id: The ID of the Reserved Instance that
2930
+ will be listed.
2931
+
2932
+ :type instance_count: int
2933
+ :param instance_count: The number of instances that are a part of a
2934
+ Reserved Instance account that will be listed in the Reserved
2935
+ Instance Marketplace. This number should be less than or equal to
2936
+ the instance count associated with the Reserved Instance ID
2937
+ specified in this call.
2938
+
2939
+ :type price_schedules: List of tuples
2940
+ :param price_schedules: A list specifying the price of the Reserved
2941
+ Instance for each month remaining in the Reserved Instance term.
2942
+ Each tuple contains two elements, the price and the term. For
2943
+ example, for an instance that 11 months remaining in its term,
2944
+ we can have a price schedule with an upfront price of $2.50.
2945
+ At 8 months remaining we can drop the price down to $2.00.
2946
+ This would be expressed as::
2947
+
2948
+ price_schedules=[('2.50', 11), ('2.00', 8)]
2949
+
2950
+ :type client_token: string
2951
+ :param client_token: Unique, case-sensitive identifier you provide
2952
+ to ensure idempotency of the request. Maximum 64 ASCII characters.
2953
+
2954
+ :rtype: list
2955
+ :return: A list of
2956
+ :class:`boto.ec2.reservedinstance.ReservedInstanceListing`
2957
+
2958
+ """
2959
+ params = {
2960
+ 'ReservedInstancesId': reserved_instances_id,
2961
+ 'InstanceCount': str(instance_count),
2962
+ 'ClientToken': client_token,
2963
+ }
2964
+ for i, schedule in enumerate(price_schedules):
2965
+ price, term = schedule
2966
+ params['PriceSchedules.%s.Price' % i] = str(price)
2967
+ params['PriceSchedules.%s.Term' % i] = str(term)
2968
+ return self.get_list('CreateReservedInstancesListing',
2969
+ params, [('item', ReservedInstanceListing)], verb='POST')
2970
+
2971
+ def cancel_reserved_instances_listing(
2972
+ self, reserved_instances_listing_ids=None):
2973
+ """Cancels the specified Reserved Instance listing.
2974
+
2975
+ :type reserved_instances_listing_ids: List of strings
2976
+ :param reserved_instances_listing_ids: The ID of the
2977
+ Reserved Instance listing to be cancelled.
2978
+
2979
+ :rtype: list
2980
+ :return: A list of
2981
+ :class:`boto.ec2.reservedinstance.ReservedInstanceListing`
2982
+
2983
+ """
2984
+ params = {}
2985
+ if reserved_instances_listing_ids is not None:
2986
+ self.build_list_params(params, reserved_instances_listing_ids,
2987
+ 'ReservedInstancesListingId')
2988
+ return self.get_list('CancelReservedInstancesListing',
2989
+ params, [('item', ReservedInstanceListing)], verb='POST')
2990
+
2991
+ #
2992
+ # Monitoring
2993
+ #
2994
+
2995
+ def monitor_instances(self, instance_ids):
2996
+ """
2997
+ Enable CloudWatch monitoring for the supplied instances.
2998
+
2999
+ :type instance_id: list of strings
3000
+ :param instance_id: The instance ids
3001
+
3002
+ :rtype: list
3003
+ :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
3004
+ """
3005
+ params = {}
3006
+ self.build_list_params(params, instance_ids, 'InstanceId')
3007
+ return self.get_list('MonitorInstances', params,
3008
+ [('item', InstanceInfo)], verb='POST')
3009
+
3010
+ def monitor_instance(self, instance_id):
3011
+ """
3012
+ Deprecated Version, maintained for backward compatibility.
3013
+ Enable CloudWatch monitoring for the supplied instance.
3014
+
3015
+ :type instance_id: string
3016
+ :param instance_id: The instance id
3017
+
3018
+ :rtype: list
3019
+ :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
3020
+ """
3021
+ return self.monitor_instances([instance_id])
3022
+
3023
+ def unmonitor_instances(self, instance_ids):
3024
+ """
3025
+ Disable CloudWatch monitoring for the supplied instance.
3026
+
3027
+ :type instance_id: list of string
3028
+ :param instance_id: The instance id
3029
+
3030
+ :rtype: list
3031
+ :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
3032
+ """
3033
+ params = {}
3034
+ self.build_list_params(params, instance_ids, 'InstanceId')
3035
+ return self.get_list('UnmonitorInstances', params,
3036
+ [('item', InstanceInfo)], verb='POST')
3037
+
3038
+ def unmonitor_instance(self, instance_id):
3039
+ """
3040
+ Deprecated Version, maintained for backward compatibility.
3041
+ Disable CloudWatch monitoring for the supplied instance.
3042
+
3043
+ :type instance_id: string
3044
+ :param instance_id: The instance id
3045
+
3046
+ :rtype: list
3047
+ :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
3048
+ """
3049
+ return self.unmonitor_instances([instance_id])
3050
+
3051
+ #
3052
+ # Bundle Windows Instances
3053
+ #
3054
+
3055
+ def bundle_instance(self, instance_id,
3056
+ s3_bucket,
3057
+ s3_prefix,
3058
+ s3_upload_policy):
3059
+ """
3060
+ Bundle Windows instance.
3061
+
3062
+ :type instance_id: string
3063
+ :param instance_id: The instance id
3064
+
3065
+ :type s3_bucket: string
3066
+ :param s3_bucket: The bucket in which the AMI should be stored.
3067
+
3068
+ :type s3_prefix: string
3069
+ :param s3_prefix: The beginning of the file name for the AMI.
3070
+
3071
+ :type s3_upload_policy: string
3072
+ :param s3_upload_policy: Base64 encoded policy that specifies condition
3073
+ and permissions for Amazon EC2 to upload the
3074
+ user's image into Amazon S3.
3075
+ """
3076
+
3077
+ params = {'InstanceId': instance_id,
3078
+ 'Storage.S3.Bucket': s3_bucket,
3079
+ 'Storage.S3.Prefix': s3_prefix,
3080
+ 'Storage.S3.UploadPolicy': s3_upload_policy}
3081
+ s3auth = boto.auth.get_auth_handler(None, boto.config,
3082
+ self.provider, ['s3'])
3083
+ params['Storage.S3.AWSAccessKeyId'] = self.aws_access_key_id
3084
+ signature = s3auth.sign_string(s3_upload_policy)
3085
+ params['Storage.S3.UploadPolicySignature'] = signature
3086
+ return self.get_object('BundleInstance', params,
3087
+ BundleInstanceTask, verb='POST')
3088
+
3089
+ def get_all_bundle_tasks(self, bundle_ids=None, filters=None):
3090
+ """
3091
+ Retrieve current bundling tasks. If no bundle id is specified, all
3092
+ tasks are retrieved.
3093
+
3094
+ :type bundle_ids: list
3095
+ :param bundle_ids: A list of strings containing identifiers for
3096
+ previously created bundling tasks.
3097
+
3098
+ :type filters: dict
3099
+ :param filters: Optional filters that can be used to limit
3100
+ the results returned. Filters are provided
3101
+ in the form of a dictionary consisting of
3102
+ filter names as the key and filter values
3103
+ as the value. The set of allowable filter
3104
+ names/values is dependent on the request
3105
+ being performed. Check the EC2 API guide
3106
+ for details.
3107
+
3108
+ """
3109
+
3110
+ params = {}
3111
+ if bundle_ids:
3112
+ self.build_list_params(params, bundle_ids, 'BundleId')
3113
+ if filters:
3114
+ self.build_filter_params(params, filters)
3115
+ return self.get_list('DescribeBundleTasks', params,
3116
+ [('item', BundleInstanceTask)], verb='POST')
3117
+
3118
+ def cancel_bundle_task(self, bundle_id):
3119
+ """
3120
+ Cancel a previously submitted bundle task
3121
+
3122
+ :type bundle_id: string
3123
+ :param bundle_id: The identifier of the bundle task to cancel.
3124
+ """
3125
+
3126
+ params = {'BundleId': bundle_id}
3127
+ return self.get_object('CancelBundleTask', params,
3128
+ BundleInstanceTask, verb='POST')
3129
+
3130
+ def get_password_data(self, instance_id):
3131
+ """
3132
+ Get encrypted administrator password for a Windows instance.
3133
+
3134
+ :type instance_id: string
3135
+ :param instance_id: The identifier of the instance to retrieve the
3136
+ password for.
3137
+ """
3138
+
3139
+ params = {'InstanceId': instance_id}
3140
+ rs = self.get_object('GetPasswordData', params, ResultSet, verb='POST')
3141
+ return rs.passwordData
3142
+
3143
+ #
3144
+ # Cluster Placement Groups
3145
+ #
3146
+
3147
+ def get_all_placement_groups(self, groupnames=None, filters=None):
3148
+ """
3149
+ Get all placement groups associated with your account in a region.
3150
+
3151
+ :type groupnames: list
3152
+ :param groupnames: A list of the names of placement groups to retrieve.
3153
+ If not provided, all placement groups will be
3154
+ returned.
3155
+
3156
+ :type filters: dict
3157
+ :param filters: Optional filters that can be used to limit
3158
+ the results returned. Filters are provided
3159
+ in the form of a dictionary consisting of
3160
+ filter names as the key and filter values
3161
+ as the value. The set of allowable filter
3162
+ names/values is dependent on the request
3163
+ being performed. Check the EC2 API guide
3164
+ for details.
3165
+
3166
+ :rtype: list
3167
+ :return: A list of :class:`boto.ec2.placementgroup.PlacementGroup`
3168
+ """
3169
+ params = {}
3170
+ if groupnames:
3171
+ self.build_list_params(params, groupnames, 'GroupName')
3172
+ if filters:
3173
+ self.build_filter_params(params, filters)
3174
+ return self.get_list('DescribePlacementGroups', params,
3175
+ [('item', PlacementGroup)], verb='POST')
3176
+
3177
+ def create_placement_group(self, name, strategy='cluster'):
3178
+ """
3179
+ Create a new placement group for your account.
3180
+ This will create the placement group within the region you
3181
+ are currently connected to.
3182
+
3183
+ :type name: string
3184
+ :param name: The name of the new placement group
3185
+
3186
+ :type strategy: string
3187
+ :param strategy: The placement strategy of the new placement group.
3188
+ Currently, the only acceptable value is "cluster".
3189
+
3190
+ :rtype: bool
3191
+ :return: True if successful
3192
+ """
3193
+ params = {'GroupName':name, 'Strategy':strategy}
3194
+ group = self.get_status('CreatePlacementGroup', params, verb='POST')
3195
+ return group
3196
+
3197
+ def delete_placement_group(self, name):
3198
+ """
3199
+ Delete a placement group from your account.
3200
+
3201
+ :type key_name: string
3202
+ :param key_name: The name of the keypair to delete
3203
+ """
3204
+ params = {'GroupName':name}
3205
+ return self.get_status('DeletePlacementGroup', params, verb='POST')
3206
+
3207
+ # Tag methods
3208
+
3209
+ def build_tag_param_list(self, params, tags):
3210
+ keys = sorted(tags.keys())
3211
+ i = 1
3212
+ for key in keys:
3213
+ value = tags[key]
3214
+ params['Tag.%d.Key'%i] = key
3215
+ if value is not None:
3216
+ params['Tag.%d.Value'%i] = value
3217
+ i += 1
3218
+
3219
+ def get_all_tags(self, filters=None):
3220
+ """
3221
+ Retrieve all the metadata tags associated with your account.
3222
+
3223
+ :type filters: dict
3224
+ :param filters: Optional filters that can be used to limit
3225
+ the results returned. Filters are provided
3226
+ in the form of a dictionary consisting of
3227
+ filter names as the key and filter values
3228
+ as the value. The set of allowable filter
3229
+ names/values is dependent on the request
3230
+ being performed. Check the EC2 API guide
3231
+ for details.
3232
+
3233
+ :rtype: dict
3234
+ :return: A dictionary containing metadata tags
3235
+ """
3236
+ params = {}
3237
+ if filters:
3238
+ self.build_filter_params(params, filters)
3239
+ return self.get_list('DescribeTags', params,
3240
+ [('item', Tag)], verb='POST')
3241
+
3242
+ def create_tags(self, resource_ids, tags):
3243
+ """
3244
+ Create new metadata tags for the specified resource ids.
3245
+
3246
+ :type resource_ids: list
3247
+ :param resource_ids: List of strings
3248
+
3249
+ :type tags: dict
3250
+ :param tags: A dictionary containing the name/value pairs.
3251
+ If you want to create only a tag name, the
3252
+ value for that tag should be the empty string
3253
+ (e.g. '').
3254
+
3255
+ """
3256
+ params = {}
3257
+ self.build_list_params(params, resource_ids, 'ResourceId')
3258
+ self.build_tag_param_list(params, tags)
3259
+ return self.get_status('CreateTags', params, verb='POST')
3260
+
3261
+ def delete_tags(self, resource_ids, tags):
3262
+ """
3263
+ Delete metadata tags for the specified resource ids.
3264
+
3265
+ :type resource_ids: list
3266
+ :param resource_ids: List of strings
3267
+
3268
+ :type tags: dict or list
3269
+ :param tags: Either a dictionary containing name/value pairs
3270
+ or a list containing just tag names.
3271
+ If you pass in a dictionary, the values must
3272
+ match the actual tag values or the tag will
3273
+ not be deleted. If you pass in a value of None
3274
+ for the tag value, all tags with that name will
3275
+ be deleted.
3276
+
3277
+ """
3278
+ if isinstance(tags, list):
3279
+ tags = {}.fromkeys(tags, None)
3280
+ params = {}
3281
+ self.build_list_params(params, resource_ids, 'ResourceId')
3282
+ self.build_tag_param_list(params, tags)
3283
+ return self.get_status('DeleteTags', params, verb='POST')
3284
+
3285
+ # Network Interface methods
3286
+
3287
+ def get_all_network_interfaces(self, filters=None):
3288
+ """
3289
+ Retrieve all of the Elastic Network Interfaces (ENI's)
3290
+ associated with your account.
3291
+
3292
+ :type filters: dict
3293
+ :param filters: Optional filters that can be used to limit
3294
+ the results returned. Filters are provided
3295
+ in the form of a dictionary consisting of
3296
+ filter names as the key and filter values
3297
+ as the value. The set of allowable filter
3298
+ names/values is dependent on the request
3299
+ being performed. Check the EC2 API guide
3300
+ for details.
3301
+
3302
+ :rtype: list
3303
+ :return: A list of :class:`boto.ec2.networkinterface.NetworkInterface`
3304
+ """
3305
+ params = {}
3306
+ if filters:
3307
+ self.build_filter_params(params, filters)
3308
+ return self.get_list('DescribeNetworkInterfaces', params,
3309
+ [('item', NetworkInterface)], verb='POST')
3310
+
3311
+ def create_network_interface(self, subnet_id, private_ip_address=None,
3312
+ description=None, groups=None):
3313
+ """
3314
+ Creates a network interface in the specified subnet.
3315
+
3316
+ :type subnet_id: str
3317
+ :param subnet_id: The ID of the subnet to associate with the
3318
+ network interface.
3319
+
3320
+ :type private_ip_address: str
3321
+ :param private_ip_address: The private IP address of the
3322
+ network interface. If not supplied, one will be chosen
3323
+ for you.
3324
+
3325
+ :type description: str
3326
+ :param description: The description of the network interface.
3327
+
3328
+ :type groups: list
3329
+ :param groups: Lists the groups for use by the network interface.
3330
+ This can be either a list of group ID's or a list of
3331
+ :class:`boto.ec2.securitygroup.SecurityGroup` objects.
3332
+
3333
+ :rtype: :class:`boto.ec2.networkinterface.NetworkInterface`
3334
+ :return: The newly created network interface.
3335
+ """
3336
+ params = {'SubnetId': subnet_id}
3337
+ if private_ip_address:
3338
+ params['PrivateIpAddress'] = private_ip_address
3339
+ if description:
3340
+ params['Description'] = description
3341
+ if groups:
3342
+ ids = []
3343
+ for group in groups:
3344
+ if isinstance(group, SecurityGroup):
3345
+ ids.append(group.id)
3346
+ else:
3347
+ ids.append(group)
3348
+ self.build_list_params(params, ids, 'SecurityGroupId')
3349
+ return self.get_object('CreateNetworkInterface', params,
3350
+ NetworkInterface, verb='POST')
3351
+
3352
+ def attach_network_interface(self, network_interface_id,
3353
+ instance_id, device_index):
3354
+ """
3355
+ Attaches a network interface to an instance.
3356
+
3357
+ :type network_interface_id: str
3358
+ :param network_interface_id: The ID of the network interface to attach.
3359
+
3360
+ :type instance_id: str
3361
+ :param instance_id: The ID of the instance that will be attached
3362
+ to the network interface.
3363
+
3364
+ :type device_index: int
3365
+ :param device_index: The index of the device for the network
3366
+ interface attachment on the instance.
3367
+ """
3368
+ params = {'NetworkInterfaceId': network_interface_id,
3369
+ 'InstanceId': instance_id,
3370
+ 'DeviceIndex': device_index}
3371
+ return self.get_status('AttachNetworkInterface', params, verb='POST')
3372
+
3373
+ def detach_network_interface(self, attachement_id, force=False):
3374
+ """
3375
+ Detaches a network interface from an instance.
3376
+
3377
+ :type attachment_id: str
3378
+ :param attachment_id: The ID of the attachment.
3379
+
3380
+ :type force: bool
3381
+ :param force: Set to true to force a detachment.
3382
+
3383
+ """
3384
+ params = {'AttachmentId': network_interface_id}
3385
+ if force:
3386
+ params['Force'] = 'true'
3387
+ return self.get_status('DetachNetworkInterface', params, verb='POST')
3388
+
3389
+ def delete_network_interface(self, network_interface_id):
3390
+ """
3391
+ Delete the specified network interface.
3392
+
3393
+ :type network_interface_id: str
3394
+ :param network_interface_id: The ID of the network interface to delete.
3395
+
3396
+ """
3397
+ params = {'NetworkInterfaceId': network_interface_id}
3398
+ return self.get_status('DeleteNetworkInterface', params, verb='POST')
3399
+
3400
+ def get_all_vmtypes(self):
3401
+ """
3402
+ Get all vmtypes available on this cloud (eucalyptus specific)
3403
+
3404
+ :rtype: list of :class:`boto.ec2.vmtype.VmType`
3405
+ :return: The requested VmType objects
3406
+ """
3407
+ params = {}
3408
+ return self.get_list('DescribeVmTypes', params, [('euca:item', VmType)], verb='POST')
3409
+