list-published-modules.ps1
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# List published modules =======================================================

# Helpers ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Get-SortableVersion {
    param([string] $Version)

    try { return [version] $Version }
    catch { return [version] "0.0.0" }
}

# Execution Entrypoint +++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Write-Host "List of Published IaC Modules in Artifactory" -ForegroundColor Yellow

# Step 1: Fetch JFRO token -----------------------------------------------------

if (-not $env:JFRO_TOKEN) {
    Write-Host "missing env var: JFRO_TOKEN" -ForegroundColor Red
    exit 1
}

# Step 2: Fetch published modules ----------------------------------------------

$base = "https://hcassc.jfrog.io/artifactory"
$headers = @{ Authorization = "Bearer $($env:JFRO_TOKEN)" }
$query = @'
items.find({"repo":"iac-tf-modules-local","name":{"$match":"*.zip"}}).include("repo","path","name","created","modified","property.*")
'@

try {
    $results = Invoke-RestMethod `
        -Uri "$base/api/search/aql" `
        -Method Post `
        -Headers $headers `
        -ContentType "text/plain" `
        -Body $query
}
catch {
    Write-Host "failed to query jfrog artifactory: $($_.Exception.Message)" -ForegroundColor Red
    exit 1
}

# Step 3: Build rows -------------------------------------------------------------

$rows = $results.results | ForEach-Object {
    $props = $_.properties | Group-Object key -AsHashTable

    $ts = [System.DateTime]::ParseExact($_.modified, "MM/dd/yyyy HH:mm:ss", $null).ToString("yyyy-MM-dd HH:mm:ss UTC")
    $namespace = $props."terraform.namespace".value
    $provider = $props."terraform.provider".value
    $module = $props."terraform.name".value
    $version = $props."terraform.version".value
    $commit = if ($props."module.commit") { $props."module.commit".value.Substring(0, 8) } else { "n/a" }

    [PSCustomObject]@{
        Namespace = $namespace
        Module    = $module
        Provider  = $provider
        Version   = $version
        SortKey   = Get-SortableVersion $version
        Commit    = $commit
        UpdatedOn = $ts
    }
}

# Step 4: Print results ----------------------------------------------------------

$moduleCount = ($rows | Select-Object -Unique Namespace, Module).Count
Write-Host "`nFound $($moduleCount) published module(s)`n"

$byCategory = $rows | Group-Object Namespace | Sort-Object Name

foreach ($categoryGroup in $byCategory) {
    $byModule = $categoryGroup.Group | Group-Object Module | Sort-Object Name

    foreach ($moduleGroup in $byModule) {
        $provider = $moduleGroup.Group[0].Provider
        $category = $moduleGroup.Group[0].Namespace

        Write-Host "$($moduleGroup.Name) module (provider: $provider | category: $category)" -ForegroundColor Green

        $versions = $moduleGroup.Group | Sort-Object SortKey -Descending
        foreach ($v in $versions) {
            $flag = if ($v.SortKey -eq [version]"0.0.0" -and $v.Version -ne "0.0.0") { " [unparseable version]" } else { "" }
            Write-Host " - $($v.Version) [commit: $($v.Commit)] (updated: $($v.UpdatedOn))$flag"
        }

        Write-Host ""
    }
}