public void TestEC2InstanceMetadataInsecureCredentialsFallbackToken() { var failFastStatusCodes = new HttpStatusCode[] { HttpStatusCode.NotFound, HttpStatusCode.Forbidden, HttpStatusCode.MethodNotAllowed }; foreach (var failFastStatusCode in failFastStatusCodes) { var token = string.Empty; using (var servlet = new EC2InstanceMetadataServlet()) { servlet.AddTokenFetchResponse(token, failFastStatusCode); servlet.AddMetadataGenericResponse("Item1", token, HttpStatusCode.OK); servlet.AddMetadataGetSecurityCredentialsResponse(_fakeValidIamSecurityCredentialMetadata, token); var metadata = EC2InstanceMetadata.IAMSecurityCredentials; Assert.IsNotNull(metadata); Assert.AreEqual(1, metadata.Count); Assert.IsTrue(metadata.ContainsKey("Item1")); var creds = metadata["Item1"]; Assert.AreEqual("value1", creds.AccessKeyId); Assert.AreEqual("value2", creds.SecretAccessKey); Assert.AreEqual("value3", creds.Token); } } }
public void TestEC2InstanceMetadataAPIToken400BadRequest() { using (var servlet = new EC2InstanceMetadataServlet()) { //DEFAULT_RETRIES of 3 for the metadata call for getting a token when BadRequest is used. servlet.AddTokenFetchResponse(string.Empty, HttpStatusCode.BadRequest); servlet.AddTokenFetchResponse(string.Empty, HttpStatusCode.BadRequest); servlet.AddTokenFetchResponse(string.Empty, HttpStatusCode.BadRequest); try { var metadata = EC2InstanceMetadata.IAMSecurityCredentials; } catch (WebException wex) { var response = wex.Response as HttpWebResponse; Assert.IsNotNull(response); Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode); throw; } } }
public void TestEC2InstanceMetadataSecureCredentialsSuccess() { var token = "ValidToken"; using (var servlet = new EC2InstanceMetadataServlet()) { servlet.AddTokenFetchResponse(token); servlet.AddMetadataGenericResponse("Item1", token, HttpStatusCode.OK); servlet.AddTokenFetchResponse(token); servlet.AddMetadataGetSecurityCredentialsResponse(_fakeValidIamSecurityCredentialMetadata, token); var metadata = EC2InstanceMetadata.IAMSecurityCredentials; Assert.IsNotNull(metadata); Assert.AreEqual(1, metadata.Count); Assert.IsTrue(metadata.ContainsKey("Item1")); var creds = metadata["Item1"]; Assert.AreEqual("value1", creds.AccessKeyId); Assert.AreEqual("value2", creds.SecretAccessKey); Assert.AreEqual("value3", creds.Token); } }
public void TestEC2InstanceMetadataInsecureCredentialsFallbackNotFound() { var token = string.Empty; using (var servlet = new EC2InstanceMetadataServlet()) { servlet.AddTokenFetchResponse(token, HttpStatusCode.NotFound); servlet.AddMetadataGenericResponse("Item1", token, HttpStatusCode.NotFound); var metadata = EC2InstanceMetadata.IAMSecurityCredentials; Assert.IsNull(metadata); } }
public void TestEC2InstanceMetadata401Unauthorized() { var token = "ValidToken"; using (var servlet = new EC2InstanceMetadataServlet()) { servlet.AddTokenFetchResponse(token); servlet.AddMetadataGetSecurityCredentialsResponse(new IAMSecurityCredentialMetadata(), token, HttpStatusCode.Unauthorized); try { var metadata = EC2InstanceMetadata.IAMSecurityCredentials; } catch (WebException wex) { var response = wex.Response as HttpWebResponse; Assert.IsNotNull(response); Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode); throw; } } }
public void StaticStabilityWhenIMDSExperiencesAnOutageScenarioTest() { var currentTime = new DateTime(1997, 8, 29, 16, 20, 0); var token = "ValidToken"; var profileMetadata = new IAMInstanceProfileMetadata { InstanceProfileArn = "profile_arn", InstanceProfileId = "profile_id" }; var validCredentialMetadata = new IAMSecurityCredentialMetadata { AccessKeyId = "value1", SecretAccessKey = "secret1", Expiration = currentTime.AddMinutes(75) }; var expiredCredentialMetadata = new IAMSecurityCredentialMetadata { AccessKeyId = "expired", SecretAccessKey = "expired", Expiration = currentTime.Subtract(TimeSpan.FromMinutes(5)) }; var validCredentialMetadata2 = new IAMSecurityCredentialMetadata { AccessKeyId = "value2", SecretAccessKey = "secret2", Expiration = currentTime.AddHours(6) }; using (new AWSConfigsDateFaker(() => currentTime.ToUniversalTime())) using (var imdsServlet = new EC2InstanceMetadataServlet()) { var instanceProfileAwsCredentials = new InstanceProfileAWSCredentials( // use a dummy role so InstanceProfileAWSCredentials doesn't try and call imds server to resolve role role: "dummyRole", proxy: null); // EXPIRED TEST 1 & 2 - can use IMDS provider if first IMDS call returns expired creds // Given IMDS service immediately returns an expired credential imdsServlet.AddTokenFetchResponse(token); imdsServlet.AddMetadataSecurityInfoResponse(profileMetadata, token); imdsServlet.AddMetadataGetSecurityCredentialsResponse(expiredCredentialMetadata, token); // When InstanceProfileAWSCredentials returns a Credential var expiredInitialCreds = instanceProfileAwsCredentials.GetCredentials(); // Then the Credential is valid and be used to call a Service AssertAreEqual(expiredCredentialMetadata, expiredInitialCreds); // REFRESH TEST 2/LOGGING TEST - Can send a request after receiving a 500 // Given 20 minutes has passed (expired credential cache time is up to 15 minutes) currentTime += TimeSpan.FromMinutes(20); // Given the IMDS service is running normally imdsServlet.AddTokenFetchResponse(token); imdsServlet.AddMetadataSecurityInfoResponse(profileMetadata, token); imdsServlet.AddMetadataGetSecurityCredentialsResponse(validCredentialMetadata, token); // When InstanceProfileAWSCredentials returns a Credential var initialCreds = instanceProfileAwsCredentials.GetCredentials(); // Then the Credential is valid and be used to call a Service AssertAreEqual(validCredentialMetadata, initialCreds); // Given 1 hour has passed (default credential cache time is 1 hour) currentTime += TimeSpan.FromMinutes(65); // And the IMDS service returns 5xx error imdsServlet.AddTokenFetchResponse(token); imdsServlet.AddMetadataSecurityInfoResponse(profileMetadata, token); imdsServlet.AddMetadataGenericResponse(contents: "", token: token, HttpStatusCode.ServiceUnavailable); // When InstanceProfileAWSCredentials returns the previously valid Credential var badCreds = instanceProfileAwsCredentials.GetCredentials(); // Then the Credential is the previously valid Credential and can be used to call a Service AssertAreEqual(validCredentialMetadata, badCreds); // And there is a log message that an expired credential is being used // Given 90 minutes has passed (credential cache time is up to 60 minutes) currentTime += TimeSpan.FromMinutes(90); // And the IMDS service is running normally (again) imdsServlet.AddTokenFetchResponse(token); imdsServlet.AddMetadataSecurityInfoResponse(profileMetadata, token); imdsServlet.AddMetadataGetSecurityCredentialsResponse(validCredentialMetadata2, token); // When InstanceProfileAWSCredentials returns a Credential var goodCreds2 = instanceProfileAwsCredentials.GetCredentials(); // Then the Credential is valid and be used to call a Service AssertAreEqual(validCredentialMetadata2, goodCreds2); // EXPIRED TEST 3 - Can perform 3 successive requests with expired credentials. IMDS must only be called once. // Given IMDS service immediately returns an expired credential imdsServlet.AddTokenFetchResponse(token); imdsServlet.AddMetadataSecurityInfoResponse(profileMetadata, token); imdsServlet.AddMetadataGetSecurityCredentialsResponse(expiredCredentialMetadata, token); // When InstanceProfileAWSCredentials returns a Credential var creds1 = instanceProfileAwsCredentials.GetCredentials(); // And InstanceProfileAWSCredentials returns a Credential var creds2 = instanceProfileAwsCredentials.GetCredentials(); // And InstanceProfileAWSCredentials returns a Credential var creds3 = instanceProfileAwsCredentials.GetCredentials(); // Then IMDS is only called once // (imdsServlet would have thrown an exception if an additional call was made) } }