Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
225 changes: 105 additions & 120 deletions go.mod

Large diffs are not rendered by default.

510 changes: 233 additions & 277 deletions go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion images/installer/Dockerfile.upi.ci
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
FROM registry.ci.openshift.org/ocp/4.22:installer-kube-apiserver-artifacts AS kas-artifacts
FROM registry.ci.openshift.org/ocp/4.22:installer-etcd-artifacts AS etcd-artifacts

FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.25-openshift-4.22 AS builder
FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-5.0 AS builder
# FIPS support is offered via the baremetal-installer image
ENV GO_COMPLIANCE_EXCLUDE=".*"
ARG TAGS=""
Expand Down
2 changes: 1 addition & 1 deletion images/libvirt/Dockerfile.ci
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
FROM registry.ci.openshift.org/ocp/4.17:etcd AS etcd
FROM registry.ci.openshift.org/ocp/4.17:hyperkube AS kas

FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.25-openshift-4.22 AS builder
FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-5.0 AS builder
ARG TAGS="libvirt fipscapable"
ARG SKIP_ENVTEST="y"
WORKDIR /go/src/github.com/openshift/installer
Expand Down
2 changes: 1 addition & 1 deletion images/openstack/Dockerfile.ci
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
FROM registry.ci.openshift.org/ocp/4.17:installer-kube-apiserver-artifacts AS kas-artifacts
FROM registry.ci.openshift.org/ocp/4.17:installer-etcd-artifacts AS etcd-artifacts

FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.25-openshift-4.22 AS builder
FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-5.0 AS builder
# FIPS support is offered via the baremetal-installer image
ENV GO_COMPLIANCE_EXCLUDE=".*"
ARG TAGS=""
Expand Down
2 changes: 1 addition & 1 deletion pkg/asset/installconfig/gcp/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func CredentialOptions(ssn *Session) ([]option.ClientOption, error) {
}
var opts []option.ClientOption
if len(ssn.Credentials.JSON) > 0 {
opts = append(opts, option.WithCredentialsJSON(ssn.Credentials.JSON))
opts = append(opts, option.WithCredentialsJSON(ssn.Credentials.JSON)) //nolint:staticcheck // SA1019: will be replaced in https://github.com/openshift/installer/pull/10694
} else {
opts = append(opts, option.WithCredentials(ssn.Credentials))
}
Expand Down
21 changes: 15 additions & 6 deletions pkg/asset/installconfig/nutanix/nutanix.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,16 +199,25 @@ func getPrismElement(ctx context.Context, client *nutanixclientv3.Client) (*nuta
}

if len(pes) == 1 {
pe.UUID = *pes[0].Metadata.UUID
pe.Endpoint.Address = *pes[0].Spec.Resources.Network.ExternalIP
logrus.Infof("Defaulting to only available prism element (cluster): %s", *pes[0].Spec.Name)
p := pes[0]
switch {
case p.Metadata == nil || p.Metadata.UUID == nil:
return nil, errors.New("missing UUID in Prism Element metadata")
case p.Spec == nil || p.Spec.Resources == nil:
return nil, errors.New("missing Resources in Prism Element spec")
case p.Spec.Resources.Network == nil || p.Spec.Resources.Network.ExternalIP == "":
return nil, errors.New("missing ExternalIP in Prism Element network spec")
}
pe.UUID = *p.Metadata.UUID
pe.Endpoint.Address = p.Spec.Resources.Network.ExternalIP
logrus.Infof("Defaulting to only available prism element (cluster): %s", p.Spec.Name)
return pe, nil
}

pesMap := make(map[string]*nutanixclientv3.ClusterIntentResponse)
var peChoices []string
for _, p := range pes {
n := *p.Spec.Name
n := p.Spec.Name
pesMap[n] = p
peChoices = append(peChoices, n)
}
Expand Down Expand Up @@ -237,12 +246,12 @@ func getPrismElement(ctx context.Context, client *nutanixclientv3.Client) (*nuta
return nil, fmt.Errorf("missing UUID in Prism Element metadata for %q", selectedPe)
case peEntry.Spec == nil || peEntry.Spec.Resources == nil:
return nil, fmt.Errorf("missing Resources in Prism Element spec for %q", selectedPe)
case peEntry.Spec.Resources.Network == nil || peEntry.Spec.Resources.Network.ExternalIP == nil:
case peEntry.Spec.Resources.Network == nil || peEntry.Spec.Resources.Network.ExternalIP == "":
return nil, fmt.Errorf("missing ExternalIP in Prism Element network spec for %q", selectedPe)
}

