Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KubeClient v2.3.5 #106

Merged
merged 3 commits into from
Oct 6, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
15 changes: 15 additions & 0 deletions KubeClient.sln
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeploymentWithRollback", "s
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WatchEvents", "samples\WatchEvents\WatchEvents.csproj", "{EA1B1086-1813-478A-96B8-D54ABAEA77BE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KubeClient.Extensions.Configuration.Tests", "test\KubeClient.Extensions.Configuration.Tests\KubeClient.Extensions.Configuration.Tests.csproj", "{F712BCDC-21FB-4598-A8D3-88746948496E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -232,6 +234,18 @@ Global
{EA1B1086-1813-478A-96B8-D54ABAEA77BE}.Release|x64.Build.0 = Release|Any CPU
{EA1B1086-1813-478A-96B8-D54ABAEA77BE}.Release|x86.ActiveCfg = Release|Any CPU
{EA1B1086-1813-478A-96B8-D54ABAEA77BE}.Release|x86.Build.0 = Release|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Debug|x64.ActiveCfg = Debug|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Debug|x64.Build.0 = Debug|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Debug|x86.ActiveCfg = Debug|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Debug|x86.Build.0 = Debug|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Release|Any CPU.Build.0 = Release|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Release|x64.ActiveCfg = Release|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Release|x64.Build.0 = Release|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Release|x86.ActiveCfg = Release|Any CPU
{F712BCDC-21FB-4598-A8D3-88746948496E}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -252,6 +266,7 @@ Global
{4DCB98B3-4B9D-4A80-A819-60281A1B0739} = {619D7194-2A3C-4C5C-A5A3-EBAD28C1D65F}
{2DEC9BCC-AA1C-4A1A-B0EA-FC5930297568} = {619D7194-2A3C-4C5C-A5A3-EBAD28C1D65F}
{EA1B1086-1813-478A-96B8-D54ABAEA77BE} = {619D7194-2A3C-4C5C-A5A3-EBAD28C1D65F}
{F712BCDC-21FB-4598-A8D3-88746948496E} = {0F92C90F-A489-4059-AE24-36361B883E81}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {191B89E7-F944-4315-9E98-F6F736D27296}
Expand Down
103 changes: 79 additions & 24 deletions samples/ConfigFromConfigMap/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ static async Task<int> Main(string[] commandLineArguments)

try
{
const string configMapName = "config-from-configmap";
const string configMap1Name = "config-from-configmap-1";
const string configMap2Name = "config-from-configmap-2";
const string configMapNamespace = "default";

KubeClientOptions clientOptions = K8sConfig.Load().ToKubeClientOptions(defaultKubeNamespace: configMapNamespace, loggerFactory: loggerFactory);
Expand All @@ -47,35 +48,68 @@ static async Task<int> Main(string[] commandLineArguments)

KubeApiClient client = KubeApiClient.Create(clientOptions);

Log.Information("Checking for existing ConfigMap...");
ConfigMapV1 configMap = await client.ConfigMapsV1().Get(configMapName, configMapNamespace);
if (configMap != null)
Log.Information("Checking for existing ConfigMaps...");

ConfigMapV1 configMap1 = await client.ConfigMapsV1().Get(configMap1Name, configMapNamespace);
if (configMap1 != null)
{
Log.Information("Deleting existing ConfigMap {ConfigMapName}...", configMap1Name);
await client.ConfigMapsV1().Delete(configMap1Name);
Log.Information("Deleted existing ConfigMap {ConfigMapName}.", configMap1Name);
}

ConfigMapV1 configMap2 = await client.ConfigMapsV1().Get(configMap2Name, configMapNamespace);
if ( configMap2 != null )
{
Log.Information("Deleting existing ConfigMap...");
await client.ConfigMapsV1().Delete(configMapName);
Log.Information("Existing ConfigMap deleted.");
Log.Information("Deleting existing ConfigMap {ConfigMapName}...", configMap2Name);
await client.ConfigMapsV1().Delete(configMap2Name);
Log.Information("Deleted existing ConfigMap {ConfigMapName}.", configMap2Name);
}

Log.Information("Creating new ConfigMap...");
configMap = await client.ConfigMapsV1().Create(new ConfigMapV1
Log.Information("Creating ConfigMaps...");

Log.Information("Creating ConfigMap {ConfigMapName}...", configMap1Name);
configMap1 = await client.ConfigMapsV1().Create(new ConfigMapV1
{
Metadata = new ObjectMetaV1
{
Name = configMap1Name,
Namespace = configMapNamespace
},
Data =
{
["Key1"] = "OneA",
["Key2"] = "TwoA",
["Key3"] = "ThreeA"
}
});

Log.Information("Creating ConfigMap {ConfigMapName}...", configMap2Name);
configMap2 = await client.ConfigMapsV1().Create(new ConfigMapV1
{
Metadata = new ObjectMetaV1
{
Name = configMapName,
Name = configMap2Name,
Namespace = configMapNamespace
},
Data =
{
["Key1"] = "One",
["Key2"] = "Two"
["Key1"] = "OneB",
["Key2"] = "TwoB",
["Key4"] = "FourB"
}
});
Log.Information("New ConfigMap created.");

Log.Information("ConfigMaps created.");

Log.Information("Building configuration...");
IConfiguration configuration = new ConfigurationBuilder()
.AddKubeConfigMap(clientOptions,
configMapName: "config-from-configmap",
configMapName: configMap1Name,
reloadOnChange: true
)
.AddKubeConfigMap(clientOptions,
configMapName: configMap2Name,
reloadOnChange: true
)
.Build();
Expand All @@ -84,7 +118,7 @@ static async Task<int> Main(string[] commandLineArguments)
Log.Information("Got configuration:");
Dump(configuration);

Log.Information("Press enter to update ConfigMap...");
Log.Information("Press enter to update ConfigMaps {ConfigMap1Name} and {ConfigMap2Name}:", configMap1Name, configMap2Name);

Console.ReadLine();

Expand All @@ -105,26 +139,47 @@ static async Task<int> Main(string[] commandLineArguments)
using (configurationChanged)
using (reloadNotifications)
{
Log.Information("Updating ConfigMap...");
Log.Information("Updating ConfigMap {ConfigMapName}...", configMap1Name);

configMap.Data["One"] = "1";
configMap.Data["Two"] = "2";
configMap1.Data["key5"] = "FiveA";
configMap1.Data["key6"] = "SixA";

// Replace the entire Data dictionary (to modify only some of the data, you'll need to use an untyped JsonPatchDocument).
await client.ConfigMapsV1().Update(configMapName, patch =>
await client.ConfigMapsV1().Update(configMap1Name, patch =>
{
patch.Replace(patchConfigMap => patchConfigMap.Data,
value: configMap.Data
value: configMap1.Data
);
});

Log.Information("Updated ConfigMap.");
Log.Information("Updated ConfigMap {ConfigMapName}.", configMap1Name);

Log.Information("Waiting for configuration change...");

configurationChanged.WaitOne();

Log.Information("Configuration changed.");
Log.Information("Configuration changed via ConfigMap {ConfigMapName}.", configMap1Name);

configurationChanged.Reset();

Log.Information("Updating ConfigMap {ConfigMapName}...", configMap2Name);

configMap2.Data["key5"] = "FiveB";
configMap2.Data["key6"] = "SixB";

// Replace the entire Data dictionary (to modify only some of the data, you'll need to use an untyped JsonPatchDocument).
await client.ConfigMapsV1().Update(configMap2Name, patch =>
{
patch.Replace(patchConfigMap => patchConfigMap.Data,
value: configMap2.Data
);
});

Log.Information("Updated ConfigMap {ConfigMapName}.", configMap2Name);

configurationChanged.WaitOne();

Log.Information("Configuration changed via ConfigMap {ConfigMapName}.", configMap2Name);
}

return ExitCodes.Success;
Expand Down Expand Up @@ -152,8 +207,8 @@ static void Dump(IConfiguration configuration)
if (configuration == null)
throw new ArgumentNullException(nameof(configuration));

foreach (var item in configuration.AsEnumerable())
Log.Information("\t'{Key}' = '{Value}'", item.Key, item.Value);
foreach ((string key, string value) in configuration.AsEnumerable().OrderBy(item => item.Key))
Log.Information("\t'{Key}' = '{Value}'", key, value);
}

/// <summary>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace KubeClient.Extensions.Configuration
{
using Models;
using Settings;

/// <summary>
/// Provider for configuration that comes from a Kubernetes ConfigMap.
Expand All @@ -17,7 +18,7 @@ sealed class ConfigMapConfigurationProvider
/// <summary>
/// The <see cref="KubeApiClient"/> used to communicate with the Kubernetes API.
/// </summary>
readonly KubeApiClient _client;
readonly IKubeApiClient _client;

/// <summary>
/// The name of the target ConfigMap.
Expand Down Expand Up @@ -52,39 +53,22 @@ sealed class ConfigMapConfigurationProvider
/// <summary>
/// Create a new <see cref="ConfigMapConfigurationProvider"/>.
/// </summary>
/// <param name="client">
/// The <see cref="KubeApiClient"/> used to communicate with the Kubernetes API.
/// </param>
/// <param name="configMapName">
/// The name of the target ConfigMap.
/// <param name="providerSettings">
/// The <see cref="ConfigMapConfigurationSettings"/> used to configure the provider.
/// </param>
/// <param name="kubeNamespace">
/// The Kubernetes namespace that contains the target ConfigMap.
/// </param>
/// <param name="sectionName">
/// The name of the target configuration section (if any).
/// </param>
/// <param name="watch">
/// Watch the ConfigMap for changes?
/// </param>
/// <param name="throwOnNotFound">
/// Throw an exception if the ConfigMap was not found?
/// </param>
public ConfigMapConfigurationProvider(KubeApiClient client, string configMapName, string kubeNamespace, string sectionName, bool watch, bool throwOnNotFound)
public ConfigMapConfigurationProvider(ConfigMapConfigurationSettings providerSettings)
{
if (client == null)
throw new ArgumentNullException(nameof(client));
if ( providerSettings == null )
throw new ArgumentNullException(nameof(providerSettings));

_client = providerSettings.Client;
_configMapName = providerSettings.ConfigMapName;
_kubeNamespace = providerSettings.KubeNamespace;
_sectionName = providerSettings.SectionName;
_watch = providerSettings.Watch;
_throwOnNotFound = providerSettings.ThrowOnNotFound;

if (String.IsNullOrWhiteSpace(configMapName))
throw new ArgumentException("Argument cannot be null, empty, or entirely composed of whitespace: 'configMapName'.", nameof(configMapName));

_client = client;
Log = _client.LoggerFactory.CreateLogger<ConfigMapConfigurationProvider>();
_configMapName = configMapName;
_kubeNamespace = kubeNamespace;
_sectionName = sectionName;
_watch = watch;
_throwOnNotFound = throwOnNotFound;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
using Microsoft.Extensions.Configuration;
using System;

namespace KubeClient.Extensions.Configuration
{
using Settings;

/// <summary>
/// Source for configuration that comes from a Kubernetes ConfigMap.
/// </summary>
sealed class ConfigMapConfigurationSource
: IConfigurationSource
{

/// <summary>
/// Create a new <see cref="ConfigMapConfigurationSource"/>.
/// </summary>
public ConfigMapConfigurationSource()
/// <param name="settings">
/// The <see cref="ConfigMapConfigurationSettings"/> used to create configuration providers.
/// </param>
public ConfigMapConfigurationSource(ConfigMapConfigurationSettings settings)
{
if ( settings == null )
throw new ArgumentNullException(nameof(settings));

Settings = settings;
}

/// <summary>
/// The <see cref="ConfigMapConfigurationSettings"/> used to create configuration providers.
/// </summary>
public ConfigMapConfigurationSettings Settings { get; }

/// <summary>
/// Build a configuration provider with configured options.
/// </summary>
Expand All @@ -25,16 +39,6 @@ public ConfigMapConfigurationSource()
/// <returns>
/// The new <see cref="IConfigurationProvider"/>.
/// </returns>
public IConfigurationProvider Build(IConfigurationBuilder configurationBuilder)
{
return new ConfigMapConfigurationProvider(
client: (KubeApiClient)configurationBuilder.Properties[ConfigMapBuilderPropertyConstants.Client],
configMapName: (string)configurationBuilder.Properties[ConfigMapBuilderPropertyConstants.Name],
kubeNamespace: (string)configurationBuilder.Properties[ConfigMapBuilderPropertyConstants.Namespace],
sectionName: (string)configurationBuilder.Properties[ConfigMapBuilderPropertyConstants.SectionName],
watch: (bool)configurationBuilder.Properties[ConfigMapBuilderPropertyConstants.Watch],
throwOnNotFound: (bool) configurationBuilder.Properties[ConfigMapBuilderPropertyConstants.ThrowOnNotFound]
);
}
public IConfigurationProvider Build(IConfigurationBuilder configurationBuilder) => new ConfigMapConfigurationProvider(Settings);
}
}
Loading