Commit Graph

292 Commits

Author SHA1 Message Date
GoodOlClint 0789601e33 Merge pull request #24 from GoodOlClint/fix/ci-concurrency
Add concurrency group to integration tests workflow
2026-03-24 15:57:25 -05:00
Clint Branham fb5d00aad0 fix(ci): add concurrency group to queue integration test runs
Prevents overlapping integration test runs on the self-hosted runner.
Uses cancel-in-progress: false so each run completes its full
lifecycle (including cleanup) before the next one starts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:53:11 -05:00
GoodOlClint 0f3e2c16d9 Merge pull request #23 from GoodOlClint/copilot/set-up-copilot-instructions
chore: add .github/copilot-instructions.md
2026-03-24 15:42:54 -05:00
GoodOlClint 5a27baa96a Merge branch 'main' into copilot/set-up-copilot-instructions 2026-03-24 15:41:29 -05:00
GoodOlClint 80652cbe92 Merge pull request #20 from GoodOlClint/feat/storage-iscsi-nfs-params
Add iSCSI/NFS parameters to New-PveStorage and shared storage integration tests
2026-03-24 15:41:09 -05:00
GoodOlClint a0c0b84323 Merge pull request #21 from GoodOlClint/copilot/sub-pr-20
fix(storage): iSCSI portal defaulting, Pool/CephPool selection, NFS format validation
2026-03-24 15:39:47 -05:00
copilot-swe-agent[bot] efc3e3a8e0 chore: add .github/copilot-instructions.md
Co-authored-by: GoodOlClint <151449+GoodOlClint@users.noreply.github.com>
Agent-Logs-Url: https://github.com/GoodOlClint/PSProxmoxVE/sessions/45c5e8bb-c3e5-461c-9064-6cdafab4daa0
2026-03-24 20:38:49 +00:00
copilot-swe-agent[bot] 3cd5400695 Initial plan 2026-03-24 20:37:18 +00:00
copilot-swe-agent[bot] f76ff513e9 fix(storage): implement Portal defaulting for iSCSI, fix Pool/CephPool selection, add NFS format validation
Co-authored-by: GoodOlClint <151449+GoodOlClint@users.noreply.github.com>
Agent-Logs-Url: https://github.com/GoodOlClint/PSProxmoxVE/sessions/d84722e4-409e-4ced-bfbc-f323715b8bdc
2026-03-24 20:36:46 +00:00
copilot-swe-agent[bot] 79c227f131 Initial plan 2026-03-24 20:30:56 +00:00
Clint Branham 2bf7f45ebf fix(ci): mount /lib/modules into NFS container for automatic kernel module loading
The NFS server image already has modprobe logic built in but needs
access to host kernel modules. Avoids requiring manual modprobe on
the runner host.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:24:06 -05:00
Clint Branham c385f4a620 fix(tests): correct NFS and iSCSI storage test parameters
NFS and iSCSI are implicitly shared in PVE — the API rejects an
explicit 'shared' parameter. iSCSI uses 'portal' (not 'server') for
the target address.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:57:45 -05:00
Clint Branham 064cc372cf feat(storage): add -Target and -Portal parameters to New-PveStorage for iSCSI
New-PveStorage now supports configuring iSCSI storage backends natively:
  -Target: iSCSI target IQN (e.g. iqn.2024-01.com.example:storage)
  -Portal: iSCSI portal address (host:port, defaults to server:3260)

Also refactored ProcessRecord to use AddIfNotEmpty helper, reducing
cognitive complexity.

Added unit tests for all iSCSI/NFS parameter metadata and a new
SharedStorage.Tests.ps1 integration test file that tests NFS and iSCSI
storage create/verify/status/delete lifecycle against the Docker-based
storage containers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:43:33 -05:00
GoodOlClint ab768e114a Merge pull request #18 from GoodOlClint/feat/multi-node-storage-vm
Multi-node PVE provisioning and Docker-based shared storage
2026-03-24 14:09:31 -05:00
GoodOlClint b3481e259b Merge pull request #19 from GoodOlClint/copilot/sub-pr-18
fix(ci): address PR #18 review feedback on Docker storage reliability and security
2026-03-24 14:02:54 -05:00
copilot-swe-agent[bot] 6a63dea923 fix: apply review feedback on Docker storage and security documentation
- Fix storage_ip derivation to use default route first, not Swarm RemoteManagers
- Make iSCSI container entrypoint idempotent (check before create for target/LUN/bind)
- Pin erichough/nfs-server from 'latest' to '2.2.1' for reproducibility
- Replace curl|sh Docker install with apt repo in Dockerfile.test
- Add docker.sock security warnings in docker-compose.test.yml and CI workflow
- Update stale 'storage VM' references in comments and .env.test.example"

