<commit_before><#
.SYNOPSIS
    powershell script to export existing azure arm template resource settings similar for portal deployed service fabric cluster

    dependencies:
        loadbalancer depends on public ip
        vmss depends on
            vnet
            loadbalancer
            storage account sflogs
            storage account diag
        cluster depends on storage account sflogs

.LINK
    invoke-webRequest "https://raw.githubusercontent.com/jagilber/powershellScripts/master/temp/azure-az-sf-export-arm-template.ps1" -outFile "$pwd\azure-az-sf-export-arm-template.ps1";
    .\azure-az-sf-export-arm-template.ps1 -resourceGroupName {{ resource group name }} -resourceName {{ resource name }} [-patch]

.DESCRIPTION  
    powershell script to export existing azure arm template resource settings similar for portal deployed service fabric cluster
    this assumes all resources in same resource group as that is the only way to deploy from portal
    
    PRECAUTION: when script queries the arm resources, if unable to determine configured api version, 
     the latest api version for that resource will be written to the template.json.

.NOTES  
    File Name  : azure-az-sf-export-arm-template.ps1
    Author     : jagilber
    Version    : 210307
    History    : 

.EXAMPLE 
    .\azure-az-sf-export-arm-template.ps1 -resourceGroupName clusterresourcegroup
    export sf resources in resource group 'clusteresourcegroup' and generate template.json

#>

[cmdletbinding()]
param (
    [string]$resourceGroupName = '',
    [string[]]$resourceNames = '',
    [string[]]$excludeResourceNames = '',
    [switch]$patch,
    [string]$templateJsonFile = "$psscriptroot/template.json", 
    [string]$templateParameterFile = '', 
    [string]$apiVersion = '' ,
    [string]$schema = 'http://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json',
    [int]$sleepSeconds = 1, 
    [ValidateSet('Incremental', 'Complete')]
    [string]$mode = 'Incremental',
    [switch]$useLatestApiVersion,
    [switch]$detail
)

set-strictMode -Version 3.0
$global:resourceTemplateObj = @{ }
$global:resourceErrors = 0
$global:resourceWarnings = 0
$global:configuredRGResources = [collections.arraylist]::new()
$global:sflogs = $null
$global:sfdiags = $null
$global:startTime = get-date
$env:SuppressAzurePowerShellBreakingChangeWarnings = $true
$PSModuleAutoLoadingPreference = 2
$currentErrorActionPreference = $ErrorActionPreference
$currentVerbosePreference = $VerbosePreference
$debugLevel = 'none'

