Permalink
Browse files

Added deployed by property to deployment api.

- Parse basic auth credentials from the incoming request (if available).
  • Loading branch information...
1 parent 6d90ba6 commit 10852d8d9323adca9709caf9bf553a839480c480 @davidfowl davidfowl committed Apr 20, 2012
View
@@ -17,7 +17,7 @@ static int Main(string[] args)
{
if (args.Length < 2)
{
- System.Console.WriteLine("Usage: kudu.exe {appRoot} {wapTargets}");
+ System.Console.WriteLine("Usage: kudu.exe appRoot wapTargets [deployer]");
return 1;
}
@@ -30,6 +30,7 @@ static int Main(string[] args)
var appRoot = args[0];
var wapTargets = args[1];
+ string deployer = args.Length == 2 ? null : args[2];
string nugetCachePath = null;
IEnvironment env = GetEnvironment(appRoot, nugetCachePath);
@@ -69,7 +70,7 @@ static int Main(string[] args)
{
try
{
- deploymentManager.Deploy();
+ deploymentManager.Deploy(deployer);
}
catch
{
@@ -23,6 +23,9 @@ public class DeployResult
[DataMember(Name = "author")]
public string Author { get; set; }
+ [DataMember(Name = "deployer")]
+ public string Deployer { get; set; }
+
[DataMember(Name = "message")]
public string Message { get; set; }
@@ -1,9 +0,0 @@
-namespace Kudu.Core.Deployment
-{
- public interface IDeploymentCommandGenerator
- {
- string DeploymentEnvironmentVariable { get; }
- string GetDeploymentExePath();
- string GetDeploymentCommand();
- }
-}
@@ -0,0 +1,20 @@
+namespace Kudu.Core.Deployment
+{
+ public interface IDeploymentEnvironment
+ {
+ /// <summary>
+ /// Path to kudu.exe
+ /// </summary>
+ string ExePath { get; }
+
+ /// <summary>
+ /// Represents _app path in the kudu service (the target application)
+ /// </summary>
+ string ApplicationPath { get; }
+
+ /// <summary>
+ /// Path to the msbuild extension path (contains wap targets etc)
+ /// </summary>
+ string MSBuildExtensionsPath { get; }
+ }
+}
@@ -12,8 +12,8 @@ public interface IDeploymentManager
IEnumerable<LogEntry> GetLogEntries(string id);
IEnumerable<LogEntry> GetLogEntryDetails(string id, string logId);
void Delete(string id);
- void Deploy(string id, bool clean);
- void Deploy();
+ void Deploy(string id, string deployer, bool clean);
+ void Deploy(string deployer);
void CreateExistingDeployment(string id);
}
}
@@ -51,7 +51,7 @@
<Compile Include="Commands\ICommandExecutor.cs" />
<Compile Include="Deployment\DeployResult.cs" />
<Compile Include="Deployment\DeployStatus.cs" />
- <Compile Include="Deployment\IDeploymentCommandGenerator.cs" />
+ <Compile Include="Deployment\IDeploymentEnvironment.cs" />
<Compile Include="Deployment\IDeploymentManager.cs" />
<Compile Include="Deployment\IDeploymentManagerFactory.cs" />
<Compile Include="Deployment\LogEntry.cs" />
@@ -4,6 +4,7 @@ namespace Kudu.Core.SourceControl.Git
{
public interface IGitServer : IServerRepository
{
+ void SetAuthor(string author);
void AdvertiseUploadPack(Stream output);
void AdvertiseReceivePack(Stream output);
bool Receive(Stream inputStream, Stream outputStream);
@@ -0,0 +1,104 @@
+using System;
+using System.Text;
+using Kudu.Services.Infrastructure;
+using Xunit;
+
+namespace Kudu.Core.Test
+{
+ public class AuthUtilityFacts
+ {
+ public class TryExtractBasicAuthUserFromHeader
+ {
+ [Fact]
+ public void FailsToParseIfHeaderIsNull()
+ {
+ // Arrange
+ string username;
+
+ // Act
+ var result = AuthUtility.TryExtractBasicAuthUserFromHeader(null, out username);
+
+ // Assert
+ Assert.False(result);
+ Assert.Null(username);
+ }
+
+ [Fact]
+ public void FailsToParseIfHeaderIsSchemeNotBasic()
+ {
+ // Arrange
+ string username;
+
+ // Act
+ var result = AuthUtility.TryExtractBasicAuthUserFromHeader("Digest: something", out username);
+
+ // Assert
+ Assert.False(result);
+ Assert.Null(username);
+ }
+
+ [Fact]
+ public void ParsesBasicAuthHeader()
+ {
+ // Arrange
+ var payload = Convert.ToBase64String(Encoding.UTF8.GetBytes("user:password"));
+ string username;
+
+ // Act
+ var result = AuthUtility.TryExtractBasicAuthUserFromHeader("Basic " + payload, out username);
+
+ // Assert
+ Assert.True(result);
+ Assert.Equal("user", username);
+ }
+ }
+
+ public class TryParseBasicAuthUserFromHeaderParameter
+ {
+ [Fact]
+ public void ParsesUsername()
+ {
+ // Arrange
+ var payload = Convert.ToBase64String(Encoding.UTF8.GetBytes("user:password"));
+ string username;
+
+ // Act
+ var result = AuthUtility.TryParseBasicAuthUserFromHeaderParameter(payload, out username);
+
+ // Assert
+ Assert.True(result);
+ Assert.Equal("user", username);
+ }
+
+ [Fact]
+ public void FailsToParseIfNoSeparator()
+ {
+ // Arrange
+ var payload = Convert.ToBase64String(Encoding.UTF8.GetBytes("userpassword"));
+ string username;
+
+ // Act
+ var result = AuthUtility.TryParseBasicAuthUserFromHeaderParameter(payload, out username);
+
+ // Assert
+ Assert.False(result);
+ Assert.Null(username);
+ }
+
+ [Fact]
+ public void FailsToParseIfNoUsername()
+ {
+ // Arrange
+ var payload = Convert.ToBase64String(Encoding.UTF8.GetBytes(":password"));
+ string username;
+
+ // Act
+ var result = AuthUtility.TryParseBasicAuthUserFromHeaderParameter(payload, out username);
+
+ // Assert
+ Assert.False(result);
+ Assert.Null(username);
+ }
+ }
+ }
+}
@@ -57,6 +57,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="AuthUtilityFacts.cs" />
<Compile Include="CommandExecutorTest.cs" />
<Compile Include="FileSystemHelpersTest.cs" />
<Compile Include="GitRepositoryRepositoryTest.cs" />
@@ -73,6 +74,10 @@
<Project>{5320177C-725A-44BD-8FA6-F88D9725B46C}</Project>
<Name>Kudu.Core</Name>
</ProjectReference>
+ <ProjectReference Include="..\Kudu.Services\Kudu.Services.csproj">
+ <Project>{D163E227-9EB6-4619-AD37-D8EEF831AEF0}</Project>
+ <Name>Kudu.Services</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@@ -149,7 +149,7 @@ public void Delete(string id)
}
}
- public void Deploy(string id, bool clean)
+ public void Deploy(string id, string deployer, bool clean)
{
ITracer tracer = _traceFactory.GetTracer();
IDisposable deployStep = null;
@@ -188,6 +188,14 @@ public void Deploy(string id, bool clean)
_serverRepository.Clean();
}
+ if (!String.IsNullOrEmpty(deployer))
+ {
+ // Update the deployer
+ DeploymentStatusFile statusFile = OpenStatusFile(id);
+ statusFile.Deployer = deployer;
+ statusFile.Save(_fileSystem);
+ }
+
// Perform the build deployment of this changeset
Build(id, tracer, deployStep);
}
@@ -204,7 +212,7 @@ public void Deploy(string id, bool clean)
}
}
- public void Deploy()
+ public void Deploy(string deployer)
{
var tracer = _traceFactory.GetTracer();
IDisposable deployStep = null;
@@ -247,7 +255,7 @@ public void Deploy()
return;
}
- ILogger logger = CreateAndPopulateStatusFile(tracer, id);
+ ILogger logger = CreateAndPopulateStatusFile(tracer, id, deployer);
using (tracer.Step("Update to " + pushInfo.Branch.Name))
{
@@ -307,7 +315,7 @@ public void CreateExistingDeployment(string id)
}
}
- private ILogger CreateAndPopulateStatusFile(ITracer tracer, string id)
+ private ILogger CreateAndPopulateStatusFile(ITracer tracer, string id, string deployer = null)
{
ILogger logger = GetLogger(id);
@@ -319,11 +327,13 @@ private ILogger CreateAndPopulateStatusFile(ITracer tracer, string id)
ChangeSet changeSet = _serverRepository.GetChangeSet(id);
statusFile.Message = changeSet.Message;
statusFile.Author = changeSet.AuthorName;
+ statusFile.Deployer = deployer;
statusFile.AuthorEmail = changeSet.AuthorEmail;
statusFile.Save(_fileSystem);
logger.Log(Resources.Log_NewDeploymentReceived);
}
+
return logger;
}
@@ -340,6 +350,7 @@ private DeployResult GetResult(string id, string activeDeploymentId, bool isDepl
{
Id = file.Id,
Author = file.Author,
+ Deployer = file.Deployer,
AuthorEmail = file.AuthorEmail,
Message = file.Message,
StartTime = file.StartTime,
@@ -70,6 +70,7 @@ public static DeploymentStatusFile Open(IFileSystem fileSystem, string path)
{
Id = document.Root.Element("id").Value,
Author = GetOptionalElementValue(document.Root, "author"),
+ Deployer = GetOptionalElementValue(document.Root, "deployer"),
AuthorEmail = GetOptionalElementValue(document.Root, "authorEmail"),
Message = GetOptionalElementValue(document.Root, "message"),
Status = status,
@@ -88,6 +89,7 @@ public static DeploymentStatusFile Open(IFileSystem fileSystem, string path)
public string AuthorEmail { get; set; }
public string Author { get; set; }
public string Message { get; set; }
+ public string Deployer { get; set; }
public DateTime ReceivedTime { get; set; }
public DateTime StartTime { get; set; }
public DateTime? EndTime { get; set; }
@@ -104,6 +106,7 @@ public void Save(IFileSystem fileSystem)
var document = new XDocument(new XElement("deployment",
new XElement("id", Id),
new XElement("author", Author),
+ new XElement("deployer", Deployer),
new XElement("authorEmail", AuthorEmail),
new XElement("message", Message),
new XElement("status", Status),
@@ -17,22 +17,23 @@ public class GitExeServer : IGitServer, IServerRepository
private readonly ITraceFactory _traceFactory;
private readonly GitExeRepository _repository;
private readonly IOperationLock _initLock;
- private readonly IDeploymentCommandGenerator _deploymentCommandGenerator;
private static readonly TimeSpan _initTimeout = TimeSpan.FromMinutes(8);
- public GitExeServer(string path, IOperationLock initLock, IDeploymentCommandGenerator deploymentCommandGenerator, ITraceFactory traceFactory)
+ public GitExeServer(string path, IOperationLock initLock, IDeploymentEnvironment deploymentEnvironment, ITraceFactory traceFactory)
{
_gitExe = new GitExecutable(path);
_gitExe.SetTraceLevel(2);
_traceFactory = traceFactory;
_repository = new GitExeRepository(path, traceFactory);
_repository.SetTraceLevel(2);
_initLock = initLock;
- _deploymentCommandGenerator = deploymentCommandGenerator;
// Setup the deployment environment variable to be used by the post receive hook
- _gitExe.EnvironmentVariables[_deploymentCommandGenerator.DeploymentEnvironmentVariable] = _deploymentCommandGenerator.GetDeploymentExePath();
+ _gitExe.EnvironmentVariables[KnownEnviornment.EXEPATH] = deploymentEnvironment.ExePath;
+ _gitExe.EnvironmentVariables[KnownEnviornment.APPPATH] = deploymentEnvironment.ApplicationPath;
+ _gitExe.EnvironmentVariables[KnownEnviornment.MSBUILD] = deploymentEnvironment.MSBuildExtensionsPath;
+ _gitExe.EnvironmentVariables[KnownEnviornment.AUTHOR] = "";
}
private string PostReceiveHookPath
@@ -191,10 +192,9 @@ private void InitializeRepository(RepositoryConfiguration configuration)
string content = @"#!/bin/sh
read i
echo $i > pushinfo
-";
- string command = "\n" + _deploymentCommandGenerator.GetDeploymentCommand();
+" + KnownEnviornment.KUDUCOMMAND + "\n";
- File.WriteAllText(PostReceiveHookPath, content + command);
+ File.WriteAllText(PostReceiveHookPath, content);
}
}
}
@@ -203,5 +203,27 @@ public RepositoryType GetRepositoryType()
{
return RepositoryType.Git;
}
+
+ public void SetAuthor(string author)
+ {
+ _gitExe.EnvironmentVariables[KnownEnviornment.AUTHOR] = author;
+ }
+
+ /// <summary>
+ /// Environment variables used for the post receive hook
+ /// </summary>
+ private static class KnownEnviornment
+ {
+ public const string EXEPATH = "KUDU_EXE";
+ public const string APPPATH = "KUDU_APPPATH";
+ public const string MSBUILD = "KUDU_MSBUILD";
+ public const string AUTHOR = "KUDU_AUTHOR";
+
+ // Command to launch the post receive hook
+ public static string KUDUCOMMAND = "$" + EXEPATH + " " +
+ "$" + APPPATH + " " +
+ "$" + MSBUILD + " " +
+ "$" + AUTHOR;
+ }
}
}
Oops, something went wrong.

0 comments on commit 10852d8

Please sign in to comment.