Co-authored-by: GoodOlClint <151449+GoodOlClint@users.noreply.github.com>
Agent-Logs-Url: https://github.com/GoodOlClint/PSProxmoxVE/sessions/534c0a63-2988-496c-b0ae-e291fcfa050b
2026-03-24 18:53:30 +00:00
copilot-swe-agent[bot] 8acd04c272 Initial plan 2026-03-24 18:47:58 +00:00
Clint Branham 9817d30a11 feat(ci): multi-node PVE provisioning and Docker-based shared storage
Provision two PVE nodes per version (a/b) for future cluster testing,
plus Docker-based iSCSI target and NFS server for shared storage tests.

Multi-node changes:
- Each PVE version gets two nodes: 9a/9b and 8a/8b (4 VMs total)
- Parameterized answer.toml FQDN for unique hostnames per node
- Per-node auto-install ISOs with unique answer files
- Node name discovered from FQDN and included in test config
- API token creation handles pre-existing tokens (delete + recreate)
- New test env vars: PVETEST_HOST_B, PVETEST_APITOKEN_B
- Removed preflight cleanup from provision (use explicit cleanup instead)

Docker storage services:
- New docker-compose.storage.yml with iSCSI (tgt) and NFS containers
- Host networking so PVE nodes can reach storage services
- Docker socket mounted into dev-infra container for host Docker access
- Docker CLI added to dev-infra Dockerfile stage
- New test env vars: PVETEST_STORAGE_VM_IP, PVETEST_ISCSI_IQN, PVETEST_NFS_EXPORT

Other fixes:
- first-boot.sh installs open-iscsi on PVE nodes
- preflight-cleanup.sh handles empty ISO filename gracefully
- TMPDIR set to work dir to avoid /tmp overflow during ISO uploads

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:34:15 -05:00
GoodOlClint 105bf4b2ba Merge pull request #17 from GoodOlClint/feat/local-integration-runner
fix(ci): add .dockerignore to prevent sending 250MB build context
2026-03-24 10:55:35 -05:00
GoodOlClint da0591c84c Merge branch 'main' into feat/local-integration-runner 2026-03-24 10:53:17 -05:00
Clint Branham 8d5df62b41 fix(ci): add .dockerignore to prevent sending 250MB build context
The Dockerfile.test stages only install packages (no COPY), but the
build context changed from tests/infrastructure/ to repo root. Without
a .dockerignore, Docker sends the entire repo (250MB) to the daemon
before building, causing CI to hang.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:51:27 -05:00
GoodOlClint cc07e110f9 Merge pull request #16 from GoodOlClint/feat/local-integration-runner
Unify CI and local integration test infrastructure
2026-03-24 10:44:32 -05:00
Clint Branham f21c7f84b7 feat(ci): unify CI and local integration test infrastructure
- Replace tests/infrastructure/Dockerfile with tests/Dockerfile.test
  (single multi-stage Dockerfile for both CI and local dev)
- CI container-image job now builds from Dockerfile.test target dev-infra
- Add ARM support: PowerShell installed via dotnet tool on arm64,
  APT package on amd64
- Replace tests/dev.sh (bash) with tests/dev.ps1 (PowerShell) for
  cross-platform support (Windows, macOS, Linux)
- Add -DockerHost parameter for running x86 containers on a remote
  Docker host from ARM Macs (rsyncs repo, uses SSH Docker transport)
- Add -NoCleanup switch to keep nested PVE VMs after integration tests
- integration command now provisions nested PVE VMs instead of testing
  against a pre-existing PVE directly
- Share /opt/pve-isos host path between CI and local dev (was separate
  Docker named volume)
