func getEc2InstanceMetadata()

in agent/envoy_bootstrap/platforminfo/platform_info_collector.go [299:351]


func getEc2InstanceMetadata(query string) (string, error) {
	httpClient := client.CreateDefaultHttpClient()
	// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html
	// EC2 Instance Metadata url to get the token: http://169.254.169.254/latest/api/token
	token := ""
	tokenRequestUrl := env.Or(ec2MetadataUriEnvForTesting, ec2MetadataHost) + ec2MetadataTokenResource
	tokenRequest, err := client.CreateStandardAgentHttpRequest(http.MethodPut, tokenRequestUrl, nil)
	if err != nil {
		log.Debugf("unable to create http request: %v. request url: %s", err, tokenRequestUrl)
	} else {
		// Setting token expiry time to just 2 seconds instead of default 21600 seconds
		tokenRequest.Header.Add(ec2ImdsTokenTtlHeader, "2")
		tokenResponse, err := httpClient.Do(tokenRequest)
		if err != nil || tokenResponse == nil || tokenResponse.Body == nil {
			log.Debugf("unable to make a put call to EC2 Instance Metadata, request url: %s, error: %s "+
				"to fetch the instance metadata token. Falling back to insure way of calling EC2 Instance Metadata.",
				tokenRequestUrl, err)
		} else {
			defer tokenResponse.Body.Close()
			if tokenResponse.StatusCode != 200 {
				log.Debugf("unable to make a put call to EC2 Instance Metadata, request url: %s, code: %s "+
					"to fetch the instance metadata token. Falling back to insure way of calling EC2 Instance Metadata.",
					tokenRequestUrl, strconv.Itoa(tokenResponse.StatusCode))
			} else if responseBody, err := ioutil.ReadAll(tokenResponse.Body); err != nil {
				log.Debugf("unable to make a put call to EC2 Instance Metadata, request url: %s, error: %s "+
					"to fetch the instance metadata token. Falling back to insure way of calling EC2 Instance Metadata.",
					tokenRequestUrl, err)
			} else {
				log.Debugf("Successfully obtained token to make secure call to EC2 Instance Metadata")
				token = string(responseBody)
			}
		}
	}
	// EC2 Instance Metadata url: http://169.254.169.254/latest/meta-data/
	requestUrl := env.Or(ec2MetadataUriEnvForTesting, ec2MetadataHost) + "/latest/meta-data/" + query
	imdsRequest, err := client.CreateStandardAgentHttpRequest(http.MethodGet, requestUrl, nil)
	if err != nil {
		return "", fmt.Errorf("unable to create http request: %v. request url: %s", err, requestUrl)
	}
	if token != "" {
		imdsRequest.Header.Add(ec2ImdsTokenHeader, token)
	}
	response, err := httpClient.Do(imdsRequest)
	if err != nil {
		return "", fmt.Errorf("unable to query from IMDSv1, request url: %s, error: %s", requestUrl, err)
	}
	defer response.Body.Close()
	if responseBody, err := ioutil.ReadAll(response.Body); err != nil {
		return "", fmt.Errorf("unable to read EC2 instance metadata for query %s: %v", query, err)
	} else {
		return string(responseBody), nil
	}
}