api_op_GetIAMInfo.go raw

   1  package imds
   2  
   3  import (
   4  	"context"
   5  	"encoding/json"
   6  	"fmt"
   7  	"io"
   8  	"strings"
   9  	"time"
  10  
  11  	"github.com/aws/smithy-go"
  12  	smithyio "github.com/aws/smithy-go/io"
  13  	"github.com/aws/smithy-go/middleware"
  14  	smithyhttp "github.com/aws/smithy-go/transport/http"
  15  )
  16  
  17  const getIAMInfoPath = getMetadataPath + "/iam/info"
  18  
  19  // GetIAMInfo retrieves an identity document describing an
  20  // instance. Error is returned if the request fails or is unable to parse
  21  // the response.
  22  func (c *Client) GetIAMInfo(
  23  	ctx context.Context, params *GetIAMInfoInput, optFns ...func(*Options),
  24  ) (
  25  	*GetIAMInfoOutput, error,
  26  ) {
  27  	if params == nil {
  28  		params = &GetIAMInfoInput{}
  29  	}
  30  
  31  	result, metadata, err := c.invokeOperation(ctx, "GetIAMInfo", params, optFns,
  32  		addGetIAMInfoMiddleware,
  33  	)
  34  	if err != nil {
  35  		return nil, err
  36  	}
  37  
  38  	out := result.(*GetIAMInfoOutput)
  39  	out.ResultMetadata = metadata
  40  	return out, nil
  41  }
  42  
  43  // GetIAMInfoInput provides the input parameters for GetIAMInfo operation.
  44  type GetIAMInfoInput struct{}
  45  
  46  // GetIAMInfoOutput provides the output parameters for GetIAMInfo operation.
  47  type GetIAMInfoOutput struct {
  48  	IAMInfo
  49  
  50  	ResultMetadata middleware.Metadata
  51  }
  52  
  53  func addGetIAMInfoMiddleware(stack *middleware.Stack, options Options) error {
  54  	return addAPIRequestMiddleware(stack,
  55  		options,
  56  		"GetIAMInfo",
  57  		buildGetIAMInfoPath,
  58  		buildGetIAMInfoOutput,
  59  	)
  60  }
  61  
  62  func buildGetIAMInfoPath(params interface{}) (string, error) {
  63  	return getIAMInfoPath, nil
  64  }
  65  
  66  func buildGetIAMInfoOutput(resp *smithyhttp.Response) (v interface{}, err error) {
  67  	defer func() {
  68  		closeErr := resp.Body.Close()
  69  		if err == nil {
  70  			err = closeErr
  71  		} else if closeErr != nil {
  72  			err = fmt.Errorf("response body close error: %v, original error: %w", closeErr, err)
  73  		}
  74  	}()
  75  
  76  	var buff [1024]byte
  77  	ringBuffer := smithyio.NewRingBuffer(buff[:])
  78  	body := io.TeeReader(resp.Body, ringBuffer)
  79  
  80  	imdsResult := &GetIAMInfoOutput{}
  81  	if err = json.NewDecoder(body).Decode(&imdsResult.IAMInfo); err != nil {
  82  		return nil, &smithy.DeserializationError{
  83  			Err:      fmt.Errorf("failed to decode instance identity document, %w", err),
  84  			Snapshot: ringBuffer.Bytes(),
  85  		}
  86  	}
  87  	// Any code other success is an error
  88  	if !strings.EqualFold(imdsResult.Code, "success") {
  89  		return nil, fmt.Errorf("failed to get EC2 IMDS IAM info, %s",
  90  			imdsResult.Code)
  91  	}
  92  
  93  	return imdsResult, nil
  94  }
  95  
  96  // IAMInfo provides the shape for unmarshaling an IAM info from the metadata
  97  // API.
  98  type IAMInfo struct {
  99  	Code               string
 100  	LastUpdated        time.Time
 101  	InstanceProfileArn string
 102  	InstanceProfileID  string
 103  }
 104