// UnmarshalError unmarshals an error response for a JSON RPC service. func UnmarshalError(req *request.Request) { defer req.HTTPResponse.Body.Close() bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body) if err != nil { req.Error = awserr.New("SerializationError", "failed reading JSON RPC error response", err) return } if len(bodyBytes) == 0 { req.Error = awserr.NewRequestFailure( awserr.New("SerializationError", req.HTTPResponse.Status, nil), req.HTTPResponse.StatusCode, "", ) return } var jsonErr jsonErrorResponse if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { req.Error = awserr.New("SerializationError", "failed decoding JSON RPC error response", err) return } codes := strings.SplitN(jsonErr.Code, "#", 2) req.Error = awserr.NewRequestFailure( awserr.New(codes[len(codes)-1], jsonErr.Message, nil), req.HTTPResponse.StatusCode, req.RequestID, ) }
func buildQueryString(query url.Values, v reflect.Value, name string) error { switch value := v.Interface().(type) { case []*string: for _, item := range value { query.Add(name, *item) } case map[string]*string: for key, item := range value { query.Add(key, *item) } case map[string][]*string: for key, items := range value { for _, item := range items { query.Add(key, *item) } } default: str, err := convertType(v) if err == errValueNotSet { return nil } else if err != nil { return awserr.New("SerializationError", "failed to encode REST request", err) } query.Set(name, str) } return nil }
// Build builds a JSON payload for a JSON RPC request. func Build(req *request.Request) { var buf []byte var err error if req.ParamsFilled() { buf, err = jsonutil.BuildJSON(req.Params) if err != nil { req.Error = awserr.New("SerializationError", "failed encoding JSON RPC request", err) return } } else { buf = emptyJSON } if req.ClientInfo.TargetPrefix != "" || string(buf) != "{}" { req.SetBufferBody(buf) } if req.ClientInfo.TargetPrefix != "" { target := req.ClientInfo.TargetPrefix + "." + req.Operation.Name req.HTTPRequest.Header.Add("X-Amz-Target", target) } if req.ClientInfo.JSONVersion != "" { jsonVersion := req.ClientInfo.JSONVersion req.HTTPRequest.Header.Add("Content-Type", "application/x-amz-json-"+jsonVersion) } }
// requestCredList requests a list of credentials from the EC2 service. // If there are no credentials, or there is an error making or receiving the request func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) { resp, err := client.GetMetadata(iamSecurityCredsPath) if err != nil { return nil, awserr.New("EC2RoleRequestError", "failed to list EC2 Roles", err) } credsList := []string{} s := bufio.NewScanner(strings.NewReader(resp)) for s.Scan() { credsList = append(credsList, s.Text()) } if err := s.Err(); err != nil { return nil, awserr.New("SerializationError", "failed to read list of EC2 Roles", err) } return credsList, nil }
func unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() _, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err) } // TODO extract the error... }
func unmarshalHandler(r *request.Request) { defer r.HTTPResponse.Body.Close() b, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err) } data := r.Data.(*metadataOutput) data.Content = string(b) }
// Unmarshal unmarshals a response for a JSON RPC service. func Unmarshal(req *request.Request) { defer req.HTTPResponse.Body.Close() if req.DataFilled() { err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body) if err != nil { req.Error = awserr.New("SerializationError", "failed decoding JSON RPC response", err) } } return }
func buildHeader(header *http.Header, v reflect.Value, name string) error { str, err := convertType(v) if err == errValueNotSet { return nil } else if err != nil { return awserr.New("SerializationError", "failed to encode REST request", err) } header.Add(name, str) return nil }
func unmarshalBody(r *request.Request, v reflect.Value) { if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok { if payloadName := field.Tag.Get("payload"); payloadName != "" { pfield, _ := v.Type().FieldByName(payloadName) if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { payload := v.FieldByName(payloadName) if payload.IsValid() { switch payload.Interface().(type) { case []byte: b, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "failed to decode REST response", err) } else { payload.Set(reflect.ValueOf(b)) } case *string: b, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "failed to decode REST response", err) } else { str := string(b) payload.Set(reflect.ValueOf(&str)) } default: switch payload.Type().String() { case "io.ReadSeeker": payload.Set(reflect.ValueOf(aws.ReadSeekCloser(r.HTTPResponse.Body))) case "aws.ReadSeekCloser", "io.ReadCloser": payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) default: r.Error = awserr.New("SerializationError", "failed to decode REST response", fmt.Errorf("unknown payload type %s", payload.Type())) } } } } } } }
func buildHeaderMap(header *http.Header, v reflect.Value, prefix string) error { for _, key := range v.MapKeys() { str, err := convertType(v.MapIndex(key)) if err == errValueNotSet { continue } else if err != nil { return awserr.New("SerializationError", "failed to encode REST request", err) } header.Add(prefix+key.String(), str) } return nil }
func buildURI(u *url.URL, v reflect.Value, name string) error { value, err := convertType(v) if err == errValueNotSet { return nil } else if err != nil { return awserr.New("SerializationError", "failed to encode REST request", err) } uri := u.Path uri = strings.Replace(uri, "{"+name+"}", EscapePath(value, true), -1) uri = strings.Replace(uri, "{"+name+"+}", EscapePath(value, false), -1) u.Path = uri return nil }
// requestCred requests the credentials for a specific credentials from the EC2 service. // // If the credentials cannot be found, or there is an error reading the response // and error will be returned. func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) { resp, err := client.GetMetadata(path.Join(iamSecurityCredsPath, credsName)) if err != nil { return ec2RoleCredRespBody{}, awserr.New("EC2RoleRequestError", fmt.Sprintf("failed to get %s EC2 Role credentials", credsName), err) } respCreds := ec2RoleCredRespBody{} if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil { return ec2RoleCredRespBody{}, awserr.New("SerializationError", fmt.Sprintf("failed to decode %s EC2 Role credentials", credsName), err) } if respCreds.Code != "Success" { // If an error code was returned something failed requesting the role. return ec2RoleCredRespBody{}, awserr.New(respCreds.Code, respCreds.Message, nil) } return respCreds, nil }
func unmarshalLocationElements(r *request.Request, v reflect.Value) { for i := 0; i < v.NumField(); i++ { m, field := v.Field(i), v.Type().Field(i) if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) { continue } if m.IsValid() { name := field.Tag.Get("locationName") if name == "" { name = field.Name } switch field.Tag.Get("location") { case "statusCode": unmarshalStatusCode(m, r.HTTPResponse.StatusCode) case "header": err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name)) if err != nil { r.Error = awserr.New("SerializationError", "failed to decode REST response", err) break } case "headers": prefix := field.Tag.Get("locationName") err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix) if err != nil { r.Error = awserr.New("SerializationError", "failed to decode REST response", err) break } } } if r.Error != nil { return } } }
// Retrieve retrieves credentials from the EC2 service. // Error will be returned if the request fails, or unable to extract // the desired credentials. func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) { credsList, err := requestCredList(m.Client) if err != nil { return credentials.Value{}, err } if len(credsList) == 0 { return credentials.Value{}, awserr.New("EmptyEC2RoleList", "empty EC2 Role list", nil) } credsName := credsList[0] roleCreds, err := requestCred(m.Client, credsName) if err != nil { return credentials.Value{}, err } m.SetExpiration(roleCreds.Expiration, m.ExpiryWindow) return credentials.Value{ AccessKeyID: roleCreds.AccessKeyID, SecretAccessKey: roleCreds.SecretAccessKey, SessionToken: roleCreds.Token, }, nil }
func buildBody(r *request.Request, v reflect.Value) { if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok { if payloadName := field.Tag.Get("payload"); payloadName != "" { pfield, _ := v.Type().FieldByName(payloadName) if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { payload := reflect.Indirect(v.FieldByName(payloadName)) if payload.IsValid() && payload.Interface() != nil { switch reader := payload.Interface().(type) { case io.ReadSeeker: r.SetReaderBody(reader) case []byte: r.SetBufferBody(reader) case string: r.SetStringBody(reader) default: r.Error = awserr.New("SerializationError", "failed to encode REST request", fmt.Errorf("unknown payload type %s", payload.Type())) } } } } } }
Body: ioutil.NopCloser(bytes.NewReader([]byte{})), } return } } if r.HTTPResponse == nil { // Add a dummy request response object to ensure the HTTPResponse // value is consistent. r.HTTPResponse = &http.Response{ StatusCode: int(0), Status: http.StatusText(int(0)), Body: ioutil.NopCloser(bytes.NewReader([]byte{})), } } // Catch all other request errors. r.Error = awserr.New("RequestError", "send request failed", err) r.Retryable = aws.Bool(true) // network errors are retryable } }} // ValidateResponseHandler is a request handler to validate service response. var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) { if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 { // this may be replaced by an UnmarshalError handler r.Error = awserr.New("UnknownError", "unknown error", nil) } }} // AfterRetryHandler performs final checks to determine if the request should // be retried and how long to delay. var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) {
package credentials import ( "github.com/paybyphone/kintail/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr" ) var ( // ErrNoValidProvidersFoundInChain Is returned when there are no valid // providers in the ChainProvider. // // @readonly ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders", "no valid providers in chain", nil) ) // A ChainProvider will search for a provider which returns credentials // and cache that provider until Retrieve is called again. // // The ChainProvider provides a way of chaining multiple providers together // which will pick the first available using priority order of the Providers // in the list. // // If none of the Providers retrieve valid credentials Value, ChainProvider's // Retrieve() will return the error ErrNoValidProvidersFoundInChain. // // If a Provider is found which returns valid credentials Value ChainProvider // will cache that Provider for all calls to IsExpired(), until Retrieve is // called again. // // Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider. // In this example EnvProvider will first check if any credentials are available // vai the environment variables. If there are none ChainProvider will check
"github.com/paybyphone/kintail/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr" "github.com/paybyphone/kintail/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/request" ) // ValidateParametersHandler is a request handler to validate the input parameters. // Validating parameters only has meaning if done prior to the request being sent. var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) { if r.ParamsFilled() { v := validator{errors: []string{}} v.validateAny(reflect.ValueOf(r.Params), "") if count := len(v.errors); count > 0 { format := "%d validation errors:\n- %s" msg := fmt.Sprintf(format, count, strings.Join(v.errors, "\n- ")) r.Error = awserr.New("InvalidParameter", msg, nil) } } }} // A validator validates values. Collects validations errors which occurs. type validator struct { errors []string } // validateAny will validate any struct, slice or map type. All validations // are also performed recursively for nested types. func (v *validator) validateAny(value reflect.Value, path string) { value = reflect.Indirect(value) if !value.IsValid() { return
package credentials import ( "os" "github.com/paybyphone/kintail/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr" ) var ( // ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be // found in the process's environment. // // @readonly ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil) // ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key // can't be found in the process's environment. // // @readonly ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil) ) // A EnvProvider retrieves credentials from the environment variables of the // running process. Environment credentials never expire. // // Environment variables used: // // * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY // * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY type EnvProvider struct { retrieved bool
package aws import "github.com/paybyphone/kintail/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr" var ( // ErrMissingRegion is an error that is returned if region configuration is // not found. // // @readonly ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil) // ErrMissingEndpoint is an error that is returned if an endpoint cannot be // resolved for a service. // // @readonly ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil) )
package credentials import ( "github.com/paybyphone/kintail/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws/awserr" ) var ( // ErrStaticCredentialsEmpty is emitted when static credentials are empty. // // @readonly ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil) ) // A StaticProvider is a set of credentials which are set pragmatically, // and will never expire. type StaticProvider struct { Value } // NewStaticCredentials returns a pointer to a new Credentials object // wrapping a static credentials value provider. func NewStaticCredentials(id, secret, token string) *Credentials { return NewCredentials(&StaticProvider{Value: Value{ AccessKeyID: id, SecretAccessKey: secret, SessionToken: token, }}) } // Retrieve returns the credentials or error if the credentials are invalid. func (s *StaticProvider) Retrieve() (Value, error) {
// Wait waits for an operation to complete, expire max attempts, or fail. Error // is returned if the operation fails. func (w *Waiter) Wait() error { client := reflect.ValueOf(w.Client) in := reflect.ValueOf(w.Input) method := client.MethodByName(w.Config.Operation + "Request") for i := 0; i < w.MaxAttempts; i++ { res := method.Call([]reflect.Value{in}) req := res[0].Interface().(*request.Request) req.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Waiter")) err := req.Send() for _, a := range w.Acceptors { if err != nil && a.Matcher != "error" { // Only matcher error is valid if there is a request error continue } result := false var vals []interface{} switch a.Matcher { case "pathAll", "path": // Require all matches to be equal for result to match vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) result = true for _, val := range vals { if !awsutil.DeepEqual(val, a.Expected) { result = false break } } case "pathAny": // Only a single match needs to equal for the result to match vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) for _, val := range vals { if awsutil.DeepEqual(val, a.Expected) { result = true break } } case "status": s := a.Expected.(int) result = s == req.HTTPResponse.StatusCode case "error": if aerr, ok := err.(awserr.Error); ok { result = aerr.Code() == a.Expected.(string) } case "pathList": // ignored matcher default: logf(client, "WARNING: Waiter for %s encountered unexpected matcher: %s", w.Config.Operation, a.Matcher) } if !result { // If there was no matching result found there is nothing more to do // for this response, retry the request. continue } switch a.State { case "success": // waiter completed return nil case "failure": // Waiter failure state triggered return awserr.New("ResourceNotReady", fmt.Sprintf("failed waiting for successful resource state"), err) case "retry": // clear the error and retry the operation err = nil default: logf(client, "WARNING: Waiter for %s encountered unexpected state: %s", w.Config.Operation, a.State) } } if err != nil { return err } time.Sleep(time.Second * time.Duration(w.Delay)) } return awserr.New("ResourceNotReady", fmt.Sprintf("exceeded %d wait attempts", w.MaxAttempts), nil) }