refactor(cache): lazy-load built-in definitions from cache on demand, add ExportBuiltInCache, and extend alzlibtool CLI#242
Conversation
…ding and GC - cache/cache.go: Add PolicyDefinitionVersionsByName and PolicySetDefinitionVersionsByName per-name lookup methods, avoiding full-map clone for individual lookups - alzlib.go: Extend BuiltInCache interface with new per-name lookup methods - alzlib.go: Add `cache BuiltInCache` field to AlzLib struct - alzlib.go: AddCache now stores only the cache reference (lazy, not eager) - alzlib.go: GetDefinitionsFromAzure defers az.cache = nil so GC can reclaim cache - alzlib.go: getBuiltInPolicies checks cache before Azure; lazy-init Azure client - alzlib.go: getBuiltInPolicySets checks cache before Azure; lazy-init Azure clients - alzlib.go: ensureReferencedPolicyDefinitions removes upfront client creation - alzlib.go: ensureReferencedPolicyDefinition checks AlzLib → cache → Azure in order - alzlib.go: Extract policyDefinitionFromCache/policySetDefinitionFromCache helpers - alzlib_test.go: Update mockBuiltInCache with new interface methods - alzlib_test.go: Replace eager-load tests with lazy-load tests - integrationtest/cache_test.go: Update TestCacheInitWithLibrary for lazy semantics - docs/cache.md: Document lazy loading and GC behaviour Co-authored-by: matt-FFFFFF <16320656+matt-FFFFFF@users.noreply.github.com>
…s constructor - cache/cache.go: Add NewCacheFromDefinitions constructor that builds a Cache from existing PolicyDefinitionVersions/PolicySetDefinitionVersions maps - alzlib.go: Add ExportBuiltInCache() method that collects only built-in and static definitions from the loaded AlzLib state, filtering out custom definitions - alzlib.go: Add isBuiltInPolicyDefinitionVersions / isBuiltInPolicySetDefinitionVersions helpers for PolicyType-based filtering - alzlib_test.go: Add 5 tests for ExportBuiltInCache covering the filter logic, save/reload round-trip, empty state, nil PolicyType, and static type Co-authored-by: matt-FFFFFF <16320656+matt-FFFFFF@users.noreply.github.com>
…ary+architecture mode to cache create - generate/architecture.go: add --from-cache flag; loads seed cache into AlzLib before Init/FromArchitecture to reduce Azure API calls - cache/create.go: add --library, --architecture, --from-cache, --rootmg, --location flags; new architecture-scoped mode uses alzlib.ExportBuiltInCache() to produce a minimal cache; same path allowed for --from-cache and --output (in-place update) Co-authored-by: matt-FFFFFF <16320656+matt-FFFFFF@users.noreply.github.com>
- ExportBuiltInCache: deep-copy *PolicyDefinitionVersions values so AlzLib mutations (e.g. SetAssignPermissionsOnDefinitionParameter) cannot affect the exported cache - GetDefinitionsFromAzure: remove defer az.cache=nil; cache is now kept for AlzLib lifetime (callers release with AddCache(nil)). Fixes bug where only the first management group could use the cache. - policyDefinitionFromCache / policySetDefinitionFromCache: snapshot az.cache under az.mu.RLock to prevent data race with AddCache - ensureReferencedPolicyDefinitions: lazily create DefinitionsClient / DefinitionVersionsClient once per invocation and reuse across all policy-set sub-references instead of creating per cache miss - Add TestExportBuiltInCacheIsDeepCopied and helper testBuiltInPolicyDefinitionWithParam - Update AddCache docstring and docs/cache.md for new cache lifecycle Co-authored-by: matt-FFFFFF <16320656+matt-FFFFFF@users.noreply.github.com>
…xportBuiltInCache docstring - getBuiltInPolicies: snapshot az.clients.policyClient under az.mu.RLock() before the Azure fallback to prevent data race with AddPolicyClient - getBuiltInPolicySets: same fix - ensureReferencedPolicyDefinition: same fix - ExportBuiltInCache: update docstring to accurately reflect that nil PolicyType is also included (treated as built-in), not only PolicyTypeBuiltIn and PolicyTypeStatic Co-authored-by: matt-FFFFFF <16320656+matt-FFFFFF@users.noreply.github.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #242 +/- ##
==========================================
- Coverage 48.43% 47.57% -0.86%
==========================================
Files 54 54
Lines 4590 4847 +257
==========================================
+ Hits 2223 2306 +83
- Misses 2087 2255 +168
- Partials 280 286 +6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR refactors alzlib’s built-in definition caching to be lazy/on-demand during GetDefinitionsFromAzure, adds an API to export a minimal built-in cache from the currently loaded definitions, and extends alzlibtool to seed lookups from a cache file (and to create architecture-scoped caches).
Changes:
- Switch
AddCacheto store a cache reference for lazy lookups duringGetDefinitionsFromAzure(rather than eagerly loading everything). - Add
AlzLib.ExportBuiltInCache()andcache.NewCacheFromDefinitions(...), plus tests for export/deep-copy behavior. - Extend
alzlibtool cache createandalzlibtool generate architecturewith--from-cache, and update docs/integration tests for lazy loading semantics.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
alzlib.go |
Implements lazy cache lookup in GetDefinitionsFromAzure, adds ExportBuiltInCache, and updates cache interface. |
cache/cache.go |
Adds NewCacheFromDefinitions and by-name accessors for version collections. |
cmd/alzlibtool/command/cache/create.go |
Adds library/architecture-scoped cache creation and --from-cache flag plumbing. |
cmd/alzlibtool/command/generate/architecture.go |
Adds --from-cache to seed built-in definition lookups before Azure calls. |
alzlib_test.go |
Updates cache-related tests and adds ExportBuiltInCache coverage. |
integrationtest/cache_test.go |
Adjusts expectations to match lazy loading (built-ins appear after hierarchy build). |
docs/cache.md |
Updates cache behavior documentation to describe lazy loading and explicit cache release. |
You can also share your feedback on Copilot code review. Take the survey.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…eate, restrict --from-cache to architecture-scoped mode - alzlib.go: properly handle 2 return values from policyDefinitionFromCache and policySetDefinitionFromCache (fixes compiler errors) - cache create: remove --rootmg and --location flags, use internal defaults - cache create: disallow --from-cache without --library/--architecture since full-scan bulk APIs fetch everything regardless and a seed cannot reduce work - cache_test.go: fix TestCacheInitWithLibrary to use correct architecture name "simple" (matching simple-existingmg testdata) and adjust assertions
There was a problem hiding this comment.
Pull request overview
This PR refactors the built-in definition cache to be lazy-loaded during GetDefinitionsFromAzure, adds the ability to export a minimal built-in cache from an initialized AlzLib, and extends alzlibtool to seed operations from an existing cache file.
Changes:
- Switch
AddCachefrom eager population to retaining a cache reference and resolving definitions on-demand inGetDefinitionsFromAzure. - Add
AlzLib.ExportBuiltInCache()plus supporting cache APIs (cache.NewCacheFromDefinitions,*ByNamelookups) and unit tests. - Extend
alzlibtool(cache create,generate architecture) with--from-cacheand library/architecture-scoped cache creation.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| integrationtest/cache_test.go | Updates integration expectations to align with lazy cache behavior. |
| docs/cache.md | Updates docs to reflect cache retention and explicit release via AddCache(nil). |
| cmd/alzlibtool/command/generate/architecture.go | Adds --from-cache to seed built-in lookups during architecture generation. |
| cmd/alzlibtool/command/cache/create.go | Adds architecture-scoped cache creation, seeding via --from-cache, and in-place update support. |
| cache/cache.go | Adds NewCacheFromDefinitions and *VersionsByName methods to support lazy lookups and exports. |
| alzlib_test.go | Adds/updates tests for lazy cache behavior and ExportBuiltInCache deep-copying/filtering. |
| alzlib.go | Implements lazy cache-first resolution in built-in fetch paths and adds ExportBuiltInCache. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
alzlib_test.go:1305
- TestAddCacheDeepCopies doesn't currently exercise any mutation: testPolicyDefinition doesn't populate Properties.Parameters, so SetAssignPermissionsOnDefinitionParameter("anyParam") is a no-op and the test would pass even if cache entries were not deep-copied. To make this test meaningful, create a cached policy definition that includes the target parameter (or use the existing helper that builds a definition with parameters), then assert the cache copy remains unmodified after mutating AlzLib.
// Mutate the definition in AlzLib via SetAssignPermissionsOnDefinitionParameter.
// This should NOT affect the original cache.
az.SetAssignPermissionsOnDefinitionParameter("deep-copy-pd", "anyParam")
// Verify the original cache's definition is unmodified.
origPd, err := pdvs.GetVersion(to.Ptr("1.0.*"))
require.NoError(t, err)
// The original should not have any AssignPermissions set on any parameter.
if origPd.Properties.Parameters != nil {
for _, p := range origPd.Properties.Parameters {
if p.Metadata != nil && p.Metadata.AssignPermissions != nil {
t.Fatal("cache definition was mutated - deep copy failed")
}
}
}
This PR replaces #241 to enable CI/CD checks with required secrets.
Original PR by @app/copilot-swe-agent
cache.NewCacheFromDefinitionsconstructorAlzLib.ExportBuiltInCache()methodalzlibtool cache createwith library/architecture flags and --from-cache--from-cacheflag toalzlibtool generate architectureExportBuiltInCacheensureReferencedPolicyDefinitionsinvocationdefer az.cache = nilfromGetDefinitionsFromAzure(cache retained for AlzLib lifetime)az.cachereads withaz.mu.RLock()inpolicyDefinitionFromCache/policySetDefinitionFromCacheaz.clients.policyClientunderaz.mu.RLock()ingetBuiltInPolicies,getBuiltInPolicySets, andensureReferencedPolicyDefinitionExportBuiltInCachedocstring to include nil PolicyType in the inclusion criteriaOriginal prompt
This pull request was created from Copilot chat.
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.