Skip to content

feat(alzlibtool): add --library-overwrite-enabled to check, generate and document - #249

Open
Yingjie Chen (Y1ngJ1eChen) wants to merge 1 commit into
mainfrom
user/yingjie/fix-issue-4191
Open

feat(alzlibtool): add --library-overwrite-enabled to check, generate and document#249
Yingjie Chen (Y1ngJ1eChen) wants to merge 1 commit into
mainfrom
user/yingjie/fix-issue-4191

Conversation

@Y1ngJ1eChen

Copy link
Copy Markdown
Contributor

Summary

Adds an opt-in --library-overwrite-enabled flag to the alzlibtool commands that
build an AlzLib, so that a library member which intentionally redefines assets
supplied by its dependencies can be validated, generated and documented. Corrects the
pre-existing help text on cache create, which over-promised what the flag does.

Refs Azure/Azure-Landing-Zones#4191.

No engine behaviour is changed. alzlib.go, assets and deployment are untouched.

Problem

AllowOverwrite has existed in the engine for a long time, and both
terraform-provider-alz (library_overwrite_enabled) and alzlibtool cache create
(--library-overwrite-enabled, added in v0.31.0) expose it. The remaining commands did
not, and initialised with alzlib.NewAlzLib(nil):

Error: library init error: Alzlib.Init: error adding processed result to AlzLib:
Alzlib.addProcessedResult: policy assignment Deploy-MCSB2-Monitoring already exists in the library

Because the failure happens during Init, every check is skipped rather than just the
conflicting asset, so the only workaround was to drop the validation step from CI
altogether.

Changes

File Change
cmd/alzlibtool/command/check/library.go Register the flag; assign to Options.AllowOverwrite before Init; document the limitations
cmd/alzlibtool/command/generate/architecture.go Same, plus a stderr warning so stdout JSON stays parseable
cmd/alzlibtool/command/document/library.go Same, plus a stderr warning so stdout Markdown stays usable
cmd/alzlibtool/command/cache/create.go Correct the long description and flag help; add the same stderr warning
internal/doc/doc.go Add AlzlibReadmeMdWithOptions; AlzlibReadmeMd delegates with nil

All four flags share one name, matching the provider attribute and avoiding a third
spelling (--allow-overwrite from the issue title was deliberately not added).

What the flag does, and does not do

Verified against the current engine and pinned by tests:

Asset type Behaviour with the flag set
Policy assignments Replaced in full by the member's version
Role definitions Replaced in full
Archetypes Replaced in full (whole set, not an incremental add)
Architectures Replaced in full (whole management group tree)
Policy default values Replaced in full
Policy definitions / policy set definitions Not replaced. The flag only suppresses the duplicate error; the dependency version is kept
Duplicate archetype override names Still an error, regardless of the flag

Assets are replaced in full, never merged field by field, so an overriding file must
contain the complete asset.

Note also that replacing an archetype can legitimately make a dependency-supplied
definition unreferenced, which then fails CheckAllDefinitionsAreReferenced. That is
existing behaviour, not a regression, and is now stated in the help text.

Out of scope

  • Changing AllowOverwrite semantics, including the policy (set) definition rule above.
    Whether "allow duplicates" or "last one wins" is the intended contract needs a separate
    design decision; this PR freezes and documents the current behaviour instead.
  • Making duplicate archetype override names honour the flag.
  • Field-level merge (Should there be a way to merge default assignments? Azure-Landing-Zones#330).
  • Any change to terraform-provider-alz, avm-ptn-alz or the accelerator. A docs-only
    clarification of the provider's library_overwrite_enabled description is worth a
    follow-up, since it currently reads as though definitions are replaced.

Testing

New command-level test scaffolding (TestMain plus a child-process helper) makes the
os.Exit calls in these commands observable as exit codes, and separates stdout from
stderr so artifacts can be asserted independently of warnings. It is reusable for any
future CLI flag.

Fixtures live in a single shared directory, cmd/alzlibtool/command/testdata/, consumed
by all three command packages. Every case is offline and needs no Azure credentials.

  • check library: fails without the flag with the reported message; passes with it. The
    member defaults require a parameter that only exists on the definition referenced by the
    member's assignment, so a passing defaults check proves the member version won.
  • generate architecture: same pair, plus an artifact test over --output asserting that
    the member policy assignment is written but a redefined policy definition still comes
    from the dependency, and that stdout remains valid JSON.
  • document library: same pair, asserting the member archetype appears in the Markdown and
    that the warning does not.
  • internal/doc: AlzlibReadmeMd and AlzlibReadmeMdWithOptions(..., nil, ...) produce
    byte-identical output.
  • Regression: a conflict-free member without the flag still passes; the policy definition
    and duplicate archetype override limitations are pinned so they cannot change silently.

Backwards compatibility

The default is false, identical to the previously hard-coded value, so any invocation
without the flag behaves exactly as before. This was confirmed by building the CLI from
this branch and from the base commit and diffing the output of check library and
document library on the same input: stdout, stderr and exit codes are byte-identical.
The only intentional output difference is the corrected cache create --help text.

internal/doc cannot be imported from outside the module, and the existing
AlzlibReadmeMd entry point is preserved, so there is no API break.

Only `cache create` exposed an opt-in for AlzLib.Options.AllowOverwrite. The
remaining commands constructed the library with NewAlzLib(nil), so a member
that intentionally redefines an asset provided by one of its dependencies
failed during Alzlib.Init with "already exists in the library", before any
check, generation or documentation step ran.

Register --library-overwrite-enabled (default false) on `check library`,
`generate architecture` and `document library`, and assign it to
Options.AllowOverwrite before Init. Fixing only `check library` would leave a
member that validates but cannot be generated or documented, which is the
worst failure mode for a validation tool.

Add doc.AlzlibReadmeMdWithOptions so the document command can pass options
through; AlzlibReadmeMd delegates to it with nil options and keeps its
signature and error text unchanged.

Correct the `cache create` long description and flag help, which claimed that
definitions are overwritten. They are not: for policy definitions and policy
set definitions the flag only suppresses the duplicate error and the earlier
library's version is kept. All four help strings now describe the same
limitations, and generate/document/cache emit a warning on stderr when the
flag is set so that JSON and Markdown artifacts on stdout stay machine
readable.

No engine behaviour is changed. alzlib.go, assets and deployment are
untouched, so consumers such as terraform-provider-alz are unaffected.

Refs Azure/Azure-Landing-Zones#4191
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 72.41379% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 49.58%. Comparing base (ff9170d) to head (a521933).

Files with missing lines Patch % Lines
cmd/alzlibtool/command/cache/create.go 0.00% 9 Missing ⚠️
cmd/alzlibtool/command/check/library.go 56.25% 6 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #249      +/-   ##
==========================================
+ Coverage   47.93%   49.58%   +1.65%     
==========================================
  Files          54       54              
  Lines        4915     4967      +52     
==========================================
+ Hits         2356     2463     +107     
+ Misses       2272     2209      -63     
- Partials      287      295       +8     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants