diff --git a/Tools/Create-Azure-Sentinel-Solution/V3/createSolutionV3.ps1 b/Tools/Create-Azure-Sentinel-Solution/V3/createSolutionV3.ps1 index 96b087290b..3312e89b4d 100644 --- a/Tools/Create-Azure-Sentinel-Solution/V3/createSolutionV3.ps1 +++ b/Tools/Create-Azure-Sentinel-Solution/V3/createSolutionV3.ps1 @@ -67,8 +67,11 @@ Write-Host "SolutionBasePath is $solutionBasePath, Solution Name $solutionName" $isPipelineRun = $false -. "$repositoryBasePath/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1" # load common functions -. "$repositoryBasePath.script/package-automation/catelogAPI.ps1" +$commonFunctionsFilePath = $repositoryBasePath + "Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1" +$catelogAPIFilePath = $repositoryBasePath + ".script/package-automation/catelogAPI.ps1" + +. $commonFunctionsFilePath # load common functions +. $catelogAPIFilePath try { foreach ($inputFile in $(Get-ChildItem -Path "$solutionFolderBasePath\$dataFolderName\$dataFileName")) { @@ -250,6 +253,9 @@ try { GeneratePackage -solutionName $solutionName -contentToImport $contentToImport -calculatedBuildPipelinePackageVersion $contentToImport.Version; RunArmTtkOnPackage -solutionName $solutionName -isPipelineRun $false; + + # check if mainTemplate and createUiDefinition json files are valid or not + CheckJsonIsValid($solutionFolderBasePath) } } catch { diff --git a/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 b/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 index bb7e6f10fd..a9338037cf 100644 --- a/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 +++ b/Tools/Create-Azure-Sentinel-Solution/common/commonFunctions.ps1 @@ -62,10 +62,128 @@ function handleEmptyInstructionProperties ($inputObj) { $outputObj } -function removePropertiesRecursively ($resourceObj, $isWorkbook = $false) { +function addBlankVariables($resourceObj) +{ + $resourceObj.$key = "[variables('blanks')]"; + if (!$global:baseMainTemplate.variables.blanks) { + $global:baseMainTemplate.variables | Add-Member -NotePropertyName "blanks" -NotePropertyValue "[replace('b', 'b', '')]" + } +} + +function addEmptyArrayVariables($resourceObj) +{ + $resourceObj.$key = "[variables('TemplateEmptyArray')]"; + if (!$global:baseMainTemplate.variables.TemplateEmptyArray) { + $global:baseMainTemplate.variables | Add-Member -NotePropertyName "TemplateEmptyArray" -NotePropertyValue "[json('[]')]" + } +} + +function addEmptyObjectVariables($resourceObj) +{ + $resourceObj.$key = "[variables('TemplateEmptyObject')]"; + if (!$global:baseMainTemplate.variables.TemplateEmptyObject) { + $global:baseMainTemplate.variables | Add-Member -NotePropertyName "TemplateEmptyObject" -NotePropertyValue "[json('{}')]" + } +} + +function addNullVariables($resourceObj) +{ + $resourceObj.$key = "[variables('TemplateNullVariable')]"; + if (!$global:baseMainTemplate.variables.TemplateNullVariable) { + $global:baseMainTemplate.variables | Add-Member -NotePropertyName "TemplateNullVariable" -NotePropertyValue "null" + } +} + +function IsSkipActionInputs($resourceObj, $key, $val, $isAction = $false) +{ + if ($isAction -and $key -eq "inputs" -and + $val -is [System.Management.Automation.PSCustomObject] -and + -not "$val") + { + # when action has "inputs": {} + addEmptyObjectVariables $resourceObj + return $true + } + + if ($isAction -and $key -eq "inputs" -and + $null -ne $val -and + $val -is [System.Array] -and + $val.count -eq 0) + { + # when action has "inputs": [] + addEmptyArrayVariables $resourceObj + return $true + } + + if ($isAction -and $key -eq "inputs" -and + $null -eq $val) + { + # when action has "inputs": null + addNullVariables $resourceObj + return $true + } + + return $false +} + +function IsSkipActionInputsValue($resourceObj, $key, $val, $isAction = $false, $isInputs = $false) +{ + if ($isAction -and $isInputs -and + $key -eq "value" -and + $val -is [System.Management.Automation.PSCustomObject] -and + -not "$val") + { + # when action has inputs--> "value": {} + addEmptyObjectVariables $resourceObj + continue + } + + if ($isAction -and $isInputs -and + $key -eq "value" -and + $null -ne $val -and + $val -is [System.Array] -and + $val.count -eq 0) + { + # when action has inputs--> "value": [] + addEmptyArrayVariables $resourceObj + continue + } + + if ($isAction -and $isInputs -and + $key -eq "value" -and + $null -eq $val) + { + # when action has inputs--> "value": null + addNullVariables $resourceObj + continue + } +} + +function removePropertiesRecursively ($resourceObj, $isWorkbook = $false, $isAction = $false, $isInputs = $false) { foreach ($prop in $resourceObj.PsObject.Properties) { $key = $prop.Name $val = $prop.Value + + if ($key -eq 'actions') { + $isAction = $true + } + + if ($key -eq 'inputs') { + $isInputs = $true + } + + # if actions --> inputs has either {} or [] or null then we skip later code + if (IsSkipActionInputs $resourceObj $key $val $isAction) + { + continue + } + + # if actions --> inputs --> value has either {} or [] or null then we skip later code + if (IsSkipActionInputsValue $resourceObj $key $val $isAction $isInputs) + { + continue + } + if ($null -eq $val) { if ($isWorkbook) { @@ -74,9 +192,15 @@ function removePropertiesRecursively ($resourceObj, $isWorkbook = $false) { } else { - $resourceObj.$key = "[variables('blanks')]"; - if (!$global:baseMainTemplate.variables.blanks) { - $global:baseMainTemplate.variables | Add-Member -NotePropertyName "blanks" -NotePropertyValue "[replace('b', 'b', '')]" + if ($isAction -and $isInputs) + { + continue + } + else { + $resourceObj.$key = "[variables('blanks')]"; + if (!$global:baseMainTemplate.variables.blanks) { + $global:baseMainTemplate.variables | Add-Member -NotePropertyName "blanks" -NotePropertyValue "[replace('b', 'b', '')]" + } } } } @@ -98,7 +222,7 @@ function removePropertiesRecursively ($resourceObj, $isWorkbook = $false) { else { foreach ($item in $val) { $itemIndex = $val.IndexOf($item) - $resourceObj.$key[$itemIndex] = $(removePropertiesRecursively $val[$itemIndex] $isWorkbook) + $resourceObj.$key[$itemIndex] = $(removePropertiesRecursively $val[$itemIndex] $isWorkbook $isAction $isInputs) } } } @@ -108,7 +232,7 @@ function removePropertiesRecursively ($resourceObj, $isWorkbook = $false) { $resourceObj.PsObject.Properties.Remove($key) } else { - $resourceObj.$key = $(removePropertiesRecursively $val $isWorkbook) + $resourceObj.$key = $(removePropertiesRecursively $val $isWorkbook $isAction $isInputs) if ($($resourceObj.$key.PsObject.Properties).Count -eq 0) { $resourceObj.PsObject.Properties.Remove($key) } @@ -1142,7 +1266,7 @@ function PrepareSolutionMetadata($solutionMetadataRawContent, $contentResourceDe $playbookData.variables | Add-Member -NotePropertyName "_operationId-$($resourceobj.$key)" -NotePropertyValue "[variables('operationId-$($resourceobj.$key)')]" $resourceObj.$key = "[variables('_operationId-$($resourceobj.$key)')]" } - if($contentToImport.TemplateSpec -and ($resourceObj.$key.StartsWith("[")) -and ($resourceObj.$key -ne "[variables('TemplateEmptyArray')]")) + if($contentToImport.TemplateSpec -and ($resourceObj.$key.StartsWith("[")) -and ($resourceObj.$key -ne "[variables('TemplateEmptyArray')]") -and $prop.Value -ne "[variables('TemplateEmptyObject')]" -and $prop.Value -ne "[variables('TemplateNullVariable')]") { $resourceObj.$key = "[" + $resourceObj.$key; } @@ -2740,6 +2864,25 @@ function PrepareSolutionMetadata($solutionMetadataRawContent, $contentResourceDe } } + # this function is to check if maintemplate and createUi files in package folder is valid or not + function CheckJsonIsValid($solutionFolderBasePath) + { + [array]$packageFolderFiles=Get-ChildItem "$solutionFolderBasePath\Package\*.json" -Recurse| select -expand fullname + Write-Host "************Validating if Package Json files are valid or not***************" + foreach ($filePath in $packageFolderFiles) + { + $isValid = Get-Content $filePath -Raw | Test-Json -ErrorAction SilentlyContinue + if ($isValid) + { + Write-Host "File $filePath is a valid Json file!" + } + else + { + Write-Host "File $filePath is Not a valid Json file!" + } + } + } + function GeneratePackage($solutionName, $contentToImport, $calculatedBuildPipelinePackageVersion = '') { if ($contentToImport.Description) { diff --git a/Tools/Create-Azure-Sentinel-Solution/pipeline/createSolutionV4.ps1 b/Tools/Create-Azure-Sentinel-Solution/pipeline/createSolutionV4.ps1 index 0df00d1ea4..834f53f282 100644 --- a/Tools/Create-Azure-Sentinel-Solution/pipeline/createSolutionV4.ps1 +++ b/Tools/Create-Azure-Sentinel-Solution/pipeline/createSolutionV4.ps1 @@ -242,6 +242,9 @@ try GeneratePackage -solutionName $solutionName -contentToImport $contentToImport -calculatedBuildPipelinePackageVersion $calculatedPackageVersion; Write-Host "Package Generated Successfully!!" + + # check if mainTemplate and createUiDefinition json files are valid or not + CheckJsonIsValid($solutionFolderBasePath) } } catch {