Repository: openshift/installer
Pull request #9600: CORS-3908: Update gcp cloud provider config map to include new endpoints
Author: login: barbacbd
Labels: name: approved
description: Indicates a PR has been approved by an approver from all required OWNERS files.
name: lgtm
description: Indicates that a PR is ready to be merged.
name: jira/valid-reference
description: Indicates that this PR references a valid Jira ticket of any type.
name: acknowledge-critical-fixes-only
description: Indicates if the issuer of the label is OK with the policy.
Created: 2025-03-26T11:26:48Z | Merged: 2025-04-08T05:34:10Z

** manifests/gcp/cloudproviderconfig: The GCP cloud provider config will now be supplied with the api-endpoint and container-api-endpoint. The GCP Cloud provider (and upstream) can accept a config with the api-endpoint (compute) and container-api-endpoint (container) values to override the endpoints for the services.

** See https://github.com/kubernetes/cloud-provider-gcp/blob/master/providers/gce/gce.go#L231 and https://github.com/kubernetes/cloud-provider-gcp/blob/master/providers/gce/gce.go#L234.


Diff:
diff --git a/pkg/asset/manifests/cloudproviderconfig.go b/pkg/asset/manifests/cloudproviderconfig.go
index ac79b18a528..30179e47b8b 100644
--- a/pkg/asset/manifests/cloudproviderconfig.go
+++ b/pkg/asset/manifests/cloudproviderconfig.go
@@ -11,6 +11,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"sigs.k8s.io/yaml"
 
+	configv1 "github.com/openshift/api/config/v1"
 	"github.com/openshift/installer/pkg/asset"
 	"github.com/openshift/installer/pkg/asset/installconfig"
 	ibmcloudmachines "github.com/openshift/installer/pkg/asset/machines/ibmcloud"
