Files
deployutils/WebConfigSetter/Program.cs
T
Samuele Locatelli f33a91efc6 WebConfigSetter:
- Aggiunta gest ServerConf in sostituzioni previste
2022-12-28 11:35:48 +01:00

370 lines
16 KiB
C#

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Reflection;
using System.Xml;
namespace WebConfigSetter
{
internal class Program
{
#region Protected Fields
protected const string separatore = "---------------------------------------------------------------------------------------";
/// <summary>
/// stringa di setup cliente
/// </summary>
protected static SetCliente currConfig = new SetCliente();
#endregion Protected Fields
#region Protected Properties
protected static string baseDir { get; set; } = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);//@"c:\Steamware\WebConfigSetter";
#if DEBUG
protected static string baseWebAppDir { get; set; } = @"\\iis02\c$\inetpub\wwwroot\MP\";
#else
protected static string baseWebAppDir { get; set; } = @"c:\inetpub\wwwroot\MP\";
#endif
protected static string confDir { get; set; } = $@"{baseDir}\CONF";
protected static string currentSetFile { get; set; } = $@"{confDir}\default.json";
/// <summary>
/// modalità scrittura (altrimenti legge e carica conf parsando i files)
/// </summary>
protected static operationMode opMode { get; set; } = operationMode.readConf;
protected static string setName { get; set; } = "Steamware";
#endregion Protected Properties
#region Private Methods
private static void Main(string[] args)
{
string userInput = "";
if (args == null || args.Length == 0)
{
Console.WriteLine(separatore);
Console.WriteLine("WebConfigSetter: Gestione configurazione config file per web applications");
Console.WriteLine("");
Console.WriteLine("Processa i file di applicazioni asp.net (XML) e dotnet core (Json), per queste ultime partendo dalla versione appsettings.Production.json");
Console.WriteLine(separatore);
Console.WriteLine("");
Console.WriteLine("Sintassi: WebConfigSetter.exe $1 $2 $3");
Console.WriteLine("$1: Modalità operativa (0=read, 1=write)");
Console.WriteLine("$2: WebApp directory di base");
Console.WriteLine("$3: SetName da applicare");
Console.WriteLine(separatore);
Console.WriteLine("");
Console.WriteLine("Nessuna parametro fornito, verranno ora richiesti i parametri");
Console.WriteLine(separatore);
}
// carico parametri opzionali
if (args.Length > 0)
{
opMode = args[0] == "1" ? operationMode.writeConf : operationMode.readConf;
}
else
{
Console.WriteLine($"Modalità operativa 0=read, 1=write [{opMode}]");
userInput = Console.ReadLine();
if (!string.IsNullOrEmpty(userInput))
{
opMode = userInput == "1" ? operationMode.writeConf : operationMode.readConf;
}
}
if (args.Length > 1)
{
baseWebAppDir = args[1];
}
else
{
Console.WriteLine($"WebApp directory di base [{baseWebAppDir}]");
userInput = Console.ReadLine();
if (!string.IsNullOrEmpty(userInput))
{
baseWebAppDir = userInput;
}
}
if (args.Length > 2)
{
setName = args[2];
}
else
{
Console.WriteLine($"SetName da applicare [{setName}]");
userInput = Console.ReadLine();
if (!string.IsNullOrEmpty(userInput))
{
setName = userInput;
}
}
Console.WriteLine(separatore);
Console.WriteLine($"Modalità operativa: {opMode}");
Console.WriteLine($"baseWebAppDir: {baseWebAppDir}");
Console.WriteLine($"setName: {setName}");
// salvo info...
currentSetFile = $"{confDir}\\{setName}.json";
// processo richiesta
processRequest();
Console.WriteLine(separatore);
}
/// <summary>
/// Esecuzione richiesta principale
/// </summary>
private static void processRequest()
{
// caso 1: acquisisco conf
if (opMode == operationMode.readConf)
{
readConfToFiles();
}
// caso 2: effettuo sostituzioni
else
{
writeConfToFiles();
}
}
private static void readConfToFiles()
{
// cerca i file web.config dalla folder richiesta in giù...
string[] configFilesXml = Directory.GetFiles(baseWebAppDir, "web.config", SearchOption.AllDirectories);
string[] configFilesJson = Directory.GetFiles(baseWebAppDir, "appsettings.Production.json", SearchOption.AllDirectories);
// se fosse vuoto usa invece il file base
if (configFilesJson.Length == 0)
{
configFilesJson = Directory.GetFiles(baseWebAppDir, "appsettings.json", SearchOption.AllDirectories);
}
// STEP 1: processo files XML (stile asp.net <= 4.8)
XmlDocument doc = new XmlDocument();
foreach (var item in configFilesXml)
{
Console.WriteLine($"XML Found: {item}");
doc = new XmlDocument();
doc.Load(item);
// cerco in appConfig
XmlNodeList appSettingsList = doc.SelectNodes("configuration/appSettings/*");
for (int i = 0; i < appSettingsList.Count; i++)
{
bool doSave = false;
// stringhe conn a DB principali
if (appSettingsList[i].Attributes["key"].Value.Contains("ConnectionString"))
{
doSave = true;
}
// stringhe conn al DB secondari (MongoDB...)
if (appSettingsList[i].Attributes["key"].Value.Contains("ConnString"))
{
doSave = true;
}
// se trovato --> salvo
if (doSave)
{
if (!currConfig.appSettRules.ContainsKey(appSettingsList[i].Attributes["key"].Value))
{
currConfig.appSettRules.Add(appSettingsList[i].Attributes["key"].Value, appSettingsList[i].Attributes["value"].Value);
}
}
}
// cerco in connectionStrings
XmlNodeList connectionStringsList = doc.SelectNodes("configuration/connectionStrings/*");
for (int i = 0; i < connectionStringsList.Count; i++)
{
if (!currConfig.connStrRules.ContainsKey(connectionStringsList[i].Attributes["name"].Value))
{
currConfig.connStrRules.Add(connectionStringsList[i].Attributes["name"].Value, connectionStringsList[i].Attributes["connectionString"].Value);
}
}
}
// STEP 2: processo files json (stile dotnetcore >= 5.0)
jsonAppConfig currJsonConf = new jsonAppConfig();
foreach (var item in configFilesJson)
{
Console.WriteLine($"JSON Found: {item}");
string currFileData = File.ReadAllText(item);
if (!string.IsNullOrEmpty(currFileData))
{
try
{
currJsonConf = JsonConvert.DeserializeObject<jsonAppConfig>(currFileData);
}
catch (Exception exc)
{
Console.WriteLine($"Eccezione in decodifica item {item}{Environment.NewLine}{exc}");
}
// processo le stringhe di connessione
if (currJsonConf.ConnectionStrings != null)
{
foreach (var chiave in currJsonConf.ConnectionStrings)
{
if (!currConfig.jsonConnStrRules.ContainsKey(chiave.Key))
{
currConfig.jsonConnStrRules.Add(chiave.Key, chiave.Value);
}
}
}
// processo area ServerConf degli altri parametri da sistemare
if (currJsonConf.ServerConf != null)
{
foreach (var chiave in currJsonConf.ServerConf)
{
if (!currConfig.jsonConnStrRules.ContainsKey(chiave.Key))
{
currConfig.jsonConnStrRules.Add(chiave.Key, chiave.Value);
}
}
}
}
}
// serializzo!
string rawData = JsonConvert.SerializeObject(currConfig, Newtonsoft.Json.Formatting.Indented);
// salvo il file di conf!
File.WriteAllText(currentSetFile, rawData);
}
private static void writeConfToFiles()
{
// check file exists...
if (File.Exists(currentSetFile))
{
// leggo il file delle configurazioni da applicare...
string rawData = File.ReadAllText(currentSetFile);
if (!string.IsNullOrEmpty(rawData))
{
currConfig = JsonConvert.DeserializeObject<SetCliente>(rawData);
// cerca i file we.config dalla folder richiesta in giù...
string[] configFiles = Directory.GetFiles(baseWebAppDir, "web.config", SearchOption.AllDirectories);
string[] configFilesJson = Directory.GetFiles(baseWebAppDir, "appsettings*.json", SearchOption.AllDirectories);
XmlDocument doc = new XmlDocument();
// STEP 1: processo files XML (stile asp.net <= 4.8)
foreach (var item in configFiles)
{
Console.Write($"XML Found: {item} --> ");
doc = new XmlDocument();
doc.Load(item);
// cerco in appConfig
XmlNodeList appSettingsList = doc.SelectNodes("configuration/appSettings/*");
for (int i = 0; i < appSettingsList.Count; i++)
{
if (appSettingsList[i].Attributes["key"].Value.Contains("ConnectionString"))
{
if (currConfig.appSettRules.ContainsKey(appSettingsList[i].Attributes["key"].Value))
{
// effettuo sostituzione
appSettingsList[i].Attributes["value"].Value = currConfig.appSettRules[appSettingsList[i].Attributes["key"].Value];
}
}
}
// cerco in connectionStrings
XmlNodeList connectionStringsList = doc.SelectNodes("configuration/connectionStrings/*");
for (int i = 0; i < connectionStringsList.Count; i++)
{
if (currConfig.connStrRules.ContainsKey(connectionStringsList[i].Attributes["name"].Value))
{
// effettuo sostituzione
connectionStringsList[i].Attributes["connectionString"].Value = currConfig.connStrRules[connectionStringsList[i].Attributes["name"].Value];
}
}
// ora lo SALVO (il documento...)
doc.Save(item);
Console.WriteLine(" values updated!");
}
// STEP 2: processo files json (stile dotnetcore >= 5.0)
JToken currJsonConf;
foreach (var item in configFilesJson)
{
Console.Write($"JSON Found: {item} --> ");
string currFileData = File.ReadAllText(item);
bool changed = false;
if (!string.IsNullOrEmpty(currFileData))
{
try
{
//currJsonConf = JsonConvert.DeserializeObject<jsonAppConfig>(currFileData);
currJsonConf = JToken.Parse(currFileData);
if (currJsonConf.HasValues)
{
if (currJsonConf["ConnectionStrings"] != null)
{
foreach (var keySubst in currConfig.jsonConnStrRules)
{
if (currJsonConf["ConnectionStrings"][keySubst.Key] != null)
{
currJsonConf["ConnectionStrings"][keySubst.Key].Replace(keySubst.Value);
changed = true;
}
}
}
if (currJsonConf["ServerConf"] != null)
{
foreach (var keySubst in currConfig.jsonConnStrRules)
{
if (currJsonConf["ServerConf"][keySubst.Key] != null)
{
currJsonConf["ServerConf"][keySubst.Key].Replace(keySubst.Value);
changed = true;
}
}
}
}
string newFileData = JsonConvert.SerializeObject(currJsonConf, Newtonsoft.Json.Formatting.Indented);
if (changed)
{
// ora lo SALVO (il documento...)
File.WriteAllText(item, newFileData);
Console.WriteLine(" values updated!");
}
else
{
Console.WriteLine("...no change...");
}
}
catch (Exception exc)
{
Console.WriteLine($"Eccezione in decodifica item {item}{Environment.NewLine}{exc}");
}
}
}
}
else
{
Console.WriteLine($"Errore: file conf vuoto: {currentSetFile}");
}
}
else
{
Console.WriteLine($"Errore: file conf non trovato: {currentSetFile}");
}
}
#endregion Private Methods
}
}