Skip to content

CORS-4549: gcp: set universe domain in Infrastructure status for GCD - #10759

Merged
openshift-merge-bot[bot] merged 3 commits into
openshift:mainfrom
patrickdillon:gcd-universe-domain
Aug 13, 2026
Merged

CORS-4549: gcp: set universe domain in Infrastructure status for GCD#10759
openshift-merge-bot[bot] merged 3 commits into
openshift:mainfrom
patrickdillon:gcd-universe-domain

Conversation

@patrickdillon

@patrickdillon patrickdillon commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

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

  • New Features
    • Added support for sovereign-cloud GCP installations.
    • GCP infrastructure generation now detects custom universe domains and records non-default domains in infrastructure status.
    • Installation configuration and feature-gate support now enable the required sovereign-cloud settings.
  • Bug Fixes
    • Improved error handling when GCP session or universe-domain information cannot be retrieved during infrastructure generation.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: fe1db5d9-e194-49ab-90ea-213ebcb1a194

📥 Commits

Reviewing files that changed from the base of the PR and between faa0dee and 1a0c7cc.

⛔ Files ignored due to path filters (7)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.model_name.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/features/features.go is excluded by !vendor/**, !**/vendor/**
  • vendor/modules.txt is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (2)
  • go.mod
  • pkg/asset/manifests/infrastructure.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/asset/manifests/infrastructure.go

📝 Walkthrough

Walkthrough

GCP 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.

Changes

GCP sovereign-cloud infrastructure

Layer / File(s) Summary
Resolve and store the GCP universe domain
pkg/asset/manifests/infrastructure.go, go.mod
When sovereign-cloud support is enabled, the generator retrieves the GCP session and universe domain. It records non-default domains and returns wrapped lookup errors. The github.com/openshift/api dependency is updated to the required revision.

Estimated code review effort: 2 (Simple) | ~10 minutes

Mergeability Score: 🔵 Low · up to 1a0c7

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)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: setting the GCP universe domain in Infrastructure status for GCD.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed The PR diff changes infrastructure generation and dependencies only; it adds no Ginkgo test files or test titles, so no unstable test name was introduced.
Test Structure And Quality ✅ Passed The PR changes no *_test.go files, and the relevant existing test uses testing/testify rather than Ginkgo; none of the stated Ginkgo quality failures is introduced.
Microshift Test Compatibility ✅ Passed The PR adds no Ginkgo e2e tests. Its nine changed files contain infrastructure, dependency, and vendored API updates only.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The PR changes only infrastructure generation, dependencies, and vendored API files; it adds no Ginkgo tests or test-related paths, so SNO compatibility criteria do not apply.
Topology-Aware Scheduling Compatibility ✅ Passed The diff only adds GCP universe-domain status lookup and API metadata changes; it introduces no replicas, affinity, topology spread, selectors, tolerations, or PDB constraints.
Ote Binary Stdout Contract ✅ Passed The PR adds only GCP session and status logic plus generated API files; no process-level stdout writes, suite setup output, or logging redirection changes were introduced.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The PR adds no Ginkgo e2e tests or test declarations; it changes infrastructure generation and dependencies only, so this compatibility check is not applicable.
No-Weak-Crypto ✅ Passed The full PR diff adds GCP session/universe-domain lookup and API metadata only; no MD5, SHA1, DES, RC4, Blowfish, ECB, custom crypto, or secret comparisons were introduced.
Container-Privileges ✅ Passed The PR diff adds GCP universe-domain status logic and dependency updates only; it adds no container or Kubernetes privilege settings such as privileged, host namespaces, SYS_ADMIN, or root execution.
No-Sensitive-Data-In-Logs ✅ Passed The diff adds no logging calls or sensitive-value output; it reads the universe domain and writes it to Infrastructure status, while credential loader logging is unchanged.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


Comment @coderabbitai help to get the list of available commands.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Aug 11, 2026
@openshift-ci-robot

openshift-ci-robot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

@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.

Details

In response to this:

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

  • New Features
  • Added support for sovereign-cloud GCP installations.
  • GCP infrastructure generation now detects custom universe domains and records them in infrastructure status.
  • Bug Fixes
  • Improved error handling when GCP session or universe-domain information cannot be retrieved.

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.

@openshift-ci-robot

openshift-ci-robot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

@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.

Details

In response to this:

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.

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.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci
openshift-ci Bot requested review from andfasano and tthvo August 11, 2026 15:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/asset/manifests/infrastructure.go (1)

227-227: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3a117ed and 40a5f63.

📒 Files selected for processing (1)
  • pkg/asset/manifests/infrastructure.go

Comment thread pkg/asset/manifests/infrastructure.go

@tthvo tthvo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm
/approve

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 11, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn

@openshift-ci

openshift-ci Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

[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

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 11, 2026
@tthvo

tthvo commented Aug 11, 2026

Copy link
Copy Markdown
Member

/test e2e-gcd-ovn-private-techpreview
/test e2e-gcp-ovn
/test e2e-gcp-ovn-techpreview

@patrickdillon

Copy link
Copy Markdown
Contributor Author

Thanks for taking a look.

Heads up:

/test e2e-gcd-ovn-private-techpreview

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.

@tthvo

tthvo commented Aug 11, 2026

Copy link
Copy Markdown
Member

Will not actually verify this, because the gate was in dev preview.

Ah whoops, thanks! I kept forgetting that lol

@tthvo

tthvo commented Aug 11, 2026

Copy link
Copy Markdown
Member

Will not actually verify this, because the gate was in dev preview.

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 🤔

@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Aug 11, 2026
@patrickdillon

Copy link
Copy Markdown
Contributor Author

now includes api bump

/test e2e-gcd-ovn-private-techpreview

@tthvo

tthvo commented Aug 11, 2026

Copy link
Copy Markdown
Member

/test e2e-gcp-ovn
/test e2e-gcp-ovn-techpreview

Expecting the field shouldn't be set there.

@tthvo tthvo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 11, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn

@tthvo

tthvo commented Aug 12, 2026

Copy link
Copy Markdown
Member

@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:

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

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'
done

Length 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
done

Length 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))}")
PY

Length 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
done

Length 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()
PY

Length 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("...")
PY

Length of output: 7173


@tthvo I verified the two regular GCP jobs.

Job Evidence Result
e2e-gcp-ovn Generated cluster-infrastructure-02-config.yml status.platformStatus.gcp has projectID and region. It does not have universeDomain.
e2e-gcp-ovn-techpreview Generated cluster-infrastructure-02-config.yml status.platformStatus.gcp has projectID and region. It does not have universeDomain.
e2e-gcd-ovn-private-techpreview No generated Infrastructure CR or rendered asset bundle is retained. The installer log does not contain universeDomain. Inconclusive.

The GCD artifact set contains the installer log, install-config.yaml, and metadata, but no cluster-infrastructure-02-config.yml or equivalent live-resource capture. Therefore, I cannot verify that GCPPlatformStatus.UniverseDomain was set for GCD from these assets.

Please rerun the GCD job with a retained generated manifest or an artifact from:

oc get infrastructure cluster -o yaml

The 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 used
Learnt from: tthvo
Repo: openshift/installer PR: 10688
File: pkg/gather/gcp/gcp.go:43-48
Timestamp: 2026-07-17T02:19:05.042Z
Learning: For GCP bootstrap gathering changes in openshift/installer, the `e2e-gcd-ovn-private-techpreview` pre-submit covers Google sovereign cloud behavior and detects the original `RESOURCE_PROJECT_INVALID` failure when OAuth credentials omit `project_id`; `e2e-gcp-ovn` provides regular GCP regression coverage.

Learnt from: CR
Repo: openshift/installer PR: 0
File: cluster-api/cluster-api/vendor/sigs.k8s.io/cluster-api/CONTRIBUTING.md:0-0
Timestamp: 2026-07-02T21:43:28.242Z
Learning: When triaging E2E failures, use prow logs, local make targets, and the artifacts link to investigate failures and inspect generated cluster logs and resources.

Learnt from: tthvo
Repo: openshift/installer PR: 0
File: :0-0
Timestamp: 2026-07-01T20:34:15.833Z
Learning: In `pkg/asset/installconfig/gcp/services.go`, the `CredentialOptions` function uses `option.WithAuthCredentialsJSON` when credentials contain a private key (service account key), instead of `option.WithCredentials`. This is intentional for two reasons: (1) the GCP SDK's WithCredentialsJSON/WithAuthCredentialsJSON codepath correctly determines a non-default UNIVERSE_DOMAIN, and (2) it enables self-signed JWT authentication, which is required in environments like GCD (GCP-related target with no OAuth2 token endpoint). This context comes from PR `#10624` (CORS-4423) discussion between patrickdillon and tthvo.

You are interacting with an AI system.

@tthvo

tthvo commented Aug 12, 2026

Copy link
Copy Markdown
Member

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?

@patrickdillon

Copy link
Copy Markdown
Contributor Author

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

@patrickdillon

Copy link
Copy Markdown
Contributor Author

/test e2e-gcd-ovn-private-techpreview

not going to test manually tonight, let's see if the gather pods get scheduled this time

@patrickdillon

Copy link
Copy Markdown
Contributor Author

/verified by e2e-gcd-ovn-private-techpreview

from must-gather

yq .status.platformStatus quay-proxy-ci-openshift-org-openshift-ci-sha256-22472d679453001f8bacd2100d04bef7f4623441adbb6f6d8574da200244f47f/cluster-scoped-resources/config.openshift.io/infrastructures/cluster.yaml
gcp:
  cloudLoadBalancerConfig:
    dnsType: PlatformDefault
  projectID: XXXXXXXXXXXXX
  region: u-germany-northeast1
  universeDomain: apis-berlin-build0.goog
type: GCP

will need a rebase, though, after kms pr merges

/hold

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 13, 2026
@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Aug 13, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@patrickdillon: This PR has been marked as verified by e2e-gcd-ovn-private-techpreview.

Details

In response to this:

/verified by e2e-gcd-ovn-private-techpreview

from must-gather

yq .status.platformStatus quay-proxy-ci-openshift-org-openshift-ci-sha256-22472d679453001f8bacd2100d04bef7f4623441adbb6f6d8574da200244f47f/cluster-scoped-resources/config.openshift.io/infrastructures/cluster.yaml
gcp:
 cloudLoadBalancerConfig:
   dnsType: PlatformDefault
 projectID: XXXXXXXXXXXXX
 region: u-germany-northeast1
 universeDomain: apis-berlin-build0.goog
type: GCP

will need a rebase, though, after kms pr merges

/hold

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.
@openshift-ci-robot openshift-ci-robot removed the verified Signifies that the PR passed pre-merge verification criteria label Aug 13, 2026
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Aug 13, 2026
@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

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.

@tthvo tthvo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm
/hold cancel

@openshift-ci openshift-ci Bot added lgtm Indicates that a PR is ready to be merged. and removed do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Aug 13, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn

@tthvo

tthvo commented Aug 13, 2026

Copy link
Copy Markdown
Member

/test e2e-gcd-ovn-private-techpreview
/test e2e-gcp-ovn-techpreview
/test e2e-gcp-ovn

Not sure you wanna do the verification again since the rebase diff should only a small change in vendor 😅 Imma run it again 👀

@patrickdillon

Copy link
Copy Markdown
Contributor Author

/verified by e2e-gcd-ovn-private-techpreview

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Aug 13, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@patrickdillon: This PR has been marked as verified by e2e-gcd-ovn-private-techpreview.

Details

In response to this:

/verified by e2e-gcd-ovn-private-techpreview

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.

@tthvo

tthvo commented Aug 13, 2026

Copy link
Copy Markdown
Member

/test okd-scos-images

@openshift-ci

openshift-ci Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

@patrickdillon: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-gcp-ovn-techpreview 1a0c7cc link false /test e2e-gcp-ovn-techpreview

Full PR test history. Your PR dashboard.

Details

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 kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-merge-bot
openshift-merge-bot Bot merged commit 4f7b554 into openshift:main Aug 13, 2026
17 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants