// Copyright Epic Games, Inc. All Rights Reserved. using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; using System.Xml; using EpicGames.Core; namespace AutomationTool.Tasks { /// /// Parameters for an AWS CLI task /// public class AwsAssumeRoleTaskParameters { /// /// Role to assume /// [TaskParameter] public string Arn { get; set; } /// /// Name of this session /// [TaskParameter] public string Session { get; set; } /// /// Duration of the token in seconds /// [TaskParameter(Optional = true)] public int Duration { get; set; } = 1000; /// /// Environment variables /// [TaskParameter(Optional = true)] public string Environment { get; set; } /// /// File to read environment variables from /// [TaskParameter(Optional = true)] public string EnvironmentFile { get; set; } /// /// Output file for the new environment /// [TaskParameter] public string OutputFile { get; set; } } /// /// Assumes an AWS role. /// [TaskElement("Aws-AssumeRole", typeof(AwsAssumeRoleTaskParameters))] public class AwsAssumeRoleTask : SpawnTaskBase { class AwsSettings { public AwsCredentials Credentials { get; set; } } class AwsCredentials { public string AccessKeyId { get; set; } public string SecretAccessKey { get; set; } public string SessionToken { get; set; } } readonly AwsAssumeRoleTaskParameters _parameters; /// /// Construct an AWS CLI task /// /// Parameters for the task public AwsAssumeRoleTask(AwsAssumeRoleTaskParameters parameters) { _parameters = parameters; } /// /// ExecuteAsync the task. /// /// Information about the current job /// Set of build products produced by this node. /// Mapping from tag names to the set of files they include public override async Task ExecuteAsync(JobContext job, HashSet buildProducts, Dictionary> tagNameToFileSet) { StringBuilder arguments = new StringBuilder("sts assume-role"); if (_parameters.Arn != null) { arguments.Append($" --role-arn {_parameters.Arn}"); } if (_parameters.Session != null) { arguments.Append($" --role-session-name {_parameters.Session}"); } arguments.Append($" --duration-seconds {_parameters.Duration}"); Dictionary environment = SpawnTaskBase.ParseEnvVars(_parameters.Environment, _parameters.EnvironmentFile); IProcessResult result = await SpawnTaskBase.ExecuteAsync("aws", arguments.ToString(), envVars: environment, logOutput: false); JsonSerializerOptions options = new JsonSerializerOptions(); options.PropertyNameCaseInsensitive = true; AwsSettings settings = JsonSerializer.Deserialize(result.Output, options); if (settings.Credentials != null) { if (settings.Credentials.AccessKeyId != null) { environment["AWS_ACCESS_KEY_ID"] = settings.Credentials.AccessKeyId; } if (settings.Credentials.SecretAccessKey != null) { environment["AWS_SECRET_ACCESS_KEY"] = settings.Credentials.SecretAccessKey; } if (settings.Credentials.SessionToken != null) { environment["AWS_SESSION_TOKEN"] = settings.Credentials.SessionToken; } } FileReference outputFile = ResolveFile(_parameters.OutputFile); DirectoryReference.CreateDirectory(outputFile.Directory); await FileReference.WriteAllLinesAsync(outputFile, environment.OrderBy(x => x.Key).Select(x => $"{x.Key}={x.Value}")); } /// /// Output this task out to an XML writer. /// public override void Write(XmlWriter writer) { Write(writer, _parameters); } /// /// Find all the tags which are used as inputs to this task /// /// The tag names which are read by this task public override IEnumerable FindConsumedTagNames() { yield break; } /// /// Find all the tags which are modified by this task /// /// The tag names which are modified by this task public override IEnumerable FindProducedTagNames() { yield break; } } }