pe.UUID = *peEntry.Metadata.UUID
pe.Endpoint.Address = *peEntry.Spec.Resources.Network.ExternalIP
pe.Endpoint.Address = peEntry.Spec.Resources.Network.ExternalIP
return pe, nil

}
Expand Down
6 changes: 0 additions & 6 deletions pkg/asset/installconfig/powervs/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1479,12 +1479,6 @@ func (c *Client) AddIPToLoadBalancerPool(ctx context.Context, lbID string, poolN
logrus.Debugf("AddIPToLoadBalancerPool: found %s", ip)
return nil
}
case *vpcv1.LoadBalancerPoolMemberTargetIP:
logrus.Debugf("AddIPToLoadBalancerPool: pmt.Address = %+v", *pmt.Address)
if ip == *pmt.Address {
logrus.Debugf("AddIPToLoadBalancerPool: found %s", ip)
return nil
}
case *vpcv1.LoadBalancerPoolMemberTargetInstanceReference:
// No IP address, ignore
default:
Expand Down
4 changes: 3 additions & 1 deletion pkg/asset/manifests/azure/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"github.com/openshift/installer/pkg/types/dns"
)

const defaultInternalLBIPAddress = "10.0.0.100"

// GenerateClusterAssets generates the manifests for the cluster-api.
func GenerateClusterAssets(installConfig *installconfig.InstallConfig, clusterID *installconfig.ClusterID) (*capiutils.GenerateClusterAssetsOutput, error) {
manifests := []*asset.RuntimeFile{}
Expand Down Expand Up @@ -605,7 +607,7 @@ func getSubnetSpec(installConfig *installconfig.InstallConfig, controlPlaneSubne
}

func getLBIP(subnets []*net.IPNet, installConfig *installconfig.InstallConfig) (string, error) {
lbip := capz.DefaultInternalLBIPAddress
lbip := defaultInternalLBIPAddress
lbip = getIPWithinCIDR(subnets, lbip)
Comment thread
patrickdillon marked this conversation as resolved.

var controlPlaneSub string
Expand Down
84 changes: 51 additions & 33 deletions pkg/asset/manifests/azure/stack/v1beta1/azurecluster_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1beta1

import (
"context"
"reflect"

apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -30,68 +31,85 @@ import (

// SetupWebhookWithManager sets up and registers the webhook with the manager.
func (c *AzureCluster) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(c).
return ctrl.NewWebhookManagedBy(mgr, c).
WithCustomDefaulter(c).
WithCustomValidator(c).
Complete()
}

// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-azurecluster,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=azureclusters,versions=v1beta1,name=validation.azurecluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
// +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1beta1-azurecluster,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=azureclusters,versions=v1beta1,name=default.azurecluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1

var _ webhook.Validator = &AzureCluster{}
var _ webhook.Defaulter = &AzureCluster{}
var _ webhook.CustomValidator = &AzureCluster{}
var _ webhook.CustomDefaulter = &AzureCluster{}

// Default implements webhook.Defaulter so a webhook will be registered for the type.
func (c *AzureCluster) Default() {
c.setDefaults()
// Default implements webhook.CustomDefaulter so a webhook will be registered for the type.
func (c *AzureCluster) Default(_ context.Context, obj runtime.Object) error {
cluster, ok := obj.(*AzureCluster)
if !ok {
return apierrors.NewBadRequest("expected an AzureCluster")
}
cluster.setDefaults()
return nil
}

// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
func (c *AzureCluster) ValidateCreate() (admission.Warnings, error) {
return c.validateCluster(nil)
// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type.
func (c *AzureCluster) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) {
cluster, ok := obj.(*AzureCluster)
if !ok {
return nil, apierrors.NewBadRequest("expected an AzureCluster")
}
return cluster.validateCluster(nil)
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
func (c *AzureCluster) ValidateUpdate(oldRaw runtime.Object) (admission.Warnings, error) {
// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type.
func (c *AzureCluster) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) {
var allErrs field.ErrorList
old := oldRaw.(*AzureCluster)
old, ok := oldObj.(*AzureCluster)
if !ok {
return nil, apierrors.NewBadRequest("expected an AzureCluster")
}
cluster, ok := newObj.(*AzureCluster)
if !ok {
return nil, apierrors.NewBadRequest("expected an AzureCluster")
}

if err := webhookutils.ValidateImmutable(
field.NewPath("spec", "resourceGroup"),
old.Spec.ResourceGroup,
c.Spec.ResourceGroup); err != nil {
cluster.Spec.ResourceGroup); err != nil {
allErrs = append(allErrs, err)
}

if err := webhookutils.ValidateImmutable(
field.NewPath("spec", "subscriptionID"),
old.Spec.SubscriptionID,
c.Spec.SubscriptionID); err != nil {
cluster.Spec.SubscriptionID); err != nil {
allErrs = append(allErrs, err)
}

if err := webhookutils.ValidateImmutable(
field.NewPath("spec", "location"),
old.Spec.Location,
c.Spec.Location); err != nil {
cluster.Spec.Location); err != nil {
allErrs = append(allErrs, err)
}

if old.Spec.ControlPlaneEndpoint.Host != "" && c.Spec.ControlPlaneEndpoint.Host != old.Spec.ControlPlaneEndpoint.Host {
if old.Spec.ControlPlaneEndpoint.Host != "" && cluster.Spec.ControlPlaneEndpoint.Host != old.Spec.ControlPlaneEndpoint.Host {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec", "controlPlaneEndpoint", "host"),
c.Spec.ControlPlaneEndpoint.Host, "field is immutable"),
cluster.Spec.ControlPlaneEndpoint.Host, "field is immutable"),
)
}

if old.Spec.ControlPlaneEndpoint.Port != 0 && c.Spec.ControlPlaneEndpoint.Port != old.Spec.ControlPlaneEndpoint.Port {
if old.Spec.ControlPlaneEndpoint.Port != 0 && cluster.Spec.ControlPlaneEndpoint.Port != old.Spec.ControlPlaneEndpoint.Port {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec", "controlPlaneEndpoint", "port"),
c.Spec.ControlPlaneEndpoint.Port, "field is immutable"),
cluster.Spec.ControlPlaneEndpoint.Port, "field is immutable"),
)
}

if !reflect.DeepEqual(c.Spec.AzureEnvironment, old.Spec.AzureEnvironment) {
if !reflect.DeepEqual(cluster.Spec.AzureEnvironment, old.Spec.AzureEnvironment) {
// The equality failure could be because of default mismatch between v1alpha3 and v1beta1. This happens because
// the new object `r` will have run through the default webhooks but the old object `old` would not have so.
// This means if the old object was in v1alpha3, it would not get the new defaults set in v1beta1 resulting
Expand All @@ -100,50 +118,50 @@ func (c *AzureCluster) ValidateUpdate(oldRaw runtime.Object) (admission.Warnings
old.setAzureEnvironmentDefault()

// if it's still not equal, return error.
if !reflect.DeepEqual(c.Spec.AzureEnvironment, old.Spec.AzureEnvironment) {
if !reflect.DeepEqual(cluster.Spec.AzureEnvironment, old.Spec.AzureEnvironment) {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec", "azureEnvironment"),
c.Spec.AzureEnvironment, "field is immutable"),
cluster.Spec.AzureEnvironment, "field is immutable"),
)
}
}

if err := webhookutils.ValidateImmutable(
field.NewPath("spec", "networkSpec", "privateDNSZoneName"),
old.Spec.NetworkSpec.PrivateDNSZoneName,
c.Spec.NetworkSpec.PrivateDNSZoneName); err != nil {
cluster.Spec.NetworkSpec.PrivateDNSZoneName); err != nil {
allErrs = append(allErrs, err)
}

if err := webhookutils.ValidateImmutable(
field.NewPath("spec", "networkSpec", "privateDNSZoneResourceGroup"),
old.Spec.NetworkSpec.PrivateDNSZoneResourceGroup,
c.Spec.NetworkSpec.PrivateDNSZoneResourceGroup); err != nil {
cluster.Spec.NetworkSpec.PrivateDNSZoneResourceGroup); err != nil {
allErrs = append(allErrs, err)
}

// Allow enabling azure bastion but avoid disabling it.
if old.Spec.BastionSpec.AzureBastion != nil && !reflect.DeepEqual(old.Spec.BastionSpec.AzureBastion, c.Spec.BastionSpec.AzureBastion) {
if old.Spec.BastionSpec.AzureBastion != nil && !reflect.DeepEqual(old.Spec.BastionSpec.AzureBastion, cluster.Spec.BastionSpec.AzureBastion) {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec", "bastionSpec", "azureBastion"),
c.Spec.BastionSpec.AzureBastion, "azure bastion cannot be removed from a cluster"),
cluster.Spec.BastionSpec.AzureBastion, "azure bastion cannot be removed from a cluster"),
)
}

