├── .gitignore ├── Controllers └── ValuesController.cs ├── EtcdConfigurationProvider.cs ├── EtcdConfigurationSource.cs ├── EtcdStaticExtensions.cs ├── Program.cs ├── Startup.cs ├── appsettings.Development.json ├── appsettings.json └── etcd-client.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | project.lock.json 2 | *~ 3 | \#* 4 | bin 5 | obj 6 | .vscode/ 7 | -------------------------------------------------------------------------------- /Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using EtcdNet; 7 | using Microsoft.Extensions.Logging; 8 | using Microsoft.Extensions.Configuration; 9 | 10 | namespace ConfigClient.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | public class ValuesController : Controller 14 | { 15 | private ILogger logger; 16 | 17 | public ValuesController(ILogger logger) 18 | { 19 | this.logger = logger; 20 | } 21 | 22 | // GET api/values 23 | [HttpGet] 24 | public IEnumerable Get() 25 | { 26 | List values = new List(); 27 | values.Add(Startup.Configuration.GetSection("/myapp/hello").Value); 28 | values.Add(Startup.Configuration.GetSection("/myapp/rate").Value); 29 | 30 | return values; 31 | } 32 | 33 | // GET api/values/5 34 | [HttpGet("{id}")] 35 | public string Get(int id) 36 | { 37 | return "value"; 38 | } 39 | 40 | // POST api/values 41 | [HttpPost] 42 | public void Post([FromBody]string value) 43 | { 44 | } 45 | 46 | // PUT api/values/5 47 | [HttpPut("{id}")] 48 | public void Put(int id, [FromBody]string value) 49 | { 50 | } 51 | 52 | // DELETE api/values/5 53 | [HttpDelete("{id}")] 54 | public void Delete(int id) 55 | { 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /EtcdConfigurationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using EtcdNet; 4 | using Microsoft.Extensions.Configuration; 5 | using Microsoft.Extensions.Primitives; 6 | 7 | namespace ConfigClient 8 | { 9 | public class EtcdConfigurationProvider : ConfigurationProvider 10 | { 11 | private EtcdConfigurationSource source; 12 | 13 | public EtcdConfigurationProvider(EtcdConfigurationSource source) 14 | { 15 | this.source = source; 16 | } 17 | 18 | public override void Load() 19 | { 20 | EtcdClientOpitions options = new EtcdClientOpitions() 21 | { 22 | Urls = source.Options.Urls, 23 | Username = source.Options.Username, 24 | Password = source.Options.Password, 25 | UseProxy = false, 26 | IgnoreCertificateError = true 27 | }; 28 | EtcdClient etcdClient = new EtcdClient(options); 29 | try 30 | { 31 | EtcdResponse resp = etcdClient.GetNodeAsync(source.Options.RootKey, 32 | recursive: true, sorted: true).Result; 33 | if (resp.Node.Nodes != null) 34 | { 35 | foreach (var node in resp.Node.Nodes) 36 | { 37 | // child node 38 | Data[node.Key] = node.Value; 39 | } 40 | } 41 | } 42 | catch (EtcdCommonException.KeyNotFound) 43 | { 44 | // key does not 45 | Console.WriteLine("key not found exception"); 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /EtcdConfigurationSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.Configuration; 3 | 4 | namespace ConfigClient 5 | { 6 | public class EtcdConfigurationSource : IConfigurationSource 7 | { 8 | public EtcdConnectionOptions Options { get; set; } 9 | 10 | public EtcdConfigurationSource(EtcdConnectionOptions options) 11 | { 12 | this.Options = options; 13 | } 14 | 15 | public IConfigurationProvider Build(IConfigurationBuilder builder) 16 | { 17 | return new EtcdConfigurationProvider(this); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /EtcdStaticExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | 3 | namespace ConfigClient 4 | { 5 | public static class EtcdStaticExtensions 6 | { 7 | public static IConfigurationBuilder AddEtcdConfiguration(this IConfigurationBuilder builder, 8 | EtcdConnectionOptions connectionOptions) 9 | { 10 | return builder.Add(new EtcdConfigurationSource(connectionOptions)); 11 | } 12 | } 13 | 14 | public class EtcdConnectionOptions 15 | { 16 | public string[] Urls { get; set; } 17 | public string Username { get; set; } 18 | public string Password { get; set; } 19 | public string RootKey { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Builder; 7 | using Microsoft.AspNetCore.Hosting; 8 | 9 | namespace ConfigClient 10 | { 11 | public class Program 12 | { 13 | public static void Main(string[] args) 14 | { 15 | var host = new WebHostBuilder() 16 | .UseKestrel() 17 | .UseContentRoot(Directory.GetCurrentDirectory()) 18 | .UseIISIntegration() 19 | .UseStartup() 20 | .Build(); 21 | 22 | host.Run(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace ConfigClient 12 | { 13 | public class Startup 14 | { 15 | public Startup(IHostingEnvironment env) 16 | { 17 | var builder = new ConfigurationBuilder() 18 | .SetBasePath(env.ContentRootPath) 19 | .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) 20 | .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 21 | .AddEtcdConfiguration(new EtcdConnectionOptions 22 | { 23 | Urls = new string[] { 24 | "https://portal1934-21.euphoric-etcd-31.capital-one-3.composedb.com:17174", 25 | "https://portal2016-22.euphoric-etcd-31.capital-one-3.composedb.com:17174" 26 | }, 27 | Username = "root", 28 | Password = "changeme", 29 | RootKey = "/myapp" 30 | }) 31 | .AddEnvironmentVariables(); 32 | Configuration = builder.Build(); 33 | } 34 | 35 | public static IConfigurationRoot Configuration { get; set; } 36 | 37 | // This method gets called by the runtime. Use this method to add services to the container. 38 | public void ConfigureServices(IServiceCollection services) 39 | { 40 | // Add framework services. 41 | services.AddMvc(); 42 | } 43 | 44 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 45 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 46 | { 47 | loggerFactory.AddConsole(); 48 | loggerFactory.AddDebug(); 49 | 50 | app.UseMvc(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /etcd-client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp1.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | --------------------------------------------------------------------------------