Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit a4a2cf7c3c8213d1160f40030760f22e8f4c7ca9 @smarx committed Sep 14, 2012
Showing with 280 additions and 0 deletions.
  1. +7 −0 .gitignore
  2. +22 −0 WazMonkey.sln
  3. +150 −0 WazMonkey/Program.cs
  4. +36 −0 WazMonkey/Properties/AssemblyInfo.cs
  5. +61 −0 WazMonkey/WazMonkey.csproj
  6. +4 −0 WazMonkey/packages.config
7 .gitignore
@@ -0,0 +1,7 @@
+obj
+bin
+*.user
+*.suo
+*.cache
+*.nupkg
+packages/
22 WazMonkey.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WazMonkey", "WazMonkey\WazMonkey.csproj", "{64597F68-E7A2-4DE1-A89C-222DB35DC2BF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{7C06F84E-6400-4C19-AF5A-541E548ECFC0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {64597F68-E7A2-4DE1-A89C-222DB35DC2BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {64597F68-E7A2-4DE1-A89C-222DB35DC2BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {64597F68-E7A2-4DE1-A89C-222DB35DC2BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {64597F68-E7A2-4DE1-A89C-222DB35DC2BF}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
150 WazMonkey/Program.cs
@@ -0,0 +1,150 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using CommandLine;
+using CommandLine.Text;
+using System.Xml.Linq;
+using System.Security.Cryptography.X509Certificates;
+using System.Net;
+using System.Globalization;
+
+namespace WazMonkey
+{
+ class Options : CommandLineOptionsBase
+ {
+ [Option("p", "publishSettings", Required = false, HelpText = ".publishSettings file - specify either this or a .pfx file")]
+ public string PublishSettingsFile { get; set; }
+
+ [Option(null, "pfx", Required = false, HelpText = ".pfx certificate file - specify either this or a .publishSettings file")]
+ public string PfxFile { get; set; }
+
+ [Option(null, "subscriptionId", Required = false, HelpText = "subscriptionId to use, defaults to first subscription found in the .publishSettings file")]
+ public string SubscriptionId { get; set; }
+
+ [Option("n", "serviceName", Required = true, HelpText = "Name of the cloud service")]
+ public string ServiceName { get; set; }
+
+ [Option("s", "slot", Required = true, HelpText = @"The slot (""production"" or ""staging"")")]
+ public string Slot { get; set; }
+
+ [HelpOption(HelpText = "Display this help screen.")]
+ public string GetUsage()
+ {
+ var help = new HelpText
+ {
+ Heading = new HeadingInfo("WazMonkey", "v0.1"),
+ Copyright = new CopyrightInfo("Steve Marx", 2012),
+ AdditionalNewLineAfterOption = true,
+ AddDashesToOption = true
+ };
+ help.AddPreOptionsLine("Usage: WazMonkey -p foo.publishSettings -n myservice -s production");
+ help.AddOptions(this);
+ return help;
+ }
+ }
+
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ var options = new Options();
+ if (CommandLineParser.Default.ParseArguments(args, options))
+ {
+ if (options.PublishSettingsFile == null && options.PfxFile == null)
+ {
+ Console.WriteLine("Required: one of --publishSettings or --pfx");
+ Console.WriteLine(options.GetUsage());
+ Environment.Exit(1);
+ }
+ if (options.PublishSettingsFile != null && options.PfxFile != null)
+ {
+ Console.WriteLine("Incompatible arguments: --publishSettings and --pfx");
+ Console.WriteLine(options.GetUsage());
+ Environment.Exit(1);
+ }
+ if (options.PublishSettingsFile == null && options.SubscriptionId == null)
+ {
+ Console.WriteLine("--subscriptionId must be provided if no .publishSettings file is being used");
+ Console.WriteLine(options.GetUsage());
+ Environment.Exit(1);
+ }
+ if (options.Slot != "production" && options.Slot != "staging")
+ {
+ Console.WriteLine(@"Slot must be one of ""production"" or ""staging""");
+ Console.WriteLine(options.GetUsage());
+ Environment.Exit(1);
+ }
+ }
+ else
+ {
+ Environment.Exit(1);
+ }
+
+ X509Certificate2 cert;
+ string subscriptionId = options.SubscriptionId;
+
+ if (options.PublishSettingsFile != null)
+ {
+ var profile = XDocument.Load(options.PublishSettingsFile);
+ if (subscriptionId == null)
+ {
+ subscriptionId = profile.Descendants("Subscription").First().Attribute("Id").Value;
+ }
+ cert = new X509Certificate2(Convert.FromBase64String(
+ profile.Descendants("PublishProfile").Single()
+ .Attribute("ManagementCertificate").Value));
+ }
+ else
+ {
+ cert = new X509Certificate2(options.PfxFile);
+ }
+
+ var baseAddress = string.Format("https://management.core.windows.net/{0}/services/hostedservices/{1}/deploymentslots/{2}", subscriptionId, options.ServiceName, options.Slot);
+
+ // request details on specified deployment
+ var req = (HttpWebRequest)WebRequest.Create(baseAddress);
+ req.Headers["x-ms-version"] = "2012-03-01";
+ req.ClientCertificates.Add(cert);
+
+ // find all instances
+ XNamespace xmlns = "http://schemas.microsoft.com/windowsazure";
+ try
+ {
+ var responseStream = req.GetResponse().GetResponseStream();
+ }
+ catch (WebException e)
+ {
+ if (((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.NotFound)
+ {
+ var titleCaseSlot = new CultureInfo("en-us", false).TextInfo.ToTitleCase(options.Slot);
+ Console.WriteLine("Error: {0} deployment for service {1} not found, or the credentials were invalid.", titleCaseSlot, options.ServiceName);
+ Environment.Exit(1);
+ }
+ else
+ {
+ throw;
+ }
+ }
+ var instances = XDocument.Load(req.GetResponse().GetResponseStream()).Descendants(xmlns + "InstanceName").Select(n => n.Value).ToArray();
+
+ // choose one at random
+ var instance = instances[new Random().Next(instances.Length)];
+ Console.WriteLine("Rebooting {0}.", instance);
+
+ // reboot it
+ req = (HttpWebRequest)WebRequest.Create(string.Format("{0}/roleinstances/{1}?comp=reboot", baseAddress, instance));
+ req.Method = "POST";
+ req.ContentLength = 0;
+ req.Headers["x-ms-version"] = "2012-03-01";
+ req.ClientCertificates.Add(cert);
+
+ // make sure the response was "accepted"
+ var response = (HttpWebResponse)req.GetResponse();
+ if (response.StatusCode != HttpStatusCode.Accepted)
+ {
+ Console.WriteLine("Got unexpected status code: {0}", response.StatusCode);
+ }
+ }
+ }
+}
36 WazMonkey/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("WazMonkey")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("WazMonkey")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("03ac350e-8227-472b-bf6b-ca08d451fcc5")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
61 WazMonkey/WazMonkey.csproj
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{64597F68-E7A2-4DE1-A89C-222DB35DC2BF}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>WazMonkey</RootNamespace>
+ <AssemblyName>WazMonkey</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="CommandLine">
+ <HintPath>..\packages\CommandLineParser.1.9.3.19\lib\CommandLine.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
4 WazMonkey/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="CommandLineParser" version="1.9.3.19" targetFramework="net40" />
+</packages>

0 comments on commit a4a2cf7

Please sign in to comment.