Skip to content
Merged
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace k8s
Expand All @@ -28,6 +29,11 @@ public partial class KubernetesClientConfiguration
// For testing
internal static string KubeConfigEnvironmentVariable { get; set; } = "KUBECONFIG";

/// <summary>
/// Exec process timeout in seconds
/// </summary>
public static int ExecTimeout { get; set; } = 10;

/// <summary>
/// Initializes a new instance of the <see cref="KubernetesClientConfiguration" /> from default locations
/// If the KUBECONFIG environment variable is set, then that will be used.
Expand Down Expand Up @@ -557,19 +563,31 @@ public static ExecCredentialResponse ExecuteExternalCommand(ExternalExecution co
throw new KubeConfigException($"external exec failed due to: {ex.Message}");
}

var stdout = process.StandardOutput.ReadToEnd();
var stderr = process.StandardError.ReadToEnd();
if (string.IsNullOrWhiteSpace(stderr) == false)
var stdOutTask = process.StandardOutput.ReadToEndAsync(); // Assumes process exits

var buffer = new char[4096];
var stdErrorTask = process.StandardError.ReadAsync(buffer, 0, buffer.Length); // Assumes process will continue

var result = Task.WaitAny(new Task[] { stdErrorTask, stdOutTask }, TimeSpan.FromSeconds(ExecTimeout));

if (result == -1)
{
throw new KubeConfigException($"external exec failed due to: {stderr}");
throw new KubeConfigException("external exec failed due to timeout");
}
else if (result == 0)
{
var stderrBuilder = new StringBuilder();
stderrBuilder.Append(buffer, 0, stdErrorTask.GetAwaiter().GetResult());

// Wait for a maximum of 5 seconds, if a response takes longer probably something went wrong...
process.WaitForExit(5);
if (stderrBuilder.Length > 0)
{
throw new KubeConfigException($"external exec failed due to: {stderrBuilder}");
}
}

try
{
var responseObject = KubernetesJson.Deserialize<ExecCredentialResponse>(stdout);
var responseObject = KubernetesJson.Deserialize<ExecCredentialResponse>(stdOutTask.GetAwaiter().GetResult());
if (responseObject == null || responseObject.ApiVersion != config.ApiVersion)
{
throw new KubeConfigException(
Expand Down