// InvokeAsync submits an invocation request to AWS Lambda. Upon receiving // the request, Lambda executes the specified function asynchronously. To // see the logs generated by the Lambda function execution, see the // CloudWatch logs console. This operation requires permission for the // lambda:InvokeAsync action. func (c *Lambda) InvokeAsync(req *InvokeAsyncRequest) (resp *InvokeAsyncResponse, err error) { resp = &InvokeAsyncResponse{} var body io.Reader var contentType string contentType = "application/json" b, err := json.Marshal(req.InvokeArgs) if err != nil { return } body = bytes.NewReader(b) uri := c.client.Endpoint + "/2014-11-13/functions/{FunctionName}/invoke-async/" if req.FunctionName != nil { uri = strings.Replace(uri, "{"+"FunctionName"+"}", aws.EscapePath(*req.FunctionName), -1) uri = strings.Replace(uri, "{"+"FunctionName+"+"}", aws.EscapePath(*req.FunctionName), -1) } q := url.Values{} if len(q) > 0 { uri += "?" + q.Encode() } httpReq, err := http.NewRequest("POST", uri, body) if err != nil { return } if contentType != "" { httpReq.Header.Set("Content-Type", contentType) } httpResp, err := c.client.Do(httpReq) if err != nil { return } defer httpResp.Body.Close() if e := json.NewDecoder(httpResp.Body).Decode(resp); e != nil && e != io.EOF { err = e return } resp.Status = aws.Integer(httpResp.StatusCode) return }
func TestMarshalingXML(t *testing.T) { r := &XMLRequest{ Integer: aws.Integer(0), DangerZone: "a zone of danger", } out, err := xml.Marshal(r) if err != nil { t.Fatal(err) } if v, want := string(out), `<Request xmlns="http://whatever"><Integer>0</Integer></Request>`; v != want { t.Errorf("XML was \n%s\n but expected \n%s", v, want) } }
func TestQueryRequest(t *testing.T) { var m sync.Mutex var httpReq *http.Request var form url.Values server := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { m.Lock() defer m.Unlock() httpReq = r if err := r.ParseForm(); err != nil { t.Fatal(err) } form = r.Form fmt.Fprintln(w, `<Thing><IpAddress>woo</IpAddress></Thing>`) }, )) defer server.Close() client := aws.QueryClient{ Context: aws.Context{ Service: "animals", Region: "us-west-2", Credentials: aws.Creds( "accessKeyID", "secretAccessKey", "securityToken", ), }, Client: http.DefaultClient, Endpoint: server.URL, APIVersion: "1.1", } req := fakeQueryRequest{ PresentString: aws.String("string"), PresentBoolean: aws.True(), PresentInteger: aws.Integer(1), PresentLong: aws.Long(2), PresentDouble: aws.Double(1.2), PresentFloat: aws.Float(2.3), PresentTime: time.Date(2001, 1, 1, 2, 1, 1, 0, time.FixedZone("UTC+1", 3600)), PresentSlice: []string{"one", "two"}, PresentStruct: &EmbeddedStruct{Value: aws.String("v")}, PresentStructSlice: []EmbeddedStruct{ {Value: aws.String("p")}, {Value: aws.String("q")}, }, PresentMap: map[string]EmbeddedStruct{ "aa": EmbeddedStruct{Value: aws.String("AA")}, "bb": EmbeddedStruct{Value: aws.String("BB")}, }, } var resp fakeQueryResponse if err := client.Do("GetIP", "POST", "/", &req, &resp); err != nil { t.Fatal(err) } m.Lock() defer m.Unlock() if v, want := httpReq.Method, "POST"; v != want { t.Errorf("Method was %v but expected %v", v, want) } if httpReq.Header.Get("Authorization") == "" { t.Error("Authorization header is missing") } if v, want := httpReq.Header.Get("Content-Type"), "application/x-www-form-urlencoded"; v != want { t.Errorf("Content-Type was %v but expected %v", v, want) } if v, want := httpReq.Header.Get("User-Agent"), "aws-go"; v != want { t.Errorf("User-Agent was %v but expected %v", v, want) } if err := httpReq.ParseForm(); err != nil { t.Fatal(err) } expectedForm := url.Values{ "Action": []string{"GetIP"}, "Version": []string{"1.1"}, "PresentString": []string{"string"}, "PresentBoolean": []string{"true"}, "PresentInteger": []string{"1"}, "PresentLong": []string{"2"}, "PresentDouble": []string{"1.2"}, "PresentFloat": []string{"2.3"}, "PresentTime": []string{"2001-01-01T01:01:01Z"}, "PresentSlice.1": []string{"one"}, "PresentSlice.2": []string{"two"}, "PresentStruct.Value": []string{"v"}, "PresentStructSlice.1.Value": []string{"p"}, "PresentStructSlice.2.Value": []string{"q"}, "PresentMap.1.Name": []string{"aa"}, "PresentMap.1.Value.Value": []string{"AA"}, "PresentMap.2.Name": []string{"bb"}, "PresentMap.2.Value.Value": []string{"BB"}, } if !reflect.DeepEqual(form, expectedForm) { t.Errorf("Post body was \n%s\n but expected \n%s", form.Encode(), expectedForm.Encode()) } if want := (fakeQueryResponse{IPAddress: "woo"}); want != resp { t.Errorf("Response was %#v, but expected %#v", resp, want) } }
func (c *AWSCluster) createStack() error { c.base.SendLog("Generating start script") startScript, discoveryToken, err := c.base.genStartScript(c.base.NumInstances, "/dev/xvdb") if err != nil { return err } c.base.DiscoveryToken = discoveryToken if err := c.base.saveField("DiscoveryToken", discoveryToken); err != nil { return err } var stackTemplateBuffer bytes.Buffer err = stackTemplate.Execute(&stackTemplateBuffer, &stackTemplateData{ Instances: make([]struct{}, c.base.NumInstances), DefaultInstanceType: DefaultInstanceType, }) if err != nil { return err } stackTemplateString := stackTemplateBuffer.String() parameters := []cloudformation.Parameter{ { ParameterKey: aws.String("ImageId"), ParameterValue: aws.String(c.ImageID), }, { ParameterKey: aws.String("ClusterDomain"), ParameterValue: aws.String(c.base.Domain.Name), }, { ParameterKey: aws.String("KeyName"), ParameterValue: aws.String(c.base.SSHKeyName), }, { ParameterKey: aws.String("UserData"), ParameterValue: aws.String(startScript), }, { ParameterKey: aws.String("InstanceType"), ParameterValue: aws.String(c.InstanceType), }, { ParameterKey: aws.String("VpcCidrBlock"), ParameterValue: aws.String(c.VpcCIDR), }, { ParameterKey: aws.String("SubnetCidrBlock"), ParameterValue: aws.String(c.SubnetCIDR), }, } stackEventsSince := time.Now() if c.StackID != "" && c.StackName != "" { if err := c.fetchStack(); err == nil && !strings.HasPrefix(*c.stack.StackStatus, "DELETE") { if c.base.YesNoPrompt(fmt.Sprintf("Stack found from previous installation (%s), would you like to delete it? (a new one will be created either way)", c.StackName)) { c.base.SendLog(fmt.Sprintf("Deleting stack %s", c.StackName)) if err := c.wrapRequest(func() error { return c.cf.DeleteStack(&cloudformation.DeleteStackInput{ StackName: aws.String(c.StackName), }) }); err != nil { c.base.SendLog(fmt.Sprintf("Unable to delete stack %s: %s", c.StackName, err)) } } } } c.base.SendLog("Creating stack") var res *cloudformation.CreateStackResult err = c.wrapRequest(func() error { var err error res, err = c.cf.CreateStack(&cloudformation.CreateStackInput{ OnFailure: aws.String("DELETE"), StackName: aws.String(c.StackName), Tags: []cloudformation.Tag{}, TemplateBody: aws.String(stackTemplateString), TimeoutInMinutes: aws.Integer(30), Parameters: parameters, }) return err }) if err != nil { return err } c.StackID = *res.StackID if err := c.saveField("StackID", c.StackID); err != nil { return err } return c.waitForStackCompletion("CREATE", stackEventsSince) }