VaultDemo.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #pragma warning disable CS0162 // 检测到无法访问的代码
  2. using Apq.Cfg;
  3. using Apq.Cfg.Vault;
  4. namespace Apq.Cfg.Samples.Demos;
  5. /// <summary>
  6. /// 示例 16: HashiCorp Vault 配置源
  7. /// 演示如何使用 Vault 作为配置源(密钥管理)
  8. /// 注意:需要运行 Vault 服务才能执行完整示例
  9. /// 快速启动:docker run -d -p 8200:8200 -e VAULT_DEV_ROOT_TOKEN_ID=root vault:latest
  10. /// </summary>
  11. public static class VaultDemo
  12. {
  13. // 是否启用实际连接测试(设为 true 需要 Vault 服务运行)
  14. private const bool EnableLiveTest = false;
  15. public static async Task RunAsync(string baseDir)
  16. {
  17. Console.WriteLine("═══════════════════════════════════════════════════════════════");
  18. Console.WriteLine("示例 16: HashiCorp Vault 配置源");
  19. Console.WriteLine("═══════════════════════════════════════════════════════════════\n");
  20. Console.WriteLine("【说明】Vault 是 HashiCorp 开源的密钥管理和数据保护工具。");
  21. Console.WriteLine("【启动】docker run -d -p 8200:8200 -e VAULT_DEV_ROOT_TOKEN_ID=root vault\n");
  22. // 示例 16.1: 基本配置(Token 认证)
  23. Demo_BasicConfiguration();
  24. // 示例 16.2: UserPass 认证
  25. Demo_UserPassConfiguration();
  26. // 示例 16.3: AppRole 认证
  27. Demo_AppRoleConfiguration();
  28. // 示例 16.4: KV 引擎版本
  29. Demo_KvVersionConfiguration();
  30. // 示例 16.5: 企业版命名空间
  31. Demo_NamespaceConfiguration();
  32. // 示例 16.6: 监听配置变更
  33. Demo_WatchConfiguration();
  34. // 示例 16.7: 实际连接测试
  35. if (EnableLiveTest)
  36. {
  37. await Demo_LiveTestAsync();
  38. }
  39. else
  40. {
  41. Console.WriteLine("--- 示例 16.7: 实际连接测试 ---");
  42. Console.WriteLine(" [跳过] 设置 EnableLiveTest = true 并启动 Vault 服务后可运行\n");
  43. }
  44. Console.WriteLine("[示例 16 完成]\n");
  45. }
  46. /// <summary>
  47. /// 示例 16.1: 基本配置(Token 认证)
  48. /// </summary>
  49. private static void Demo_BasicConfiguration()
  50. {
  51. Console.WriteLine("--- 示例 16.1: 基本配置(Token 认证)---");
  52. // 方式1: 使用 Action 配置
  53. var builder1 = new CfgBuilder()
  54. .AddVault(options =>
  55. {
  56. options.Address = "http://localhost:8200"; // Vault 地址
  57. options.Token = "root"; // 认证令牌
  58. options.EnginePath = "secret"; // 密钥引擎路径
  59. options.Path = "myapp/config"; // 密钥路径
  60. }, level: 0);
  61. Console.WriteLine(" 方式1: AddVault(options => { ... })");
  62. Console.WriteLine(" options.Address = \"http://localhost:8200\"");
  63. Console.WriteLine(" options.Token = \"root\"");
  64. Console.WriteLine(" options.EnginePath = \"secret\"");
  65. Console.WriteLine(" options.Path = \"myapp/config\"");
  66. // 方式2: 使用简化方法(KV V2)
  67. var builder2 = new CfgBuilder()
  68. .AddVaultV2("http://localhost:8200", "root", path: "myapp/config", level: 0);
  69. Console.WriteLine(" 方式2: AddVaultV2(address, token, path: \"myapp/config\")");
  70. Console.WriteLine();
  71. }
  72. /// <summary>
  73. /// 示例 16.2: UserPass 认证
  74. /// </summary>
  75. private static void Demo_UserPassConfiguration()
  76. {
  77. Console.WriteLine("--- 示例 16.2: UserPass 认证 ---");
  78. var builder = new CfgBuilder()
  79. .AddVault(options =>
  80. {
  81. options.Address = "http://localhost:8200";
  82. options.AuthMethod = VaultAuthMethod.UserPass; // 使用 UserPass 认证
  83. options.Username = "myuser"; // 用户名
  84. options.Password = "mypassword"; // 密码
  85. options.EnginePath = "secret";
  86. options.Path = "myapp/config";
  87. }, level: 0);
  88. Console.WriteLine(" options.AuthMethod = VaultAuthMethod.UserPass");
  89. Console.WriteLine(" options.Username = \"myuser\"");
  90. Console.WriteLine(" options.Password = \"mypassword\"");
  91. Console.WriteLine();
  92. }
  93. /// <summary>
  94. /// 示例 16.3: AppRole 认证
  95. /// </summary>
  96. private static void Demo_AppRoleConfiguration()
  97. {
  98. Console.WriteLine("--- 示例 16.3: AppRole 认证 ---");
  99. var builder = new CfgBuilder()
  100. .AddVault(options =>
  101. {
  102. options.Address = "http://localhost:8200";
  103. options.AuthMethod = VaultAuthMethod.AppRole; // 使用 AppRole 认证
  104. options.RoleId = "your-role-id"; // AppRole ID
  105. options.RoleSecret = "your-role-secret"; // AppRole Secret
  106. options.EnginePath = "secret";
  107. options.Path = "myapp/config";
  108. }, level: 0);
  109. Console.WriteLine(" options.AuthMethod = VaultAuthMethod.AppRole");
  110. Console.WriteLine(" options.RoleId = \"your-role-id\"");
  111. Console.WriteLine(" options.RoleSecret = \"your-role-secret\"");
  112. Console.WriteLine();
  113. }
  114. /// <summary>
  115. /// 示例 16.4: KV 引擎版本
  116. /// </summary>
  117. private static void Demo_KvVersionConfiguration()
  118. {
  119. Console.WriteLine("--- 示例 16.4: KV 引擎版本 ---");
  120. // KV V2(默认,支持版本控制)
  121. var builder1 = new CfgBuilder()
  122. .AddVault(options =>
  123. {
  124. options.Address = "http://localhost:8200";
  125. options.Token = "root";
  126. options.EnginePath = "secret";
  127. options.Path = "myapp/config";
  128. options.KvVersion = 2; // KV V2(默认)
  129. }, level: 0);
  130. Console.WriteLine(" KV V2: options.KvVersion = 2 // 支持版本控制");
  131. // KV V1(不支持版本控制)
  132. var builder2 = new CfgBuilder()
  133. .AddVault(options =>
  134. {
  135. options.Address = "http://localhost:8200";
  136. options.Token = "root";
  137. options.EnginePath = "kv"; // KV V1 引擎
  138. options.Path = "myapp/config";
  139. options.KvVersion = 1; // KV V1
  140. }, level: 0);
  141. Console.WriteLine(" KV V1: options.KvVersion = 1 // 不支持版本控制");
  142. Console.WriteLine();
  143. }
  144. /// <summary>
  145. /// 示例 16.5: 企业版命名空间
  146. /// </summary>
  147. private static void Demo_NamespaceConfiguration()
  148. {
  149. Console.WriteLine("--- 示例 16.5: 企业版命名空间 ---");
  150. // Vault Enterprise 支持命名空间隔离
  151. var builder = new CfgBuilder()
  152. .AddVault(options =>
  153. {
  154. options.Address = "http://vault.example.com:8200";
  155. options.Token = "your-token";
  156. options.Namespace = "myorg/myteam"; // 企业版命名空间
  157. options.EnginePath = "secret";
  158. options.Path = "myapp/config";
  159. }, level: 0);
  160. Console.WriteLine(" options.Namespace = \"myorg/myteam\" // Vault Enterprise");
  161. Console.WriteLine();
  162. }
  163. /// <summary>
  164. /// 示例 16.6: 监听配置变更
  165. /// </summary>
  166. private static void Demo_WatchConfiguration()
  167. {
  168. Console.WriteLine("--- 示例 16.6: 监听配置变更 ---");
  169. var builder = new CfgBuilder()
  170. .AddVault(options =>
  171. {
  172. options.Address = "http://localhost:8200";
  173. options.Token = "root";
  174. options.EnginePath = "secret";
  175. options.Path = "myapp/config";
  176. options.EnableHotReload = true; // 启用热重载
  177. options.PollInterval = TimeSpan.FromSeconds(30); // 轮询间隔
  178. options.ReconnectInterval = TimeSpan.FromSeconds(5);
  179. }, level: 0);
  180. Console.WriteLine(" options.EnableHotReload = true");
  181. Console.WriteLine(" options.PollInterval = TimeSpan.FromSeconds(30)");
  182. Console.WriteLine(" options.ReconnectInterval = TimeSpan.FromSeconds(5)");
  183. Console.WriteLine();
  184. Console.WriteLine(" // 订阅配置变更");
  185. Console.WriteLine(" cfg.ConfigChanges.Subscribe(change =>");
  186. Console.WriteLine(" {");
  187. Console.WriteLine(" Console.WriteLine($\"密钥变更: {change.Key} = {change.NewValue}\");");
  188. Console.WriteLine(" });");
  189. Console.WriteLine();
  190. }
  191. /// <summary>
  192. /// 示例 16.7: 实际连接测试
  193. /// </summary>
  194. private static async Task Demo_LiveTestAsync()
  195. {
  196. Console.WriteLine("--- 示例 16.7: 实际连接测试 ---");
  197. try
  198. {
  199. // 创建配置
  200. var cfg = new CfgBuilder()
  201. .AddVault(options =>
  202. {
  203. options.Address = "http://localhost:8200";
  204. options.Token = "root"; // 开发模式默认 token
  205. options.EnginePath = "secret";
  206. options.Path = "apq-cfg-demo";
  207. }, level: 0, isPrimaryWriter: true)
  208. .Build();
  209. Console.WriteLine(" ✓ 连接 Vault 成功");
  210. // 写入测试配置
  211. cfg.Set("App:Name", "VaultDemo");
  212. cfg.Set("App:Version", "1.0.0");
  213. cfg.Set("Database:Host", "localhost");
  214. cfg.Set("Database:Password", "secret-password");
  215. await cfg.SaveAsync();
  216. Console.WriteLine(" ✓ 写入密钥成功");
  217. // 读取配置
  218. Console.WriteLine($" App:Name = {cfg.Get("App:Name")}");
  219. Console.WriteLine($" App:Version = {cfg.Get("App:Version")}");
  220. Console.WriteLine($" Database:Host = {cfg.Get("Database:Host")}");
  221. Console.WriteLine($" Database:Password = {cfg.Get("Database:Password")}");
  222. // 枚举所有键
  223. var keys = cfg.GetChildKeys();
  224. Console.WriteLine($" 密钥数量: {keys.Count()}");
  225. // 清理测试数据
  226. cfg.Remove("App:Name");
  227. cfg.Remove("App:Version");
  228. cfg.Remove("Database:Host");
  229. cfg.Remove("Database:Password");
  230. await cfg.SaveAsync();
  231. Console.WriteLine(" ✓ 清理测试数据成功");
  232. cfg.Dispose();
  233. }
  234. catch (Exception ex)
  235. {
  236. Console.WriteLine($" ✗ 连接失败: {ex.Message}");
  237. Console.WriteLine(" 提示: 请确保 Vault 服务正在运行");
  238. }
  239. Console.WriteLine();
  240. }
  241. }