if err := webhookutils.ValidateImmutable(
field.NewPath("spec", "networkSpec", "controlPlaneOutboundLB"),
old.Spec.NetworkSpec.ControlPlaneOutboundLB,
c.Spec.NetworkSpec.ControlPlaneOutboundLB); err != nil {
cluster.Spec.NetworkSpec.ControlPlaneOutboundLB); err != nil {
allErrs = append(allErrs, err)
}

allErrs = append(allErrs, c.validateSubnetUpdate(old)...)
allErrs = append(allErrs, cluster.validateSubnetUpdate(old)...)

if len(allErrs) == 0 {
return c.validateCluster(old)
return cluster.validateCluster(old)
}

return nil, apierrors.NewInvalid(GroupVersion.WithKind(AzureClusterKind).GroupKind(), c.Name, allErrs)
return nil, apierrors.NewInvalid(GroupVersion.WithKind(AzureClusterKind).GroupKind(), cluster.Name, allErrs)
}

// validateSubnetUpdate validates a ClusterSpec.NetworkSpec.Subnets for immutability.
Expand Down Expand Up @@ -194,7 +212,7 @@ func (c *AzureCluster) validateSubnetUpdate(old *AzureCluster) field.ErrorList {
return allErrs
}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
func (c *AzureCluster) ValidateDelete() (admission.Warnings, error) {
// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type.
func (c *AzureCluster) ValidateDelete(_ context.Context, _ runtime.Object) (admission.Warnings, error) {
return nil, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package v1beta1

import (
"context"

apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
Expand All @@ -28,37 +30,48 @@ import (

// SetupWebhookWithManager sets up and registers the webhook with the manager.
func (c *AzureClusterIdentity) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(c).
return ctrl.NewWebhookManagedBy(mgr, c).
WithCustomValidator(c).
Complete()
}

// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-azureclusteridentity,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=azureclusteridentities,versions=v1beta1,name=validation.azureclusteridentity.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1

var _ webhook.Validator = &AzureClusterIdentity{}
var _ webhook.CustomValidator = &AzureClusterIdentity{}

// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
func (c *AzureClusterIdentity) ValidateCreate() (admission.Warnings, error) {
return c.validateClusterIdentity()
// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type.
func (c *AzureClusterIdentity) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) {
identity, ok := obj.(*AzureClusterIdentity)
if !ok {
return nil, apierrors.NewBadRequest("expected an AzureClusterIdentity")
}
return identity.validateClusterIdentity()
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
func (c *AzureClusterIdentity) ValidateUpdate(oldRaw runtime.Object) (admission.Warnings, error) {
// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type.
func (c *AzureClusterIdentity) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) {
var allErrs field.ErrorList
old := oldRaw.(*AzureClusterIdentity)
old, ok := oldObj.(*AzureClusterIdentity)
if !ok {
return nil, apierrors.NewBadRequest("expected an AzureClusterIdentity")
}
identity, ok := newObj.(*AzureClusterIdentity)
if !ok {
return nil, apierrors.NewBadRequest("expected an AzureClusterIdentity")
}
if err := webhookutils.ValidateImmutable(
field.NewPath("Spec", "Type"),
old.Spec.Type,
c.Spec.Type); err != nil {
identity.Spec.Type); err != nil {
allErrs = append(allErrs, err)
}
if len(allErrs) == 0 {
return c.validateClusterIdentity()
return identity.validateClusterIdentity()
}
return nil, apierrors.NewInvalid(GroupVersion.WithKind(AzureClusterIdentityKind).GroupKind(), c.Name, allErrs)
return nil, apierrors.NewInvalid(GroupVersion.WithKind(AzureClusterIdentityKind).GroupKind(), identity.Name, allErrs)
}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
func (c *AzureClusterIdentity) ValidateDelete() (admission.Warnings, error) {
// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type.
func (c *AzureClusterIdentity) ValidateDelete(_ context.Context, _ runtime.Object) (admission.Warnings, error) {
return nil, nil
}
Loading