using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using Amazon.Runtime.Internal;
using Amazon.Util;
using AWSSDK_DotNet35.UnitTests.TestTools;
using Json.LitJson;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace AWSSDK_DotNet.CommonTest.Utils
{
///
/// emulating the EC2 Instance Metadata Service.
///
public class EC2InstanceMetadataServlet : MultipleResponseServlet
{
private readonly DisposableSwitch _metadataServiceEndpointSwitch;
public EC2InstanceMetadataServlet()
{
ResetUseNullToken();
SetupResponseHandler();
var currentEndpointUrl = Environment.GetEnvironmentVariable("AWS_EC2_METADATA_SERVICE_ENDPOINT");
_metadataServiceEndpointSwitch =
new DisposableSwitch(
onStart: () => SetEC2InstanceMetadataEndpoint(ServiceURL),
onEnd: () => SetEC2InstanceMetadataEndpoint(currentEndpointUrl));
}
public override void Dispose()
{
_metadataServiceEndpointSwitch.Dispose();
ResetUseNullToken();
base.Dispose();
}
public Queue Responses { get; } = new Queue();
public void AddTokenFetchResponse(string token, HttpStatusCode statusCode = HttpStatusCode.OK)
{
var headers = new Dictionary();
headers.Add(HeaderKeys.XAwsEc2MetadataTokenTtlSeconds, "21600");
Responses.Enqueue(new MultipleResponseServlet.Response
{
Contents = token,
Headers = headers,
StatusCode = (int)statusCode
});
}
public void AddMetadataGetSecurityCredentialsResponse(
IAMSecurityCredentialMetadata metadata,
string token,
HttpStatusCode statusCode = HttpStatusCode.OK)
{
AddMetadataGenericResponse(JsonMapper.ToJson(metadata), token, statusCode);
}
public void AddMetadataSecurityInfoResponse(IAMInstanceProfileMetadata metadata, string token, HttpStatusCode statusCode = HttpStatusCode.OK)
{
AddMetadataGenericResponse(JsonMapper.ToJson(metadata), token, statusCode);
}
public void AddMetadataGenericResponse(string contents, string token, HttpStatusCode statusCode)
{
var headers = new Dictionary();
if (!string.IsNullOrEmpty(token))
{
headers.Add(HeaderKeys.XAwsEc2MetadataToken, token);
}
Responses.Enqueue(new MultipleResponseServlet.Response
{
Contents = contents,
Headers = headers,
StatusCode = (int)statusCode
});
}
private void SetupResponseHandler()
{
OnRequest += path =>
{
if (Responses.Count == 0)
Assert.Fail("Number or responses requested exceeds the number of mocked responses.");
var response = Responses.Dequeue();
return response;
};
}
private static IDictionary GetSecurityCredentials(MultipleResponseServlet servlet)
{
var currentEMSValue = Environment.GetEnvironmentVariable("AWS_EC2_METADATA_SERVICE_ENDPOINT");
Action setEMSAction = () => SetEC2InstanceMetadataEndpoint(servlet.ServiceURL);
Action resetEMSAction = () => SetEC2InstanceMetadataEndpoint(currentEMSValue);
using (new DisposableSwitch(setEMSAction, resetEMSAction))
{
var metadata = EC2InstanceMetadata.IAMSecurityCredentials;
return metadata;
}
}
private static void SetEC2InstanceMetadataEndpoint(string address)
{
Environment.SetEnvironmentVariable("AWS_EC2_METADATA_SERVICE_ENDPOINT", address);
FallbackInternalConfigurationFactory.Reset();
}
private static FieldInfo ResetUseNullToken()
{
var nullTokenField =
typeof(EC2InstanceMetadata)
.GetField("useNullToken", BindingFlags.NonPublic | BindingFlags.Static);
nullTokenField.SetValue(null, false);
Assert.IsFalse((bool)nullTokenField.GetValue(null));
return nullTokenField;
}
}
}