diff --git a/ec2/ec2.go b/ec2/ec2.go index 8fc381ec..4211aad1 100644 --- a/ec2/ec2.go +++ b/ec2/ec2.go @@ -156,6 +156,7 @@ func (ec2 *EC2) query(params map[string]string, resp interface{}) error { if r.StatusCode != 200 { return buildError(r) } + err = xml.NewDecoder(r.Body).Decode(resp) return err } @@ -906,6 +907,37 @@ func (ec2 *EC2) Instances(instIds []string, filter *Filter) (resp *InstancesResp return } +// Response to a GetPasswordData request. +// +// If PasswordData is empty, then one of two conditions is likely: either the +// instance is not running Windows, or the password is not yet available. The +// API documentation suggests that the password should be available within 15 +// minutes of launch. +// +// See http://goo.gl/7Dppx0 for more details. +type PasswordDataResponse struct { + RequestId string `xml:"requestId"` + InstanceId string `xml:"instanceId"` + Timestamp time.Time `xml:"timestamp"` + PasswordData string `xml:"passwordData"` +} + +// GetPasswordData retrieves the encrypted administrator password for an +// instance running Windows. The password is encrypted using the key pair, +// so must be decrypted with the corresponding key pair file. +// +// See http://goo.gl/7Dppx0 for more details. +func (ec2 *EC2) GetPasswordData(instId string) (resp *PasswordDataResponse, err error) { + params := makeParams("GetPasswordData") + addParamsList(params, "InstanceId", []string{instId}) + resp = &PasswordDataResponse{} + ec2.query(params, resp) + if err != nil { + return nil, err + } + return +} + // ---------------------------------------------------------------------------- // Volume management diff --git a/ec2/ec2_test.go b/ec2/ec2_test.go index aac13ae4..a282f054 100644 --- a/ec2/ec2_test.go +++ b/ec2/ec2_test.go @@ -2,6 +2,7 @@ package ec2_test import ( "testing" + "time" "github.com/mitchellh/goamz/aws" "github.com/mitchellh/goamz/ec2" @@ -124,6 +125,22 @@ func (s *S) TestRequestSpotInstancesErrorWithoutXML(c *C) { c.Assert(ec2err.RequestId, Equals, "") } +func (s *S) TestGetPasswordDataExample(c *C) { + testServer.Response(200, nil, GetPasswordDataResponseExample) + + resp, err := s.ec2.GetPasswordData("i-2574e22a") + + req := testServer.WaitRequest() + + c.Assert(req.Form["InstanceId.1"], DeepEquals, []string{"i-2574e22a"}) + + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") + c.Assert(resp.InstanceId, Equals, "i-2574e22a") + c.Assert(resp.Timestamp, Equals, time.Date(2009, 10, 24, 15, 0, 0, 0, time.UTC)) + c.Assert(resp.PasswordData, Equals, "TGludXggdmVyc2lvbiAyLjYuMTYteGVuVSAoYnVpbGRlckBwYXRjaGJhdC5hbWF6b25zYSkgKGdj") +} + func (s *S) TestRunInstancesExample(c *C) { testServer.Response(200, nil, RunInstancesExample) diff --git a/ec2/responses_test.go b/ec2/responses_test.go index 66046eeb..f2f135ee 100644 --- a/ec2/responses_test.go +++ b/ec2/responses_test.go @@ -1261,3 +1261,11 @@ var DeleteCustomerGatewayResponseExample = ` 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE true ` + +var GetPasswordDataResponseExample = ` + + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + i-2574e22a + 2009-10-24T15:00:00.000Z + TGludXggdmVyc2lvbiAyLjYuMTYteGVuVSAoYnVpbGRlckBwYXRjaGJhdC5hbWF6b25zYSkgKGdj +`