@@ -170,7 +171,28 @@ func (cpc *CloudProviderConfig) Generate(ctx context.Context, dependencies asset
 		if installConfig.Config.GCP.ComputeSubnet != "" {
 			subnet = installConfig.Config.GCP.ComputeSubnet
 		}
-		gcpConfig, err := gcpmanifests.CloudProviderConfig(clusterID.InfraID, installConfig.Config.GCP.ProjectID, subnet, installConfig.Config.GCP.NetworkProjectID)
+
+		apiEndpoint := ""
+		containerAPIEndpoint := ""
+		for _, endpoint := range installConfig.Config.GCP.ServiceEndpoints {
+			// the installconfig should only allow one service endpoint for each
+			// name, otherwise this would take the last one.
+			switch endpoint.Name {
+			case configv1.GCPServiceEndpointNameCompute:
+				apiEndpoint = endpoint.URL
+			case configv1.GCPServiceEndpointNameContainer:
+				containerAPIEndpoint = endpoint.URL
+			}
+		}
+
+		gcpConfig, err := gcpmanifests.CloudProviderConfig(
+			clusterID.InfraID,
+			installConfig.Config.GCP.ProjectID,
+			subnet,
+			installConfig.Config.GCP.NetworkProjectID,
+			apiEndpoint,
+			containerAPIEndpoint,
+		)
 		if err != nil {
 			return errors.Wrap(err, "could not create cloud provider config")
 		}
diff --git a/pkg/asset/manifests/gcp/cloudproviderconfig.go b/pkg/asset/manifests/gcp/cloudproviderconfig.go
index c0488e7e90c..4da458189ce 100644
--- a/pkg/asset/manifests/gcp/cloudproviderconfig.go
+++ b/pkg/asset/manifests/gcp/cloudproviderconfig.go
@@ -24,10 +24,17 @@ type global struct {
 	SubnetworkName string `gcfg:"subnetwork-name"`
 
 	NetworkProjectID string `gcfg:"network-project-id"`
+
+	// APIEndpoint is the compute API endpoint to use. If this is blank,
+	// then the default endpoint is used.
+	APIEndpoint string `gcfg:"api-endpoint"`
+	// ContainerAPIEndpoint is the container API endpoint to use. If this is blank,
+	// then the default endpoint is used.
+	ContainerAPIEndpoint string `gcfg:"container-api-endpoint"`
 }
 
 // CloudProviderConfig generates the cloud provider config for the GCP platform.
-func CloudProviderConfig(infraID, projectID, subnet, networkProjectID string) (string, error) {
+func CloudProviderConfig(infraID, projectID, subnet, networkProjectID, apiEndpoint, containerAPIEndpoint string) (string, error) {
 	config := &config{
 		Global: global{
 			ProjectID: projectID,
@@ -47,6 +54,10 @@ func CloudProviderConfig(infraID, projectID, subnet, networkProjectID string) (s
 
 			// Used for shared vpc installations,
 			NetworkProjectID: networkProjectID,
+
+			// Used for api endpoint overrides in the cloud provider.
+			APIEndpoint:          apiEndpoint,
+			ContainerAPIEndpoint: containerAPIEndpoint,
 		},
 	}
 
@@ -68,6 +79,8 @@ node-tags       = {{$tag}}
 node-instance-prefix = {{.Global.NodeInstancePrefix}}
 external-instance-groups-prefix = {{.Global.ExternalInstanceGroupsPrefix}}
 subnetwork-name = {{.Global.SubnetworkName}}
-{{ if ne .Global.NetworkProjectID "" }}network-project-id = {{.Global.NetworkProjectID}}{{end}}
+{{- if ne .Global.NetworkProjectID "" }}{{"\n"}}network-project-id = {{.Global.NetworkProjectID}}{{ end }}
+{{- if ne .Global.APIEndpoint "" }}{{"\n"}}api-endpoint = {{.Global.APIEndpoint}}{{ end }}
+{{- if ne .Global.ContainerAPIEndpoint "" }}{{"\n"}}container-api-endpoint = {{.Global.ContainerAPIEndpoint}}{{ end }}
 
 `
diff --git a/pkg/asset/manifests/gcp/cloudproviderconfig_test.go b/pkg/asset/manifests/gcp/cloudproviderconfig_test.go
index 11418db49f8..fa557349671 100644
--- a/pkg/asset/manifests/gcp/cloudproviderconfig_test.go
+++ b/pkg/asset/manifests/gcp/cloudproviderconfig_test.go
@@ -18,9 +18,8 @@ node-instance-prefix = uid
 external-instance-groups-prefix = uid
 subnetwork-name = uid-worker-subnet
 
-
 `
-	actualConfig, err := CloudProviderConfig("uid", "test-project-id", "uid-worker-subnet", "")
+	actualConfig, err := CloudProviderConfig("uid", "test-project-id", "uid-worker-subnet", "", "", "")
 	assert.NoError(t, err, "failed to create cloud provider config")
 	assert.Equal(t, expectedConfig, actualConfig, "unexpected cloud provider config")
 }
@@ -39,7 +38,27 @@ subnetwork-name = uid-worker-subnet
 network-project-id = test-network-project-id
 
 `
-	actualConfig, err := CloudProviderConfig("uid", "test-project-id", "uid-worker-subnet", "test-network-project-id")
+	actualConfig, err := CloudProviderConfig("uid", "test-project-id", "uid-worker-subnet", "test-network-project-id", "", "")
+	assert.NoError(t, err, "failed to create cloud provider config")
+	assert.Equal(t, expectedConfig, actualConfig, "unexpected cloud provider config")
+}
+
+func TestCloudProviderConfigWithEndpoints(t *testing.T) {
+	expectedConfig := `[global]
+project-id      = test-project-id
+regional        = true
+multizone       = true
+node-tags       = uid-master
+node-tags       = uid-control-plane
+node-tags       = uid-worker
+node-instance-prefix = uid
+external-instance-groups-prefix = uid
+subnetwork-name = uid-worker-subnet
+api-endpoint = compute-testendpoint.p.googleapis.com
+container-api-endpoint = container-testendpoint.p.googleapis.com
+
+`
+	actualConfig, err := CloudProviderConfig("uid", "test-project-id", "uid-worker-subnet", "", "compute-testendpoint.p.googleapis.com", "container-testendpoint.p.googleapis.com")
 	assert.NoError(t, err, "failed to create cloud provider config")
 	assert.Equal(t, expectedConfig, actualConfig, "unexpected cloud provider config")
 }


Reviews:
user: login: patrickdillon
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-31T19:43:51Z
user: login: barbacbd
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-31T20:03:50Z
user: login: patrickdillon
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T19:47:45Z
user: login: tthvo
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-03T23:58:56Z
user: login: barbacbd
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T11:26:29Z
user: login: barbacbd
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T11:29:13Z
user: login: patrickdillon
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T17:13:18Z
user: login: tthvo
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-07T17:46:59Z
user: login: tthvo
body: LGTM also!

/lgtm
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-07T18:02:30Z

Review comments:
diff_hunk: @@ -68,6 +79,8 @@ node-tags       = {{$tag}}
 node-instance-prefix = {{.Global.NodeInstancePrefix}}
 external-instance-groups-prefix = {{.Global.ExternalInstanceGroupsPrefix}}
 subnetwork-name = {{.Global.SubnetworkName}}
-{{ if ne .Global.NetworkProjectID "" }}network-project-id = {{.Global.NetworkProjectID}}{{end}}
+{{- if ne .Global.NetworkProjectID "" }}{{"\n"}}network-project-id = {{.Global.NetworkProjectID}}{{ end }}
+{{- if ne .Global.APIEndpoint "" }}{{"\n"}}api-endpoint = {{.Global.APIEndpoint}}{{ end }}
+{{- if ne .Global.ContainerAPIEndpoint "" }}{{"\n"}}container-api-endpoint = {{.Global.ContainerAPIEndpoint}}{{ end }}
path: pkg/asset/manifests/gcp/cloudproviderconfig.go
user: login: patrickdillon
body: I think we should be able to drop the new lines `{{"\n"}}`. It's been a while since I've played with templates, but I think what's happening is the beginning `{{-` is removing the whitespace. See [the docs here](https://pkg.go.dev/text/template#hdr-Text_and_spaces) which say:

> if an action's left delimiter (by default "{{") is followed immediately by a minus sign and white space, all trailing white space is trimmed from the immediately preceding text. 

So let me suggest this, but I haven't tested it:
```suggestion
{{ if ne .Global.NetworkProjectID "" }}network-project-id = {{.Global.NetworkProjectID}}{{ end }}
{{ if ne .Global.APIEndpoint "" }}api-endpoint = {{.Global.APIEndpoint}}{{ end }}
{{ if ne .Global.ContainerAPIEndpoint "" }}container-api-endpoint = {{.Global.ContainerAPIEndpoint}}{{ end }}
```

created_at: 2025-03-31T19:43:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -68,6 +79,8 @@ node-tags       = {{$tag}}
 node-instance-prefix = {{.Global.NodeInstancePrefix}}
 external-instance-groups-prefix = {{.Global.ExternalInstanceGroupsPrefix}}
 subnetwork-name = {{.Global.SubnetworkName}}
-{{ if ne .Global.NetworkProjectID "" }}network-project-id = {{.Global.NetworkProjectID}}{{end}}
+{{- if ne .Global.NetworkProjectID "" }}{{"\n"}}network-project-id = {{.Global.NetworkProjectID}}{{ end }}
+{{- if ne .Global.APIEndpoint "" }}{{"\n"}}api-endpoint = {{.Global.APIEndpoint}}{{ end }}
+{{- if ne .Global.ContainerAPIEndpoint "" }}{{"\n"}}container-api-endpoint = {{.Global.ContainerAPIEndpoint}}{{ end }}
path: pkg/asset/manifests/gcp/cloudproviderconfig.go
user: login: barbacbd
body: I had a discussion with Sandhya about this was something that was bothering me. So those fields are optional and if we don't add them then a new line is entered. I purposefully remove the whitespace then enter a newline only if that exists. Something like this could happen if I bring back my original changes and I dont think it looks good.
```
project-id      = test-project-id
regional        = true
multizone       = true
node-tags       = uid-master
node-tags       = uid-control-plane
node-tags       = uid-worker
node-instance-prefix = uid
external-instance-groups-prefix = uid
subnetwork-name = uid-worker-subnet


container-api-endpoint = container-testendpoint.p.googleapis.com

```
If network project id and api endpoint are "". 
if you want me to leave it that way thats fine but I think that looks kind of weird doing it that way. It is also possible to remove whitespace after with the { end -} but this didn't do what I needed either.
created_at: 2025-03-31T20:03:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -68,6 +79,8 @@ node-tags       = {{$tag}}
 node-instance-prefix = {{.Global.NodeInstancePrefix}}
 external-instance-groups-prefix = {{.Global.ExternalInstanceGroupsPrefix}}
 subnetwork-name = {{.Global.SubnetworkName}}
-{{ if ne .Global.NetworkProjectID "" }}network-project-id = {{.Global.NetworkProjectID}}{{end}}
+{{- if ne .Global.NetworkProjectID "" }}{{"\n"}}network-project-id = {{.Global.NetworkProjectID}}{{ end }}
+{{- if ne .Global.APIEndpoint "" }}{{"\n"}}api-endpoint = {{.Global.APIEndpoint}}{{ end }}
+{{- if ne .Global.ContainerAPIEndpoint "" }}{{"\n"}}container-api-endpoint = {{.Global.ContainerAPIEndpoint}}{{ end }}
path: pkg/asset/manifests/gcp/cloudproviderconfig.go
user: login: patrickdillon
body: > It is also possible to remove whitespace after with the { end -} but this didn't do what I needed either.

Did you try `{{- end }}`? I think that's what you want `{{- ` will remove preceding whitespace, ` -}}` removes following whitespace.
created_at: 2025-04-02T19:47:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -68,6 +79,8 @@ node-tags       = {{$tag}}
 node-instance-prefix = {{.Global.NodeInstancePrefix}}
 external-instance-groups-prefix = {{.Global.ExternalInstanceGroupsPrefix}}
 subnetwork-name = {{.Global.SubnetworkName}}
-{{ if ne .Global.NetworkProjectID "" }}network-project-id = {{.Global.NetworkProjectID}}{{end}}
+{{- if ne .Global.NetworkProjectID "" }}{{"\n"}}network-project-id = {{.Global.NetworkProjectID}}{{ end }}
+{{- if ne .Global.APIEndpoint "" }}{{"\n"}}api-endpoint = {{.Global.APIEndpoint}}{{ end }}
+{{- if ne .Global.ContainerAPIEndpoint "" }}{{"\n"}}container-api-endpoint = {{.Global.ContainerAPIEndpoint}}{{ end }}
path: pkg/asset/manifests/gcp/cloudproviderconfig.go
user: login: tthvo
body: ```go
{{ if ... }}text{{- end }}
\n{{ if ... }}text{{- end }}
```

IIUC the  `{{- end }}` trims up to the content within the if block, but instead the newline comes at the front of the if block so it will still be there (I tried :cry:). While working with helm charts, I saw a common pattern:

```
# The entry carries its newline 
# so if it is not rendered, the newline is not either
{{- if ... }}
\nText
{{- end }}
```

It is basically what Brent currently has but rewritten like below with a less compact format. WDYT?

```go
{{- if ne .Global.NetworkProjectID "" }}
network-project-id = {{.Global.NetworkProjectID}}
{{- end }}
{{- if ne .Global.APIEndpoint "" }}
api-endpoint = {{.Global.APIEndpoint}}
{{- end }}
{{- if ne .Global.ContainerAPIEndpoint "" }}
container-api-endpoint = {{.Global.ContainerAPIEndpoint}}
{{- end }}
```
created_at: 2025-04-03T23:58:56Z
author_association: MEMBER
diff_hunk: @@ -68,6 +79,8 @@ node-tags       = {{$tag}}
 node-instance-prefix = {{.Global.NodeInstancePrefix}}
 external-instance-groups-prefix = {{.Global.ExternalInstanceGroupsPrefix}}
 subnetwork-name = {{.Global.SubnetworkName}}
-{{ if ne .Global.NetworkProjectID "" }}network-project-id = {{.Global.NetworkProjectID}}{{end}}
+{{- if ne .Global.NetworkProjectID "" }}{{"\n"}}network-project-id = {{.Global.NetworkProjectID}}{{ end }}
+{{- if ne .Global.APIEndpoint "" }}{{"\n"}}api-endpoint = {{.Global.APIEndpoint}}{{ end }}
+{{- if ne .Global.ContainerAPIEndpoint "" }}{{"\n"}}container-api-endpoint = {{.Global.ContainerAPIEndpoint}}{{ end }}
path: pkg/asset/manifests/gcp/cloudproviderconfig.go
user: login: barbacbd
body: @tthvo & @patrickdillon  I have already tried this pattern and I believe that there was a reason this did not work either. I believe that it was with the required newline at the end of the pattern. There is a seperator between sections of the text. I only showed the top portion. If you do the `{{- end}}` it will cause other formatting issues.
created_at: 2025-04-07T11:26:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -68,6 +79,8 @@ node-tags       = {{$tag}}
 node-instance-prefix = {{.Global.NodeInstancePrefix}}
 external-instance-groups-prefix = {{.Global.ExternalInstanceGroupsPrefix}}
 subnetwork-name = {{.Global.SubnetworkName}}
-{{ if ne .Global.NetworkProjectID "" }}network-project-id = {{.Global.NetworkProjectID}}{{end}}
+{{- if ne .Global.NetworkProjectID "" }}{{"\n"}}network-project-id = {{.Global.NetworkProjectID}}{{ end }}
+{{- if ne .Global.APIEndpoint "" }}{{"\n"}}api-endpoint = {{.Global.APIEndpoint}}{{ end }}
+{{- if ne .Global.ContainerAPIEndpoint "" }}{{"\n"}}container-api-endpoint = {{.Global.ContainerAPIEndpoint}}{{ end }}
path: pkg/asset/manifests/gcp/cloudproviderconfig.go
user: login: barbacbd
body: If this the discussion point of this PR then I can/will just remove the formatting and keep the unnecessary newlines. No one would have probably noticed those newlines (because they didn't before with the way it was formatted). 
created_at: 2025-04-07T11:29:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -68,6 +79,8 @@ node-tags       = {{$tag}}
 node-instance-prefix = {{.Global.NodeInstancePrefix}}
 external-instance-groups-prefix = {{.Global.ExternalInstanceGroupsPrefix}}
 subnetwork-name = {{.Global.SubnetworkName}}
-{{ if ne .Global.NetworkProjectID "" }}network-project-id = {{.Global.NetworkProjectID}}{{end}}
+{{- if ne .Global.NetworkProjectID "" }}{{"\n"}}network-project-id = {{.Global.NetworkProjectID}}{{ end }}
+{{- if ne .Global.APIEndpoint "" }}{{"\n"}}api-endpoint = {{.Global.APIEndpoint}}{{ end }}
+{{- if ne .Global.ContainerAPIEndpoint "" }}{{"\n"}}container-api-endpoint = {{.Global.ContainerAPIEndpoint}}{{ end }}
path: pkg/asset/manifests/gcp/cloudproviderconfig.go
user: login: patrickdillon
body: Ah ok. Thanks for clarifying. I agree Brent's current solution looks good.
created_at: 2025-04-07T17:13:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -68,6 +79,8 @@ node-tags       = {{$tag}}
 node-instance-prefix = {{.Global.NodeInstancePrefix}}
 external-instance-groups-prefix = {{.Global.ExternalInstanceGroupsPrefix}}
 subnetwork-name = {{.Global.SubnetworkName}}
-{{ if ne .Global.NetworkProjectID "" }}network-project-id = {{.Global.NetworkProjectID}}{{end}}
+{{- if ne .Global.NetworkProjectID "" }}{{"\n"}}network-project-id = {{.Global.NetworkProjectID}}{{ end }}
+{{- if ne .Global.APIEndpoint "" }}{{"\n"}}api-endpoint = {{.Global.APIEndpoint}}{{ end }}
+{{- if ne .Global.ContainerAPIEndpoint "" }}{{"\n"}}container-api-endpoint = {{.Global.ContainerAPIEndpoint}}{{ end }}
path: pkg/asset/manifests/gcp/cloudproviderconfig.go
user: login: tthvo
body: Thanks. Sounds good to me too :D
created_at: 2025-04-07T17:46:59Z
author_association: MEMBER

PR comments:
user: login: openshift-ci-robot
created_at: 2025-03-26T11:26:52Z
body: @barbacbd: This pull request references [CORS-3908](https://issues.redhat.com//browse/CORS-3908) 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 "4.19.0" version, but no target version was set.

<details>

In response to [this](https://github.com/openshift/installer/pull/9600):

>** manifests/gcp/cloudproviderconfig: The GCP cloud provider config will now be supplied with the api-endpoint and container-api-endpoint. The GCP Cloud provider (and upstream) can accept a config with the api-endpoint (compute) and container-api-endpoint (container) values to override the endpoints for the services.
>
>** See https://github.com/kubernetes/cloud-provider-gcp/blob/master/providers/gce/gce.go#L231 and https://github.com/kubernetes/cloud-provider-gcp/blob/master/providers/gce/gce.go#L234.


Instructions for interacting with me using PR comments are available [here](https://prow.ci.openshift.org/command-help?repo=openshift%2Finstaller).  If you have questions or suggestions related to my behavior, please file an issue against the [openshift-eng/jira-lifecycle-plugin](https://github.com/openshift-eng/jira-lifecycle-plugin/issues/new) repository.
</details>
author_association: CONTRIBUTOR
user: login: barbacbd
created_at: 2025-03-26T11:29:19Z
body: The following are examples with the api-endpoint and container-api-endpoint set in the cloud provider config:

```
% cat manifests/cloud-provider-config.yaml                                                   
apiVersion: v1
data:
  config: |+
    [global]
    project-id      = dev-project
    regional        = true
    multizone       = true
    node-tags       = example-gcp-endpoint-q4fcj-master
    node-tags       = example-gcp-endpoint-q4fcj-control-plane
    node-tags       = example-gcp-endpoint-q4fcj-worker
    node-instance-prefix = example-gcp-endpoint-q4fcj
    external-instance-groups-prefix = example-gcp-endpoint-q4fcj
    subnetwork-name = example-gcp-endpoint-q4fcj-worker-subnet
    api-endpoint = compute-exampleendpoint.p.googleapis.com
    container-api-endpoint = container-exampleendpoint.p.googleapis.com

kind: ConfigMap
metadata:
  creationTimestamp: null
  name: cloud-provider-config
  namespace: openshift-config
```
author_association: CONTRIBUTOR
user: login: barbacbd
created_at: 2025-03-26T11:29:37Z
body: /cc @sadasu 
author_association: CONTRIBUTOR
user: login: barbacbd
created_at: 2025-03-26T18:52:07Z
body: /retest required
author_association: CONTRIBUTOR
user: login: openshift-ci[bot]
created_at: 2025-03-26T18:52:13Z
body: @barbacbd: The `/retest` command does not accept any targets.
The following commands are available to trigger required jobs:
```
/test altinfra-images
```
```
/test aro-unit
```
```
/test artifacts-images
```
```
/test artifacts-okd-scos-images
```
```
/test e2e-agent-compact-ipv4
```
```
/test e2e-aws-ovn
```
```
/test e2e-aws-ovn-edge-zones-manifest-validation
```
```
/test e2e-aws-ovn-upi
```
```
/test e2e-azure-ovn
```
```
/test e2e-gcp-ovn
```
```
/test e2e-gcp-ovn-upi
```
```
/test e2e-metal-ipi-ovn-ipv6
```
```
/test e2e-openstack-ovn
```
```
/test e2e-vsphere-ovn
```
```
/test e2e-vsphere-ovn-upi
```
```
/test gofmt
```
```
/test golint
```
```
/test govet
```
```
/test images
```
```
/test integration-tests
```
```
/test integration-tests-nodejoiner
```
```
/test okd-scos-images
```
```
/test openstack-manifests
```
```
/test terraform-images
```
```
/test terraform-okd-scos-images
```
```
/test terraform-okd-scos-verify-vendor
```
```
/test terraform-verify-vendor
```
```
/test unit
```
```
/test verify-codegen
```
```
/test verify-vendor
```

The following commands are available to trigger optional jobs:
```
/test altinfra-e2e-aws-custom-security-groups
```
```
/test altinfra-e2e-aws-ovn
```
```
/test altinfra-e2e-aws-ovn-fips
```
```
/test altinfra-e2e-aws-ovn-imdsv2
```
```
/test altinfra-e2e-aws-ovn-localzones
```
```
/test altinfra-e2e-aws-ovn-proxy
```
```
/test altinfra-e2e-aws-ovn-shared-vpc
```
```
/test altinfra-e2e-aws-ovn-shared-vpc-local-zones
```
```
/test altinfra-e2e-aws-ovn-shared-vpc-wavelength-zones
```
```
/test altinfra-e2e-aws-ovn-single-node
```
```
/test altinfra-e2e-aws-ovn-wavelengthzones
```
```
/test altinfra-e2e-azure-capi-ovn
```
```
/test altinfra-e2e-azure-ovn-shared-vpc
```
```
/test altinfra-e2e-gcp-capi-ovn
```
```
/test altinfra-e2e-gcp-ovn-byo-network-capi
```
```
/test altinfra-e2e-gcp-ovn-secureboot-capi
```
```
/test altinfra-e2e-gcp-ovn-xpn-capi
```
```
/test altinfra-e2e-ibmcloud-capi-ovn
```
```
/test altinfra-e2e-nutanix-capi-ovn
```
```
/test altinfra-e2e-openstack-capi-ccpmso
```
```
/test altinfra-e2e-openstack-capi-ccpmso-zone
```
```
/test altinfra-e2e-openstack-capi-dualstack
```
```
/test altinfra-e2e-openstack-capi-dualstack-upi
```
```
/test altinfra-e2e-openstack-capi-dualstack-v6primary
```
```
/test altinfra-e2e-openstack-capi-externallb
```
```
/test altinfra-e2e-openstack-capi-nfv-intel
```
```
/test altinfra-e2e-openstack-capi-ovn
```
```
/test altinfra-e2e-openstack-capi-proxy
```
```
/test altinfra-e2e-vsphere-capi-multi-vcenter-ovn
```
```
/test altinfra-e2e-vsphere-capi-ovn
```
```
/test altinfra-e2e-vsphere-capi-static-ovn
```
```
/test altinfra-e2e-vsphere-capi-zones
```
```
/test azure-ovn-marketplace-images
```
```
/test e2e-agent-4control-ipv4
```
```
/test e2e-agent-5control-ipv4
```
```
/test e2e-agent-compact-ipv4-appliance-diskimage
```
```
/test e2e-agent-compact-ipv4-none-platform
```
```
/test e2e-agent-compact-ipv6-minimaliso
```
```
/test e2e-agent-ha-dualstack
```
```
/test e2e-agent-sno-ipv4-pxe
```
```
/test e2e-agent-sno-ipv6
```
```
/test e2e-aws-default-config
```
```
/test e2e-aws-overlay-mtu-ovn-1200
```
```
/test e2e-aws-ovn-custom-iam-profile
```
```
/test e2e-aws-ovn-edge-zones
```
```
/test e2e-aws-ovn-fips
```
```
/test e2e-aws-ovn-heterogeneous
```
```
/test e2e-aws-ovn-imdsv2
```
```
/test e2e-aws-ovn-proxy
```
```
/test e2e-aws-ovn-public-ipv4-pool
```
```
/test e2e-aws-ovn-public-ipv4-pool-disabled
```
```
/test e2e-aws-ovn-public-subnets
```
```
/test e2e-aws-ovn-shared-vpc-custom-security-groups
```
```
/test e2e-aws-ovn-shared-vpc-edge-zones
```
```
/test e2e-aws-ovn-single-node
```
```
/test e2e-aws-ovn-techpreview
```
```
/test e2e-aws-ovn-upgrade
```
```
/test e2e-aws-ovn-user-provisioned-dns
```
```
/test e2e-aws-upi-proxy
```
```
/test e2e-azure-default-config
```
```
/test e2e-azure-ovn-resourcegroup
```
```
/test e2e-azure-ovn-shared-vpc
```
```
/test e2e-azure-ovn-techpreview
```
```
/test e2e-azure-ovn-upi
```
```
/test e2e-azurestack
```
```
/test e2e-azurestack-upi
```
```
/test e2e-crc
```
```
/test e2e-external-aws
```
```
/test e2e-external-aws-ccm
```
```
/test e2e-gcp-default-config
```
```
/test e2e-gcp-ovn-byo-vpc
```
```
/test e2e-gcp-ovn-heterogeneous
```
```
/test e2e-gcp-ovn-techpreview
```
```
/test e2e-gcp-ovn-xpn
```
```
/test e2e-gcp-secureboot
```
```
/test e2e-gcp-upgrade
```
```
/test e2e-gcp-upi-xpn
```
```
/test e2e-gcp-user-provisioned-dns
```
```
/test e2e-ibmcloud-ovn
```
```
/test e2e-metal-assisted
```
```
/test e2e-metal-ipi-ovn
```
```
/test e2e-metal-ipi-ovn-dualstack
```
```
/test e2e-metal-ipi-ovn-swapped-hosts
```
```
/test e2e-metal-ipi-ovn-virtualmedia
```
```
/test e2e-metal-single-node-live-iso
```
```
/test e2e-nutanix-ovn
```
```
/test e2e-openstack-ccpmso
```
```
/test e2e-openstack-ccpmso-zone
```
```
/test e2e-openstack-dualstack
```
```
/test e2e-openstack-dualstack-upi
```
```
/test e2e-openstack-externallb
```
```
/test e2e-openstack-nfv-intel
```
```
/test e2e-openstack-proxy
```
```
/test e2e-openstack-singlestackv6
```
```
/test e2e-powervs-capi-ovn
```
```
/test e2e-vsphere-externallb-ovn
```
```
/test e2e-vsphere-host-groups-ovn-custom-no-upgrade
```
```
/test e2e-vsphere-multi-vcenter-ovn
```
```
/test e2e-vsphere-ovn-multi-disk
```
```
/test e2e-vsphere-ovn-multi-network
```
```
/test e2e-vsphere-ovn-techpreview
```
```
/test e2e-vsphere-ovn-upi-zones
```
```
/test e2e-vsphere-ovn-zones
```
```
/test e2e-vsphere-ovn-zones-techpreview
```
```
/test e2e-vsphere-static-ovn
```
```
/test okd-scos-e2e-aws-ovn
```

Use `/test all` to run the following jobs that were automatically triggered:
```
pull-ci-openshift-installer-main-altinfra-images
```
```
pull-ci-openshift-installer-main-aro-unit
```
```
pull-ci-openshift-installer-main-artifacts-images
```
```
pull-ci-openshift-installer-main-artifacts-okd-scos-images
```
```
pull-ci-openshift-installer-main-e2e-aws-ovn
```
```
pull-ci-openshift-installer-main-e2e-azure-ovn-resourcegroup
```
```
pull-ci-openshift-installer-main-e2e-gcp-default-config
```
```
pull-ci-openshift-installer-main-e2e-gcp-ovn
```
```
pull-ci-openshift-installer-main-e2e-gcp-ovn-byo-vpc
```
```
pull-ci-openshift-installer-main-e2e-gcp-ovn-xpn
```
```
pull-ci-openshift-installer-main-e2e-gcp-secureboot
```
```
pull-ci-openshift-installer-main-e2e-vsphere-externallb-ovn
```
```
pull-ci-openshift-installer-main-e2e-vsphere-ovn-multi-network
```
```
pull-ci-openshift-installer-main-e2e-vsphere-static-ovn
```
```
pull-ci-openshift-installer-main-gofmt
```
```
pull-ci-openshift-installer-main-golint
```
```
pull-ci-openshift-installer-main-govet
```
```
pull-ci-openshift-installer-main-images
```
```
pull-ci-openshift-installer-main-okd-scos-e2e-aws-ovn
```
```
pull-ci-openshift-installer-main-okd-scos-images
```
```
pull-ci-openshift-installer-main-terraform-images
```
```
pull-ci-openshift-installer-main-terraform-okd-scos-images
```
```
pull-ci-openshift-installer-main-unit
```
```
pull-ci-openshift-installer-main-verify-codegen
```
```
pull-ci-openshift-installer-main-verify-vendor
```



<details>

In response to [this](https://github.com/openshift/installer/pull/9600#issuecomment-2755454745):

>/retest required


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>
author_association: CONTRIBUTOR
user: login: barbacbd
created_at: 2025-03-26T18:52:57Z
body: /label acknowledge-critical-fixes-only
author_association: CONTRIBUTOR
user: login: barbacbd
created_at: 2025-03-26T18:53:04Z
body: /retest

author_association: CONTRIBUTOR
user: login: barbacbd
created_at: 2025-03-27T10:27:25Z
body: /retest-required

Looks like some UPI and Installer Artifact stages are failing. I am not sure if the images error is flaky or not.
author_association: CONTRIBUTOR
user: login: openshift-ci[bot]
created_at: 2025-03-27T12:32:43Z
body: @barbacbd: The following tests **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-azure-ovn-resourcegroup | 922cac0e3c724a680c47959b02d9fe77a88b4c6a | [link](https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/openshift_installer/9600/pull-ci-openshift-installer-main-e2e-azure-ovn-resourcegroup/1904914346635431936) | false | `/test e2e-azure-ovn-resourcegroup`
ci/prow/okd-scos-e2e-aws-ovn | 922cac0e3c724a680c47959b02d9fe77a88b4c6a | [link](https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/openshift_installer/9600/pull-ci-openshift-installer-main-okd-scos-e2e-aws-ovn/1904973057429082112) | false | `/test okd-scos-e2e-aws-ovn`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=openshift&repo=installer&pr=9600). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:barbacbd).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
author_association: CONTRIBUTOR
user: login: sadasu
created_at: 2025-03-31T18:21:33Z
body: /approve

Had a quick discussion with @barbacbd, regarding missing values and error scenarios. Those seem to be handled too.
author_association: CONTRIBUTOR
user: login: openshift-ci[bot]
created_at: 2025-03-31T18:21:48Z
body: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/openshift/installer/pull/9600#issuecomment-2767048432" title="Approved">sadasu</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=openshift%2Finstaller).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/openshift/installer/blob/main/OWNERS)~~ [sadasu]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
author_association: CONTRIBUTOR
user: login: patrickdillon
created_at: 2025-04-07T17:14:13Z
body: /lgtm
author_association: CONTRIBUTOR
user: login: openshift-bot
created_at: 2025-04-08T20:11:17Z
body: **[ART PR BUILD NOTIFIER]**

Distgit: ose-installer-terraform-providers
This PR has been included in build [ose-installer-terraform-providers-container-v4.20.0-202504081610.p0.gef0993a.assembly.stream.el9](https://brewweb.engineering.redhat.com/brew/buildinfo?buildID=3594097).
All builds following this will include this PR.
author_association: CONTRIBUTOR
user: login: openshift-bot
created_at: 2025-04-08T22:02:30Z
body: **[ART PR BUILD NOTIFIER]**

Distgit: ose-installer-altinfra
This PR has been included in build [ose-installer-altinfra-container-v4.20.0-202504081610.p0.gef0993a.assembly.stream.el9](https://brewweb.engineering.redhat.com/brew/buildinfo?buildID=3594248).
All builds following this will include this PR.
author_association: CONTRIBUTOR
user: login: openshift-bot
created_at: 2025-04-08T22:14:34Z
body: **[ART PR BUILD NOTIFIER]**

Distgit: ose-baremetal-installer
This PR has been included in build [ose-baremetal-installer-container-v4.20.0-202504081610.p0.gef0993a.assembly.stream.el9](https://brewweb.engineering.redhat.com/brew/buildinfo?buildID=3594249).
All builds following this will include this PR.
author_association: CONTRIBUTOR
user: login: openshift-bot
created_at: 2025-04-08T23:39:50Z
body: **[ART PR BUILD NOTIFIER]**

Distgit: ose-installer-artifacts
This PR has been included in build [ose-installer-artifacts-container-v4.19.0-202504081639.p0.gef0993a.assembly.stream.el9](https://brewweb.engineering.redhat.com/brew/buildinfo?buildID=3594300).
All builds following this will include this PR.
author_association: CONTRIBUTOR