make upstream url available to policies#2585
Conversation
|
Warning Review limit reached
Next review available in: 36 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (14)
📝 WalkthroughWalkthroughChangesDefault upstream routing
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant ControllerTransform
participant RouteConfigResource
participant XDSHandler
participant PolicyExecutionContext
participant RequestTranslator
ControllerTransform->>RouteConfigResource: attach default_upstream
RouteConfigResource->>XDSHandler: deliver route config
XDSHandler->>PolicyExecutionContext: populate DefaultUpstream
PolicyExecutionContext->>RequestTranslator: provide default upstream
RequestTranslator->>RequestTranslator: apply directive override or default
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
gateway/gateway-runtime/policy-engine/internal/kernel/translator.go (1)
369-382: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the triplicated resolve/apply routing block into a shared helper.
The following 7-line pattern is copy-pasted across
translateRequestActionsCore(lines 373-382),TranslateRequestHeaderActions(lines 524-533), andTranslateRequestHeaderActionsWithBodyMerge(lines 718-727):applied := false if directive.isSet() { if info, label, basePathKnown, ok := resolveUpstreamRedirect(execCtx, directive); ok { applyUpstreamRedirect(execCtx, headerOps, dynamicMetadata, &mutations.Path, info, label, basePathKnown) applied = true } } if !applied && execCtx.defaultUpstreamCluster != "" { applyDefaultUpstream(execCtx, headerOps, dynamicMetadata) }All three sites use identical parameter types. Extracting this into a single helper would eliminate the duplication and ensure consistent behavior if the routing logic changes in the future.
♻️ Proposed helper extraction
+// applyUpstreamRouting resolves and applies the last-write-wins upstream directive, +// falling back to the route's compiled-in default when no directive is set or +// the directive cannot be resolved. +func applyUpstreamRouting( + execCtx *PolicyExecutionContext, + directive upstreamRedirectDirective, + headerOps map[string][]*headerOp, + localDynamicMetadata map[string]map[string]interface{}, + pathMutation **string, +) { + applied := false + if directive.isSet() { + if info, label, basePathKnown, ok := resolveUpstreamRedirect(execCtx, directive); ok { + applyUpstreamRedirect(execCtx, headerOps, localDynamicMetadata, pathMutation, info, label, basePathKnown) + applied = true + } + } + if !applied && execCtx.defaultUpstreamCluster != "" { + applyDefaultUpstream(execCtx, headerOps, localDynamicMetadata) + } +}Then each call site becomes a single line:
- applied := false - if directive.isSet() { - if info, label, basePathKnown, ok := resolveUpstreamRedirect(execCtx, directive); ok { - applyUpstreamRedirect(execCtx, headerOps, out.DynamicMetadata, &out.Mutations.Path, info, label, basePathKnown) - applied = true - } - } - if !applied && execCtx.defaultUpstreamCluster != "" { - applyDefaultUpstream(execCtx, headerOps, out.DynamicMetadata) - } + applyUpstreamRouting(execCtx, directive, headerOps, out.DynamicMetadata, &out.Mutations.Path)Also applies to: 523-533, 717-727
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@gateway/gateway-runtime/policy-engine/internal/kernel/translator.go` around lines 369 - 382, Extract the duplicated upstream routing logic into a shared helper near the existing routing helpers, accepting the execution context, directive, header operations, dynamic metadata, and path mutations. Move the resolveUpstreamRedirect/applyUpstreamRedirect and default-cluster fallback behavior into that helper, then replace the blocks in translateRequestActionsCore, TranslateRequestHeaderActions, and TranslateRequestHeaderActionsWithBodyMerge with calls to it.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@gateway/gateway-runtime/policy-engine/internal/kernel/translator.go`:
- Around line 158-187: Ensure applyDefaultUpstream always populates
CurrentUpstreamKey in both execCtx.dynamicMetadata and localDynamicMetadata
whenever a default upstream cluster is configured, including when
execCtx.defaultUpstream is nil; construct a partial UpstreamInfo using
execCtx.defaultUpstreamCluster (and any available fields) before calling ToMap.
Also reconcile the constants.go documentation if the contract remains
conditional.
---
Nitpick comments:
In `@gateway/gateway-runtime/policy-engine/internal/kernel/translator.go`:
- Around line 369-382: Extract the duplicated upstream routing logic into a
shared helper near the existing routing helpers, accepting the execution
context, directive, header operations, dynamic metadata, and path mutations.
Move the resolveUpstreamRedirect/applyUpstreamRedirect and default-cluster
fallback behavior into that helper, then replace the blocks in
translateRequestActionsCore, TranslateRequestHeaderActions, and
TranslateRequestHeaderActionsWithBodyMerge with calls to it.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 53fc4b27-f981-4147-8875-0ba05c632423
⛔ Files ignored due to path filters (1)
gateway/gateway-runtime/policy-engine/go.sumis excluded by!**/*.sum
📒 Files selected for processing (12)
gateway/gateway-controller/pkg/models/runtime_deploy_config.gogateway/gateway-controller/pkg/policyxds/snapshot.gogateway/gateway-controller/pkg/transform/restapi.gogateway/gateway-controller/pkg/xds/translator.gogateway/gateway-runtime/policy-engine/go.modgateway/gateway-runtime/policy-engine/internal/admin/dumper.gogateway/gateway-runtime/policy-engine/internal/admin/types.gogateway/gateway-runtime/policy-engine/internal/constants/constants.gogateway/gateway-runtime/policy-engine/internal/kernel/execution_context.gogateway/gateway-runtime/policy-engine/internal/kernel/extproc.gogateway/gateway-runtime/policy-engine/internal/kernel/translator.gogateway/gateway-runtime/policy-engine/internal/xdsclient/handler.go
420eb5c to
23238f0
Compare
Dependency Validation Results |
1 similar comment
Dependency Validation Results |
23238f0 to
4ebe762
Compare
Dependency Validation Results |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
gateway/gateway-controller/pkg/xds/translator.go (1)
1070-1083: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
upstreamDefPathsstill isn't consumed increateRoute
If this legacy path still handlesUpstreamName-based routing, the selected upstream's base path never reaches the policy engine, so requests can be rewritten against the wrong backend path.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@gateway/gateway-controller/pkg/xds/translator.go` around lines 1070 - 1083, Pass the populated upstreamDefPaths map into createRoute and consume it when resolving UpstreamName-based routes, applying the selected upstream definition’s base path before policy-engine path transformation. Preserve the "/" fallback for definitions without an explicit BasePath and ensure all relevant createRoute call sites receive the map.
🧹 Nitpick comments (1)
gateway/gateway-controller/pkg/transform/restapi_test.go (1)
439-452: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider also asserting the sandbox cluster exists in
UpstreamClusters.The assertion change from
UseClusterHeader=false/emptyDefaultClustertoUseClusterHeader=true/DefaultCluster=expectedSandboxClusteris correct — it matches the implementation logicuseClusterHeader := hasUpstreamDefinitions || hasSandboxand the sandbox patch inrestapi.go:302-324. TheexpectedSandboxClustervalue (upstream_sandbox_sandbox-backend_9080) correctly uses the ClusterKey format, notEnvoyClusterName.For additional robustness, consider also verifying the cluster actually exists in the map, as
TestRestAPITransformer_DefaultClusterReferencesRealClusterdoes at lines 503-509. Based on learnings, tests should assert thatrdc.UpstreamClusters[r.Upstream.DefaultCluster]exists rather than only comparingDefaultClusterto a string literal.♻️ Optional: add cluster-existence assertion
assert.True(t, r.Upstream.UseClusterHeader) assert.Equal(t, expectedSandboxCluster, r.Upstream.DefaultCluster, "sandbox route must default to the sandbox cluster, not main") + _, ok := rdc.UpstreamClusters[r.Upstream.DefaultCluster] + assert.True(t, ok, "default cluster %q must exist in UpstreamClusters", r.Upstream.DefaultCluster) })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@gateway/gateway-controller/pkg/transform/restapi_test.go` around lines 439 - 452, Extend the sandbox route test around NewRestAPITransformer and the rdc.Routes[sandboxRouteKey] assertions to verify that r.Upstream.DefaultCluster exists in rdc.UpstreamClusters, matching the pattern used by TestRestAPITransformer_DefaultClusterReferencesRealCluster. Keep the existing UseClusterHeader and expectedSandboxCluster assertions unchanged.Source: Learnings
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@gateway/gateway-controller/pkg/xds/translator.go`:
- Around line 431-466: Update buildMatchHeaders to normalize the method
parameter with strings.ToUpper before constructing the mandatory :method
matcher, and use the normalized value in the exact StringMatcher. Leave the
configured header matching logic unchanged.
---
Outside diff comments:
In `@gateway/gateway-controller/pkg/xds/translator.go`:
- Around line 1070-1083: Pass the populated upstreamDefPaths map into
createRoute and consume it when resolving UpstreamName-based routes, applying
the selected upstream definition’s base path before policy-engine path
transformation. Preserve the "/" fallback for definitions without an explicit
BasePath and ensure all relevant createRoute call sites receive the map.
---
Nitpick comments:
In `@gateway/gateway-controller/pkg/transform/restapi_test.go`:
- Around line 439-452: Extend the sandbox route test around
NewRestAPITransformer and the rdc.Routes[sandboxRouteKey] assertions to verify
that r.Upstream.DefaultCluster exists in rdc.UpstreamClusters, matching the
pattern used by TestRestAPITransformer_DefaultClusterReferencesRealCluster. Keep
the existing UseClusterHeader and expectedSandboxCluster assertions unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 27e8bc83-275e-4898-9189-04bde2f53416
⛔ Files ignored due to path filters (2)
gateway/gateway-controller/go.sumis excluded by!**/*.sumgateway/gateway-runtime/policy-engine/go.sumis excluded by!**/*.sum
📒 Files selected for processing (14)
gateway/gateway-controller/go.modgateway/gateway-controller/pkg/models/runtime_deploy_config.gogateway/gateway-controller/pkg/policyxds/snapshot.gogateway/gateway-controller/pkg/transform/restapi.gogateway/gateway-controller/pkg/transform/restapi_test.gogateway/gateway-controller/pkg/xds/translator.gogateway/gateway-runtime/policy-engine/go.modgateway/gateway-runtime/policy-engine/internal/admin/dumper.gogateway/gateway-runtime/policy-engine/internal/admin/types.gogateway/gateway-runtime/policy-engine/internal/constants/constants.gogateway/gateway-runtime/policy-engine/internal/kernel/execution_context.gogateway/gateway-runtime/policy-engine/internal/kernel/extproc.gogateway/gateway-runtime/policy-engine/internal/kernel/translator.gogateway/gateway-runtime/policy-engine/internal/xdsclient/handler.go
🚧 Files skipped from review as they are similar to previous changes (10)
- gateway/gateway-runtime/policy-engine/internal/admin/dumper.go
- gateway/gateway-runtime/policy-engine/internal/kernel/extproc.go
- gateway/gateway-runtime/policy-engine/internal/constants/constants.go
- gateway/gateway-controller/pkg/models/runtime_deploy_config.go
- gateway/gateway-controller/pkg/policyxds/snapshot.go
- gateway/gateway-runtime/policy-engine/internal/admin/types.go
- gateway/gateway-runtime/policy-engine/internal/xdsclient/handler.go
- gateway/gateway-runtime/policy-engine/internal/kernel/execution_context.go
- gateway/gateway-controller/pkg/transform/restapi.go
- gateway/gateway-runtime/policy-engine/internal/kernel/translator.go
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
gateway/gateway-controller/pkg/xds/translator.go (1)
1070-1083: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
upstreamDefPathsstill isn't consumed increateRoute
If this legacy path still handlesUpstreamName-based routing, the selected upstream's base path never reaches the policy engine, so requests can be rewritten against the wrong backend path.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@gateway/gateway-controller/pkg/xds/translator.go` around lines 1070 - 1083, Pass the populated upstreamDefPaths map into createRoute and consume it when resolving UpstreamName-based routes, applying the selected upstream definition’s base path before policy-engine path transformation. Preserve the "/" fallback for definitions without an explicit BasePath and ensure all relevant createRoute call sites receive the map.
🧹 Nitpick comments (1)
gateway/gateway-controller/pkg/transform/restapi_test.go (1)
439-452: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider also asserting the sandbox cluster exists in
UpstreamClusters.The assertion change from
UseClusterHeader=false/emptyDefaultClustertoUseClusterHeader=true/DefaultCluster=expectedSandboxClusteris correct — it matches the implementation logicuseClusterHeader := hasUpstreamDefinitions || hasSandboxand the sandbox patch inrestapi.go:302-324. TheexpectedSandboxClustervalue (upstream_sandbox_sandbox-backend_9080) correctly uses the ClusterKey format, notEnvoyClusterName.For additional robustness, consider also verifying the cluster actually exists in the map, as
TestRestAPITransformer_DefaultClusterReferencesRealClusterdoes at lines 503-509. Based on learnings, tests should assert thatrdc.UpstreamClusters[r.Upstream.DefaultCluster]exists rather than only comparingDefaultClusterto a string literal.♻️ Optional: add cluster-existence assertion
assert.True(t, r.Upstream.UseClusterHeader) assert.Equal(t, expectedSandboxCluster, r.Upstream.DefaultCluster, "sandbox route must default to the sandbox cluster, not main") + _, ok := rdc.UpstreamClusters[r.Upstream.DefaultCluster] + assert.True(t, ok, "default cluster %q must exist in UpstreamClusters", r.Upstream.DefaultCluster) })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@gateway/gateway-controller/pkg/transform/restapi_test.go` around lines 439 - 452, Extend the sandbox route test around NewRestAPITransformer and the rdc.Routes[sandboxRouteKey] assertions to verify that r.Upstream.DefaultCluster exists in rdc.UpstreamClusters, matching the pattern used by TestRestAPITransformer_DefaultClusterReferencesRealCluster. Keep the existing UseClusterHeader and expectedSandboxCluster assertions unchanged.Source: Learnings
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@gateway/gateway-controller/pkg/xds/translator.go`:
- Around line 431-466: Update buildMatchHeaders to normalize the method
parameter with strings.ToUpper before constructing the mandatory :method
matcher, and use the normalized value in the exact StringMatcher. Leave the
configured header matching logic unchanged.
---
Outside diff comments:
In `@gateway/gateway-controller/pkg/xds/translator.go`:
- Around line 1070-1083: Pass the populated upstreamDefPaths map into
createRoute and consume it when resolving UpstreamName-based routes, applying
the selected upstream definition’s base path before policy-engine path
transformation. Preserve the "/" fallback for definitions without an explicit
BasePath and ensure all relevant createRoute call sites receive the map.
---
Nitpick comments:
In `@gateway/gateway-controller/pkg/transform/restapi_test.go`:
- Around line 439-452: Extend the sandbox route test around
NewRestAPITransformer and the rdc.Routes[sandboxRouteKey] assertions to verify
that r.Upstream.DefaultCluster exists in rdc.UpstreamClusters, matching the
pattern used by TestRestAPITransformer_DefaultClusterReferencesRealCluster. Keep
the existing UseClusterHeader and expectedSandboxCluster assertions unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 27e8bc83-275e-4898-9189-04bde2f53416
⛔ Files ignored due to path filters (2)
gateway/gateway-controller/go.sumis excluded by!**/*.sumgateway/gateway-runtime/policy-engine/go.sumis excluded by!**/*.sum
📒 Files selected for processing (14)
gateway/gateway-controller/go.modgateway/gateway-controller/pkg/models/runtime_deploy_config.gogateway/gateway-controller/pkg/policyxds/snapshot.gogateway/gateway-controller/pkg/transform/restapi.gogateway/gateway-controller/pkg/transform/restapi_test.gogateway/gateway-controller/pkg/xds/translator.gogateway/gateway-runtime/policy-engine/go.modgateway/gateway-runtime/policy-engine/internal/admin/dumper.gogateway/gateway-runtime/policy-engine/internal/admin/types.gogateway/gateway-runtime/policy-engine/internal/constants/constants.gogateway/gateway-runtime/policy-engine/internal/kernel/execution_context.gogateway/gateway-runtime/policy-engine/internal/kernel/extproc.gogateway/gateway-runtime/policy-engine/internal/kernel/translator.gogateway/gateway-runtime/policy-engine/internal/xdsclient/handler.go
🚧 Files skipped from review as they are similar to previous changes (10)
- gateway/gateway-runtime/policy-engine/internal/admin/dumper.go
- gateway/gateway-runtime/policy-engine/internal/kernel/extproc.go
- gateway/gateway-runtime/policy-engine/internal/constants/constants.go
- gateway/gateway-controller/pkg/models/runtime_deploy_config.go
- gateway/gateway-controller/pkg/policyxds/snapshot.go
- gateway/gateway-runtime/policy-engine/internal/admin/types.go
- gateway/gateway-runtime/policy-engine/internal/xdsclient/handler.go
- gateway/gateway-runtime/policy-engine/internal/kernel/execution_context.go
- gateway/gateway-controller/pkg/transform/restapi.go
- gateway/gateway-runtime/policy-engine/internal/kernel/translator.go
🛑 Comments failed to post (1)
gateway/gateway-controller/pkg/xds/translator.go (1)
431-466: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Normalize HTTP method before building the
:methodmatcher.
buildMatchHeadersbuilds the Envoy:methodmatcher directly from themethodparameter without uppercasing it. As per coding guidelines: "Normalize any user-supplied HTTP method string to uppercase withstrings.ToUpper()at the earliest extraction point before comparisons, map key creation, route generation, or Envoy:methodmatcher construction." This is a newly-introduced shared helper and a natural place to add the guard, independent of whether upstream CRD/API validation already constrains the value.🛡️ Proposed fix
func buildMatchHeaders(method string, rdcRoute *models.Route) []*route.HeaderMatcher { headerMatchers := []*route.HeaderMatcher{{ Name: ":method", HeaderMatchSpecifier: &route.HeaderMatcher_StringMatch{ StringMatch: &matcher.StringMatcher{ - MatchPattern: &matcher.StringMatcher_Exact{Exact: method}, + MatchPattern: &matcher.StringMatcher_Exact{Exact: strings.ToUpper(strings.TrimSpace(method))}, }, }, }}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.func buildMatchHeaders(method string, rdcRoute *models.Route) []*route.HeaderMatcher { headerMatchers := []*route.HeaderMatcher{{ Name: ":method", HeaderMatchSpecifier: &route.HeaderMatcher_StringMatch{ StringMatch: &matcher.StringMatcher{ MatchPattern: &matcher.StringMatcher_Exact{Exact: strings.ToUpper(strings.TrimSpace(method))}, }, }, }} for _, hm := range rdcRoute.MatchHeaders { name := strings.ToLower(strings.TrimSpace(hm.Name)) matchType := strings.TrimSpace(hm.Type) if matchType == "RegularExpression" { headerMatchers = append(headerMatchers, &route.HeaderMatcher{ Name: name, HeaderMatchSpecifier: &route.HeaderMatcher_SafeRegexMatch{ SafeRegexMatch: &matcher.RegexMatcher{Regex: hm.Value}, }, }) } else { headerMatchers = append(headerMatchers, &route.HeaderMatcher{ Name: name, HeaderMatchSpecifier: &route.HeaderMatcher_StringMatch{ StringMatch: &matcher.StringMatcher{ MatchPattern: &matcher.StringMatcher_Exact{Exact: hm.Value}, }, }, }) } } return headerMatchers }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@gateway/gateway-controller/pkg/xds/translator.go` around lines 431 - 466, Update buildMatchHeaders to normalize the method parameter with strings.ToUpper before constructing the mandatory :method matcher, and use the normalized value in the exact StringMatcher. Leave the configured header matching logic unchanged.Source: Coding guidelines
4ebe762 to
4764ff0
Compare
Dependency Validation Results |
make upstream url available to policies