Skip to content

Commit b5f5681

Browse files
authored
Fix declaration of authentication environment variables and add test. (#459)
* Fix declaration of authentication environment variables and add test. * Run dotnet format * Run dotnet format
1 parent 187ec8f commit b5f5681

File tree

3 files changed

+61
-14
lines changed

3 files changed

+61
-14
lines changed

src/KubernetesClient/KubeConfigModels/ExternalExecution.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class ExternalExecution
1717
/// Environment variables to set when executing the plugin. Optional.
1818
/// </summary>
1919
[YamlMember(Alias = "env")]
20-
public IDictionary<string, string> EnvironmentVariables { get; set; }
20+
public IList<Dictionary<string, string>> EnvironmentVariables { get; set; }
2121

2222
/// <summary>
2323
/// Arguments to pass when executing the plugin. Optional.

src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -407,16 +407,7 @@ public static string RenewAzureToken(string tenantId, string clientId, string ap
407407
throw new KubeConfigException("Refresh not supported.");
408408
}
409409

410-
/// <summary>
411-
/// Implementation of the proposal for out-of-tree client
412-
/// authentication providers as described here --
413-
/// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/auth/kubectl-exec-plugins.md
414-
/// Took inspiration from python exec_provider.py --
415-
/// https://github.com/kubernetes-client/python-base/blob/master/config/exec_provider.py
416-
/// </summary>
417-
/// <param name="config">The external command execution configuration</param>
418-
/// <returns>The token received from the external command execution</returns>
419-
public static string ExecuteExternalCommand(ExternalExecution config)
410+
public static Process CreateRunnableExternalProcess(ExternalExecution config)
420411
{
421412
var execInfo = new Dictionary<string, dynamic>
422413
{
@@ -430,10 +421,19 @@ public static string ExecuteExternalCommand(ExternalExecution config)
430421
process.StartInfo.EnvironmentVariables.Add("KUBERNETES_EXEC_INFO", JsonConvert.SerializeObject(execInfo));
431422
if (config.EnvironmentVariables != null)
432423
{
433-
foreach (var configEnvironmentVariableKey in config.EnvironmentVariables.Keys)
424+
foreach (var configEnvironmentVariable in config.EnvironmentVariables)
434425
{
435-
process.StartInfo.EnvironmentVariables.Add(key: configEnvironmentVariableKey,
436-
value: config.EnvironmentVariables[configEnvironmentVariableKey]);
426+
if (configEnvironmentVariable.ContainsKey("name") && configEnvironmentVariable.ContainsKey("value"))
427+
{
428+
process.StartInfo.EnvironmentVariables.Add(
429+
configEnvironmentVariable["name"],
430+
configEnvironmentVariable["value"]);
431+
}
432+
else
433+
{
434+
var badVariable = string.Join(",", configEnvironmentVariable.Select(x => $"{x.Key}={x.Value}"));
435+
throw new KubeConfigException($"Invalid environment variable defined: {badVariable}");
436+
}
437437
}
438438
}
439439

@@ -447,6 +447,22 @@ public static string ExecuteExternalCommand(ExternalExecution config)
447447
process.StartInfo.RedirectStandardError = true;
448448
process.StartInfo.UseShellExecute = false;
449449

450+
return process;
451+
}
452+
453+
/// <summary>
454+
/// Implementation of the proposal for out-of-tree client
455+
/// authentication providers as described here --
456+
/// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/auth/kubectl-exec-plugins.md
457+
/// Took inspiration from python exec_provider.py --
458+
/// https://github.com/kubernetes-client/python-base/blob/master/config/exec_provider.py
459+
/// </summary>
460+
/// <param name="config">The external command execution configuration</param>
461+
/// <returns>The token received from the external command execution</returns>
462+
public static string ExecuteExternalCommand(ExternalExecution config)
463+
{
464+
var process = CreateRunnableExternalProcess(config);
465+
450466
try
451467
{
452468
process.Start();
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
using k8s.KubeConfigModels;
4+
using Xunit;
5+
6+
namespace k8s.Tests
7+
{
8+
public class ExternalExecutionTests
9+
{
10+
[Fact]
11+
public void CreateRunnableExternalProcess()
12+
{
13+
var actual = KubernetesClientConfiguration.CreateRunnableExternalProcess(new ExternalExecution
14+
{
15+
ApiVersion = "testingversion",
16+
Command = "command",
17+
Arguments = new List<string> { "arg1", "arg2" },
18+
EnvironmentVariables = new List<Dictionary<string, string>>
19+
{ new Dictionary<string, string> { { "name", "testkey" }, { "value", "testvalue" } } }
20+
});
21+
22+
var actualExecInfo = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(actual.StartInfo.EnvironmentVariables["KUBERNETES_EXEC_INFO"]);
23+
Assert.Equal("testingversion", actualExecInfo["apiVersion"]);
24+
Assert.Equal("ExecCredentials", actualExecInfo["kind"]);
25+
26+
Assert.Equal("command", actual.StartInfo.FileName);
27+
Assert.Equal("arg1 arg2", actual.StartInfo.Arguments);
28+
Assert.Equal("testvalue", actual.StartInfo.EnvironmentVariables["testkey"]);
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)