private async Task ConvergeConfiguration(KongvergeConfiguration existingConfiguration, KongvergeConfiguration targetConfiguration) { async Task DeleteService(KongService service) { await _kongWriter.DeleteService(service.Id); _deletedStats.Increment <KongRoute>(service.Routes.Count); _deletedStats.Increment <KongPlugin>(service.Plugins.Count + service.Routes.Sum(x => x.Plugins.Count)); } _createdStats = new OperationStats(); _updatedStats = new OperationStats(); _deletedStats = new OperationStats(); await ConvergeChildrenPlugins(null, existingConfiguration.GlobalConfig, targetConfiguration.GlobalConfig); await ConvergeObjects( null, KongService.ObjectName, existingConfiguration.Services, targetConfiguration.Services, DeleteService, x => _kongWriter.AddService(x), x => _kongWriter.UpdateService(x), ConvergeServiceChildren); Log.Information($"Created {_createdStats}"); Log.Information($"Updated {_updatedStats}"); Log.Information($"Deleted {_deletedStats}"); if (_updatedStats.Any()) { Log.Verbose("See https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md for delta format"); } }
public virtual async Task <KongvergeConfiguration> FromKong(IKongAdminReader kongReader) { Log.Information("Reading configuration from Kong"); Log.Verbose("Getting plugins from Kong"); var plugins = await kongReader.GetPlugins(); Log.Verbose("Getting services from Kong"); var services = await kongReader.GetServices(); Log.Verbose("Getting routes from Kong"); var routes = await kongReader.GetRoutes(); foreach (var existingService in services) { PopulateServiceTree(existingService, routes, plugins); } var configuration = new KongvergeConfiguration { Services = services.ToArray(), GlobalConfig = new GlobalConfig { Plugins = plugins.Where(x => x.IsGlobal()).ToArray() } }; Log.Information($"Configuration from Kong: {configuration}"); return(configuration); }
private async Task ConvergeConfiguration(KongvergeConfiguration existingConfiguration, KongvergeConfiguration targetConfiguration) { async Task DeleteService(KongService service) { await _kongWriter.DeleteService(service.Id); _deletedStats.Increment <KongRoute>(service.Routes.Count); _deletedStats.Increment <KongPlugin>(service.Plugins.Count + service.Routes.Sum(x => x.Plugins.Count)); } _createdStats = new OperationStats(); _updatedStats = new OperationStats(); _deletedStats = new OperationStats(); await ConvergeChildrenPlugins(null, existingConfiguration.GlobalConfig, targetConfiguration.GlobalConfig); await ConvergeObjects( null, KongService.ObjectName, existingConfiguration.Services, targetConfiguration.Services, DeleteService, x => _kongWriter.AddService(x), x => _kongWriter.UpdateService(x), ConvergeServiceChildren); Log.Information($"Created {_createdStats}"); Log.Information($"Updated {_updatedStats}"); Log.Information($"Deleted {_deletedStats}"); }
private static void LogObjectCounts(KongvergeConfiguration configuration) { var routes = configuration.Services.SelectMany(x => x.Routes).ToArray(); var pluginsCount = configuration.GlobalConfig.Plugins.Count; pluginsCount += configuration.Services.Sum(x => x.Plugins.Count) + routes.Sum(x => x.Plugins.Count); Log.Information($"Configuration from files contains {configuration.Services.Count} {KongObject.GetName(0, "service")}, {pluginsCount} {KongObject.GetName(0, "plugin")}, {routes.Length} {KongObject.GetName(0, "route")}"); }
public async Task <KongvergeConfiguration> ReadConfiguration(string folderPath, IDictionary <string, AsyncLazy <KongSchema> > schemas) { Log.Information($"Reading files from {folderPath}"); var filePaths = _fileProvider.EnumerateFiles(folderPath).ToArray(); var fileErrorMessages = new FileErrorMessages(); var services = new Dictionary <string, KongService>(); GlobalConfig globalConfig = null; var globalConfigFilePaths = filePaths.Where(x => x.EndsWith(Constants.GlobalConfigFileName)).ToArray(); if (globalConfigFilePaths.Length > 1) { foreach (var globalConfigFilePath in globalConfigFilePaths) { fileErrorMessages.AddErrors(globalConfigFilePath, $"Cannot have more than one {Constants.GlobalConfigFileName} file."); await ParseFile <GlobalConfig>(globalConfigFilePath, schemas, fileErrorMessages); } } else if (globalConfigFilePaths.Any()) { globalConfig = await ParseFile <GlobalConfig>(globalConfigFilePaths.Single(), schemas, fileErrorMessages); } foreach (var serviceConfigFilePath in filePaths.Except(globalConfigFilePaths)) { services.Add(serviceConfigFilePath, await ParseFile <KongService>(serviceConfigFilePath, schemas, fileErrorMessages)); } foreach (var serviceConfigFilePath in services.Keys) { if (services.Keys.Except(new [] { serviceConfigFilePath }).Any(x => services[x]?.Name == services[serviceConfigFilePath]?.Name)) { fileErrorMessages.AddErrors(serviceConfigFilePath, $"{KongSchema.Violation<KongService>()} (field 'name' must be unique)."); } } if (fileErrorMessages.Any()) { throw new InvalidConfigurationFilesException(fileErrorMessages.CreateMessage()); } var configuration = new KongvergeConfiguration { Services = services.Values.ToArray(), GlobalConfig = globalConfig ?? new GlobalConfig() }; Log.Information($"Configuration from files: {configuration}"); return(configuration); }
public async Task WriteConfiguration(KongvergeConfiguration configuration, string folderPath) { Log.Information($"Writing files to {folderPath}"); PrepareOutputFolder(folderPath); foreach (var service in configuration.Services) { await WriteConfigObject(service, folderPath, $"{service.Name}{Constants.FileExtension}"); } if (configuration.GlobalConfig.Plugins.Any() || configuration.GlobalConfig.Consumers.Any()) { await WriteConfigObject(configuration.GlobalConfig, folderPath, Constants.GlobalConfigFileName); } }
public virtual async Task <KongvergeConfiguration> ReadConfiguration(string folderPath, IReadOnlyCollection <string> availablePlugins) { Log.Information($"Reading files from {folderPath}"); var filePaths = Directory.EnumerateFiles(folderPath, $"*{Settings.FileExtension}", SearchOption.AllDirectories).ToArray(); var fileErrorMessages = new FileErrorMessages(); var services = new List <KongService>(); GlobalConfig globalConfig = null; var globalConfigFilePaths = filePaths.Where(x => x.EndsWith(Settings.GlobalConfigFileName)).ToArray(); if (globalConfigFilePaths.Length > 1) { foreach (var globalConfigFilePath in globalConfigFilePaths) { fileErrorMessages.AddErrors(globalConfigFilePath, $"Cannot have more than one {Settings.GlobalConfigFileName} file."); await ParseFile <GlobalConfig>(globalConfigFilePath, availablePlugins, fileErrorMessages); } } else if (globalConfigFilePaths.Any()) { globalConfig = await ParseFile <GlobalConfig>(globalConfigFilePaths.Single(), availablePlugins, fileErrorMessages); } foreach (var serviceConfigFilePath in filePaths.Except(globalConfigFilePaths)) { services.Add(await ParseFile <KongService>(serviceConfigFilePath, availablePlugins, fileErrorMessages)); } if (fileErrorMessages.Any()) { throw new InvalidConfigurationFilesException(fileErrorMessages.CreateMessage()); } var configuration = new KongvergeConfiguration { Services = services.AsReadOnly(), GlobalConfig = globalConfig ?? new GlobalConfig() }; LogObjectCounts(configuration); return(configuration); }
public virtual async Task <KongvergeConfiguration> FromKong(IKongAdminReader kongReader, IReadOnlyCollection <string> ignoreTags) { ignoreTags ??= Array.Empty <string>(); Log.Information("Reading configuration from Kong"); Log.Verbose("Getting consumers from Kong"); var consumers = IgnoreByTag(ignoreTags, await kongReader.GetConsumers()); Log.Verbose("Getting plugins from Kong"); var plugins = IgnoreByTag(ignoreTags, await kongReader.GetPlugins()); Log.Verbose("Getting services from Kong"); var services = IgnoreByTag(ignoreTags, await kongReader.GetServices()); Log.Verbose("Getting routes from Kong"); var routes = IgnoreByTag(ignoreTags, await kongReader.GetRoutes()); foreach (var consumer in consumers) { consumer.Plugins = plugins.Where(x => x.Consumer?.Id == consumer.Id).ToArray(); } foreach (var service in services) { PopulateServiceTree(service, routes, plugins); } var configuration = new KongvergeConfiguration { Services = services.ToArray(), GlobalConfig = new GlobalConfig { Plugins = plugins.Where(x => x.IsGlobal()).ToArray(), Consumers = consumers.ToArray() } }; Log.Information($"Configuration from Kong: {configuration}"); return(configuration); }