/*
* Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: MIT-0
*
* Description: Auto Scaling console main window
*/
using Amazon.AutoScaling;
using Amazon.AutoScaling.Model;
using Amazon.EC2;
using Amazon.EC2.Model;
using Amazon.ElasticLoadBalancing;
using Amazon.ElasticLoadBalancing.Model;
using AWS.AutoScale.Console.DataBinding;
using AWS.AutoScale.Console.Utility;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace AWS.AutoScale.Console
{
///
/// Interaction logic for ConsoleView.xaml
///
public partial class ConsoleView : Page
{
System.Windows.Threading.DispatcherTimer monitorTimer;
System.Windows.Threading.DispatcherTimer shutdownTimer;
private BackgroundWorker loadworker;
private BackgroundWorker vpcworker;
ViewModel vm;
#region "Constructor"
///
/// Console View window constructor
///
public ConsoleView()
{
InitializeComponent();
vm = new ViewModel();
this.DataContext = vm;
rbClassic.Click += new RoutedEventHandler(rbEnvironment_Checked);
rbVpc.Click += new RoutedEventHandler(rbEnvironment_Checked);
cboVPC.SelectionChanged += new SelectionChangedEventHandler(cboVPC_SelectionChanged);
vm.SelectedLaunchConfigurationChanged += new EventHandler(LaunchConfigurationSelectionChanged);
vm.SelectedAutoScaleGroupChanged += new EventHandler(AutoScaleGroupSelectionChanged);
Loaded += ConsoleView_Loaded;
}
#endregion
#region "View Load Event"
///
/// Auto Scaling Console load event handler
///
///
///
private void ConsoleView_Loaded(object sender, RoutedEventArgs e)
{
try
{
AmazonEC2Client ec2Client = new AmazonEC2Client();
DescribeRegionsRequest rreq = new DescribeRegionsRequest();
DescribeRegionsResponse rresp = ec2Client.DescribeRegions(rreq);
((ViewModel)this.DataContext).Regions.Clear();
foreach (Region r in rresp.DescribeRegionsResult.Region)
{
((ViewModel)this.DataContext).Regions.Add(new Models.Region(r.RegionName));
}
((ViewModel)this.DataContext).Region = ((ViewModel)this.DataContext).Regions.Where(o => o.Name.ToLower() == "us-east-1").FirstOrDefault();
AmazonAutoScalingClient client = GetAutoScaleClient();
if (client == null)
{
MessageBoxResult mbr = MessageBox.Show(Window.GetWindow(this), "AWS Credentials and region must be defined in app.config file.");
Application.Current.Shutdown();
}
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
((ViewModel)this.DataContext).IsBusy = false;
MessageBox.Show(Window.GetWindow(this), "Error occured while setting credentials. Please ensure your credentials are correct in app.config.", "Error", MessageBoxButton.OK);
Application.Current.Shutdown();
}
}
#endregion
#region "AWS Clients"
///
/// Creates AWS auto scaling group client
///
/// AmazonAutoScalingClient
private AmazonAutoScalingClient GetAutoScaleClient()
{
if (vm.Region == null)
{
throw new InvalidRegionException("No region defined when creating auto scaling client");
}
AmazonAutoScalingConfig config = new AmazonAutoScalingConfig();
config.ServiceURL = vm.Region.Url;
AmazonAutoScalingClient client = new AmazonAutoScalingClient(config);
return client;
}
///
/// Creates AWS EC2 client
///
/// AmazonEC2Client
private AmazonEC2Client GetEc2Client()
{
if (vm.Region == null)
{
throw new InvalidRegionException("No region defined when creating EC2 client");
}
AmazonEC2Config config = new AmazonEC2Config();
config.ServiceURL = vm.Region.Ec2Url;
AmazonEC2Client client = new AmazonEC2Client(config);
return client;
}
///
/// Creates AWS Elastic Load Balancing client
///
/// AmazonElasticLoadBalancingClient
private AmazonElasticLoadBalancingClient GetElbClient()
{
if (vm.Region == null)
{
throw new InvalidRegionException("No region defined when creating elastic load balancing client");
}
AmazonElasticLoadBalancingConfig config = new AmazonElasticLoadBalancingConfig();
config.ServiceURL = vm.Region.ElbUrl;
AmazonElasticLoadBalancingClient client = new AmazonElasticLoadBalancingClient(config);
return client;
}
#endregion
#region "Regional Load"
///
/// Event handler for cboRegion combo box selection change
///
///
///
private void cboRegion_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
initializeRegion();
}
///
/// Initializes contents of console based on region selected and EC2 classic/vpc
///
private void initializeRegion()
{
try
{
((ViewModel)this.DataContext).IsBusy = true;
((ViewModel)this.DataContext).BusyContent = "Verifying AWS Credentials, setting region and loading data...";
if (vm.IsVpc)
{
vpcworker = new BackgroundWorker();
vpcworker.DoWork += new DoWorkEventHandler(LoadAwsVpcDataContext);
vpcworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(LoadAwsVpcDataContextDone);
vpcworker.RunWorkerAsync();
}
else
{
vm.SelectedVpc = null;
InitiateAwsDataLoadBackgroundworker();
}
if (monitorTimer != null && monitorTimer.IsEnabled)
monitorTimer.Stop();
monitorTimer = new System.Windows.Threading.DispatcherTimer();
monitorTimer.Tick += new EventHandler(monitorTimer_Tick);
monitorTimer.Interval = new TimeSpan(0, 0, 1);
monitorTimer.Start();
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
((ViewModel)this.DataContext).IsBusy = false;
MessageBox.Show(Window.GetWindow(this), "Error occured while initializing the region.", "Error", MessageBoxButton.OK);
}
}
#endregion
#region "Load AWS data"
///
/// loads view model with AWS data based on region selected and EC2 classic/vpc in background
///
private void InitiateAwsDataLoadBackgroundworker()
{
try
{
loadworker = new BackgroundWorker();
loadworker.DoWork += new DoWorkEventHandler(LoadAwsData);
loadworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(LoadAwsDataDone);
loadworker.RunWorkerAsync();
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
MessageBox.Show(Window.GetWindow(this), "Error occured while loading AWS data for specified region and ec2 enivronment. Please review error log for more details.", "Error", MessageBoxButton.OK);
}
}
///
/// loadworker DoWork event handler to load view model with AWS data based on region selected and EC2 classic/vpc
///
private void LoadAwsData(object sender, DoWorkEventArgs e)
{
try
{
AmazonEC2Client ec2Client = GetEc2Client();
AmazonAutoScalingClient asClient = GetAutoScaleClient();
AmazonElasticLoadBalancingClient elbClient = GetElbClient();
LoadSecurityGroups(ec2Client);
LoadLaunchConfigurations(asClient);
LoadAvailabilityZones(ec2Client);
LoadKeyPairs(ec2Client);
LoadElasticLoadBalancers(elbClient);
LoadAutoScalingGroups(asClient);
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
MessageBox.Show(Window.GetWindow(this), "Error occured while loading AWS data for specified region and ec2 enivronment. Please review error log for more details.", "Error", MessageBoxButton.OK);
}
}
///
/// Load security groups to view model with AWS data based on region selected and EC2 classic/vpc
///
private void LoadSecurityGroups(AmazonEC2Client ec2Client)
{
try
{
DescribeSecurityGroupsRequest sgreq = new DescribeSecurityGroupsRequest();
DescribeSecurityGroupsResponse sgresp = ec2Client.DescribeSecurityGroups(sgreq);
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.SecurityGroups.Clear();
}));
foreach (SecurityGroup sg in sgresp.DescribeSecurityGroupsResult.SecurityGroup)
{
if (vm.IsVpc)
{
if (sg.VpcId != null && vm.SelectedVpc != null)
{
if (sg.VpcId == vm.SelectedVpc.VPC.VpcId)
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.SecurityGroups.Add(new Models.ConsoleSG() { SecurityGroup = sg, DisplayName = string.Concat(sg.GroupName, " ( VPC: ", sg.VpcId, " )") });
}));
}
}
}
else
{
if (!(sg.VpcId != null && sg.VpcId != string.Empty && !vm.IsVpc))
{
//vm.SecurityGroups.Add(new Models.LcSecurityGroup() { SecurityGroup = sg, DisplayName = sg.GroupName });
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.SecurityGroups.Add(new Models.ConsoleSG() { SecurityGroup = sg, DisplayName = sg.GroupName });
}));
}
}
}
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
throw new DataLoadingException("Error occurred loading security groups for region and environment type");
}
}
///
/// Load launch configurations to view model with AWS data based on region selected and EC2 classic/vpc
///
private void LoadLaunchConfigurations(AmazonAutoScalingClient asClient)
{
try
{
DescribeLaunchConfigurationsRequest lcreq = new DescribeLaunchConfigurationsRequest();
DescribeLaunchConfigurationsResponse lcresp = asClient.DescribeLaunchConfigurations(lcreq);
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.LaunchConfigurations.Clear();
}));
foreach (LaunchConfiguration lcg in lcresp.DescribeLaunchConfigurationsResult.LaunchConfigurations)
{
if (lcg.SecurityGroups.Count() == 0)
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.LaunchConfigurations.Add(new Models.ConsoleLC() { LaunchConfiguration = lcg });
}));
}
else
{
foreach (Models.ConsoleSG lcsg in vm.SecurityGroups)
{
if (lcg.SecurityGroups.Contains(lcsg.SecurityGroup.GroupId))
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.LaunchConfigurations.Add(new Models.ConsoleLC() { LaunchConfiguration = lcg });
}));
break;
}
}
}
}
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
throw new DataLoadingException("Error occurred loading launch configurations for region and environment type");
}
}
///
/// Load availability zones to view model with AWS data based on region selected and EC2 classic/vpc
///
private void LoadAvailabilityZones(AmazonEC2Client ec2Client)
{
try
{
DescribeAvailabilityZonesRequest azreq = new DescribeAvailabilityZonesRequest();
DescribeAvailabilityZonesResponse azresp = ec2Client.DescribeAvailabilityZones(azreq);
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.Zones.Clear();
}));
foreach (AvailabilityZone az in azresp.DescribeAvailabilityZonesResult.AvailabilityZone)
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.Zones.Add(az);
}));
}
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
throw new DataLoadingException("Error occurred loading availability zones for region and environment type");
}
}
///
/// Load key pairs to view model with AWS data based on region selected and EC2 classic/vpc
///
private void LoadKeyPairs(AmazonEC2Client ec2Client)
{
try
{
DescribeKeyPairsRequest keyreq = new DescribeKeyPairsRequest();
DescribeKeyPairsResponse keyresp = ec2Client.DescribeKeyPairs(keyreq);
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.KeyPairs.Clear();
}));
foreach (KeyPair kp in keyresp.DescribeKeyPairsResult.KeyPair)
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.KeyPairs.Add(kp.KeyName);
}));
}
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
throw new DataLoadingException("Error occurred loading key pairs for region and environment type");
}
}
///
/// Load elastic load balancers to view model with AWS data based on region selected and EC2 classic/vpc
///
private void LoadElasticLoadBalancers(AmazonElasticLoadBalancingClient elbClient)
{
try
{
DescribeLoadBalancersRequest elbreq = new DescribeLoadBalancersRequest();
DescribeLoadBalancersResponse elbresp = elbClient.DescribeLoadBalancers(elbreq);
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.LoadBalancers.Clear();
}));
foreach (LoadBalancerDescription lbd in elbresp.DescribeLoadBalancersResult.LoadBalancerDescriptions)
{
if (vm.IsVpc)
{
if (lbd.VPCId != null && vm.SelectedVpc != null && lbd.VPCId == vm.SelectedVpc.VPC.VpcId)
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.LoadBalancers.Add(lbd);
}));
}
}
else
{
if (!(lbd.VPCId != null && lbd.VPCId != string.Empty && !vm.IsVpc))
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.LoadBalancers.Add(lbd);
}));
}
}
}
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
throw new DataLoadingException("Error occurred loading elastic load balancers for region and environment type");
}
}
///
/// Load auto scaling groups to view model with AWS data based on region selected and EC2 classic/vpc
///
private void LoadAutoScalingGroups(AmazonAutoScalingClient asClient)
{
try
{
DescribeAutoScalingGroupsRequest asreq = new DescribeAutoScalingGroupsRequest();
DescribeAutoScalingGroupsResponse asresp = asClient.DescribeAutoScalingGroups(asreq);
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.AutoScalingGroups.Clear();
}));
foreach (AutoScalingGroup asg in asresp.DescribeAutoScalingGroupsResult.AutoScalingGroups)
{
if (vm.IsVpc)
{
if (!string.IsNullOrEmpty(asg.VPCZoneIdentifier) && vm.SelectedVpc != null)
{
foreach (Models.ConsoleSubnet subnet in vm.SelectedVpc.Subnets)
{
if (asg.VPCZoneIdentifier.Contains(subnet.Subnet.SubnetId))
{
//vm.AutoScalingGroups.Add(asg);
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.AutoScalingGroups.Add(new Models.ConsoleASG() { AutoScalingGroup = asg });
}));
break;
}
}
}
}
else
{
if (string.IsNullOrEmpty(asg.VPCZoneIdentifier))
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.AutoScalingGroups.Add(new Models.ConsoleASG() { AutoScalingGroup = asg });
}));
}
}
}
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
for (int i = 0; i < vm.AutoScalingGroups.Count(); i++)
{
DescribeNotificationConfigurationsRequest nreq = new DescribeNotificationConfigurationsRequest();
nreq.WithAutoScalingGroupNames(vm.AutoScalingGroups[i].AutoScalingGroup.AutoScalingGroupName);
DescribeNotificationConfigurationsResponse nresp = asClient.DescribeNotificationConfigurations(nreq);
vm.AutoScalingGroups[i].NotificationConfigurations = new List();
foreach (NotificationConfiguration nc in nresp.DescribeNotificationConfigurationsResult.NotificationConfigurations)
{
vm.AutoScalingGroups[i].NotificationConfigurations.Add(nc);
}
}
}));
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
throw new DataLoadingException("Error occurred loading auto scaling groups for region and environment type");
}
}
///
/// loadworker RunWorkerCompleted event handler to disable busy mode of console
///
///
///
private void LoadAwsDataDone(object sender, RunWorkerCompletedEventArgs e)
{
((ViewModel)this.DataContext).IsBusy = false;
}
#endregion
#region "Auto Scaling Group Informaiton Polling"
///
/// Tick event handler for monitorTimer to poll AWS for updated information on instance information for auto scaling groups
///
///
///
private void monitorTimer_Tick(object sender, EventArgs e)
{
if (vm.RefreshCountdown == 0)
{
vm.RefreshCountdown = vm.SelectedRefreshPeriod.Period; //vm.RefreshRate;
AmazonAutoScalingClient client = GetAutoScaleClient();
DescribeAutoScalingGroupsRequest asreq = new DescribeAutoScalingGroupsRequest();
asreq.AutoScalingGroupNames.Add(((ViewModel)this.DataContext).SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName);
IAsyncResult asresult = client.BeginDescribeAutoScalingGroups(asreq, AutoScalingGroupInfoCallback, "instances");
}
else
{
vm.RefreshCountdown -= 1;
}
}
///
/// Callback function for DescribeAutoScalingGroups async call
///
///
private void AutoScalingGroupInfoCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
AmazonAutoScalingClient client = GetAutoScaleClient();
DescribeAutoScalingGroupsResponse resp = client.EndDescribeAutoScalingGroups(result);
List asgroups = resp.DescribeAutoScalingGroupsResult.AutoScalingGroups;
foreach (AutoScalingGroup asg in asgroups)
{
Models.ConsoleASG _asg = vm.AutoScalingGroups.Where(o => o.AutoScalingGroup.AutoScalingGroupName == asg.AutoScalingGroupName).FirstOrDefault();
if (_asg != null)
{
if (result.AsyncState != null)
{
if (result.AsyncState.ToString() == "instances")
{
vm.AutoScalingGroups.Where(o => o.AutoScalingGroup.AutoScalingGroupName == asg.AutoScalingGroupName).First().AutoScalingGroup = asg;
}
else if (result.AsyncState.ToString().Contains("full"))
{
((ViewModel)this.DataContext).SelectedAutoScalingGroup = new Models.ConsoleASG() { AutoScalingGroup = asg };
}
}
}
}
if (result.AsyncState != null)
{
if (result.AsyncState.ToString().Contains("full"))
{
string cursel = vm.SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName;
vm.AutoScalingGroups.Clear();
foreach (AutoScalingGroup asg in asgroups)
{
if (result.AsyncState.ToString().Contains("delete") &&
asg.AutoScalingGroupName == cursel)
{
continue;
}
if (vm.IsVpc && vm.SelectedVpc != null)
{
if (!string.IsNullOrEmpty(asg.VPCZoneIdentifier))
{
foreach (Models.ConsoleSubnet subnet in vm.SelectedVpc.Subnets)
{
if (asg.VPCZoneIdentifier.Contains(subnet.Subnet.SubnetId))
{
vm.AutoScalingGroups.Add(new Models.ConsoleASG() { AutoScalingGroup = asg });
break;
}
}
}
}
else
{
if (string.IsNullOrEmpty(asg.VPCZoneIdentifier))
{
vm.AutoScalingGroups.Add(new Models.ConsoleASG() { AutoScalingGroup = asg });
}
}
}
if (result.AsyncState.ToString().Contains("new"))
{
vm.ASGroup = null;
}
if (result.AsyncState.ToString().Contains("delete"))
{
vm.SelectedAutoScalingGroup = null;
}
InitiateAwsDataLoadBackgroundworker();
}
}
}));
}
#endregion
#region "Environment Selection"
///
/// Event handler for rbEnvironment radio button checked. Sets whether console should read EC2 classic or a VPC
///
///
///
private void rbEnvironment_Checked(object sender, RoutedEventArgs e)
{
vm.IsVpc = (sender as RadioButton).Tag.ToString() == "1";
spVpc.Visibility = vm.IsVpc ? Visibility.Visible : Visibility.Collapsed;
RadioButton rb = sender as RadioButton;
((ViewModel)this.DataContext).SelectedAutoScalingGroup = null;
((ViewModel)this.DataContext).SelectedLaunchConfiguration = null;
vm.IsBusy = true;
vm.BusyContent = "Loading environmental information for Classic EC2...";
if (vm.IsVpc)
{
vpcworker = new BackgroundWorker();
vpcworker.DoWork += new DoWorkEventHandler(LoadAwsVpcDataContext);
vpcworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(LoadAwsVpcDataContextDone);
vpcworker.RunWorkerAsync();
}
else
{
vm.SelectedVpc = null;
InitiateAwsDataLoadBackgroundworker();
}
}
///
/// vpcworker DoWork event handler to load view model with selected VPC data
///
///
///
private void LoadAwsVpcDataContext(object sender, DoWorkEventArgs e)
{
AmazonEC2Client ec2Client = GetEc2Client();
DescribeVpcsRequest vpcreq = new DescribeVpcsRequest();
DescribeVpcsResponse vpcresp = ec2Client.DescribeVpcs(vpcreq);
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.Vpcs.Clear();
}));
foreach (Vpc vpc in vpcresp.DescribeVpcsResult.Vpc)
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vm.Vpcs.Add(new Models.ConsoleVPC() { VPC = vpc });
}));
}
DescribeSubnetsRequest sncreq = new DescribeSubnetsRequest();
DescribeSubnetsResponse cnresp = ec2Client.DescribeSubnets(sncreq);
foreach (Subnet subnet in cnresp.DescribeSubnetsResult.Subnet)
{
Models.ConsoleVPC vpc = vm.Vpcs.Where(o => o.VPC.VpcId == subnet.VpcId).FirstOrDefault();
if (vpc != null)
{
Models.ConsoleSubnet cs = vpc.Subnets.Where(o => o.Subnet == subnet).FirstOrDefault();
if (cs == null)
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
vpc.Subnets.Add(new Models.ConsoleSubnet() { DisplayName = string.Concat(subnet.SubnetId, " (", subnet.AvailabilityZone, ")"), Subnet = subnet });
}));
}
}
}
}
///
/// loadworker Run Worker Completed event handler to refresh view model data in console based on VPC loaded
///
///
///
private void LoadAwsVpcDataContextDone(object sender, RunWorkerCompletedEventArgs e)
{
InitiateAwsDataLoadBackgroundworker();
this.cboVPC.SelectedIndex = 0;
}
///
/// Event handler for cboVPC combobox selection change
///
///
///
private void cboVPC_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (((ViewModel)this.DataContext).SelectedVpc != null)
{
((ViewModel)this.DataContext).IsBusy = true;
((ViewModel)this.DataContext).BusyContent = "Loading data for the selected VPC...";
((ViewModel)this.DataContext).SelectedAutoScalingGroup = null;
((ViewModel)this.DataContext).SelectedLaunchConfiguration = null;
InitiateAwsDataLoadBackgroundworker();
}
}
#endregion
#region "LC and ASG selection handlers"
///
/// Event handler when launch configuration selection changes
///
///
///
private void LaunchConfigurationSelectionChanged(object sender, EventArgs e)
{
bool validConfig = ((ViewModel)this.DataContext).SelectedLaunchConfiguration != null && !string.IsNullOrEmpty((((ViewModel)this.DataContext).SelectedLaunchConfiguration.LaunchConfiguration.LaunchConfigurationName));
gEmptySelectedLC.Visibility = !validConfig ? Visibility.Visible : Visibility.Hidden;
gSelectedLC.Visibility = validConfig ? Visibility.Visible : Visibility.Hidden;
}
///
/// Event handler when auto scaling group selection changes
///
///
///
private void AutoScaleGroupSelectionChanged(object sender, EventArgs e)
{
bool validConfig = vm.SelectedAutoScalingGroup != null && !string.IsNullOrEmpty(vm.SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName);
gEmptySelectedASG.Visibility = !validConfig ? Visibility.Visible : Visibility.Hidden;
gSelectedASG.Visibility = validConfig ? Visibility.Visible : Visibility.Hidden;
}
#endregion
#region "Shutdown / Delete Auto Scaling Group"
///
/// Event handler for "View Instances" context menu click
///
///
///
private void mnuViewAsgInstances(object sender, EventArgs e)
{
Window win = new InstancesWindow((ViewModel)this.DataContext);
win.Owner = Window.GetWindow(this);
win.ShowDialog();
}
///
/// Event handler for "Shutdown Auto Scaling Group" context menu click
///
///
///
private void mnuShutdownAsg(object sender, EventArgs e)
{
if (((ViewModel)this.DataContext).SelectedAutoScalingGroup == null || ((ViewModel)this.DataContext).SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName == null)
{
MessageBox.Show(Window.GetWindow(this), "Please select a Auto Scaling Group.", "Make Selection", MessageBoxButton.OK);
return;
}
if (MessageBox.Show(Window.GetWindow(this), string.Concat("Do you want to shutdown the Auto Scaling Group: ", ((ViewModel)this.DataContext).SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName, "?"), "Confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
((ViewModel)this.DataContext).IsBusy = true;
((ViewModel)this.DataContext).BusyContent = "Shuting down group. Waiting for all activities to complete.";
AmazonAutoScalingClient client = GetAutoScaleClient();
UpdateAutoScalingGroupRequest req = new UpdateAutoScalingGroupRequest();
req.AutoScalingGroupName = ((ViewModel)this.DataContext).SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName;
req.MinSize = 0;
req.MaxSize = 0;
IAsyncResult result = client.BeginUpdateAutoScalingGroup(req, ShutdownAutoScaleGroupCallback, null);
}
}
///
/// Event handler for "Delete Auto Scaling Group" context menu click
///
///
///
private void mnuDeleteAsg(object sender, RoutedEventArgs e)
{
if (vm.SelectedAutoScalingGroup == null || vm.SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName == null)
{
MessageBox.Show(Window.GetWindow(this), "Please select a Auto Scaling Group.", "Make Selection", MessageBoxButton.OK);
return;
}
if (MessageBox.Show(Window.GetWindow(this), string.Concat("Do you want to delete the Auto Scaling Group: ", vm.SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName, "?"), "Confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
vm.IsBusy = true;
vm.BusyContent = "Shuting down group. Waiting for activities to complete.";
AmazonAutoScalingClient client = GetAutoScaleClient();
UpdateAutoScalingGroupRequest req = new UpdateAutoScalingGroupRequest();
req.AutoScalingGroupName = vm.SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName;
req.MinSize = 0;
req.MaxSize = 0;
IAsyncResult result = client.BeginUpdateAutoScalingGroup(req, ShutdownAutoScaleGroupCallback, "Delete");
}
}
///
/// Callback function for BeginUpdateAutoScalinGroup async call to set min/max size of ASG to 0 "shutting down" the ASG
///
///
private void ShutdownAutoScaleGroupCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
AmazonAutoScalingClient client = GetAutoScaleClient();
UpdateAutoScalingGroupResponse resp = client.EndUpdateAutoScalingGroup(result);
shutdownTimer = new System.Windows.Threading.DispatcherTimer();
shutdownTimer.Tick += new EventHandler(shutdownTimer_Tick);
shutdownTimer.Interval = new TimeSpan(0, 0, 5);
shutdownTimer.Tag = result.AsyncState != null ? result.AsyncState.ToString() : null;
shutdownTimer.Start();
}));
}
///
/// Tick event handler for shutdownTimer to poll AWS for updated information on auto scaling group shutdown
///
///
///
private void shutdownTimer_Tick(object sender, EventArgs e)
{
AmazonAutoScalingClient client = GetAutoScaleClient();
if (shutdownTimer.Tag != null)
{
if (shutdownTimer.Tag.ToString() == "activities")
{
DescribeScalingActivitiesRequest req = new DescribeScalingActivitiesRequest();
req.AutoScalingGroupName = ((ViewModel)this.DataContext).SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName;
IAsyncResult dasgresult = client.BeginDescribeScalingActivities(req, AutoScalingGroupScalingActivityInfoCallback, null);
return;
}
}
DescribeAutoScalingGroupsRequest asreq = new DescribeAutoScalingGroupsRequest();
IAsyncResult asresult = client.BeginDescribeAutoScalingGroups(asreq, AutoScalingGroupShutdownInfoCallback, shutdownTimer.Tag);
}
///
/// Callback function for BeginDescribeScalingActivities async call to monitor the activities of an ASG during shutdown
///
///
private void AutoScalingGroupScalingActivityInfoCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
AmazonAutoScalingClient client = GetAutoScaleClient();
DescribeScalingActivitiesResponse resp = client.EndDescribeScalingActivities(result);
foreach (Activity activity in resp.DescribeScalingActivitiesResult.Activities)
{
if (activity.StatusCode.ToLower() != "successful" && activity.StatusCode.ToLower() != "failed")
{
return;
}
}
shutdownTimer.Stop();
DeleteAutoScalingGroupRequest req = new DeleteAutoScalingGroupRequest();
((ViewModel)this.DataContext).BusyContent = "Deleting auto scaling group";
req.AutoScalingGroupName = ((ViewModel)this.DataContext).SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName;
IAsyncResult dasgresult = client.BeginDeleteAutoScalingGroup(req, DeleteAutoScalingGroupCallback, null);
}));
}
///
/// Callback function for BeginDescribeAutoScalingGroups async call to monitor the shutdown of a ASG
///
///
private void AutoScalingGroupShutdownInfoCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
AmazonAutoScalingClient client = GetAutoScaleClient();
DescribeAutoScalingGroupsResponse resp = client.EndDescribeAutoScalingGroups(result);
List asgroups = resp.DescribeAutoScalingGroupsResult.AutoScalingGroups;
foreach (AutoScalingGroup asg in asgroups)
{
if (asg.AutoScalingGroupName == ((ViewModel)this.DataContext).SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName)
{
if (asg.Instances.Count() == 0)
{
shutdownTimer.Stop();
if (result.AsyncState != null)
{
((ViewModel)this.DataContext).BusyContent = "Scanning Auto Scaling Activities";
shutdownTimer.Tag = "activities";
shutdownTimer.Start();
}
else
{
DescribeAutoScalingGroupsRequest asreq = new DescribeAutoScalingGroupsRequest();
IAsyncResult asresult = client.BeginDescribeAutoScalingGroups(asreq, AutoScalingGroupInfoCallback, "full");
}
}
}
}
}));
}
///
/// Callback function for BeginDeleteAutoScalingGroup async call to delete an ASG
///
///
private void DeleteAutoScalingGroupCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
AmazonAutoScalingClient client = GetAutoScaleClient();
DeleteAutoScalingGroupResponse resp = client.EndDeleteAutoScalingGroup(result);
DescribeAutoScalingGroupsRequest asreq = new DescribeAutoScalingGroupsRequest();
IAsyncResult asresult = client.BeginDescribeAutoScalingGroups(asreq, AutoScalingGroupInfoCallback, "full,delete");
}));
}
#endregion
#region "Add Availability Group"
///
/// Add auto scaling group click event handler
///
///
///
private void btnAddASG_Click(object sender, RoutedEventArgs e)
{
if (this.vm.IsVpc && this.vm.SelectedVpc == null)
{
MessageBox.Show("Currently there is no VPC selected. Please select a VPC and then try again.", "No Selected VPC", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
Window win = new AsgWindow((ViewModel)this.DataContext, false);
win.Owner = Window.GetWindow(this);
((AsgWindow)win).AsgAdded += new EventHandler(asgitem_added);
win.ShowDialog();
}
///
/// Event handler when an Auto Scaling Group is added from the AsgWindow
///
///
///
private void asgitem_added(object sender, EventArgs e)
{
try
{
AmazonAutoScalingClient client = GetAutoScaleClient();
CreateAutoScalingGroupRequest req = ((AWS.AutoScale.Console.AsgWindow)sender).ASGRequest;
IAsyncResult result = client.BeginCreateAutoScalingGroup(req, CreateAutoScaleGroupCallback, null);
}
catch
{
((ViewModel)this.DataContext).IsBusy = false;
MessageBox.Show(Window.GetWindow(this), "Error occured while creating auto scaling group. Please ensure your parameters are correct.", "Error", MessageBoxButton.OK);
}
}
///
/// Callback function for BeginCreateAutoScalingGroup async call to create an ASG
///
///
private void CreateAutoScaleGroupCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
try
{
AmazonAutoScalingClient client = GetAutoScaleClient();
CreateAutoScalingGroupResponse resp = client.EndCreateAutoScalingGroup(result);
DescribeAutoScalingGroupsRequest asreq = new DescribeAutoScalingGroupsRequest();
IAsyncResult asresult = client.BeginDescribeAutoScalingGroups(asreq, AutoScalingGroupInfoCallback, "full,new");
}
catch (Exception ex)
{
((ViewModel)this.DataContext).IsBusy = false;
MessageBox.Show(Window.GetWindow(this), "Error occured while creating auto scaling group.\n" + ex.Message, "Error", MessageBoxButton.OK);
}
}));
}
#endregion
#region "Update Availability Group"
///
/// Event handler for "Update Auto Scaling Group" context menu click
///
///
///
private void mnuUpdateAsg(object sender, RoutedEventArgs e)
{
Window win = new AsgWindow((ViewModel)this.DataContext, true);
win.Owner = Window.GetWindow(this);
((AsgWindow)win).AsgUpdated += new EventHandler(asgitem_updated);
win.ShowDialog();
}
///
/// Event handler when an Auto Scaling Group is updated from the AsgWindow
///
///
///
private void asgitem_updated(object sender, EventArgs e)
{
try
{
AmazonAutoScalingClient client = GetAutoScaleClient();
UpdateAutoScalingGroupRequest req = ((AWS.AutoScale.Console.AsgWindow)sender).ASGUpdateRequest;
IAsyncResult result = client.BeginUpdateAutoScalingGroup(req, UpdateAutoScaleGroupCallback, null);
}
catch (Exception ex)
{
LogManager.LogEntry(ex.Message);
LogManager.LogEntry(ex.StackTrace);
((ViewModel)this.DataContext).IsBusy = false;
MessageBox.Show(Window.GetWindow(this), "Error occured while updating auto scaling group. Please ensure your parmaters are correct.", "Error", MessageBoxButton.OK);
}
}
///
/// Callback function for BeginUpdateAutoScalingGroup async call to update an ASG based on user changes in AsgWindow
///
///
private void UpdateAutoScaleGroupCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
AmazonAutoScalingClient client = GetAutoScaleClient();
UpdateAutoScalingGroupResponse resp = client.EndUpdateAutoScalingGroup(result);
if (vm.ASGroup.DesiredCapacity != vm.SelectedAutoScalingGroup.AutoScalingGroup.DesiredCapacity)
{
if (vm.ASGroup.DesiredCapacity > vm.ASGroup.MaxSize)
{
vm.ASGroup.DesiredCapacity = vm.ASGroup.MaxSize;
}
if (vm.ASGroup.DesiredCapacity < vm.ASGroup.MinSize)
{
vm.ASGroup.DesiredCapacity = vm.ASGroup.MinSize;
}
if (((ViewModel)this.DataContext).ASGroup.DesiredCapacity != 0)
{
vm.IsBusy = true;
SetDesiredCapacityRequest sdcreq = new SetDesiredCapacityRequest();
sdcreq.AutoScalingGroupName = vm.SelectedAutoScalingGroup.AutoScalingGroup.AutoScalingGroupName;
sdcreq.DesiredCapacity = vm.ASGroup.DesiredCapacity;
IAsyncResult sdcresult = client.BeginSetDesiredCapacity(sdcreq, SetDesiredCapacityCallback, null);
return;
}
vm.ASGroup = new Models.AsgShell();
DescribeAutoScalingGroupsRequest asreq = new DescribeAutoScalingGroupsRequest();
IAsyncResult asresult = client.BeginDescribeAutoScalingGroups(asreq, AutoScalingGroupInfoCallback, "full");
}
else
{
vm.IsBusy = false;
}
vm.ASGroup = null;
}));
}
///
/// Callback function for BeginSetDesiredCapacity async call to update an ASG desired capacity based on user changes in AsgWindow
///
///
private void SetDesiredCapacityCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
AmazonAutoScalingClient client = GetAutoScaleClient();
SetDesiredCapacityResponse resp = client.EndSetDesiredCapacity(result);
DescribeAutoScalingGroupsRequest asreq = new DescribeAutoScalingGroupsRequest();
IAsyncResult asresult = client.BeginDescribeAutoScalingGroups(asreq, AutoScalingGroupInfoCallback, "full");
vm.IsBusy = false;
}));
}
#endregion
#region "Create Launch Config"
///
/// Event handler for Add launch configuration button
///
///
///
private void btnAddLC_Click(object sender, RoutedEventArgs e)
{
if (this.vm.IsVpc && this.vm.SelectedVpc == null)
{
MessageBox.Show("Currently there is no VPC selected. Please select a VPC and then try again.", "No Selected VPC", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
Window win = new LcWindow((ViewModel)this.DataContext);
win.Owner = Window.GetWindow(this);
((LcWindow)win).LcAdded += new EventHandler(lcitem_added);
win.ShowDialog();
}
///
/// Event handler when a launch configuration is created from the LcWindow
///
///
///
private void lcitem_added(object sender, EventArgs e)
{
try
{
AmazonAutoScalingClient client = GetAutoScaleClient();
CreateLaunchConfigurationRequest req = ((AWS.AutoScale.Console.LcWindow)sender).LcRequest;
IAsyncResult result = client.BeginCreateLaunchConfiguration(req, CreateLaunchConfigCallback, null);
}
catch
{
((ViewModel)this.DataContext).IsBusy = false;
MessageBox.Show(Window.GetWindow(this), "Error occured while creating auto scaling group. Please ensure your parameters are correct.", "Error", MessageBoxButton.OK);
}
}
///
/// Callback function for BeginCreateLaunchConfiguration async call to create a Launch configuration based on user input from LcWindow
///
///
private void CreateLaunchConfigCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
InitiateAwsDataLoadBackgroundworker();
}));
}
#endregion
#region "Delete Launch Config"
///
/// Event handler for "Delete Launch Configuration" context menu click
///
///
///
private void mnuDeleteLc(object sender, EventArgs e)
{
if (vm.SelectedLaunchConfiguration == null || vm.SelectedLaunchConfiguration.LaunchConfiguration.LaunchConfigurationName == null)
{
MessageBox.Show(Window.GetWindow(this), "Please select a Launch Configuration.", "Make Selection", MessageBoxButton.OK);
return;
}
if (MessageBox.Show(Window.GetWindow(this), string.Concat("Do you want to delete the Launch Configuration: ", vm.SelectedLaunchConfiguration.LaunchConfiguration.LaunchConfigurationName, "?"), "Confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
vm.IsBusy = true;
vm.BusyContent = "Deleting Launch Configuration";
AmazonAutoScalingClient client = GetAutoScaleClient();
DeleteLaunchConfigurationRequest req = new DeleteLaunchConfigurationRequest();
req.LaunchConfigurationName = vm.SelectedLaunchConfiguration.LaunchConfiguration.LaunchConfigurationName;
IAsyncResult result = client.BeginDeleteLaunchConfiguration(req, DeleteLaunchConfigCallback, vm.SelectedLaunchConfiguration.LaunchConfiguration.LaunchConfigurationName);
}
}
///
/// Callback function for DeleteLaunchConfigurationRequest async call to delete a Launch configuration
///
///
private void DeleteLaunchConfigCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
InitiateAwsDataLoadBackgroundworker();
}));
}
#endregion
#region "Create Notification"
///
/// Event handler for "Add Notification" context menu click
///
///
///
private void mnuAddNotification(object sender, RoutedEventArgs e)
{
Window win = new NcWindow((ViewModel)this.DataContext);
win.Owner = Window.GetWindow(this);
((NcWindow)win).NcAdded += new EventHandler(ncitem_added);
win.ShowDialog();
}
///
/// Event handler when a notification configuration is created from the NcWindow
///
///
///
private void ncitem_added(object sender, EventArgs e)
{
try
{
AmazonAutoScalingClient client = GetAutoScaleClient();
PutNotificationConfigurationRequest req = ((NcWindow)sender).PutNcRequest;
IAsyncResult result = client.BeginPutNotificationConfiguration(req, PutNotificationConfigCallback, null);
}
catch
{
((ViewModel)this.DataContext).IsBusy = false;
MessageBox.Show(Window.GetWindow(this), "Error occured while adding notification configuration.", "Error", MessageBoxButton.OK);
}
}
///
/// Callback function for BeginPutNotificationConfiguration async call to put a notification configuration with a ASG
///
///
private void PutNotificationConfigCallback(IAsyncResult result)
{
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
InitiateAwsDataLoadBackgroundworker();
}));
}
#endregion
///
/// Close button click event handler
///
///
///
private void btnCloseConfig_Click(object sender, RoutedEventArgs e)
{
reConfiguration.IsExpanded = false;
}
}
}