/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Amazon.Runtime;
using Amazon.EC2.Model;
using System.IO;
using Amazon.Util;
using Amazon.Runtime.Internal.Util;
using Amazon.Runtime.Internal.Transform;
using Amazon.Runtime.Internal;
namespace Amazon.EC2.Internal
{
///
/// Custom pipeline handler.
///
public class AmazonEC2ResponseHandler : PipelineHandler
{
///
/// Calls the post invoke logic after calling the next handler
/// in the pipeline.
///
/// The execution context which contains both the
/// requests and response context.
public override void InvokeSync(IExecutionContext executionContext)
{
base.InvokeSync(executionContext);
PostInvoke(executionContext);
}
#if AWS_ASYNC_API
///
/// Calls the and post invoke logic after calling the next handler
/// in the pipeline.
///
/// The response type for the current request.
/// The execution context, it contains the
/// request and response context.
/// A task that represents the asynchronous operation.
public override async System.Threading.Tasks.Task InvokeAsync(IExecutionContext executionContext)
{
var response = await base.InvokeAsync(executionContext).ConfigureAwait(false);
PostInvoke(executionContext);
return response;
}
#elif AWS_APM_API
///
/// Calls the PostInvoke methods after calling the next handler
/// in the pipeline.
///
/// The execution context, it contains the
/// request and response context.
protected override void InvokeAsyncCallback(IAsyncExecutionContext executionContext)
{
// Process the response if an exception hasn't occured
if (executionContext.ResponseContext.AsyncResult.Exception == null)
{
PostInvoke(ExecutionContext.CreateFromAsyncContext(executionContext));
}
base.InvokeAsyncCallback(executionContext);
}
#endif
///
/// Custom pipeline handler
///
///
protected virtual void PostInvoke(IExecutionContext executionContext)
{
var request = executionContext.RequestContext.OriginalRequest;
var response = executionContext.ResponseContext.Response;
var webResponseData = executionContext.ResponseContext.HttpResponse;
var dsirr = response as DescribeSpotInstanceRequestsResponse;
if (dsirr != null)
{
if (dsirr.SpotInstanceRequests != null)
{
foreach (var spotInstanceRequest in dsirr.SpotInstanceRequests)
{
var launchSpecification = spotInstanceRequest.LaunchSpecification;
PopulateLaunchSpecificationSecurityGroupNames(launchSpecification);
}
}
return;
}
var rsir = response as RequestSpotInstancesResponse;
if (rsir != null)
{
if (rsir.SpotInstanceRequests != null)
{
foreach (var spotInstanceRequest in rsir.SpotInstanceRequests)
{
var launchSpecification = spotInstanceRequest.LaunchSpecification;
PopulateLaunchSpecificationSecurityGroupNames(launchSpecification);
}
}
return;
}
var dir = response as DescribeInstancesResponse;
if (dir != null)
{
if (dir.Reservations != null)
{
foreach (var reservation in dir.Reservations)
{
PopulateReservationSecurityGroupNames(reservation);
}
}
return;
}
var rir = response as RunInstancesResponse;
if (rir != null)
{
PopulateReservationSecurityGroupNames(rir.Reservation);
return;
}
// In case of DescribeSecurityGroupsResponse type, the Ipv4Ranges values for each of the retured IpPermissions is unmarshalled
// and the extracted Cidr values is set on the IpRanges property of IpPermission. If the customer is using IpRanges, then they will not be broken.
var describeSecurityGroupsResponse = response as DescribeSecurityGroupsResponse;
if(describeSecurityGroupsResponse!=null)
{
if(describeSecurityGroupsResponse.IsSetSecurityGroups())
{
foreach (var securityGroup in describeSecurityGroupsResponse.SecurityGroups)
{
if (securityGroup.IsSetIpPermissions())
{
SetIpRangesProperty(securityGroup.IpPermissions);
}
else if(securityGroup.IsSetIpPermissionsEgress())
{
SetIpRangesProperty(securityGroup.IpPermissionsEgress);
}
}
}
return;
}
var authorizeSecurityGroupEgressRequest = request as AuthorizeSecurityGroupEgressRequest;
if (authorizeSecurityGroupEgressRequest != null)
if (authorizeSecurityGroupEgressRequest.IsSetIpPermissions())
{
RestoreRequestIpPermissions(authorizeSecurityGroupEgressRequest.IpPermissions);
return;
}
var authorizeSecurityGroupIngressRequest = request as AuthorizeSecurityGroupIngressRequest;
if (authorizeSecurityGroupIngressRequest != null)
if (authorizeSecurityGroupIngressRequest.IsSetIpPermissions())
{
RestoreRequestIpPermissions(authorizeSecurityGroupIngressRequest.IpPermissions);
return;
}
var revokeSecurityGroupEgressRequest = request as RevokeSecurityGroupEgressRequest;
if (revokeSecurityGroupEgressRequest != null)
if (revokeSecurityGroupEgressRequest.IsSetIpPermissions())
{
RestoreRequestIpPermissions(revokeSecurityGroupEgressRequest.IpPermissions);
return;
}
var revokeSecurityGroupIngressRequest = request as RevokeSecurityGroupIngressRequest;
if (revokeSecurityGroupIngressRequest != null)
if (revokeSecurityGroupIngressRequest.IsSetIpPermissions())
{
RestoreRequestIpPermissions(revokeSecurityGroupIngressRequest.IpPermissions);
return;
}
var updateSecurityGroupRuleDescriptionsEgressRequest = request as UpdateSecurityGroupRuleDescriptionsEgressRequest;
if (updateSecurityGroupRuleDescriptionsEgressRequest != null)
if (updateSecurityGroupRuleDescriptionsEgressRequest.IsSetIpPermissions())
{
RestoreRequestIpPermissions(updateSecurityGroupRuleDescriptionsEgressRequest.IpPermissions);
return;
}
var updateSecurityGroupRuleDescriptionsIngressRequest = request as UpdateSecurityGroupRuleDescriptionsIngressRequest;
if (updateSecurityGroupRuleDescriptionsIngressRequest != null)
if (updateSecurityGroupRuleDescriptionsIngressRequest.IsSetIpPermissions())
{
RestoreRequestIpPermissions(updateSecurityGroupRuleDescriptionsIngressRequest.IpPermissions);
return;
}
}
///
/// Cidr values from Ipv4Ranges is extracted and set on IpRanges.
/// The internal dictionary collection is also set to the Ipv4Range values.
///
///
private static void SetIpRangesProperty(List ipPermissions)
{
foreach (var ipPermission in ipPermissions)
{
ipPermission.IpRanges = ipPermission.Ipv4Ranges.Select(i => i.CidrIp).ToList();
ipPermission.CopyIpv4RangesToInternalCollection(ipPermission.Ipv4Ranges);
}
}
///
/// The original values used by the customer in the Ipv4Ranges property on the request
/// object is restored. This is done when the customer is using the deprecated IpRanges property.
///
///
private static void RestoreRequestIpPermissions(List IpPermissions)
{
foreach (var ipPermission in IpPermissions)
{
if(ipPermission.RestoreOldIpV4Range)
{
ipPermission.Ipv4Ranges = ipPermission.PreIpv4Ranges;
ipPermission.RestoreOldIpV4Range = false;
}
}
}
private static void PopulateLaunchSpecificationSecurityGroupNames(LaunchSpecification launchSpecification)
{
if (launchSpecification != null)
{
var groupNames = new List();
foreach (GroupIdentifier group in launchSpecification.AllSecurityGroups)
{
groupNames.Add(group.GroupName);
}
launchSpecification.SecurityGroups = groupNames;
}
}
private static void PopulateReservationSecurityGroupNames(Reservation reservation)
{
if (reservation != null)
{
var groupNames = new List();
foreach (GroupIdentifier group in reservation.Groups)
{
groupNames.Add(group.GroupName);
}
reservation.GroupNames = groupNames;
}
}
}
}