- Delete tools/Invoke-Tests.ps1 (unused, overlapped with run-integration.sh)
- Add .gitignore entries for Terraform state/artifacts
- Update all documentation references

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:41:28 -05:00
GoodOlClint 629551021c Merge pull request #15 from GoodOlClint/fix/unmask-target-node
fix(ci): move PVE_TARGET_NODE from secret to variable to stop log masking
2026-03-24 09:55:15 -05:00
Clint Branham c1e1442155 fix(ci): move PVE_TARGET_NODE from secret to variable
The node name "pve" was being masked in all CI logs because GitHub
Actions auto-masks secret values. Since the node name is not sensitive,
use vars.PVE_TARGET_NODE instead of secrets.PVE_TARGET_NODE.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:49:21 -05:00
GoodOlClint da9e553683 Merge pull request #13 from GoodOlClint/refactor/integration-test-orchestration
refactor: extract integration test orchestration, add dev container
2026-03-24 09:44:19 -05:00
GoodOlClint cddb3ef71a Merge pull request #14 from GoodOlClint/copilot/sub-pr-13
fix: harden run-integration.sh against special chars, token leakage, and ARM
2026-03-24 09:40:06 -05:00
copilot-swe-agent[bot] 2291379040 fix: apply security and correctness fixes from PR #13 review
Co-authored-by: GoodOlClint <151449+GoodOlClint@users.noreply.github.com>
Agent-Logs-Url: https://github.com/GoodOlClint/PSProxmoxVE/sessions/677fba6b-906d-4cf6-82fa-3b7ab6afc648
2026-03-24 14:36:51 +00:00
copilot-swe-agent[bot] bdb62a3fbf Initial plan 2026-03-24 14:34:00 +00:00
Clint Branham ee717cccd1 docs: update CLAUDE.md with PR workflow and dev container instructions
All changes now go through pull requests. Branch protection is enabled
on main (required build checks, required review, admin enforced).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:21:59 -05:00
Clint Branham fc092ea5b3 feat: add dev container for local build, test, and provisioning
- Dockerfile.test: multi-stage build with dev (ARM+x86) and dev-infra
  (x86 only, adds Terraform + PVE provisioning tools) targets
- docker-compose.test.yml: services for both targets, .env.test support
- dev.sh: helper script wrapping container lifecycle and run-integration.sh
- .env.test.example: template for integration test configuration
- .gitignore: exclude .env.test, whitelist .env.*.example

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:21:52 -05:00
Clint Branham 9752b854e4 refactor(ci): simplify workflow to delegate to run-integration.sh
Provision, test, and cleanup jobs now call run-integration.sh instead
of inlining ~170 lines of shell. Logic changes only need to be made
in one place, shared between CI and local dev.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:21:14 -05:00
Clint Branham 7f3430cd50 refactor(ci): extract integration test orchestration into run-integration.sh
Single source of truth for the provision → test → cleanup lifecycle,
callable from both CI workflows and local dev containers.

Subcommands: provision, test [8|9|all], cleanup, all
Detects CI vs local via $GITHUB_ACTIONS and adjusts output accordingly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:21:08 -05:00
Clint Branham 6a1253c37b fix: remove pull_request trigger from integration tests workflow 2026-03-24 08:39:16 -05:00
Clint Branham b4754c72a0 docs: update README, CHANGELOG, SECURITY.md, and review artifacts
- README: move Set-PveStorage to Storage section, Set-PveApiToken to
  Access section (were miscategorized under "Access — Groups & Domains")
- CHANGELOG: add Changed section with 13 architectural improvements,
  expand Fixed section with all ConfirmImpact and credential fixes
- SECURITY.md: add SecureString detail, Input Validation section,
  Dependabot mention, SkipCertificateCheck warning note
- CLAUDE.md: update review system reference to scan-7
- findings.json: F050 resolved (URL encoding), F031 resolved (credentials)
- REVIEW_REPORT.md: scan-7 report

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 17:41:19 -05:00
Clint Branham f6a2f843db docs: update cmdlet help via platyPS merge, fix generate-help.ps1
- generate-help.ps1: rewritten to use Update-MarkdownHelp (merge) by
  default, preserving hand-written descriptions and examples. Only
  New-MarkdownHelp on genuinely new cmdlets. -Force flag for full regen.
- docs/cmdlets: parameter metadata updated via platyPS merge, CRLF
  normalized to LF
- Removed stale Send-PveIso.md (cmdlet renamed to Send-PveFile)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 17:41:04 -05:00
Clint Branham d5f4e13637 fix(security): move hardcoded test password to GitHub Actions secret
- CI workflow: PVE_PASSWORD now reads from secrets.PVE_TEST_PASSWORD
- variables.tf: removed default password, requires TF_VAR env var
- Integration README: examples use <your-test-password> placeholder
- create-api-token.sh: example IP changed to pve.example.com
- .gitignore: added .env/.env.* exclusion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 17:40:47 -05:00
Clint Branham 053fd4c06a fix(security): add Uri.EscapeDataString to all URL path parameters
20 instances across 5 service files were missing URL encoding on
dynamic path segments (node, iface, zone, vnet). Fixes D003 regression.

