Reputation: 143
I have two JSON files with a bunch of configurations. When new custom configurations are added in globalconfigs.json
, I want to add those key value pairs in another app1configs.json
. Let me explain it a bit.
globalconfigs.json:
{
"App1": {
"files": [
"app1configs.json"
],
"values": {
"NewConfigsBool": true,
"NewConfigsValues": {
"App1SampleConfigs": "CustomConfig1"
},
"CustomSQLFiles": true,
"SQLPaths": [
"D:\\some\\location\\to\\myconfigs.sql"
]
}
}
The above json code is a little snippet of the globalconfigurations.json
. If the "NewConfigsBool":
is true, I want to copy the key value pairs in "NewConfigsValues"
to another JSON file which looks like this. App1
is one of many, however they all follow the same syntax. And each app has its own appconfigs.json
.
app1configs.json
:
{
"globalsettings": {
"values": {
"sqlstring": "alkjsdaklsjdklajsd3910840294",
"hostname": "somesite.local",
"filepath": "D:\\dummy\\location"
}
},
"files": [
"mysettings.json",
"executors.dll",
"logrecords.txt"
]
}
The above code is how app1configs.json
normally looks. However, once "NewConfigsBool"
is true, app1configs.json
should look like this:
{
"globalsettings": {
"values": {
"sqlstring": "alkjsdaklsjdklajsd3910840294",
"hostname": "somesite.local",
"filepath": "D:\\dummy\\location",
"App1SampleConfigs": "CustomConfig1"
}
},
"files": [
"mysettings.json",
"executors.dll",
"logrecords.txt"
],
"SQLPaths": [
"D:\\some\\location\\to\\myconfigs.sql"
]
}
These custom configurations are not always going to have the same "keys". The user enters the key and the value so it can change. I'd like to highlight the changes here too. Basically, the configurations in NewConfigsValues
in globalconfigs.json
are stored in globalsettings
in app1configs.json
. And the SQLPaths
are stored as well like I have shown above.
I thought I could do text replacement here however, since the keys are not the same, I wasn't able to do text replacement.
I would very much appreciate help here or any kind of feedback.
Upvotes: 1
Views: 270
Reputation: 4644
Solution Example:
It reads globalconfigs.json
, loops through each application, checks if NewConfigsBool
is true or false.
If NewConfigsBool
is true, it loops through all application .files
and adds or upodates %file%.globalsettings.values.%parameterName%
.
The part for SQL is not implemented so it's similar and it's for you 😉
$root = 'S:\SCRIPTS\GC'
$backupNameFormat = '{0}.b{1}.bak'
$pathGS = [System.IO.Path]::Combine($root,'globalconfigs.json')
$GSData = [System.IO.File]::ReadAllText($pathGS) | ConvertFrom-Json
$applicationNames = @($GSData | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty 'Name' )
$applicationDataList = $applicationNames |
ForEach-Object {
[PSCustomObject]@{
Name = $_
Data = $GSData.($_)
}
}
forEach ($ad in $applicationDataList) {
if (($null -ne $ad.Data) -and ($null -ne $ad.Data.values) -and ($ad.Data.values.NewConfigsBool -eq $true)) {
$files = @($ad.Data.files)
if ($files.Count -le 0) {
Write-Warning "For application $($ad.Name) new config is requested, but no files to patch"
} else {
foreach ($fName in $files) {
$fPath = [System.IO.Path]::Combine($root, $fName)
if (-not [System.IO.File]::Exists($fPath)) {
Write-Warning "For application $($ad.Name) new config is requested, but no file $($fPath) can not be found"
} else {
$fData = $null
try {
$fData = [System.IO.File]::ReadAllText($fPath) | ConvertFrom-Json -ErrorAction Stop
} catch {
Write-Warning "For application $($ad.Name) new config is requested, but file $($fPath) can not be read: $($_.Exception.Message)"
}
if (($null -ne $fData) -and ($null -ne $fData.globalsettings) -and ($null -ne $fData.globalsettings.values)) {
if ($null -ne $ad.Data.values.NewConfigsValues) {
$newValues = $ad.Data.values.NewConfigsValues
$newValueNames = @($newValues | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty 'Name')
$hasErrors = $false
try {
$newValueNames |
% {Add-Member -InputObject $fData.globalsettings.values -MemberType NoteProperty -Name $_ -Value ($newValues.($_)) -Force -ErrorAction Stop}
} catch {
$hasErrors = $true
Write-Warning "For application $($ad.Name) new config application failed for file $($fPath): $($_.Exception.Message)"
}
if ($hasErrors -eq $false) {
$backupName = [String]::Format($backupNameFormat, [System.IO.Path]::GetFileName($fPath), [DateTime]::UtcNow.ToString('yyyy_MM_dd.HH_mm_ss'))
$backupPath = [System.IO.Path]::Combine($root,$backupName)
$backupComplete = $false
try {
[System.IO.File]::Copy($fPath, $backupPath, $false)
$backupComplete = $true
} catch {
Write-Warning "Unable to backup file $($fPath) to $($backupPath): $($_.Exception.Message)"
$backupComplete = $false
}
if ($backupComplete -eq $true) {
try {
$fData | ConvertTo-Json -Depth 100 | Out-File -FilePath $fPath -Force -Confirm:$false -ErrorAction Stop
} catch {
Write-Warning -Message "Unable to save file $($fPath): $($_.Exception.Message)"
}
}
}
} else {
Write-Warning -Message "For application $($ad.Name) new config is requested, but file $($fPath) can not be patched because `"NewConfigsValues`" is empty"
}
}
}
}
}
} else {
Write-Verbose "Ignoring application $($ad.Name) configuration because it's `"values.NewConfigsBool`" NE True"
}
}
Upvotes: 1