diff --git a/src/Runner.Common/RunnerDotcomServer.cs b/src/Runner.Common/RunnerDotcomServer.cs index 510877e2e..77fdaf88e 100644 --- a/src/Runner.Common/RunnerDotcomServer.cs +++ b/src/Runner.Common/RunnerDotcomServer.cs @@ -17,7 +17,7 @@ namespace GitHub.Runner.Common { Task> GetRunnersAsync(int runnerGroupId, string githubUrl, string githubToken, string agentName); - Task AddRunnerAsync(int runnerGroupId, TaskAgent agent, string githubUrl, string githubToken); + Task AddRunnerAsync(int runnerGroupId, TaskAgent agent, string githubUrl, string githubToken, string publicKey, string hostId); Task> GetRunnerGroupsAsync(string githubUrl, string githubToken); string GetGitHubRequestId(HttpResponseHeaders headers); @@ -136,7 +136,7 @@ namespace GitHub.Runner.Common return agentPools?.ToAgentPoolList(); } - public async Task AddRunnerAsync(int runnerGroupId, TaskAgent agent, string githubUrl, string githubToken) + public async Task AddRunnerAsync(int runnerGroupId, TaskAgent agent, string githubUrl, string githubToken, string publicKey, string hostId) { var gitHubUrlBuilder = new UriBuilder(githubUrl); var path = gitHubUrlBuilder.Path.Split('/', '\\', StringSplitOptions.RemoveEmptyEntries); @@ -159,11 +159,19 @@ namespace GitHub.Runner.Common {"updates_disabled", agent.DisableUpdate}, {"ephemeral", agent.Ephemeral}, {"labels", agent.Labels}, + {"public_key", publicKey}, + {"host_id", hostId}, }; var body = new StringContent(StringUtil.ConvertToJson(bodyObject), null, "application/json"); - var responseAgent = await RetryRequest(githubApiUrl, githubToken, RequestType.Post, 3, "Failed to add agent", body); - agent.Id = responseAgent.Id; + + var runner = await RetryRequest(githubApiUrl, githubToken, RequestType.Post, 3, "Failed to add agent", body); + agent.Id = runner.Id; + agent.Authorization = new TaskAgentAuthorization() + { + AuthorizationUrl = runner.RunnerAuthorization.AuthorizationUrl, + ClientId = new Guid(runner.RunnerAuthorization.ClientId), + }; return agent; } diff --git a/src/Runner.Listener/Configuration/ConfigurationManager.cs b/src/Runner.Listener/Configuration/ConfigurationManager.cs index 492bea042..327879474 100644 --- a/src/Runner.Listener/Configuration/ConfigurationManager.cs +++ b/src/Runner.Listener/Configuration/ConfigurationManager.cs @@ -14,6 +14,7 @@ using GitHub.Runner.Sdk; using GitHub.Services.Common; using GitHub.Services.Common.Internal; using GitHub.Services.OAuth; +using GitHub.Services.WebApi.Jwt; namespace GitHub.Runner.Listener.Configuration { @@ -116,6 +117,7 @@ namespace GitHub.Runner.Listener.Configuration VssCredentials creds = null; _term.WriteSection("Authentication"); string registerToken = string.Empty; + string hostId = string.Empty; while (true) { // When testing against a dev deployment of Actions Service, set this environment variable @@ -140,6 +142,7 @@ namespace GitHub.Runner.Listener.Configuration _term.WriteLine($"Using V2 flow: {runnerSettings.UseV2Flow}"); creds = authResult.ToVssCredentials(); Trace.Info("cred retrieved via GitHub auth"); + hostId = GetHostId(authResult.Token); } try @@ -181,9 +184,11 @@ namespace GitHub.Runner.Listener.Configuration // We want to use the native CSP of the platform for storage, so we use the RSACSP directly RSAParameters publicKey; var keyManager = HostContext.GetService(); + string publicKeyXML; using (var rsa = keyManager.CreateKey()) { publicKey = rsa.ExportParameters(false); + publicKeyXML = rsa.ToXmlString(includePrivateParameters: false); } _term.WriteSection("Runner Registration"); @@ -297,7 +302,7 @@ namespace GitHub.Runner.Listener.Configuration { if (runnerSettings.UseV2Flow) { - agent = await _dotcomServer.AddRunnerAsync(runnerSettings.PoolId, agent, runnerSettings.GitHubUrl, registerToken); + agent = await _dotcomServer.AddRunnerAsync(runnerSettings.PoolId, agent, runnerSettings.GitHubUrl, registerToken, publicKeyXML, hostId); } else { @@ -773,5 +778,12 @@ namespace GitHub.Runner.Listener.Configuration } return null; } + + // Temporary hack for sending legacy host id using v2 flow + private string GetHostId(string accessToken) + { + var claims = JsonWebToken.Create(accessToken).ExtractClaims(); + return claims.FirstOrDefault(x => x.Type == "aud").Value.Split(':').LastOrDefault(); + } } } diff --git a/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs b/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs index 292b8d668..ddc83813f 100644 --- a/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs +++ b/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs @@ -41,8 +41,6 @@ namespace GitHub.DistributedTask.WebApi public List ToTaskAgents() { - List taskAgents = new List(); - return Runners.Select(runner => new TaskAgent() { Name = runner.Name }).ToList(); } } diff --git a/src/Sdk/DTWebApi/WebApi/Runner.cs b/src/Sdk/DTWebApi/WebApi/Runner.cs index 2103bf3a2..7e981bc97 100644 --- a/src/Sdk/DTWebApi/WebApi/Runner.cs +++ b/src/Sdk/DTWebApi/WebApi/Runner.cs @@ -1,12 +1,28 @@ +using System; using Newtonsoft.Json; namespace GitHub.DistributedTask.WebApi { public class Runner { - /// - /// Name of the agent - /// + + public class Authorization + { + [JsonProperty("authorization_url")] + public Uri AuthorizationUrl + { + get; + internal set; + } + + [JsonProperty("client_id")] + public string ClientId + { + get; + internal set; + } + } + [JsonProperty("name")] public string Name { @@ -14,5 +30,18 @@ namespace GitHub.DistributedTask.WebApi internal set; } + [JsonProperty("id")] + public Int32 Id + { + get; + internal set; + } + + [JsonProperty("authorization")] + public Authorization RunnerAuthorization + { + get; + internal set; + } } }