From 97c15fd816dd2ce60c1dfe799cca18c18c6d83ee Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 15 Mar 2023 15:03:27 -0700 Subject: [PATCH 1/3] Parse runners and send publicKey --- src/Runner.Common/RunnerDotcomServer.cs | 5 +++-- src/Runner.Listener/Configuration/ConfigurationManager.cs | 4 +++- src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs | 7 +++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Runner.Common/RunnerDotcomServer.cs b/src/Runner.Common/RunnerDotcomServer.cs index 510877e2e..399719e91 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); 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) { var gitHubUrlBuilder = new UriBuilder(githubUrl); var path = gitHubUrlBuilder.Path.Split('/', '\\', StringSplitOptions.RemoveEmptyEntries); @@ -159,6 +159,7 @@ namespace GitHub.Runner.Common {"updates_disabled", agent.DisableUpdate}, {"ephemeral", agent.Ephemeral}, {"labels", agent.Labels}, + {"public_key", publicKey}, }; var body = new StringContent(StringUtil.ConvertToJson(bodyObject), null, "application/json"); diff --git a/src/Runner.Listener/Configuration/ConfigurationManager.cs b/src/Runner.Listener/Configuration/ConfigurationManager.cs index 492bea042..867624d9f 100644 --- a/src/Runner.Listener/Configuration/ConfigurationManager.cs +++ b/src/Runner.Listener/Configuration/ConfigurationManager.cs @@ -181,9 +181,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 +299,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); } else { diff --git a/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs b/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs index 292b8d668..e223083cd 100644 --- a/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs +++ b/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs @@ -34,6 +34,13 @@ namespace GitHub.DistributedTask.WebApi set; } + public List ToTaskAgents() + { + List taskAgents = new List(); + + return Runners.Select(runner => new TaskAgent() { Name = runner.Name }).ToList(); + } + public ListRunnersResponse Clone() { return new ListRunnersResponse(this); From 97d28f7803999ef3d7d3e9028396919a5facfd80 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Thu, 16 Mar 2023 10:30:15 -0700 Subject: [PATCH 2/3] wip --- src/Runner.Common/RunnerDotcomServer.cs | 16 ++++++--- .../Configuration/ConfigurationManager.cs | 12 ++++++- src/Sdk/DTWebApi/WebApi/Runner.cs | 35 +++++++++++++++++-- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/Runner.Common/RunnerDotcomServer.cs b/src/Runner.Common/RunnerDotcomServer.cs index 399719e91..96cf82b00 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, string publicKey); + 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, string publicKey) + 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); @@ -160,11 +160,19 @@ namespace GitHub.Runner.Common {"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 response = await RetryRequest(githubApiUrl, githubToken, RequestType.Post, 3, "Failed to add agent", body); + var runner = StringUtil.ConvertFromJson(response); + 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 867624d9f..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 @@ -299,7 +302,7 @@ namespace GitHub.Runner.Listener.Configuration { if (runnerSettings.UseV2Flow) { - agent = await _dotcomServer.AddRunnerAsync(runnerSettings.PoolId, agent, runnerSettings.GitHubUrl, registerToken, publicKeyXML); + agent = await _dotcomServer.AddRunnerAsync(runnerSettings.PoolId, agent, runnerSettings.GitHubUrl, registerToken, publicKeyXML, hostId); } else { @@ -775,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/Runner.cs b/src/Sdk/DTWebApi/WebApi/Runner.cs index 2103bf3a2..e6d9de992 100644 --- a/src/Sdk/DTWebApi/WebApi/Runner.cs +++ b/src/Sdk/DTWebApi/WebApi/Runner.cs @@ -1,12 +1,28 @@ using Newtonsoft.Json; +using System.Security.AccessControl; 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; + } } } From 534bcec44bf1435c0fd37ca6d7c55d4d530d2453 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Tue, 21 Mar 2023 11:29:42 -0400 Subject: [PATCH 3/3] Fix conflicts --- src/Runner.Common/RunnerDotcomServer.cs | 3 +-- src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs | 9 --------- src/Sdk/DTWebApi/WebApi/Runner.cs | 2 +- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/Runner.Common/RunnerDotcomServer.cs b/src/Runner.Common/RunnerDotcomServer.cs index 96cf82b00..77fdaf88e 100644 --- a/src/Runner.Common/RunnerDotcomServer.cs +++ b/src/Runner.Common/RunnerDotcomServer.cs @@ -165,8 +165,7 @@ namespace GitHub.Runner.Common var body = new StringContent(StringUtil.ConvertToJson(bodyObject), null, "application/json"); - var response = await RetryRequest(githubApiUrl, githubToken, RequestType.Post, 3, "Failed to add agent", body); - var runner = StringUtil.ConvertFromJson(response); + var runner = await RetryRequest(githubApiUrl, githubToken, RequestType.Post, 3, "Failed to add agent", body); agent.Id = runner.Id; agent.Authorization = new TaskAgentAuthorization() { diff --git a/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs b/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs index e223083cd..ddc83813f 100644 --- a/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs +++ b/src/Sdk/DTWebApi/WebApi/ListRunnersResponse.cs @@ -34,13 +34,6 @@ namespace GitHub.DistributedTask.WebApi set; } - public List ToTaskAgents() - { - List taskAgents = new List(); - - return Runners.Select(runner => new TaskAgent() { Name = runner.Name }).ToList(); - } - public ListRunnersResponse Clone() { return new ListRunnersResponse(this); @@ -48,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 e6d9de992..7e981bc97 100644 --- a/src/Sdk/DTWebApi/WebApi/Runner.cs +++ b/src/Sdk/DTWebApi/WebApi/Runner.cs @@ -1,5 +1,5 @@ +using System; using Newtonsoft.Json; -using System.Security.AccessControl; namespace GitHub.DistributedTask.WebApi {