PageRenderTime 97ms CodeModel.GetById 41ms app.highlight 49ms RepoModel.GetById 1ms app.codeStats 1ms

/trunk/Resources/Companion/AdminRole/Controllers/AdminController.cs

#
C# | 749 lines | 612 code | 60 blank | 77 comment | 70 complexity | 09e154bb93ece724b229cf0847785bad MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Web;
  5using System.Web.Mvc;
  6using Microsoft.WindowsAzure;
  7using Microsoft.WindowsAzure.ServiceRuntime;
  8using System.Diagnostics;
  9using Microsoft.WindowsAzure.Companion.Models;
 10using WindowsAzureCompanion.VMManagerService;
 11using System.IO;
 12using System.Drawing;
 13using System.Collections.Specialized;
 14using System.Data.Services.Client;
 15
 16namespace Microsoft.WindowsAzure.Companion.Controllers
 17{
 18    public class AdminController : BaseController
 19    {
 20        public AdminController()
 21        {
 22            ViewData["CurrentTab"] = "Admin";
 23        }
 24
 25        //
 26        // GET: /Admin/
 27
 28        [Authorize]
 29        public ActionResult Admin()
 30        {
 31            // Check for error message
 32            string errorMessage = ViewData["ErrorMessage"] as string;
 33            if (!string.IsNullOrEmpty(errorMessage))
 34            {
 35                return RedirectToAction("Error", "Home", new { ErrorMessage = errorMessage });
 36            }
 37
 38            if (Request.QueryString["Subtab"] == null)
 39            {
 40                ViewData["Subtab"] = "WindowsAzureLogs";
 41            }
 42            else
 43            {
 44                ViewData["Subtab"] = Request.QueryString["Subtab"];
 45            }
 46
 47            try
 48            {
 49                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
 50                if (ViewData["Subtab"].ToString().Equals("WindowsAzureLogs"))
 51                {
 52                    try
 53                    {
 54                        CloudStorageAccount storageAccount = WindowsAzureVMManager.GetStorageAccount(true);
 55                        WindowsAzureLogDataServiceContext context = new WindowsAzureLogDataServiceContext(
 56                            storageAccount.TableEndpoint.ToString(), storageAccount.Credentials);
 57                        ViewData["WindowsAzureLogs"] = context.WindowsAzureLogs;
 58                    }
 59                    catch (Exception ex)
 60                    {
 61                        Trace.TraceError("Unable to create storage credetials and account: {0}", ex.Message);
 62                        return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to create storage credetials and account." });
 63                    }
 64                }
 65                else if (ViewData["Subtab"].ToString().Equals("PHPLogs"))
 66                {
 67                    try
 68                    {
 69                        // Set php log file name
 70                        ViewData["PHPLogFileName"] = vmManager.GetPHPLogFileName();
 71                    }
 72                    catch (Exception ex)
 73                    {
 74                        Trace.TraceError("Unable to get PHP log file: {0}", ex.Message);
 75                        return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to get PHP log file." });
 76                    }
 77                }
 78                else if (ViewData["Subtab"].ToString().Equals("PerformanceMonitor"))
 79                {
 80                    try
 81                    {
 82                        CloudStorageAccount storageAccount = WindowsAzureVMManager.GetStorageAccount(true);
 83                        WindowsAzurePerformanceCounterDataServiceContext context = new WindowsAzurePerformanceCounterDataServiceContext(
 84                            storageAccount.TableEndpoint.ToString(), storageAccount.Credentials);
 85
 86                        // TODO: Currently used while loop, need to use LINQ
 87                        long cpuUsageCount = 0;                    
 88                        double maxCPUUsage = Double.NaN;
 89                        double minCPUUsage = Double.NaN;
 90                        double cpuUsageSum = 0;
 91                        long availableMemoryCount = 0;                    
 92                        double maxAvailableMemory = Double.NaN;
 93                        double minAvailableMemory = Double.NaN;
 94                        double availableMemorySum = 0;
 95                        foreach (WindowsAzurePerformanceCounter counter in context.WindowsAzurePerformanceCounters)
 96                        {
 97                            if (counter.CounterName.Equals(@"\Processor(_Total)\% Processor Time"))
 98                            {
 99                                if ((maxCPUUsage.Equals(Double.NaN)) || (counter.CounterValue > maxCPUUsage))
100                                {
101                                    maxCPUUsage = counter.CounterValue;
102                                }
103                                if ((minCPUUsage.Equals(Double.NaN)) || (counter.CounterValue < minCPUUsage))
104                                {
105                                    minCPUUsage = counter.CounterValue;
106                                }
107
108                                cpuUsageSum += counter.CounterValue;
109                                cpuUsageCount++;
110                            }
111                            else if (counter.CounterName.Equals(@"\Memory\Available Mbytes"))
112                            {
113                                if ((maxAvailableMemory.Equals(Double.NaN)) || (counter.CounterValue > maxAvailableMemory))
114                                {
115                                    maxAvailableMemory = counter.CounterValue;
116                                }
117                                if ((minAvailableMemory.Equals(Double.NaN)) || (counter.CounterValue < minAvailableMemory))
118                                {
119                                    minAvailableMemory = counter.CounterValue;
120                                }
121
122                                availableMemorySum += counter.CounterValue;
123                                availableMemoryCount++;
124                            }
125                        }
126
127                        if ((cpuUsageCount != 0) && (availableMemoryCount != 0))
128                        {
129                            double avgCpuUsage = Math.Round(cpuUsageSum / cpuUsageCount, 2);
130                            double avgAvailableMemory = Math.Round(availableMemorySum / availableMemoryCount, 2);
131
132                            ViewData["CPUUsageCount"] = cpuUsageCount.ToString();
133                            ViewData["AvailableMemoryCount"] = availableMemoryCount.ToString();
134
135                            ViewData["MaxCPUUsage"] = Math.Round(maxCPUUsage, 2).ToString();
136                            ViewData["MaxAvailableMemory"] = Math.Round(maxAvailableMemory, 2).ToString();
137
138                            ViewData["MinCPUUsage"] = Math.Round(minCPUUsage, 2).ToString();
139                            ViewData["MinAvailableMemory"] = Math.Round(minAvailableMemory, 2).ToString();
140
141                            ViewData["AvgCPUUsage"] = avgCpuUsage.ToString();
142                            ViewData["AvgAvailableMemory"] = avgAvailableMemory.ToString();
143
144                            ViewData["DiagnosticsAndPerformanceCounterCaptureFrequencyInMinutes"] = 
145                                RoleEnvironment.GetConfigurationSettingValue("DiagnosticsAndPerformanceCounterCaptureFrequencyInMinutes");
146                        }
147                    }
148                    catch (DataServiceQueryException ex)
149                    {
150                        Trace.TraceError("Error fetching Performance. Error: {0}", ex.Message);
151                        Trace.TraceInformation("Performance Counters not yet available.");
152                    }
153                    catch (Exception ex)
154                    {
155                        Trace.TraceError("Unable to create storage credetials and account: {0}", ex.Message);
156                        return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to create storage credetials and account." });
157                    }
158                }            
159                else if (ViewData["Subtab"].ToString().Equals("ConfigureRuntime"))
160                {
161                    // Set MySQL based server status                
162                    string isMySQLBasedDBInstalled = vmManager.IsMySQLServerInstalled().ToString();
163                    ViewData["IsMySQLBasedDBInstalled"] = isMySQLBasedDBInstalled;
164                    if (isMySQLBasedDBInstalled.ToLower().Equals("true"))
165                    {                    
166                        ViewData["MySQLBasedDBName"] = vmManager.GetMySQLBasedDBName().ToString();
167                        ViewData["IsMySQLBasedDBStarted"] = vmManager.IsMySQLServerStarted().ToString();
168                        ViewData["MySQLBasedDBServerPortNumber"] = vmManager.GetMySQLBasedDBServerPortNumber();
169                        ViewData["MySQLBasedDBServerIPAddress"] = vmManager.GetMySQLBasedDBServerIPAddress();
170                    }
171
172                    // Set php.ini file name
173                    ViewData["PHPIniFileName"] = vmManager.GetPHPIniFileName();
174
175                    // Set PHP Web Site status
176                    if (vmManager.IsPHPWebSiteStarted())
177                    {
178                        ViewData["PHPWebSiteStatus"] = "Started";
179                    }
180                    else
181                    {
182                        ViewData["PHPWebSiteStatus"] = "Stopped";
183                    }
184
185                    // Set php log file name
186                    ViewData["PHPLogFileName"] = vmManager.GetPHPLogFileName();
187                }
188                else if (ViewData["Subtab"].ToString().Equals("CronJobs"))
189                {
190                    try
191                    {
192                        // Set php cron jobs
193                        ViewData["CronJobs"] = vmManager.GetCronJobs();
194                    }
195                    catch (Exception ex)
196                    {
197                        Trace.TraceError("Unable to get PHP Cron Jobs: {0}", ex.Message);
198                        return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to get PHP Cron Jobs." });
199                    }
200                }
201                else if (ViewData["Subtab"].ToString().Equals("BackupAndCleanup"))
202                {
203                    string message = Request.QueryString["Message"];
204                    if (!string.IsNullOrEmpty(message))
205                    {
206                        ViewData["Message"] = message;
207                    }
208
209                    string resetWindowsAzureDrive = Request.QueryString["ResetWindowsAzureDrive"];
210                    if (!string.IsNullOrEmpty(resetWindowsAzureDrive))
211                    {
212                        ViewData["ResetWindowsAzureDrive"] = resetWindowsAzureDrive;
213                    }
214
215                    // Get list of Windows Azure Drive Snapshots
216                    try
217                    {
218                        List<string> snapshotUris = vmManager.GetWindowsAzureDriveSnapshots();
219                        ViewData["WindowsAzureDriveSnapshots"] = snapshotUris;
220                    }
221                    catch (Exception ex)
222                    {
223                        Trace.TraceError("Unable to list Windows Azure Drive Snapshots: {0}", ex.Message);
224                        return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to list Windows Azure Drive Snapshots." });
225                    }
226                }            
227                else if (ViewData["Subtab"].ToString().Equals("ProgressInformation"))
228                {
229                    // Get progress information of current activity
230                    IDictionary<string, string> progressInformation = vmManager.GetProgressInformation();
231                    if (progressInformation == null || progressInformation.Count == 0)
232                    {
233                        // No progress information, redirect to caller if possible
234                        string actionName = Request.QueryString["ActionName"];
235                        string controllerName = Request.QueryString["ControllerName"];
236                        string actionSubtabName = Request.QueryString["ActionSubtabName"];
237                        string currentTab = Request.QueryString["CurrentTab"];
238                        if ((actionName != null) && (controllerName != null) && (actionSubtabName != null))
239                        {
240                            return RedirectToAction(
241                                actionName,
242                                controllerName,
243                                new
244                                {
245                                    Subtab = actionSubtabName,
246                                    CurrentTab = currentTab
247                                });
248                        }
249                        else
250                        {
251                            return RedirectToAction("Error", "Home", new { ErrorMessage = "No progress information available." });
252                        }
253                    }
254                    else
255                    {
256                        // Get first entry as title and remove it
257                        string titleKey = progressInformation.Keys.First();
258                        string[] messageInfo = progressInformation[titleKey].Split('|');
259                        string progressInformationTitle = messageInfo[1];
260                        progressInformation.Remove(titleKey);
261
262                        ViewData["ProgressInformation"] = progressInformation;
263                        ViewData["ProgressInformationTitle"] = progressInformationTitle;
264
265                        // Check if last message is an error
266                        if (progressInformation.Count > 0)
267                        {
268                            string lastKey = progressInformation.Keys.Last();
269                            messageInfo = progressInformation[lastKey].Split('|');
270                            if (messageInfo[2].ToLower().Equals("true"))
271                            {
272                                // Error found indicating async operation failed, do not refresh page
273                                ViewData["ErrorMessage"] = messageInfo[1];
274                            }
275                            else
276                            {
277                                // No error, refresh the page after 5 second
278                                Response.AppendHeader("Refresh", "5; URL=" + Request.Url.PathAndQuery);
279                            }
280                        }
281                        else
282                        {
283                            // No progress info yet, refresh the page after 5 second
284                            Response.AppendHeader("Refresh", "5; URL=" + Request.Url.PathAndQuery);
285                        }
286                    }
287                }
288                else if (ViewData["Subtab"].ToString().Equals("ManageInstances"))
289                {
290                    // TODO for v2
291                }
292            }
293            catch (Exception ex)
294            {
295                Trace.TraceError("Unknown error: {0}", ex.Message);
296                return RedirectToAction("Error", "Home", new { ErrorMessage = string.Format("Unknown error: {0}", ex.Message) });
297            }
298            return View();
299        }
300
301        // GET: /Admin/WindowsAzureLogs
302        [Authorize]
303        public ActionResult WindowsAzureLogs()
304        {
305            return RedirectToAction("Admin", "Admin", new { Subtab = "WindowsAzureLogs" });
306        }
307
308        // GET: /Admin/PHPLogs
309        [Authorize]
310        public ActionResult PHPLogs()
311        {
312            return RedirectToAction("Admin", "Admin", new { Subtab = "PHPLogs" });
313        }
314
315        // GET: /Admin/PerformanceMonitor
316        [Authorize]
317        public ActionResult PerformanceMonitor()
318        {
319            return RedirectToAction("Admin", "Admin", new { Subtab = "PerformanceMonitor" });
320        }
321
322        // GET: /Admin/ConfigureRuntime
323        [Authorize]
324        public ActionResult ConfigureRuntime()
325        {
326            return RedirectToAction("Admin", "Admin", new { Subtab = "ConfigureRuntime" });
327        }
328
329        // GET: /Admin/CronJobs
330        [Authorize]
331        public ActionResult CronJobs()
332        {
333            return RedirectToAction("Admin", "Admin", new { Subtab = "CronJobs" });
334        }
335
336        // GET: /Admin/ConfigureRuntime
337        [Authorize, ValidateInput(false)]
338        public ActionResult UpdatePHPRuntime(FormCollection form)
339        {
340            // Update php.ini content
341            IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
342            string phpIniFileName = vmManager.GetPHPIniFileName();
343            if (System.IO.File.Exists(phpIniFileName))
344            {
345                // Get new ini file content
346                string content =  form.Get("PHPIniContent");
347
348                // Update php.ini file
349                StreamWriter streamWriter = System.IO.File.CreateText(phpIniFileName);
350                streamWriter.Write(content);
351                streamWriter.Close();
352
353                // Now restart the PHP web site (required by FastCGI/IIS)
354                vmManager.RestartPHPWebSite();
355            }
356
357            // Redirect to same ConfigureRuntime subtab
358            return RedirectToAction("Admin", "Admin", new { Subtab = "ConfigureRuntime" });
359        }
360
361        // GET: /Admin/BackupAndCleanup
362        [Authorize]
363        public ActionResult CreateSnapshot(FormCollection form)
364        {
365            try
366            {
367                // Create Windows Azure Drive Snapshot
368                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
369                string uristring = vmManager.CreateWindowsAzureDriveSnapshot(form.Get("SnapshotComment"));
370                if (string.IsNullOrEmpty(uristring))
371                {
372                    Trace.TraceError("Unable to Create Windows Azure Drive Snapshot.");
373
374                    return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to Create Windows Azure Drive Snapshot." });                    
375                }
376                else
377                {
378                    // Redirect to same BackupAndCleanup subtab
379                    return RedirectToAction("Admin", "Admin", 
380                        new { 
381                            Subtab = "BackupAndCleanup",
382                            Message = "Created new Windows Azure Drive Snapshot: " + uristring
383                        });
384                }
385            }
386            catch (Exception ex)
387            {
388                Trace.TraceError("Unable to create Windows Azure Drive Snapshot: {0}", ex.Message);
389                return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to create Windows Azure Drive Snapshot." });
390            }
391        }
392
393        // GET: /Admin/BackupAndCleanup
394        [Authorize]
395        public ActionResult PromoteSnapshot(FormCollection form)
396        {
397            try
398            {
399                // Promote Windows Azure Drive Snapshot
400                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
401                bool result = vmManager.PromoteWindowsAzureDriveSnapshot(form.Get("snapshotUri"));
402                if (!result)
403                {
404                    Trace.TraceError("Unable to promote Windows Azure Drive Snapshot.");
405
406                    return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to promote Windows Azure Drive Snapshot." });
407                }
408                else
409                {
410                    return RedirectToAction(
411                       "ProgressInformation",
412                       "Admin",
413                       new
414                       {
415                           ActionName = "Admin",
416                           ControllerName = "Admin",
417                           ActionSubtabName = "BackupAndCleanup",
418                           CurrentTab = "Admin"
419                       }
420                   );                    
421                }
422            }
423            catch (Exception ex)
424            {
425                Trace.TraceError("Unable to propote Windows Azure Drive Snapshot: {0}", ex.Message);
426                return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to create Windows Azure Drive Snapshot." });
427            }
428        }
429
430        // GET: /Admin/BackupAndCleanup
431        [Authorize]
432        public ActionResult DeleteSnapshot(FormCollection form)
433        {
434            try
435            {
436                // Delete Windows Azure Drive Snapshot
437                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
438                bool result = vmManager.DeleteWindowsAzureDriveSnapshot(form.Get("snapshotUri"));
439                if (!result)
440                {
441                    Trace.TraceError("Unable to delete Windows Azure Drive Snapshot.");
442
443                    return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to delete Windows Azure Drive Snapshot." });
444                }
445                else
446                {
447                    // Redirect to same BackupAndCleanup subtab
448                    return RedirectToAction("Admin", "Admin",
449                        new
450                        {
451                            Subtab = "BackupAndCleanup",
452                            Message = "Deleted Windows Azure Drive snapshot " + form.Get("snapshotUri")
453                        });
454                }
455            }
456            catch (Exception ex)
457            {
458                Trace.TraceError("Unable to delete Windows Azure Drive Snapshot: {0}", ex.Message);
459                return RedirectToAction("Error", "Home", new { ErrorMessage = "Unable to delete Windows Azure Drive Snapshot." });
460            }
461        }
462
463        // GET: /Admin/BackupAndCleanup
464        [Authorize]
465        public ActionResult ResetWindowsAzureDrive()
466        {            
467            // Create Windows Azure Drive Snapshot
468            IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
469            if (vmManager.ResetWindowsAzureDrive())
470            {
471                return RedirectToAction(
472                   "ProgressInformation",
473                   "Admin",
474                   new
475                   {
476                       ActionName = "Admin",
477                       ControllerName = "Admin",
478                       ActionSubtabName = "BackupAndCleanup",
479                       CurrentTab = "Admin"
480                   }
481               );
482            }
483            else
484            {
485                return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to Reset Windows Azure Drive." });
486            }
487        }
488
489        // GET: /Admin/ConfigureRuntime
490        [Authorize]
491        public ActionResult StopPHPRuntime()
492        {
493            try
494            {
495                // Stop PHP Web Site
496                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
497                vmManager.StopPHPWebSite();
498            }
499            catch (Exception ex)
500            {
501                Trace.TraceError("Failed to stop PHP web site. Error: {0}", ex.Message);
502                return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to stop PHP web site." });
503            }
504
505            // Redirect to same ConfigureRuntime page
506            return RedirectToAction("Admin", "Admin", new { Subtab = "ConfigureRuntime" });
507        }
508
509        // GET: /Admin/ConfigureRuntime
510        [Authorize]
511        public ActionResult StartPHPRuntime()
512        {
513            try
514            {
515                // Start PHP Web Site
516                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
517                vmManager.StartPHPWebSite();
518            }
519            catch (Exception ex)
520            {
521                Trace.TraceError("Failed to start PHP web site. Error: {0}", ex.Message);
522                return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to start PHP web site." });
523            }
524
525            // Check is PHP web site startup is requested from applications tab
526            string actionName = Request.QueryString["ActionName"];
527            string controllerName = Request.QueryString["ControllerName"];
528            string actionSubtabName = Request.QueryString["ActionSubtabName"];
529            string currentTab = Request.QueryString["CurrentTab"];
530            if ((actionName != null) && (controllerName != null) && (actionSubtabName != null) && (currentTab != null))
531            {
532                return RedirectToAction(
533                    actionName,
534                    controllerName,
535                    new
536                    {
537                        Subtab = actionSubtabName,
538                        CurrentTab = currentTab
539                    });
540            }
541            else
542            {
543                // Redirect to same ConfigureRuntime page
544                return RedirectToAction("Admin", "Admin", new { Subtab = "ConfigureRuntime" });
545            }
546        }
547
548        // GET: /Admin/ConfigureRuntime
549        [Authorize]
550        public ActionResult RestartPHPRuntime()
551        {
552            try
553            {
554                // Restart PHP Web Site
555                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
556                vmManager.RestartPHPWebSite();
557            }
558            catch (Exception ex)
559            {
560                Trace.TraceError("Failed to restart PHP web site. Error: {0}", ex.Message);
561                return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to restart PHP web site." });
562            }
563
564            // Redirect to same ConfigureRuntime page
565            return RedirectToAction("Admin", "Admin", new { Subtab = "ConfigureRuntime" });
566        }
567
568        // GET: /Admin/ConfigureRuntime
569        [Authorize]
570        public ActionResult StopMySQLServer()
571        {
572            try
573            {
574                // Stop MySQL Server
575                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
576                vmManager.StopMySQLServer();
577            }
578            catch (Exception ex)
579            {
580                Trace.TraceError("Failed to stop MySQL based server. Error: {0}", ex.Message);
581                return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to stop MySQL based server." });
582            }
583
584            // Redirect to same ConfigureRuntime page
585            return RedirectToAction("Admin", "Admin", new { Subtab = "ConfigureRuntime" });
586        }
587
588        // GET: /Admin/ConfigureRuntime
589        [Authorize]
590        public ActionResult StartMySQLServer()
591        {
592            try
593            {
594                // Start MySQL based server
595                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
596                vmManager.StartMySQLServer();
597            }
598            catch (Exception ex)
599            {
600                Trace.TraceError("Failed to start MySQL based server. Error: {0}", ex.Message);
601                return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to start MySQL based server." });
602            }
603
604            // Redirect to same ConfigureRuntime page
605            return RedirectToAction("Admin", "Admin", new { Subtab = "ConfigureRuntime" });
606        }
607
608        // GET: /Admin/ConfigureRuntime
609        [Authorize]
610        public ActionResult RestartMySQLServer()
611        {
612            try
613            {
614                // Restart MySQL based server
615                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
616                vmManager.RestartMySQLServer();
617            }
618            catch (Exception ex)
619            {
620                Trace.TraceError("Failed to restart MySQL based server. Error: {0}", ex.Message);
621                return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to restart MySQL based server." });
622            }
623
624            // Redirect to same ConfigureRuntime page
625            return RedirectToAction("Admin", "Admin", new { Subtab = "ConfigureRuntime" });
626        }
627
628        /// <summary>
629        /// Start the Cron Job
630        /// </summary>
631        /// <param name="form">The form.</param>
632        /// <returns></returns>
633        [AcceptVerbs(HttpVerbs.Post)]
634        public ActionResult StartCronJob(FormCollection form)
635        {
636            try
637            {
638                string productId = form.Get("productId");
639                int cronJobIndex = int.Parse(form.Get("cronJobIndex"));
640
641                // Start cron job
642                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
643                if (!vmManager.StartCronJob(productId, cronJobIndex))
644                {
645                    Trace.TraceError("Failed to start cron job.");
646                    return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to start cron job." });
647                }
648            }
649            catch (Exception ex)
650            {
651                Trace.TraceError("Failed to start cron job. Error: {0}", ex.Message);
652                return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to start cron job." });
653            }
654
655            return RedirectToAction("Admin", "Admin", new { Subtab = "CronJobs" });
656        }
657
658        /// <summary>
659        /// Stop the Cron Job
660        /// </summary>
661        /// <param name="form">The form.</param>
662        /// <returns></returns>
663        [AcceptVerbs(HttpVerbs.Post)]
664        public ActionResult StopCronJob(FormCollection form)
665        {
666            try
667            {
668                string productId = form.Get("productId");
669                int cronJobIndex = int.Parse(form.Get("cronJobIndex"));
670
671                // Stop cron job
672                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
673                if (!vmManager.StopCronJob(productId, cronJobIndex))
674                {
675                    Trace.TraceError("Failed to stop cron job.");
676                    return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to stop cron job." });
677                }
678            }
679            catch (Exception ex)
680            {
681                Trace.TraceError("Failed to stop cron job. Error: {0}", ex.Message);
682                return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to stop cron job." });
683            }
684
685            return RedirectToAction("Admin", "Admin", new { Subtab = "CronJobs" });
686        }
687
688        // GET: /Admin/ProgressInformation
689        [Authorize]
690        public ActionResult ClearProgressInformation()
691        {
692            try
693            {
694                // Clear Progress Information
695                IVMManager vmManager = WindowsAzureVMManager.GetVMManager();
696                vmManager.ClearProgressInformation();
697            
698                return RedirectToAction("Admin", "Admin");
699            }
700            catch (Exception ex)
701            {
702                Trace.TraceError("Failed to clear profress information. Error: {0}", ex.Message);
703                return RedirectToAction("Error", "Home", new { ErrorMessage = "Failed to clear progress information." });
704            }
705        }
706
707        // GET: /Admin/BackupAndCleanup
708        [Authorize]
709        public ActionResult BackupAndCleanup()
710        {
711            return RedirectToAction("Admin", "Admin", new { Subtab = "BackupAndCleanup" });
712        }
713
714        // GET: /Admin/ManageInstances
715        [Authorize]
716        public ActionResult ManageInstances()
717        {
718            return RedirectToAction("Admin", "Admin", new { Subtab = "ManageInstances" });
719        }
720
721        // GET: /Admin/ProgressInformation
722        public ActionResult ProgressInformation()
723        {
724            // Passon caller information, if any
725            string actionName = Request.QueryString["ActionName"];
726            string controllerName = Request.QueryString["ControllerName"];
727            string actionSubtabName = Request.QueryString["ActionSubtabName"];
728            string currentTab = Request.QueryString["CurrentTab"];
729            if ((actionName != null) && (controllerName != null) && (actionSubtabName != null))
730            {
731                return RedirectToAction(
732                    "Admin",
733                    "Admin",
734                    new
735                    {
736                        Subtab = "ProgressInformation",
737                        ActionName = actionName,
738                        ControllerName = controllerName,
739                        ActionSubtabName = actionSubtabName,
740                        CurrentTab = currentTab
741                    });
742            }
743            else
744            {
745                return RedirectToAction("Admin", "Admin", new { Subtab = "ProgressInformation" });
746            }
747        }
748    }
749}