Example #1
0
        /// <summary>
        /// Send an Signature Version 4 signed HTTP request as an asynchronous operation.
        /// </summary>
        /// <param name="self">
        /// The extension target.
        /// </param>
        /// <param name="request">
        /// The HTTP request message to send.
        /// </param>
        /// <param name="completionOption">
        /// When the operation should complete (as soon as a response is available or after reading
        /// the whole response content).
        /// </param>
        /// <param name="cancellationToken">
        /// The cancellation token to cancel operation.
        /// </param>
        /// <param name="regionName">
        /// The system name of the AWS region associated with the endpoint, e.g. "us-east-1".
        /// </param>
        /// <param name="serviceName">
        /// The signing name of the service, e.g. "execute-api".
        /// </param>
        /// <param name="credentials">
        /// AWS credentials containing the following parameters:
        /// - The AWS public key for the account making the service call.
        /// - The AWS secret key for the account making the call, in clear text.
        /// - The session token obtained from STS if request is authenticated using temporary
        ///   security credentials, e.g. a role.
        /// </param>
        /// <returns>
        /// The task object representing the asynchronous operation.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="request"/> is null.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// The request message was already sent by the <see cref="HttpClient"/> instance.
        /// </exception>
        /// <exception cref="HttpRequestException">
        /// The request failed due to an underlying issue such as network connectivity, DNS
        /// failure, server certificate validation or timeout.
        /// </exception>
        /// <remarks>
        /// This operation will not block. Depending on the value of the
        /// <paramref name="completionOption"/> parameter, the returned <see cref="Task{TResult}"/>
        /// object will complete as soon as a response is available or the entire response
        /// including content is read.
        /// </remarks>
        public static async Task <HttpResponseMessage> SendAsync(
            this HttpClient self,
            HttpRequestMessage request,
            HttpCompletionOption completionOption,
            CancellationToken cancellationToken,
            string regionName,
            string serviceName,
            AWSCredentials credentials)
        {
            if (credentials == null)
            {
                throw new ArgumentNullException(nameof(credentials));
            }

            var immutableCredentials = await credentials.GetCredentialsAsync();

            var response = await self.SendAsync(
                request,
                completionOption,
                cancellationToken,
                regionName,
                serviceName,
                immutableCredentials);

            return(response);
        }
Example #2
0
        public static async Task <AWSCredentials> AssumeRoleAsync(AWSCredentials credentials, string roleArn,
                                                                  string roleSessionName)
        {
            var assumedCredentials   = new AssumeRoleAWSCredentials(credentials, roleArn, roleSessionName);
            var immutableCredentials = await credentials.GetCredentialsAsync();

            if (string.IsNullOrWhiteSpace(immutableCredentials.Token))
            {
                throw new InvalidOperationException($"Unable to assume role {roleArn}");
            }

            return(assumedCredentials);
        }
Example #3
0
        private async Task <bool> CanLoadCredentials(AWSCredentials credentials)
        {
            if (null == credentials)
            {
                return(false);
            }

            try
            {
                await credentials.GetCredentialsAsync();

                return(true);
            }
            catch
            {
                return(false);
            }
        }
Example #4
0
        /// <summary>
        /// AWS Credentials and Region information is determined after DI container is built.
        /// <see cref="RegisterAWSContext"/> extension method allows to register late bound properties (credentials & region) to
        /// <see cref="ICommandLineWrapper"/> instance.
        /// </summary>
        public static void RegisterAWSContext(
            this ICommandLineWrapper commandLineWrapper,
            AWSCredentials awsCredentials,
            string region)
        {
            commandLineWrapper.ConfigureProcess(async processStartInfo =>
            {
                var credentials = await awsCredentials.GetCredentialsAsync();

                // use this syntax to make sure we don't create duplicate entries
                processStartInfo.EnvironmentVariables["AWS_ACCESS_KEY_ID"]     = credentials.AccessKey;
                processStartInfo.EnvironmentVariables["AWS_SECRET_ACCESS_KEY"] = credentials.SecretKey;
                processStartInfo.EnvironmentVariables["AWS_REGION"]            = region;

                if (credentials.UseToken)
                {
                    processStartInfo.EnvironmentVariables["AWS_SESSION_TOKEN"] = credentials.Token;
                }
            });
        }
Example #5
0
        public async ValueTask <AwsCredentials> GetCredentialsAsync(CancellationToken cancellationToken = default)
        {
            var credentials = await _awsCredentials.GetCredentialsAsync().ConfigureAwait(false);

            return(new AwsCredentials(credentials.AccessKey, credentials.SecretKey, credentials.UseToken ? credentials.Token : null));
        }
Example #6
0
        /// <inheritdoc />
        public async Task Run(
            string command,
            string workingDirectory = "",
            bool streamOutputToInteractiveService = true,
            Action <TryRunResult> onComplete      = null,
            bool redirectIO = true,
            CancellationToken cancelToken = default)
        {
            StringBuilder strOutput   = new StringBuilder();
            StringBuilder strError    = new StringBuilder();
            var           credentials = await _awsCredentials.GetCredentialsAsync();

            var processStartInfo = new ProcessStartInfo
            {
                FileName = GetSystemShell(),

                Arguments =
                    RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
                        ? $"/c {command}"
                        : $"-c \"{command}\"",

                RedirectStandardInput  = redirectIO,
                RedirectStandardOutput = redirectIO,
                RedirectStandardError  = redirectIO,
                UseShellExecute        = false,
                CreateNoWindow         = redirectIO,
                WorkingDirectory       = workingDirectory
            };

            // environment variables could already be set at the machine level,
            // use this syntax to make sure we don't create duplicate entries
            processStartInfo.EnvironmentVariables["AWS_ACCESS_KEY_ID"]     = credentials.AccessKey;
            processStartInfo.EnvironmentVariables["AWS_SECRET_ACCESS_KEY"] = credentials.SecretKey;
            processStartInfo.EnvironmentVariables["AWS_REGION"]            = _awsRegion;

            if (credentials.UseToken)
            {
                processStartInfo.EnvironmentVariables["AWS_SESSION_TOKEN"] = credentials.Token;
            }

            var process = Process.Start(processStartInfo);

            if (null == process)
            {
                throw new Exception("Process.Start failed to return a non-null process");
            }

            if (redirectIO && streamOutputToInteractiveService)
            {
                process.OutputDataReceived += (sender, e) => {
                    _interactiveService.LogMessageLine(e.Data);
                    strOutput.Append(e.Data);
                };
                process.ErrorDataReceived += (sender, e) => {
                    _interactiveService.LogMessageLine(e.Data);
                    strError.Append(e.Data);
                };
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
            }

            // poll for process to prevent blocking the main thread
            // as opposed to using process.WaitForExit()
            // in .net5 we can use process.WaitForExitAsync()
            while (true)
            {
                if (process.HasExited)
                {
                    break;
                }

                await Task.Delay(TimeSpan.FromMilliseconds(50), cancelToken);
            }

            if (onComplete != null)
            {
                var result = new TryRunResult
                {
                    ExitCode = process.ExitCode
                };

                if (redirectIO)
                {
                    result.StandardError = streamOutputToInteractiveService ? strError.ToString() : await process.StandardError.ReadToEndAsync();

                    result.StandardOut = streamOutputToInteractiveService ? strOutput.ToString() : await process.StandardOutput.ReadToEndAsync();
                }

                onComplete(result);
            }
        }