- NodeService: 7 methods
- NetworkService: 7 methods (5 node-network + 2 SDN remove)
- CloudInitService: 3 methods
- TaskService: 2 methods (GetTask, GetTaskLog)
- TemplateService: 1 method (CreateTemplate)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 17:40:36 -05:00
Clint Branham 625ea0fa28 docs: update README for netstandard2.0, add missing cmdlets, fix version ref
- .NET compatibility table: module ships as netstandard2.0 (not net48/net8.0)
- Add Integration Tests badge
- Add missing cmdlets: Get-PveTaskList, Stop-PveTask, Get/New/Remove-PveApiToken
- Remove "(v1)" from Known Limitations header (currently v0.1.0-preview)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:57:28 -05:00
Clint Branham 1faaba0a20 perf(ci): run PVE 8 and PVE 9 tests in parallel (max-parallel: 2)
Runner VM now has 2 runner instances registered, so both test matrix
entries can execute simultaneously against their respective pre-
provisioned nested PVE VMs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:41:59 -05:00
Clint Branham 68c528e278 fix(ci): pass test config via shared volume instead of job outputs
GitHub Actions redacts any value that matches a secret or masked string
in job outputs, making them empty in downstream jobs. This affected
host IPs, tokens, and even port 8006 (substring of PVE_ENDPOINT).

The provision job now writes connection details to
/opt/pve-isos/test-config.json on the shared volume. Test jobs read
this file directly with jq — no job outputs needed for sensitive values.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:29:18 -05:00
Clint Branham 1dd677a50c fix(ci): stop masking nested PVE IPs so job outputs pass through
::add-mask:: on the VM IP addresses caused GitHub Actions to redact
them in job outputs, making needs.provision.outputs.pve*_host empty
in the test jobs. The IPs are internal lab addresses, not sensitive.
Token masking is retained.

Also removes terraform debug output from prior commit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:18:32 -05:00
Clint Branham c8c285e000 fix(ci): use RUNNER_TEMP env var in tfvars heredoc, add debug output
${{ runner.temp }} may resolve differently inside containers. Use
${RUNNER_TEMP} shell variable with unquoted heredoc instead. Added
debug output to diagnose ISO path issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:10:26 -05:00
Clint Branham a424dd18ac refactor(ci): parallel provisioning, file caching, provision/test/cleanup split
Restructures the integration test workflow from a monolithic sequential
job into separate provision → test → cleanup stages:

- provision: creates ALL nested PVE VMs in a single terraform apply
  (parallel), waits for APIs, creates tokens, passes outputs to tests
- test: matrix [pve9, pve8] consumes provision outputs, no provisioning
- cleanup: always runs, API-only teardown for all VMs

Terraform refactored to for_each with pve_instances map variable,
enabling parallel ISO upload and VM creation.

New caching scripts reduce redundant downloads:
- ensure-base-iso.sh: downloads PVE ISOs to /opt/pve-isos if missing
- ensure-cloud-images.sh: caches cloud image + OVA with 7-day TTL
- prepare-auto-iso.sh: --cache-dir flag with hash-based skip

Runner no longer needs manual ISO provisioning (zero-touch setup).
cleanup-images bumped to min-versions-to-keep: 3 to survive overlapping
runs. All jobs gated against dependabot.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:05:20 -05:00
Clint Branham d19c6f0c4b fix: upgrade SharpCompress from 0.38.0 to 0.47.3 (#12)
SharpCompress 0.47.3 renamed ReaderFactory.Open() to OpenReader() and
now requires an explicit ReaderOptions parameter. The synchronous API
is still available — no async conversion needed.

Closes #12

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 15:53:56 -05:00
GoodOlClint 40a1390094 Merge pull request #10 from GoodOlClint/dependabot/nuget/tests/PSProxmoxVE.Core.Tests/main/xunit-2.9.3
Bump xunit from 2.7.0 to 2.9.3
2026-03-23 15:49:57 -05:00
dependabot[bot] 6f9ffd9ad1 Bump xunit from 2.7.0 to 2.9.3
---
updated-dependencies:
- dependency-name: xunit
  dependency-version: 2.9.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-23 20:47:03 +00:00
GoodOlClint 81291d98fd Merge pull request #7 from GoodOlClint/dependabot/nuget/tests/PSProxmoxVE.Core.Tests/main/Moq-4.20.72
Bump Moq from 4.20.70 to 4.20.72
2026-03-23 15:44:20 -05:00
dependabot[bot] 17b42b6a89 Bump Moq from 4.20.70 to 4.20.72
---
updated-dependencies:
- dependency-name: Moq
  dependency-version: 4.20.72
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-23 20:41:03 +00:00
GoodOlClint c5ad5bcca7 Merge pull request #11 from GoodOlClint/dependabot/nuget/tests/PSProxmoxVE.Core.Tests/main/xunit.runner.visualstudio-3.1.5
Bump xunit.runner.visualstudio from 2.5.7 to 3.1.5
2026-03-23 15:38:00 -05:00