CORS-4549: gcp: set universe domain in Infrastructure status for GCD - #10759
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Central YAML (inherited) Review profile: CHILL Plan: Enterprise Run ID: ⛔ Files ignored due to path filters (7)
📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughGCP infrastructure generation now uses sovereign-cloud feature gating to obtain the GCP session and universe domain. It records non-default domains in infrastructure status and returns errors when either lookup fails. ChangesGCP sovereign-cloud infrastructure
Estimated code review effort: 2 (Simple) | ~10 minutes Mergeability Score: 🔵 Low · up to The PR adds universe-domain data for sovereign GCP installations and updates the related API definitions. It is mergeable with explicit owner follow-up to confirm the generated install-config schema includes the new fields; otherwise downstream consumers may not receive them. 🚥 Pre-merge checks | ✅ 15✅ Passed checks (15 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions Comment |
|
@patrickdillon: This pull request references CORS-4549 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
@patrickdillon: This pull request references CORS-4549 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
Pipeline controller notification For optional jobs, comment This repository is configured in: LGTM mode |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
pkg/asset/manifests/infrastructure.go (1)
227-227: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAdd unit coverage for the GCP sovereign-cloud path
types.InstallConfig.Enabled(...)is valid. Keep the current feature-gate call. Add tests for universe-domain propagation and session errors.🤖 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 `@pkg/asset/manifests/infrastructure.go` at line 227, Add unit tests for the GCP sovereign-cloud branch guarded by installConfig.Config.Enabled(features.FeatureGateGCPSovereignCloudInstall), covering universe-domain propagation and session-error handling. Preserve the existing feature-gate call and use types.InstallConfig.Enabled(...) in the test setup.Source: Coding guidelines
🤖 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 `@pkg/asset/manifests/infrastructure.go`:
- Around line 227-239: Add deterministic tests in infrastructure_test.go for the
GCPSovereignCloudInstall logic in the infrastructure manifest flow, using mocked
or injected GCP session behavior rather than ambient credentials. Cover a
disabled feature gate, default and non-default universe domains, GetSession
errors, and GetUniverseDomain errors; verify non-default domains update
config.Status.PlatformStatus.GCP.UniverseDomain and all error paths return the
expected wrapped errors.
---
Nitpick comments:
In `@pkg/asset/manifests/infrastructure.go`:
- Line 227: Add unit tests for the GCP sovereign-cloud branch guarded by
installConfig.Config.Enabled(features.FeatureGateGCPSovereignCloudInstall),
covering universe-domain propagation and session-error handling. Preserve the
existing feature-gate call and use types.InstallConfig.Enabled(...) in the test
setup.
🪄 Autofix
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: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: dc7d6e05-23e2-46c5-85c0-782d65224a80
📒 Files selected for processing (1)
pkg/asset/manifests/infrastructure.go
|
Scheduling tests matching the |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: tthvo The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/test e2e-gcd-ovn-private-techpreview |
|
Thanks for taking a look. Heads up:
Will not actually verify this, because the gate was in dev preview. openshift/api#2970 just merged, so I will pull it into this pr and then we can use that e2e to verify. |
Ah whoops, thanks! I kept forgetting that lol |
Hmm, that got me wonder if we should add any validation to allow GCD install only when the feature gate is enabled (like AWS EUSC). Right now, the gcd e2e can install just fine because there's none 🤔 |
|
now includes api bump /test e2e-gcd-ovn-private-techpreview |
|
/test e2e-gcp-ovn Expecting the field shouldn't be set there. |
|
Scheduling tests matching the |
|
@coderabbitai We ran a few e2e tests to verify the PR's changes. Could you look into the assets of the below e2e jobs to verify if GCPPlatformStatus.UniverseDomain is set in infrastructure CR for Google Cloud Dedicated environment (gcd) but not set for other cases: |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
urls=(
"https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcd-ovn-private-techpreview/2087273364476399616"
"https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcp-ovn/2087281636096872448"
"https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcp-ovn-techpreview/2087281638630232064"
)
for url in "${urls[@]}"; do
echo "===== $url ====="
curl -fsSL --retry 2 "$url" -o /tmp/prow-page.html
printf '%s\n' "Page title:"
grep -oE '<title>[^<]*' /tmp/prow-page.html | head -1 || true
printf '%s\n' "Potential artifact references:"
grep -oiE 'href="[^"]*(infrastructure|artifact|log|gather|must-gather|install-config)[^"]*"' /tmp/prow-page.html | head -80 || true
printf '\n'
doneLength of output: 3019 🏁 Script executed: #!/bin/bash
set -euo pipefail
base="https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/test-platform-results/pr-logs/pull/openshift_installer/10759"
jobs=(
"pull-ci-openshift-installer-main-e2e-gcd-ovn-private-techpreview/2087273364476399616"
"pull-ci-openshift-installer-main-e2e-gcp-ovn/2087281636096872448"
"pull-ci-openshift-installer-main-e2e-gcp-ovn-techpreview/2087281638630232064"
)
for job in "${jobs[@]}"; do
echo "===== $job ====="
curl -fsSL --retry 2 "$base/$job/" -o /tmp/gcs-listing.html
echo "Artifact links and relevant text:"
grep -oiE '(href|src)="[^"]+"|[^<]{0,100}(infrastructure|universeDomain|must-gather|cluster-dump|artifacts)[^<]{0,100}' \
/tmp/gcs-listing.html \
| sed -E 's/^[[:space:]]+//' \
| head -250 || true
echo
doneLength of output: 7553 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from html.parser import HTMLParser
from urllib.parse import urljoin, urlparse
from urllib.request import Request, urlopen
from collections import deque
base = "https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com"
roots = [
"/gcs/test-platform-results/pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcd-ovn-private-techpreview/2087273364476399616/artifacts/",
"/gcs/test-platform-results/pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcp-ovn/2087281636096872448/artifacts/",
"/gcs/test-platform-results/pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcp-ovn-techpreview/2087281638630232064/artifacts/",
]
class Links(HTMLParser):
def __init__(self):
super().__init__()
self.links = []
def handle_starttag(self, tag, attrs):
if tag == "a":
href = dict(attrs).get("href")
if href:
self.links.append(href)
def get(url):
req = Request(url, headers={"User-Agent": "artifact-inspector"})
with urlopen(req, timeout=30) as r:
return r.read().decode("utf-8", "replace")
for root in roots:
root_url = base + root
print(f"\n===== {root_url} =====")
queue = deque([(root_url, 0)])
visited = set()
files = []
while queue:
url, depth = queue.popleft()
if url in visited or depth > 6:
continue
visited.add(url)
try:
page = get(url)
except Exception as exc:
print(f"LISTING-ERROR {url}: {exc}")
continue
parser = Links()
parser.feed(page)
for href in parser.links:
child = urljoin(url, href)
if not child.startswith(root_url):
continue
if child.endswith("/"):
queue.append((child, depth + 1))
else:
files.append(child)
for path in sorted(set(files)):
lower = path.lower()
if any(token in lower for token in (
"infrastructure", "cluster-dump", "must-gather", "manifest",
"install-config", "kubeconfig", "debug", "gather", "log"
)):
print(path)
print(f"FILES_DISCOVERED={len(set(files))}")
PYLength of output: 4220 🏁 Script executed: #!/bin/bash
set -euo pipefail
bucket="test-platform-results"
prefixes=(
"pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcd-ovn-private-techpreview/2087273364476399616/artifacts/"
"pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcp-ovn/2087281636096872448/artifacts/"
"pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcp-ovn-techpreview/2087281638630232064/artifacts/"
)
for prefix in "${prefixes[@]}"; do
echo "===== $prefix ====="
page_token=""
: > /tmp/gcs-objects.jsonl
while :; do
url="https://storage.googleapis.com/storage/v1/b/${bucket}/o?prefix=${prefix}&fields=items(name,size,contentType),nextPageToken&maxResults=1000"
if [[ -n "$page_token" ]]; then
url+="&pageToken=${page_token}"
fi
response=$(curl -fsSL --retry 2 --get \
--data-urlencode "prefix=$prefix" \
--data-urlencode "fields=items(name,size,contentType),nextPageToken" \
--data-urlencode "maxResults=1000" \
${page_token:+--data-urlencode "pageToken=$page_token"} \
"https://storage.googleapis.com/storage/v1/b/${bucket}/o")
printf '%s\n' "$response" >> /tmp/gcs-objects.jsonl
page_token=$(printf '%s' "$response" | jq -r '.nextPageToken // empty')
[[ -n "$page_token" ]] || break
done
jq -r '.items[]? | [.name, .size, .contentType] | `@tsv`' /tmp/gcs-objects.jsonl \
| grep -Ei '(infrastructure|manifest|must-gather|cluster-dump|gather|install-config|\.log|\.txt)' \
| head -300 || true
echo "OBJECTS=$(jq -s '[.[].items[]?] | length' /tmp/gcs-objects.jsonl)"
echo
doneLength of output: 202161 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
import json
import subprocess
import sys
import urllib.parse
bucket = "test-platform-results"
jobs = {
"gcd-techpreview": "pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcd-ovn-private-techpreview/2087273364476399616/artifacts/",
"gcp": "pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcp-ovn/2087281636096872448/artifacts/",
"gcp-techpreview": "pr-logs/pull/openshift_installer/10759/pull-ci-openshift-installer-main-e2e-gcp-ovn-techpreview/2087281638630232064/artifacts/",
}
def curl(url):
return subprocess.check_output(
["curl", "-fsSL", "--retry", "2", url], text=True
)
def objects(prefix):
token = None
values = []
while True:
query = {
"prefix": prefix,
"fields": "items(name,size,contentType),nextPageToken",
"maxResults": "1000",
}
if token:
query["pageToken"] = token
endpoint = (
f"https://storage.googleapis.com/storage/v1/b/{bucket}/o?"
+ urllib.parse.urlencode(query)
)
data = json.loads(curl(endpoint))
values.extend(data.get("items", []))
token = data.get("nextPageToken")
if not token:
return values
def media_url(name):
return (
f"https://storage.googleapis.com/download/storage/v1/b/{bucket}/o/"
f"{urllib.parse.quote(name, safe='')}?alt=media"
)
needles = (
"infrastructures/cluster",
"/infrastructure",
"infrastructure.",
"infrastructure-",
"infrastructure_",
)
fallback_names = (
".openshift_install",
"metadata.json",
"install-config",
"manifests",
)
for label, prefix in jobs.items():
print(f"\n===== {label} =====")
items = objects(prefix)
candidates = []
for item in items:
name = item["name"]
size = int(item.get("size", 0))
low = name.lower()
if any(needle in low for needle in needles):
candidates.append(item)
elif size <= 2_000_000 and any(term in low for term in fallback_names):
candidates.append(item)
print(f"CANDIDATE_FILES={len(candidates)}")
for item in candidates:
name = item["name"]
size = int(item.get("size", 0))
try:
content = curl(media_url(name))
except subprocess.CalledProcessError as exc:
print(f"DOWNLOAD_ERROR {name}: {exc}")
continue
low = content.lower()
if "universedomain" in low or (
"infrastructure" in low and
("gcp" in low or "platformstatus" in low)
):
print(f"\n--- OBJECT: {name} ({size} bytes) ---")
lines = content.splitlines()
for index, line in enumerate(lines):
if (
"universedomain" in line.lower()
or "kind: infrastructure" in line.lower()
or '"kind": "infrastructure"' in line.lower()
or "gcp:" in line.lower()
or '"gcp"' in line.lower()
):
start = max(0, index - 5)
end = min(len(lines), index + 16)
print("\n".join(lines[start:end]))
print("...")
print()
PYLength of output: 103473 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
import json
import subprocess
import urllib.parse
bucket = "test-platform-results"
prefix = (
"pr-logs/pull/openshift_installer/10759/"
"pull-ci-openshift-installer-main-e2e-gcd-ovn-private-techpreview/"
"2087273364476399616/artifacts/"
)
def curl(url):
return subprocess.check_output(["curl", "-fsSL", "--retry", "2", url], text=True)
def list_objects():
output = []
token = None
while True:
query = {
"prefix": prefix,
"fields": "items(name,size,contentType),nextPageToken",
"maxResults": "1000",
}
if token:
query["pageToken"] = token
data = json.loads(curl(
"https://storage.googleapis.com/storage/v1/b/"
+ bucket + "/o?" + urllib.parse.urlencode(query)
))
output.extend(data.get("items", []))
token = data.get("nextPageToken")
if not token:
return output
def media_url(name):
return (
"https://storage.googleapis.com/download/storage/v1/b/"
+ bucket + "/o/" + urllib.parse.quote(name, safe="") + "?alt=media"
)
items = list_objects()
name_terms = (
"cluster-infrastructure",
"controllerconfig",
"infrastructures",
".openshift_install",
"metadata.json",
"install-config",
"manifest",
)
selected = [
item for item in items
if any(term in item["name"].lower() for term in name_terms)
and int(item.get("size", 0)) <= 3_000_000
]
print(f"OBJECTS={len(items)} SELECTED={len(selected)}")
for item in selected:
print(f"{item['size']:>9} {item['name']}")
print("\n===== CONTENT MATCHES =====")
for item in selected:
name = item["name"]
try:
content = curl(media_url(name))
except subprocess.CalledProcessError:
continue
lines = content.splitlines()
matches = [
i for i, line in enumerate(lines)
if any(term in line.lower() for term in (
"universedomain", "googleapis", "restricted.googleapis",
"platformstatus:", "kind: infrastructure",
))
]
if matches:
print(f"\n--- {name} ---")
for i in matches:
print("\n".join(lines[max(0, i - 8):min(len(lines), i + 12)]))
print("...")
PYLength of output: 7173
The GCD artifact set contains the installer log, Please rerun the GCD job with a retained generated manifest or an artifact from: oc get infrastructure cluster -o yamlThe retrieved test-coverage guidance matches this result: the GCD TechPreview job is the relevant sovereign-cloud check, while the regular GCP job provides the standard regression control. 🧠 Learnings usedYou are interacting with an AI system. |
|
Arghh, bootstrap gather didn't collect anything in GCD job 😅 Well, at least, we can confirm the expected behaviour in standard GCP. Maybe, we can verify via manual testing if you have any? |
Right, and there should also be gather steps, which also didn't work... will need to look into what's going on, because the job ran for 9 hours! Will do it manually |
|
/test e2e-gcd-ovn-private-techpreview not going to test manually tonight, let's see if the gather pods get scheduled this time |
|
/verified by e2e-gcd-ovn-private-techpreview from must-gather will need a rebase, though, after kms pr merges /hold |
|
@patrickdillon: This PR has been marked as verified by DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
Populate GCPPlatformStatus.UniverseDomain in the Infrastructure manifest when the GCPSovereignCloudInstall feature gate is enabled and the credential's universe domain is non-default. This allows downstream operators to read the universe domain from the Infrastructure CR. When the feature gate is not enabled, the block is skipped entirely so there is no change in behavior for standard GCP installs.
Bring in GCD TechPreview gate.
go mod vendor
8d5f78d to
1a0c7cc
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
|
Scheduling tests matching the |
|
/test e2e-gcd-ovn-private-techpreview Not sure you wanna do the verification again since the rebase diff should only a small change in vendor 😅 Imma run it again 👀 |
|
/verified by e2e-gcd-ovn-private-techpreview |
|
@patrickdillon: This PR has been marked as verified by DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
/test okd-scos-images |
|
@patrickdillon: The following test failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
4f7b554
into
openshift:main
Populate GCPPlatformStatus.UniverseDomain in the Infrastructure manifest when the GCPSovereignCloudInstall feature gate is enabled and the credential's universe domain is non-default. This allows downstream operators to read the universe domain from the Infrastructure CR.
When the feature gate is not enabled, the block is skipped entirely so there is no change in behavior for standard GCP installs.
Summary by CodeRabbit