Sprint SPRINT_20260417_024_DevOps_dotnet_release_image_stabilization. - Dockerfile.platform + Dockerfile.dotnet-service adjustments for deterministic layer ordering and cache-friendly publish. - devops/release/components.json updates. - devops/compose: .env, README, legacy + stella-services docker-compose, stellaops env example, postgres-init 04/04b/15/16 authority + release schemas, setup.bootstrap.local.yaml. - Gitea build_release.py script. - scripts/register-local-integrations.ps1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
303 lines
11 KiB
PowerShell
303 lines
11 KiB
PowerShell
#!/usr/bin/env pwsh
|
|
<#
|
|
.SYNOPSIS
|
|
Registers the locally reachable integration catalog entries for a tenant.
|
|
.DESCRIPTION
|
|
Uses the live Integrations API exposed by the local Docker stack to create
|
|
any missing local-capable providers, then runs test and health checks for
|
|
each entry so the catalog converges to a ready local lane.
|
|
.PARAMETER Tenant
|
|
Tenant identifier used for the catalog operations. Defaults to default; override
|
|
it if your setup flow created a different tenant identifier.
|
|
.PARAMETER BaseUrl
|
|
Base URL for the local Integrations API. Defaults to the host-mapped
|
|
integrations-web endpoint.
|
|
.PARAMETER IncludeGitLab
|
|
Also register the GitLab Server and GitLab CI providers. This requires
|
|
authref://vault/gitlab#access-token to be populated in Vault.
|
|
.PARAMETER IncludeGitLabRegistry
|
|
Also register the GitLab Container Registry provider. This requires the
|
|
heavy GitLab profile with registry enabled plus authref://vault/gitlab#registry-basic.
|
|
.PARAMETER BootstrapGitLabSecrets
|
|
When used with `-IncludeGitLab` or `-IncludeGitLabRegistry`, bootstrap or
|
|
rotate the local GitLab PAT material into Vault automatically before the
|
|
GitLab-backed integrations are registered.
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$Tenant = 'default',
|
|
[string]$BaseUrl = 'http://127.1.0.42',
|
|
[switch]$IncludeGitLab,
|
|
[switch]$IncludeGitLabRegistry,
|
|
[switch]$BootstrapGitLabSecrets
|
|
)
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = 'Stop'
|
|
$BaseUrl = $BaseUrl.TrimEnd('/')
|
|
|
|
$Headers = @{
|
|
'X-StellaOps-Tenant' = $Tenant
|
|
'X-StellaOps-Actor' = 'local-scratch-setup'
|
|
}
|
|
|
|
if ($BootstrapGitLabSecrets -and ($IncludeGitLab -or $IncludeGitLabRegistry)) {
|
|
& (Join-Path $PSScriptRoot 'bootstrap-local-gitlab-secrets.ps1') -VerifyRegistry:$IncludeGitLabRegistry
|
|
}
|
|
|
|
function Invoke-IntegrationApi {
|
|
param(
|
|
[Parameter(Mandatory)]
|
|
[ValidateSet('GET', 'POST')]
|
|
[string]$Method,
|
|
|
|
[Parameter(Mandatory)]
|
|
[string]$Path,
|
|
|
|
[object]$Body
|
|
)
|
|
|
|
$invokeParameters = @{
|
|
Method = $Method
|
|
Uri = "$BaseUrl$Path"
|
|
Headers = $Headers
|
|
TimeoutSec = 30
|
|
ErrorAction = 'Stop'
|
|
}
|
|
|
|
if ($null -ne $Body) {
|
|
$invokeParameters['ContentType'] = 'application/json'
|
|
$invokeParameters['Body'] = $Body | ConvertTo-Json -Depth 10
|
|
}
|
|
|
|
return Invoke-RestMethod @invokeParameters
|
|
}
|
|
|
|
function Get-HealthName {
|
|
param([int]$Status)
|
|
|
|
switch ($Status) {
|
|
1 { return 'Healthy' }
|
|
2 { return 'Degraded' }
|
|
3 { return 'Unhealthy' }
|
|
default { return 'Unknown' }
|
|
}
|
|
}
|
|
|
|
function New-IntegrationDefinition {
|
|
param(
|
|
[Parameter(Mandatory)][string]$Name,
|
|
[Parameter(Mandatory)][string]$Description,
|
|
[Parameter(Mandatory)][int]$Type,
|
|
[Parameter(Mandatory)][int]$Provider,
|
|
[Parameter(Mandatory)][string]$Endpoint,
|
|
[string]$AuthRefUri,
|
|
[string]$OrganizationId,
|
|
[hashtable]$ExtendedConfig,
|
|
[string[]]$Tags
|
|
)
|
|
|
|
return [ordered]@{
|
|
name = $Name
|
|
description = $Description
|
|
type = $Type
|
|
provider = $Provider
|
|
endpoint = $Endpoint
|
|
authRefUri = $AuthRefUri
|
|
organizationId = $OrganizationId
|
|
extendedConfig = $ExtendedConfig
|
|
tags = $Tags
|
|
}
|
|
}
|
|
|
|
$definitions = @(
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local Harbor Fixture' `
|
|
-Description 'Local Harbor mock fixture for registry onboarding and health checks.' `
|
|
-Type 1 `
|
|
-Provider 100 `
|
|
-Endpoint 'http://harbor-fixture.stella-ops.local' `
|
|
-OrganizationId 'local-fixtures' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'registry')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local Docker Registry' `
|
|
-Description 'Local open OCI registry for catalog and tag probe validation.' `
|
|
-Type 1 `
|
|
-Provider 104 `
|
|
-Endpoint 'http://registry.stella-ops.local:5000' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'registry')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local Nexus Registry' `
|
|
-Description 'Local Nexus Repository Manager for registry integration checks.' `
|
|
-Type 1 `
|
|
-Provider 107 `
|
|
-Endpoint 'http://nexus.stella-ops.local:8081' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'registry')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local GitHub App Fixture' `
|
|
-Description 'Deterministic GitHub App fixture for SCM integration checks.' `
|
|
-Type 2 `
|
|
-Provider 200 `
|
|
-Endpoint 'http://github-app-fixture.stella-ops.local' `
|
|
-OrganizationId 'local-fixtures' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'scm')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local Gitea Server' `
|
|
-Description 'Local Gitea service for SCM connectivity and repository discovery.' `
|
|
-Type 2 `
|
|
-Provider 203 `
|
|
-Endpoint 'http://gitea.stella-ops.local:3000' `
|
|
-OrganizationId 'local' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'scm')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local Jenkins' `
|
|
-Description 'Local Jenkins service for CI/CD integration checks.' `
|
|
-Type 3 `
|
|
-Provider 302 `
|
|
-Endpoint 'http://jenkins.stella-ops.local:8080' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'cicd')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local eBPF Runtime Host' `
|
|
-Description 'Local runtime-host fixture exposing the eBPF agent contract.' `
|
|
-Type 5 `
|
|
-Provider 500 `
|
|
-Endpoint 'http://runtime-host-fixture.stella-ops.local' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'runtime-host')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local StellaOps Mirror' `
|
|
-Description 'Local Concelier mirror health surface for the StellaOps mirror provider.' `
|
|
-Type 6 `
|
|
-Provider 600 `
|
|
-Endpoint 'http://concelier.stella-ops.local' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'feed-mirror')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local NVD Mirror' `
|
|
-Description 'Local Concelier mirror health surface for the NVD mirror provider.' `
|
|
-Type 6 `
|
|
-Provider 601 `
|
|
-Endpoint 'http://concelier.stella-ops.local' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'feed-mirror')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local OSV Mirror' `
|
|
-Description 'Local Concelier mirror health surface for the OSV mirror provider.' `
|
|
-Type 6 `
|
|
-Provider 602 `
|
|
-Endpoint 'http://concelier.stella-ops.local' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'feed-mirror')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local Vault' `
|
|
-Description 'Local HashiCorp Vault dev server for secrets integration checks.' `
|
|
-Type 9 `
|
|
-Provider 550 `
|
|
-Endpoint 'http://vault.stella-ops.local:8200' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'secrets')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local Consul' `
|
|
-Description 'Local Consul server for settings and service-discovery checks.' `
|
|
-Type 9 `
|
|
-Provider 551 `
|
|
-Endpoint 'http://consul.stella-ops.local:8500' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'secrets')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local MinIO' `
|
|
-Description 'Local MinIO server for S3-compatible storage integration checks.' `
|
|
-Type 10 `
|
|
-Provider 450 `
|
|
-Endpoint 'http://minio.stella-ops.local:9000' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'storage'))
|
|
)
|
|
|
|
if ($IncludeGitLab) {
|
|
$definitions += @(
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local GitLab Server' `
|
|
-Description 'Local GitLab server for SCM connectivity and discovery probes.' `
|
|
-Type 2 `
|
|
-Provider 201 `
|
|
-Endpoint 'http://gitlab.stella-ops.local:8929' `
|
|
-AuthRefUri 'authref://vault/gitlab#access-token' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'scm')),
|
|
(New-IntegrationDefinition `
|
|
-Name 'Local GitLab CI' `
|
|
-Description 'Local GitLab CI surface for CI/CD connectivity checks.' `
|
|
-Type 3 `
|
|
-Provider 301 `
|
|
-Endpoint 'http://gitlab.stella-ops.local:8929' `
|
|
-AuthRefUri 'authref://vault/gitlab#access-token' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'cicd'))
|
|
)
|
|
}
|
|
|
|
if ($IncludeGitLabRegistry) {
|
|
$definitions += New-IntegrationDefinition `
|
|
-Name 'Local GitLab Container Registry' `
|
|
-Description 'Local GitLab container registry surface. Requires authref://vault/gitlab#registry-basic.' `
|
|
-Type 1 `
|
|
-Provider 109 `
|
|
-Endpoint 'http://gitlab.stella-ops.local:5050' `
|
|
-AuthRefUri 'authref://vault/gitlab#registry-basic' `
|
|
-ExtendedConfig @{ scheduleType = 'manual' } `
|
|
-Tags @('local', 'scratch-setup', 'registry')
|
|
}
|
|
|
|
$existingResponse = Invoke-IntegrationApi -Method GET -Path '/api/v1/integrations?pageSize=200'
|
|
$existingItems = @($existingResponse.items)
|
|
$results = New-Object System.Collections.Generic.List[object]
|
|
|
|
foreach ($definition in $definitions) {
|
|
$match = $existingItems | Where-Object {
|
|
$_.provider -eq $definition.provider -and $_.endpoint -eq $definition.endpoint
|
|
} | Select-Object -First 1
|
|
|
|
if ($null -eq $match) {
|
|
$created = Invoke-IntegrationApi -Method POST -Path '/api/v1/integrations/' -Body $definition
|
|
$id = $created.id
|
|
$action = 'created'
|
|
} else {
|
|
$id = $match.id
|
|
$action = 'existing'
|
|
}
|
|
|
|
$test = Invoke-IntegrationApi -Method POST -Path "/api/v1/integrations/$id/test"
|
|
$health = Invoke-IntegrationApi -Method GET -Path "/api/v1/integrations/$id/health"
|
|
|
|
$results.Add([pscustomobject]@{
|
|
Name = $definition.name
|
|
Provider = $definition.provider
|
|
Action = $action
|
|
TestSuccess = [bool]$test.success
|
|
Health = Get-HealthName -Status ([int]$health.status)
|
|
Endpoint = $definition.endpoint
|
|
Id = "$id"
|
|
})
|
|
}
|
|
|
|
$results |
|
|
Sort-Object Name |
|
|
Format-Table Name, Action, TestSuccess, Health, Endpoint -AutoSize |
|
|
Out-String |
|
|
Write-Host
|
|
|
|
$failures = @($results | Where-Object { -not $_.TestSuccess -or $_.Health -ne 'Healthy' })
|
|
if ($failures.Count -gt 0) {
|
|
Write-Error "Local integration registration completed with $($failures.Count) failing or non-healthy entry/entries for tenant '$Tenant'."
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "Registered and verified $($results.Count) local integration entries for tenant '$Tenant' via $BaseUrl." -ForegroundColor Green
|