function main () {
    write-host "starting"
    if ($detail) {
        $ErrorActionPreference = 'continue'
        $VerbosePreference = 'continue'
        $debugLevel = 'all'
    }

    if (!(check-module)) {
        return
    }
    
    Enable-AzureRmAlias
    if (!(Get-AzContext)) {
        write-host "connecting to azure"
        Connect-AzAccount
    }

    if (!$resourceGroupName -or !$templateJsonFile) {
        write-error 'specify resourceGroupName'
        return
    }

    if ($resourceNames) {
        foreach ($resourceName in $resourceNames) {
            write-host "getting resource $resourceName"
            $global:configuredRGResources.AddRange(@((get-azresource -ResourceGroupName $resourceGroupName -resourceName $resourceName)))
        }
    }
    else {
        $resourceIds = enum-allResources
        foreach ($resourceId in $resourceIds) {
            $resource = get-azresource -resourceId "$resourceId" -ExpandProperties
            if ($resource.ResourceGroupName -ieq $resourceGroupName) {
                write-host "adding resource id to configured resources: $($resource.resourceId)" -ForegroundColor Cyan
                [void]$global:configuredRGResources.Add($resource)
            }
            else {
                write-warning "skipping resource $($resource.resourceid) as it is out of resource group scope $($resource.ResourceGroupName)"
            }
        }
    }

    display-settings -resources $global:configuredRGResources

    if ($global:configuredRGResources.count -lt 1) {
        Write-Warning "error enumerating resource $($error | format-list * | out-string)"
        return
    }

    $deploymentName = "$resourceGroupName-$((get-date).ToString("yyyyMMdd-HHmms"))"

    if ($patch) {
        remove-jobs
        if (!(deploy-template -configuredResources $global:configuredRGResources)) { return }
        wait-jobs
    }
    else {
        export-template -configuredResources $global:configuredRGResources -jsonFile $templateJsonFile
        write-host "template exported to $templateJsonFile" -ForegroundColor Yellow
        write-host "to update arm resource, modify $templateJsonFile.  when finished, execute script with -patch to update resource" -ForegroundColor Yellow

        $currentConfig = Get-Content -raw $templateJsonFile | convertfrom-json
        
        # save raw file
        $currentConfig | convertto-json -depth 99 | out-file $templateJsonFile.Replace(".json", ".export.json")

        # create base /current template
        remove-duplicateResources($currentConfig)
        modify-lbResources($currentConfig)
        modify-vmssResources($currentConfig)

        # add-paramaters($currentConfig)
        # verify-config($clusterResource)
        
        # save base / current json
        $currentConfig | convertto-json -depth 99 | out-file $templateJsonFile.Replace(".json", ".current.json")

        # # create redeploy template
        # modify-clusterResourcesForReDeploy($currentConfig)
        # modify-vmssResourcesForReDeploy($currentConfig)
        
        # # save redeploy json
        # $currentConfig | convertto-json -depth 99 | out-file $templateJsonFile.Replace(".json", ".redeploy.json")
        # # save redeploy readme
        # $redeployReadme = 'redeploy modifications:
        #     - microsoft monitoring agent extension has been removed (provisions automatically on deployment)
        #     - adminPassword required parameter added (needs to be set or one will be generated)
        #     - upgradeMode for cluster resource is set to manual with clusterCodeVersion set to current version
        #     - protectedSettings for vmss extensions cluster and diagnostic extensions are added and set to storage account settings
        #     '
        # $redeployReadme | out-file $templateJsonFile.Replace(".json", ".redeploy.readme.txt")

        # # create deploy / new / add template
        # modify-clusterResourcesForDeploy($currentConfig)
        # modify-vmssResourcesForDeploy($currentConfig)
        # modify-ipResourcesForDeploy($currentConfig)
        # modify-storageResourcesForDeploy($currentConfig)
        
        # # save add json
        # $currentConfig | convertto-json -depth 99 | out-file $templateJsonFile.Replace(".json", ".new.json")
        # # save add readme
        # $addReadme = 'new / add modifications:
        #     - microsoft monitoring agent extension has been removed (provisions automatically on deployment)
        #     - adminPassword required parameter added (needs to be set or one will be generated)
        #     - upgradeMode for cluster resource is set to manual with clusterCodeVersion set to current version
        #     - protectedSettings for vmss extensions cluster and diagnostic extensions are added and set to storage account settings
        #     - dnsSettings for public Ip Address
        #     - storageAccountNames required paramaters (needs to be unique or will be generated)
        #     - if adding new vmss, each vmms resource needs a cluster nodetype resource added
        #     '
        # $addReadme | out-file $templateJsonFile.Replace(".json", ".new.readme.txt")

        $templateJsonFile = $templateJsonFile.Replace(".json", ".current.json")
        $error.clear()
        code $templateJsonFile
        if ($error) {
            . $templateJsonFile
        }<commit_msg>redeploy and add outlines added<commit_after><#
.SYNOPSIS
    powershell script to export existing azure arm template resource settings similar for portal deployed service fabric cluster

    dependencies:
        loadbalancer depends on public ip
        vmss depends on
            vnet
            loadbalancer
            storage account sflogs
            storage account diag
        cluster depends on storage account sflogs

.LINK
    invoke-webRequest "https://raw.githubusercontent.com/jagilber/powershellScripts/master/temp/azure-az-sf-export-arm-template.ps1" -outFile "$pwd\azure-az-sf-export-arm-template.ps1";
    .\azure-az-sf-export-arm-template.ps1 -resourceGroupName {{ resource group name }} -resourceName {{ resource name }} [-patch]

.DESCRIPTION  
    powershell script to export existing azure arm template resource settings similar for portal deployed service fabric cluster
    this assumes all resources in same resource group as that is the only way to deploy from portal
    
    PRECAUTION: when script queries the arm resources, if unable to determine configured api version, 
     the latest api version for that resource will be written to the template.json.

.NOTES  
    File Name  : azure-az-sf-export-arm-template.ps1
    Author     : jagilber
    Version    : 210307
    History    : 

.EXAMPLE 
    .\azure-az-sf-export-arm-template.ps1 -resourceGroupName clusterresourcegroup
    export sf resources in resource group 'clusteresourcegroup' and generate template.json

#>

[cmdletbinding()]
param (
    [string]$resourceGroupName = '',
    [string[]]$resourceNames = '',
    [string[]]$excludeResourceNames = '',
    [switch]$patch,
    [string]$templateJsonFile = "$psscriptroot/template.json", 
    [string]$templateParameterFile = '', 
    [string]$apiVersion = '' ,
    [string]$schema = 'http://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json',
    [int]$sleepSeconds = 1, 
    [ValidateSet('Incremental', 'Complete')]
    [string]$mode = 'Incremental',
    [switch]$useLatestApiVersion,
    [switch]$detail
)

set-strictMode -Version 3.0
$global:resourceTemplateObj = @{ }
$global:resourceErrors = 0
$global:resourceWarnings = 0
$global:configuredRGResources = [collections.arraylist]::new()
$global:sflogs = $null
$global:sfdiags = $null
$global:startTime = get-date
$env:SuppressAzurePowerShellBreakingChangeWarnings = $true
$PSModuleAutoLoadingPreference = 2
$currentErrorActionPreference = $ErrorActionPreference
$currentVerbosePreference = $VerbosePreference
$debugLevel = 'none'

function main () {
    write-host "starting"
    if ($detail) {
        $ErrorActionPreference = 'continue'
        $VerbosePreference = 'continue'
        $debugLevel = 'all'
    }

    if (!(check-module)) {
        return
    }
    
    Enable-AzureRmAlias
    if (!(Get-AzContext)) {
        write-host "connecting to azure"
        Connect-AzAccount
    }

    if (!$resourceGroupName -or !$templateJsonFile) {
        write-error 'specify resourceGroupName'
        return
    }

    if ($resourceNames) {
        foreach ($resourceName in $resourceNames) {
            write-host "getting resource $resourceName"
            $global:configuredRGResources.AddRange(@((get-azresource -ResourceGroupName $resourceGroupName -resourceName $resourceName)))
        }
    }
    else {
        $resourceIds = enum-allResources
        foreach ($resourceId in $resourceIds) {
            $resource = get-azresource -resourceId "$resourceId" -ExpandProperties
            if ($resource.ResourceGroupName -ieq $resourceGroupName) {
                write-host "adding resource id to configured resources: $($resource.resourceId)" -ForegroundColor Cyan
                [void]$global:configuredRGResources.Add($resource)
            }
            else {
                write-warning "skipping resource $($resource.resourceid) as it is out of resource group scope $($resource.ResourceGroupName)"
            }
        }
    }

    display-settings -resources $global:configuredRGResources

    if ($global:configuredRGResources.count -lt 1) {
        Write-Warning "error enumerating resource $($error | format-list * | out-string)"
        return
    }

    $deploymentName = "$resourceGroupName-$((get-date).ToString("yyyyMMdd-HHmms"))"

    if ($patch) {
        remove-jobs
        if (!(deploy-template -configuredResources $global:configuredRGResources)) { return }
        wait-jobs
    }
    else {
        export-template -configuredResources $global:configuredRGResources -jsonFile $templateJsonFile
        write-host "template exported to $templateJsonFile" -ForegroundColor Yellow
        write-host "to update arm resource, modify $templateJsonFile.  when finished, execute script with -patch to update resource" -ForegroundColor Yellow

        $currentConfig = Get-Content -raw $templateJsonFile | convertfrom-json
        
        # save raw file
        $currentConfig | convertto-json -depth 99 | out-file $templateJsonFile.Replace(".json", ".export.json")

        # create base /current template
        remove-duplicateResources($currentConfig)
        modify-lbResources($currentConfig)
        modify-vmssResources($currentConfig)

        # add-paramaters($currentConfig)
        # verify-config($clusterResource)
        
        # save base / current json
        $currentConfig | convertto-json -depth 99 | out-file $templateJsonFile.Replace(".json", ".current.json")

        # # create redeploy template
        # modify-clusterResourcesForReDeploy($currentConfig)
        # modify-vmssResourcesForReDeploy($currentConfig)
        
        # # save redeploy json
        # $currentConfig | convertto-json -depth 99 | out-file $templateJsonFile.Replace(".json", ".redeploy.json")
        # # save redeploy readme
        $redeployReadme = 'redeploy modifications:
            - microsoft monitoring agent extension has been removed (provisions automatically on deployment)
            - adminPassword required parameter added (needs to be set or one will be generated)
            - upgradeMode for cluster resource is set to manual with clusterCodeVersion set to current version
            - protectedSettings for vmss extensions cluster and diagnostic extensions are added and set to storage account settings
            '
        $redeployReadme | out-file $templateJsonFile.Replace(".json", ".redeploy.readme.txt")

        # # create deploy / new / add template
        # modify-clusterResourcesForDeploy($currentConfig)
        # modify-vmssResourcesForDeploy($currentConfig)
        # modify-ipResourcesForDeploy($currentConfig)
        # modify-storageResourcesForDeploy($currentConfig)
        
        # # save add json
        # $currentConfig | convertto-json -depth 99 | out-file $templateJsonFile.Replace(".json", ".new.json")
        # save add readme
        $addReadme = 'new / add modifications:
            - microsoft monitoring agent extension has been removed (provisions automatically on deployment)
            - adminPassword required parameter added (needs to be set or one will be generated)
            - upgradeMode for cluster resource is set to manual with clusterCodeVersion set to current version
            - protectedSettings for vmss extensions cluster and diagnostic extensions are added and set to storage account settings
            - dnsSettings for public Ip Address needs to be unique
            - storageAccountNames required parameters (needs to be unique or will be generated)
            - if adding new vmss, each vmms resource needs a cluster nodetype resource added
            '
        $addReadme | out-file $templateJsonFile.Replace(".json", ".new.readme.txt")

        $templateJsonFile = $templateJsonFile.Replace(".json", ".current.json")
        $error.clear()
        code $templateJsonFile
        if ($error) {
            . $templateJsonFile
        }
{'fraction_non_alphanumeric': 0.09238958240922629, 'fraction_numerical': 0.004308979152144984, 'mean_word_length': 2.917101017622239, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2396063', 'n_tokens_mistral': 4166, 'n_tokens_neox': 4022, 'n_words': 1144}