diff --git a/cmd/cluster/core/dump.go b/cmd/cluster/core/dump.go index ca9ccf35758a..5fda93e90fe9 100644 --- a/cmd/cluster/core/dump.go +++ b/cmd/cluster/core/dump.go @@ -22,7 +22,7 @@ import ( kvinfra "github.com/openshift/hypershift/kubevirtexternalinfra" hyperapi "github.com/openshift/hypershift/support/api" supportforwarder "github.com/openshift/hypershift/support/forwarder" - supportutil "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" configv1 "github.com/openshift/api/config/v1" imagev1 "github.com/openshift/api/image/v1" @@ -232,7 +232,7 @@ func dumpGuestCluster(ctx context.Context, opts *DumpOptions) error { Out: forwarderOutput, ErrOut: forwarderOutput, } - podPort := supportutil.KASPodPortFromHostedCluster(hostedCluster) + podPort := netutil.KASPodPortFromHostedCluster(hostedCluster) forwarderStop = make(chan struct{}) if err := forwarder.ForwardPorts([]string{fmt.Sprintf("%d:%d", localPort, podPort)}, forwarderStop); err != nil { return fmt.Errorf("cannot forward kube apiserver port: %w, output: %s", err, forwarderOutput.String()) diff --git a/cmd/kubeconfig/create.go b/cmd/kubeconfig/create.go index 0eaf07affa65..7fb8e6d89eb4 100644 --- a/cmd/kubeconfig/create.go +++ b/cmd/kubeconfig/create.go @@ -8,7 +8,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/cmd/util" - hyperutil "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -120,7 +120,7 @@ func Render(ctx context.Context, namespace string, name string, portForward bool if !hasData || len(data) == 0 { return fmt.Errorf("kubeconfig secret has no kubeconfig") } - if portForward && hyperutil.IsPrivateHC(&cluster) { + if portForward && netutil.IsPrivateHC(&cluster) { data, err = rewriteServerForPrivateCluster(ctx, c, &cluster, data) if err != nil { return fmt.Errorf("failed to rewrite kubeconfig for private cluster: %w", err) @@ -175,7 +175,7 @@ func buildCombinedConfig(ctx context.Context, c client.Client, namespace string, log.Printf("missing kubeconfig contents") continue } - if portForward && hyperutil.IsPrivateHC(&cluster) { + if portForward && netutil.IsPrivateHC(&cluster) { var err error data, err = rewriteServerForPrivateCluster(ctx, c, &cluster, data) if err != nil { diff --git a/cmd/oadp/common.go b/cmd/oadp/common.go index 4da714bc8694..1ff8e33994cd 100644 --- a/cmd/oadp/common.go +++ b/cmd/oadp/common.go @@ -9,7 +9,7 @@ import ( "strings" "github.com/openshift/hypershift/api/hypershift/v1beta1" - utilroute "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -171,7 +171,7 @@ func (o *CreateOptions) buildBackupSpec(includedNamespaces, includedResources [] func generateName(hcName, hcNamespace string) string { randomSuffix := utilrand.String(6) baseName := fmt.Sprintf("%s-%s", hcName, hcNamespace) - return utilroute.ShortenName(baseName, randomSuffix, validation.DNS1123LabelMaxLength) + return netutil.ShortenName(baseName, randomSuffix, validation.DNS1123LabelMaxLength) } // GenerateResourcePolicyName creates a deterministic resource policy ConfigMap name @@ -182,7 +182,7 @@ func GenerateResourcePolicyName(hcName, hcNamespace string) string { baseName := fmt.Sprintf("%s-%s", hcName, hcNamespace) hash := sha256.Sum256([]byte(baseName)) hashSuffix := hex.EncodeToString(hash[:])[:6] - return utilroute.ShortenName(baseName, hashSuffix, validation.DNS1123LabelMaxLength) + return netutil.ShortenName(baseName, hashSuffix, validation.DNS1123LabelMaxLength) } // GenerateResourcePolicyConfigMap creates a ConfigMap with a Velero volume policy that skips diff --git a/cmd/oadp/restore.go b/cmd/oadp/restore.go index 4b1b97f02a8f..5134db9761bc 100644 --- a/cmd/oadp/restore.go +++ b/cmd/oadp/restore.go @@ -7,8 +7,8 @@ import ( "github.com/openshift/hypershift/cmd/log" "github.com/openshift/hypershift/cmd/util" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/oadp" - utilroute "github.com/openshift/hypershift/support/util" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" utilrand "k8s.io/apimachinery/pkg/util/rand" @@ -101,7 +101,7 @@ func GenerateRestoreName(hcName, hcNamespace string) string { randomSuffix := utilrand.String(6) baseName := fmt.Sprintf("%s-%s", hcName, hcNamespace) // Use ShortenName to ensure it doesn't exceed DNS1123 subdomain max length (63 chars) - return utilroute.ShortenName(baseName, randomSuffix, validation.DNS1123LabelMaxLength) + return netutil.ShortenName(baseName, randomSuffix, validation.DNS1123LabelMaxLength) } func (o *CreateOptions) RunRestore(ctx context.Context) error { diff --git a/control-plane-operator/controllers/awsprivatelink/awsprivatelink_controller.go b/control-plane-operator/controllers/awsprivatelink/awsprivatelink_controller.go index ed9f5f373170..03b147a05a54 100644 --- a/control-plane-operator/controllers/awsprivatelink/awsprivatelink_controller.go +++ b/control-plane-operator/controllers/awsprivatelink/awsprivatelink_controller.go @@ -13,6 +13,7 @@ import ( "github.com/openshift/hypershift/support/awsapi" supportawsutil "github.com/openshift/hypershift/support/awsutil" "github.com/openshift/hypershift/support/config" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/upsert" "github.com/openshift/hypershift/support/util" @@ -764,7 +765,7 @@ func (r *AWSEndpointServiceReconciler) reconcileAWSEndpointService(ctx context.C awsEndpointService.Status.DNSNames = fqdns awsEndpointService.Status.DNSZoneID = zoneID - if isPublic, externalNames := util.IsPublicHCP(hcp), hcpExternalNames(hcp); !isPublic && len(externalNames) > 0 { + if isPublic, externalNames := netutil.IsPublicHCP(hcp), hcpExternalNames(hcp); !isPublic && len(externalNames) > 0 { // only if not public and external names are configured, create services of type ExternalName so external-dns // can create records for them var errs []error @@ -967,12 +968,12 @@ func reconcileExternalService(svc *corev1.Service, hcp *hyperv1.HostedControlPla func hcpExternalNames(hcp *hyperv1.HostedControlPlane) map[string]string { result := map[string]string{} - apiStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) + apiStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) if apiStrategy != nil && apiStrategy.Type == hyperv1.Route && apiStrategy.Route != nil && apiStrategy.Route.Hostname != "" { result["api"] = apiStrategy.Route.Hostname } - oauthStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.OAuthServer) + oauthStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.OAuthServer) if oauthStrategy != nil && oauthStrategy.Type == hyperv1.Route && oauthStrategy.Route != nil && oauthStrategy.Route.Hostname != "" { result["oauth"] = oauthStrategy.Route.Hostname } @@ -998,7 +999,7 @@ func recordsForService(awsEndpointService *hyperv1.AWSEndpointService, hcp *hype // If the kas is exposed through a route, the router needs to have DNS entries for both // the kas and the apps domain - if m := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer); m != nil && m.Type == hyperv1.Route { + if m := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer); m != nil && m.Type == hyperv1.Route { return []string{"api", "*." + routerDomain} } diff --git a/control-plane-operator/controllers/gcpprivateserviceconnect/psc_endpoint_controller.go b/control-plane-operator/controllers/gcpprivateserviceconnect/psc_endpoint_controller.go index 69ba5908aff3..c1918c4a8dec 100644 --- a/control-plane-operator/controllers/gcpprivateserviceconnect/psc_endpoint_controller.go +++ b/control-plane-operator/controllers/gcpprivateserviceconnect/psc_endpoint_controller.go @@ -11,6 +11,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests" "github.com/openshift/hypershift/support/config" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/upsert" "github.com/openshift/hypershift/support/util" @@ -455,7 +456,7 @@ func (r *GCPPrivateServiceConnectReconciler) cleanupDNS(ctx context.Context, gcp // reconcileExternalServices creates external-dns services for private clusters with external names // This enables external-dns to create DNS records for private PSC endpoints with custom hostnames func (r *GCPPrivateServiceConnectReconciler) reconcileExternalServices(ctx context.Context, gcpPSC *hyperv1.GCPPrivateServiceConnect, hcp *hyperv1.HostedControlPlane, log logr.Logger) (ctrl.Result, error) { //nolint:unparam // result kept for interface/API consistency - if isPublic, externalNames := util.IsPublicHCP(hcp), hcpExternalNamesGCP(hcp); !isPublic && len(externalNames) > 0 { + if isPublic, externalNames := netutil.IsPublicHCP(hcp), hcpExternalNamesGCP(hcp); !isPublic && len(externalNames) > 0 { // Only if not public and external names are configured, create services of type ExternalName so external-dns // can create records for them var errs []error @@ -504,12 +505,12 @@ func (r *GCPPrivateServiceConnectReconciler) reconcileExternalServices(ctx conte // hcpExternalNamesGCP extracts external hostnames from HCP configuration for GCP func hcpExternalNamesGCP(hcp *hyperv1.HostedControlPlane) map[string]string { result := map[string]string{} - apiStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) + apiStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) if apiStrategy != nil && apiStrategy.Type == hyperv1.Route && apiStrategy.Route != nil && apiStrategy.Route.Hostname != "" { result["api"] = apiStrategy.Route.Hostname } - oauthStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.OAuthServer) + oauthStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.OAuthServer) if oauthStrategy != nil && oauthStrategy.Type == hyperv1.Route && oauthStrategy.Route != nil && oauthStrategy.Route.Hostname != "" { result["oauth"] = oauthStrategy.Route.Hostname } diff --git a/control-plane-operator/controllers/hostedcontrolplane/cloud/openstack/providerconfig.go b/control-plane-operator/controllers/hostedcontrolplane/cloud/openstack/providerconfig.go index 91cafa29a3f3..e463cc9269a8 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/cloud/openstack/providerconfig.go +++ b/control-plane-operator/controllers/hostedcontrolplane/cloud/openstack/providerconfig.go @@ -2,7 +2,7 @@ package openstack import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" corev1 "k8s.io/api/core/v1" "k8s.io/utils/ptr" @@ -67,7 +67,7 @@ func getCloudConfig(platformSpec *hyperv1.OpenStackPlatformSpec, credentialsSecr } } config += "\n[Networking]\n" - config += "address-sort-order = " + util.MachineNetworksToList(machineNetwork) + "\n" + config += "address-sort-order = " + netutil.MachineNetworksToList(machineNetwork) + "\n" return config } diff --git a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go index be1d7ccbaa10..085553fdc54e 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go +++ b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go @@ -81,6 +81,7 @@ import ( "github.com/openshift/hypershift/support/globalconfig" karpenterutil "github.com/openshift/hypershift/support/karpenter" "github.com/openshift/hypershift/support/metrics" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/releaseinfo" "github.com/openshift/hypershift/support/upsert" "github.com/openshift/hypershift/support/util" @@ -681,9 +682,9 @@ func (r *HostedControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.R Reason: hyperv1.StatusUnknownReason, } - kasExternalHostname := util.ServiceExternalDNSHostname(hostedControlPlane, hyperv1.APIServer) + kasExternalHostname := netutil.ServiceExternalDNSHostname(hostedControlPlane, hyperv1.APIServer) if kasExternalHostname != "" { - if err := util.ResolveDNSHostname(ctx, kasExternalHostname); err != nil { + if err := netutil.ResolveDNSHostname(ctx, kasExternalHostname); err != nil { newCondition = metav1.Condition{ Type: string(hyperv1.ExternalDNSReachable), Status: metav1.ConditionFalse, @@ -911,13 +912,13 @@ func reconcileAvailabilityStatus( // healthCheckKASLoadBalancers performs a health check on the KubeAPI server /healthz endpoint using the public and private load balancers hostnames directly // This will detect if load balancers are down or deleted out of band func (r *HostedControlPlaneReconciler) healthCheckKASLoadBalancers(ctx context.Context, hcp *hyperv1.HostedControlPlane) error { - serviceStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) + serviceStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) if serviceStrategy == nil { return fmt.Errorf("APIServer service strategy not specified") } switch { - case !util.IsPublicHCP(hcp): + case !netutil.IsPublicHCP(hcp): // When the cluster is private, checking the load balancers will depend on whether the load balancer is // using the right subnets. To avoid uncertainty, we'll limit the check to the service endpoint. if hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform { @@ -1647,7 +1648,7 @@ func (r *HostedControlPlaneReconciler) reconcilePKI(ctx context.Context, hcp *hy // cert secret ourselves. // Multus Admission Controller Serving Cert - only if Multus is not disabled - if !util.IsDisableMultiNetwork(hcp) { + if !netutil.IsDisableMultiNetwork(hcp) { multusAdmissionControllerService := manifests.MultusAdmissionControllerService(hcp.Namespace) if err = r.Get(ctx, client.ObjectKeyFromObject(multusAdmissionControllerService), multusAdmissionControllerService); err != nil { if !apierrors.IsNotFound(err) { @@ -1940,7 +1941,7 @@ func (r *HostedControlPlaneReconciler) cleanupClusterNetworkOperatorResources(ct // CNO manages overall multus-admission-controller deployment. CPO manages restarts. // TODO: why is this not done in CNO? // Only restart multus deployment if Multus is not disabled - if !util.IsDisableMultiNetwork(hcp) { + if !netutil.IsDisableMultiNetwork(hcp) { multusDeployment := manifests.MultusAdmissionControllerDeployment(hcp.Namespace) if err := cnov2.SetRestartAnnotationAndPatch(ctx, r.Client, multusDeployment, restartAnnotation); err != nil { return fmt.Errorf("failed to restart multus admission controller: %w", err) @@ -2140,7 +2141,7 @@ func (r *HostedControlPlaneReconciler) removeHCPIngressFromRoutes(ctx context.Co for i := range routeList.Items { route := &routeList.Items[i] - if _, hasHCPLabel := route.Labels[util.HCPRouteLabel]; hasHCPLabel { + if _, hasHCPLabel := route.Labels[netutil.HCPRouteLabel]; hasHCPLabel { // Skip routes that should be managed by the HCP router continue } diff --git a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller_test.go b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller_test.go index fab1afdb57cb..e239a773ea11 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller_test.go +++ b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller_test.go @@ -31,6 +31,7 @@ import ( fakecapabilities "github.com/openshift/hypershift/support/capabilities/fake" "github.com/openshift/hypershift/support/certs" controlplanecomponent "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/releaseinfo" fakereleaseprovider "github.com/openshift/hypershift/support/releaseinfo/fake" "github.com/openshift/hypershift/support/releaseinfo/testutils" @@ -1841,7 +1842,7 @@ func TestRemoveHCPIngressFromRoutes(t *testing.T) { Name: "hcp-managed-route", Namespace: namespace, Labels: map[string]string{ - util.HCPRouteLabel: namespace, + netutil.HCPRouteLabel: namespace, }, }, Status: routev1.RouteStatus{ @@ -1858,7 +1859,7 @@ func TestRemoveHCPIngressFromRoutes(t *testing.T) { Name: "hcp-managed-route", Namespace: namespace, Labels: map[string]string{ - util.HCPRouteLabel: namespace, + netutil.HCPRouteLabel: namespace, }, }, Status: routev1.RouteStatus{ @@ -1990,7 +1991,7 @@ func TestRemoveHCPIngressFromRoutes(t *testing.T) { Name: "hcp-managed", Namespace: namespace, Labels: map[string]string{ - util.HCPRouteLabel: namespace, + netutil.HCPRouteLabel: namespace, }, }, Status: routev1.RouteStatus{ @@ -2029,7 +2030,7 @@ func TestRemoveHCPIngressFromRoutes(t *testing.T) { Name: "hcp-managed", Namespace: namespace, Labels: map[string]string{ - util.HCPRouteLabel: namespace, + netutil.HCPRouteLabel: namespace, }, }, Status: routev1.RouteStatus{ diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go b/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go index 138470b5bac1..36a19c7d4143 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go +++ b/control-plane-operator/controllers/hostedcontrolplane/infra/infra.go @@ -18,6 +18,7 @@ import ( hyperazureutil "github.com/openshift/hypershift/support/azureutil" "github.com/openshift/hypershift/support/config" "github.com/openshift/hypershift/support/events" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/upsert" "github.com/openshift/hypershift/support/util" @@ -180,7 +181,7 @@ func (r *Reconciler) AdmitHCPManagedRoutes(ctx context.Context, hcp *hyperv1.Hos // to work as before. for i := range routeList.Items { route := &routeList.Items[i] - if _, hasHCPLabel := route.Labels[util.HCPRouteLabel]; !hasHCPLabel { + if _, hasHCPLabel := route.Labels[netutil.HCPRouteLabel]; !hasHCPLabel { // If the hypershift.openshift.io/hosted-control-plane label is not present, // then it means the route should be fulfilled by the management cluster's router. continue @@ -198,7 +199,7 @@ func (r *Reconciler) AdmitHCPManagedRoutes(ctx context.Context, hcp *hyperv1.Hos } func (r *Reconciler) reconcileAPIServerService(ctx context.Context, hcp *hyperv1.HostedControlPlane, createOrUpdate upsert.CreateOrUpdateFN) error { - serviceStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) + serviceStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) if serviceStrategy == nil { return errors.New("APIServer service strategy not specified") } @@ -208,7 +209,7 @@ func (r *Reconciler) reconcileAPIServerService(ctx context.Context, hcp *hyperv1 if hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform { kasSVCPort = config.KASSVCIBMCloudPort } - if serviceStrategy.Type == hyperv1.LoadBalancer && util.IsPublicHCP(hcp) && (hcp.Spec.Platform.Type == hyperv1.AzurePlatform || + if serviceStrategy.Type == hyperv1.LoadBalancer && netutil.IsPublicHCP(hcp) && (hcp.Spec.Platform.Type == hyperv1.AzurePlatform || hcp.Annotations[hyperv1.ManagementPlatformAnnotation] == string(hyperv1.AzurePlatform)) { // For Azure or Kubevirt on Azure we currently hardcode 7443 for the SVC LB as 6443 collides with public LB rule for the management cluster. // https://bugzilla.redhat.com/show_bug.cgi?id=2060650 @@ -222,7 +223,7 @@ func (r *Reconciler) reconcileAPIServerService(ctx context.Context, hcp *hyperv1 return fmt.Errorf("failed to reconcile API server service: %w", err) } - if serviceStrategy.Type == hyperv1.LoadBalancer && util.IsPublicHCP(hcp) && (hcp.Spec.Platform.Type == hyperv1.AzurePlatform || + if serviceStrategy.Type == hyperv1.LoadBalancer && netutil.IsPublicHCP(hcp) && (hcp.Spec.Platform.Type == hyperv1.AzurePlatform || hcp.Spec.Platform.Type == hyperv1.KubevirtPlatform && hcp.Annotations[hyperv1.ManagementPlatformAnnotation] == string(hyperv1.AzurePlatform)) { // Create the svc clusterIP for Azure on config.KASSVCPort as expected by internal consumers. kasSVC := manifests.KubeAPIServerService(hcp.Namespace) @@ -236,7 +237,7 @@ func (r *Reconciler) reconcileAPIServerService(ctx context.Context, hcp *hyperv1 if serviceStrategy.Type == hyperv1.Route { externalPublicRoute := manifests.KubeAPIServerExternalPublicRoute(hcp.Namespace) externalPrivateRoute := manifests.KubeAPIServerExternalPrivateRoute(hcp.Namespace) - if util.IsPublicHCP(hcp) { + if netutil.IsPublicHCP(hcp) { // Remove the external private route if it exists err := r.Client.Get(ctx, client.ObjectKeyFromObject(externalPrivateRoute), externalPrivateRoute) if err != nil { @@ -289,7 +290,7 @@ func (r *Reconciler) reconcileAPIServerService(ctx context.Context, hcp *hyperv1 }); err != nil { return fmt.Errorf("failed to reconcile apiserver internal route %s: %w", internalRoute.Name, err) } - } else if serviceStrategy.Type == hyperv1.LoadBalancer && util.IsPrivateHCP(hcp) { + } else if serviceStrategy.Type == hyperv1.LoadBalancer && netutil.IsPrivateHCP(hcp) { apiServerPrivateService := manifests.KubeAPIServerPrivateService(hcp.Namespace) if _, err := createOrUpdate(ctx, r.Client, apiServerPrivateService, func() error { return kas.ReconcilePrivateService(apiServerPrivateService, hcp, p.OwnerReference) @@ -303,7 +304,7 @@ func (r *Reconciler) reconcileAPIServerService(ctx context.Context, hcp *hyperv1 func (r *Reconciler) reconcileKonnectivityServerService(ctx context.Context, hcp *hyperv1.HostedControlPlane, createOrUpdate upsert.CreateOrUpdateFN) error { p := konnectivity.NewKonnectivityServiceParams(hcp) - serviceStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.Konnectivity) + serviceStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.Konnectivity) if serviceStrategy == nil { //lint:ignore ST1005 Konnectivity is proper name return fmt.Errorf("Konnectivity service strategy not specified") @@ -318,7 +319,7 @@ func (r *Reconciler) reconcileKonnectivityServerService(ctx context.Context, hcp return nil } konnectivityRoute := manifests.KonnectivityServerRoute(hcp.Namespace) - if util.IsPrivateHCP(hcp) { + if netutil.IsPrivateHCP(hcp) { if _, err := createOrUpdate(ctx, r.Client, konnectivityRoute, func() error { return kas.ReconcileKonnectivityInternalRoute(konnectivityRoute, p.OwnerRef) }); err != nil { @@ -330,7 +331,7 @@ func (r *Reconciler) reconcileKonnectivityServerService(ctx context.Context, hcp if serviceStrategy.Route != nil { hostname = serviceStrategy.Route.Hostname } - return kas.ReconcileKonnectivityExternalRoute(konnectivityRoute, p.OwnerRef, hostname, r.DefaultIngressDomain, util.LabelHCPRoutes(hcp)) + return kas.ReconcileKonnectivityExternalRoute(konnectivityRoute, p.OwnerRef, hostname, r.DefaultIngressDomain, netutil.LabelHCPRoutes(hcp)) }); err != nil { return fmt.Errorf("failed to reconcile Konnectivity server external route: %w", err) } @@ -339,14 +340,14 @@ func (r *Reconciler) reconcileKonnectivityServerService(ctx context.Context, hcp } func (r *Reconciler) reconcileOAuthServerService(ctx context.Context, hcp *hyperv1.HostedControlPlane, createOrUpdate upsert.CreateOrUpdateFN) error { - serviceStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.OAuthServer) + serviceStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.OAuthServer) if serviceStrategy == nil { return fmt.Errorf("OAuthServer service strategy not specified") } p := oauth.NewOAuthServiceParams(hcp) oauthServerService := manifests.OauthServerService(hcp.Namespace) if _, err := createOrUpdate(ctx, r.Client, oauthServerService, func() error { - return oauth.ReconcileService(oauthServerService, p.OwnerRef, serviceStrategy, hcp.Spec.Platform.Type, util.IsPrivateHCP(hcp)) + return oauth.ReconcileService(oauthServerService, p.OwnerRef, serviceStrategy, hcp.Spec.Platform.Type, netutil.IsPrivateHCP(hcp)) }); err != nil { return fmt.Errorf("failed to reconcile OAuth service: %w", err) } @@ -355,7 +356,7 @@ func (r *Reconciler) reconcileOAuthServerService(ctx context.Context, hcp *hyper } oauthExternalPublicRoute := manifests.OauthServerExternalPublicRoute(hcp.Namespace) oauthExternalPrivateRoute := manifests.OauthServerExternalPrivateRoute(hcp.Namespace) - if util.IsPublicHCP(hcp) { + if netutil.IsPublicHCP(hcp) { // Remove the external private route if it exists _, err := util.DeleteIfNeeded(ctx, r.Client, oauthExternalPrivateRoute) if err != nil { @@ -368,7 +369,7 @@ func (r *Reconciler) reconcileOAuthServerService(ctx context.Context, hcp *hyper if serviceStrategy.Route != nil { hostname = serviceStrategy.Route.Hostname } - return oauth.ReconcileExternalPublicRoute(oauthExternalPublicRoute, p.OwnerRef, hostname, r.DefaultIngressDomain, util.LabelHCPRoutes(hcp)) + return oauth.ReconcileExternalPublicRoute(oauthExternalPublicRoute, p.OwnerRef, hostname, r.DefaultIngressDomain, netutil.LabelHCPRoutes(hcp)) }); err != nil { return fmt.Errorf("failed to reconcile OAuth external public route: %w", err) } @@ -382,7 +383,7 @@ func (r *Reconciler) reconcileOAuthServerService(ctx context.Context, hcp *hyper // Reconcile the external private route if a hostname is specified if serviceStrategy.Route != nil && serviceStrategy.Route.Hostname != "" { if _, err := createOrUpdate(ctx, r.Client, oauthExternalPrivateRoute, func() error { - return oauth.ReconcileExternalPrivateRoute(oauthExternalPrivateRoute, p.OwnerRef, serviceStrategy.Route.Hostname, r.DefaultIngressDomain, util.LabelHCPRoutes(hcp)) + return oauth.ReconcileExternalPrivateRoute(oauthExternalPrivateRoute, p.OwnerRef, serviceStrategy.Route.Hostname, r.DefaultIngressDomain, netutil.LabelHCPRoutes(hcp)) }); err != nil { return fmt.Errorf("failed to reconcile OAuth external private route: %w", err) } @@ -394,7 +395,7 @@ func (r *Reconciler) reconcileOAuthServerService(ctx context.Context, hcp *hyper } } } - if util.IsPrivateHCP(hcp) { + if netutil.IsPrivateHCP(hcp) { oauthInternalRoute := manifests.OauthServerInternalRoute(hcp.Namespace) if _, err := createOrUpdate(ctx, r.Client, oauthInternalRoute, func() error { return oauth.ReconcileInternalRoute(oauthInternalRoute, p.OwnerRef) @@ -467,7 +468,7 @@ func (r *Reconciler) reconcileHCPRouterServices(ctx context.Context, hcp *hyperv } // Create the Service type LB internal for private endpoints. - if util.IsPrivateHCP(hcp) { + if netutil.IsPrivateHCP(hcp) { if _, err := createOrUpdate(ctx, r.Client, privSvc, func() error { return ingress.ReconcileRouterService(privSvc, true, true, hcp) }); err != nil { @@ -481,9 +482,9 @@ func (r *Reconciler) reconcileHCPRouterServices(ctx context.Context, hcp *hyperv // When Public access endpoint AND routes use HCP router, create a Service type LB external. // This ensures we only create public router infrastructure when routes are labeled for it. - if util.IsPublicHCP(hcp) && util.LabelHCPRoutes(hcp) { + if netutil.IsPublicHCP(hcp) && netutil.LabelHCPRoutes(hcp) { if _, err := createOrUpdate(ctx, r.Client, pubSvc, func() error { - return ingress.ReconcileRouterService(pubSvc, false, util.IsPrivateHCP(hcp), hcp) + return ingress.ReconcileRouterService(pubSvc, false, netutil.IsPrivateHCP(hcp), hcp) }); err != nil { return fmt.Errorf("failed to reconcile router service: %w", err) } @@ -520,7 +521,7 @@ func reconcileAROPrivateRouterService(svc *corev1.Service, _ *hyperv1.HostedCont } func (r *Reconciler) reconcileAPIServerServiceStatus(ctx context.Context, hcp *hyperv1.HostedControlPlane) (host string, port int32, message string, err error) { - serviceStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) + serviceStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) if serviceStrategy == nil { return "", 0, "", errors.New("APIServer service strategy not specified") } @@ -531,13 +532,13 @@ func (r *Reconciler) reconcileAPIServerServiceStatus(ctx context.Context, hcp *h var svc *corev1.Service if serviceStrategy.Type == hyperv1.Route { - if util.IsPublicHCP(hcp) { + if netutil.IsPublicHCP(hcp) { svc = manifests.RouterPublicService(hcp.Namespace) } else { svc = manifests.PrivateRouterService(hcp.Namespace) } } else { - if util.IsPublicHCP(hcp) { + if netutil.IsPublicHCP(hcp) { svc = manifests.KubeAPIServerService(hcp.Namespace) } else { svc = manifests.KubeAPIServerPrivateService(hcp.Namespace) @@ -552,7 +553,7 @@ func (r *Reconciler) reconcileAPIServerServiceStatus(ctx context.Context, hcp *h hcp.Annotations[hyperv1.ManagementPlatformAnnotation] == string(hyperv1.AzurePlatform)) { // Azure uses port 7443 for KAS LB because port 6443 collides with the management cluster's KAS. kasSVCLBPort = config.KASSVCLBAzurePort - if util.IsPublicHCP(hcp) { + if netutil.IsPublicHCP(hcp) { // Public Azure clusters use a dedicated kube-apiserverlb service. // Private-only clusters use kube-apiserver-private (already set above). svc = manifests.KubeAPIServerServiceAzureLB(hcp.Namespace) @@ -572,7 +573,7 @@ func (r *Reconciler) reconcileAPIServerServiceStatus(ctx context.Context, hcp *h } func (r *Reconciler) reconcileKonnectivityServiceStatus(ctx context.Context, hcp *hyperv1.HostedControlPlane) (host string, port int32, message string, err error) { - serviceStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.Konnectivity) + serviceStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.Konnectivity) if serviceStrategy == nil { err = fmt.Errorf("konnectivity service strategy not specified") return @@ -602,7 +603,7 @@ func (r *Reconciler) reconcileKonnectivityServiceStatus(ctx context.Context, hcp } func (r *Reconciler) reconcileOAuthServiceStatus(ctx context.Context, hcp *hyperv1.HostedControlPlane) (host string, port int32, message string, err error) { - serviceStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.OAuthServer) + serviceStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.OAuthServer) if serviceStrategy == nil { err = fmt.Errorf("OAuth strategy not specified") return @@ -621,7 +622,7 @@ func (r *Reconciler) reconcileOAuthServiceStatus(ctx context.Context, hcp *hyper return oauth.ReconcileServiceStatus(svc, nil, serviceStrategy) } if serviceStrategy.Type == hyperv1.Route { - if util.IsPublicHCP(hcp) { + if netutil.IsPublicHCP(hcp) { route = manifests.OauthServerExternalPublicRoute(hcp.Namespace) if err = r.Client.Get(ctx, client.ObjectKeyFromObject(route), route); err != nil { if apierrors.IsNotFound(err) { @@ -683,14 +684,14 @@ func (r *Reconciler) reconcileClusterIPServiceStatus(ctx context.Context, svc *c func (r *Reconciler) reconcileInternalRouterServiceStatus(ctx context.Context, hcp *hyperv1.HostedControlPlane) (host string, needed bool, message string, err error) { // ARO is always private but there's no router service. Connection goes through swift. - if !util.IsPrivateHCP(hcp) || hyperazureutil.IsAroHCP() || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform { + if !netutil.IsPrivateHCP(hcp) || hyperazureutil.IsAroHCP() || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform { return } return r.reconcileRouterServiceStatus(ctx, manifests.PrivateRouterService(hcp.Namespace), events.NewMessageCollector(ctx, r.Client)) } func (r *Reconciler) reconcileExternalRouterServiceStatus(ctx context.Context, hcp *hyperv1.HostedControlPlane) (host string, needed bool, message string, err error) { - if !util.IsPublicHCP(hcp) || !util.LabelHCPRoutes(hcp) || sharedingress.UseSharedIngress() || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform { + if !netutil.IsPublicHCP(hcp) || !netutil.LabelHCPRoutes(hcp) || sharedingress.UseSharedIngress() || hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform { return } return r.reconcileRouterServiceStatus(ctx, manifests.RouterPublicService(hcp.Namespace), events.NewMessageCollector(ctx, r.Client)) diff --git a/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go b/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go index 1fd09db41e46..201be0623801 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go +++ b/control-plane-operator/controllers/hostedcontrolplane/infra/infra_test.go @@ -11,9 +11,9 @@ import ( "github.com/openshift/hypershift/support/api" "github.com/openshift/hypershift/support/config" "github.com/openshift/hypershift/support/events" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/testutil" "github.com/openshift/hypershift/support/upsert" - "github.com/openshift/hypershift/support/util" routev1 "github.com/openshift/api/route/v1" @@ -1249,7 +1249,7 @@ func TestReconcileAPIServerService(t *testing.T) { Labels: map[string]string{ "hypershift.openshift.io/hosted-control-plane": targetNamespace, hyperv1.RouteVisibilityLabel: string(hyperv1.RouteVisibilityPrivate), - util.InternalRouteLabel: "true", + netutil.InternalRouteLabel: "true", }, OwnerReferences: []metav1.OwnerReference{ownerRef}, }, diff --git a/control-plane-operator/controllers/hostedcontrolplane/ingress/router.go b/control-plane-operator/controllers/hostedcontrolplane/ingress/router.go index f3bc157134de..c6930b3120cd 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/ingress/router.go +++ b/control-plane-operator/controllers/hostedcontrolplane/ingress/router.go @@ -5,6 +5,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/support/azureutil" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/util" routev1 "github.com/openshift/api/route/v1" @@ -84,7 +85,7 @@ func ReconcileRouterService(svc *corev1.Service, internal, crossZoneLoadBalancin // Apply LoadBalancerSourceRanges for external router services to restrict CIDR access // Only apply for external (non-internal) services and when not running on ARO HCP - allowedCIDRBlocks := util.AllowedCIDRBlocks(hcp) + allowedCIDRBlocks := netutil.AllowedCIDRBlocks(hcp) if !internal && !azureutil.IsAroHCP() { svc.Spec.LoadBalancerSourceRanges = allowedCIDRBlocks } @@ -94,7 +95,7 @@ func ReconcileRouterService(svc *corev1.Service, internal, crossZoneLoadBalancin func ReconcileRouteStatus(route *routev1.Route, externalHostname, internalHostname string) { var canonicalHostName string - if _, isInternal := route.Labels[util.InternalRouteLabel]; isInternal { + if _, isInternal := route.Labels[netutil.InternalRouteLabel]; isInternal { canonicalHostName = internalHostname } else { canonicalHostName = externalHostname diff --git a/control-plane-operator/controllers/hostedcontrolplane/ingress/router_test.go b/control-plane-operator/controllers/hostedcontrolplane/ingress/router_test.go index 2a5a280be88c..b9b9720b6b6f 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/ingress/router_test.go +++ b/control-plane-operator/controllers/hostedcontrolplane/ingress/router_test.go @@ -4,7 +4,7 @@ import ( "testing" hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" @@ -72,7 +72,7 @@ func TestReconcileRouterService_AppliesLoadBalancerSourceRanges(t *testing.T) { } // Then LoadBalancerSourceRanges should be set to match AllowedCIDRBlocks - expectedCIDRs := sets.New(util.AllowedCIDRBlocks(hcp)...) + expectedCIDRs := sets.New(netutil.AllowedCIDRBlocks(hcp)...) actualCIDRs := sets.New(svc.Spec.LoadBalancerSourceRanges...) if !expectedCIDRs.Equal(actualCIDRs) { diff --git a/control-plane-operator/controllers/hostedcontrolplane/kas/params.go b/control-plane-operator/controllers/hostedcontrolplane/kas/params.go index b7c2396171e2..229a676d1fc2 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/kas/params.go +++ b/control-plane-operator/controllers/hostedcontrolplane/kas/params.go @@ -3,7 +3,7 @@ package kas import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/support/config" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -21,7 +21,7 @@ const ( func NewKubeAPIServerServiceParams(hcp *hyperv1.HostedControlPlane) *KubeAPIServerServiceParams { return &KubeAPIServerServiceParams{ - AllowedCIDRBlocks: util.AllowedCIDRBlocks(hcp), + AllowedCIDRBlocks: netutil.AllowedCIDRBlocks(hcp), OwnerReference: config.ControllerOwnerRef(hcp), } } diff --git a/control-plane-operator/controllers/hostedcontrolplane/kas/service.go b/control-plane-operator/controllers/hostedcontrolplane/kas/service.go index 3934c0506509..1ad969144517 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/kas/service.go +++ b/control-plane-operator/controllers/hostedcontrolplane/kas/service.go @@ -10,6 +10,7 @@ import ( "github.com/openshift/hypershift/support/azureutil" "github.com/openshift/hypershift/support/config" "github.com/openshift/hypershift/support/events" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/util" routev1 "github.com/openshift/api/route/v1" @@ -28,8 +29,8 @@ func kasLabels() map[string]string { } func ReconcileService(svc *corev1.Service, strategy *hyperv1.ServicePublishingStrategy, owner *metav1.OwnerReference, apiServerServicePort int, apiAllowedCIDRBlocks []string, hcp *hyperv1.HostedControlPlane) error { - isPublic := util.IsPublicHCP(hcp) - isPrivate := util.IsPrivateHCP(hcp) + isPublic := netutil.IsPublicHCP(hcp) + isPrivate := netutil.IsPrivateHCP(hcp) util.EnsureOwnerRef(svc, owner) if svc.Spec.Selector == nil { svc.Spec.Selector = kasLabels() @@ -228,7 +229,7 @@ func ReconcileExternalPrivateRoute(route *routev1.Route, owner *metav1.OwnerRefe route.Labels = map[string]string{} } route.Labels[hyperv1.RouteVisibilityLabel] = hyperv1.RouteVisibilityPrivate - util.AddInternalRouteLabel(route) + netutil.AddInternalRouteLabel(route) return nil } @@ -237,7 +238,7 @@ func reconcileExternalRoute(route *routev1.Route, owner *metav1.OwnerReference, return fmt.Errorf("route hostname is required for service APIServer") } util.EnsureOwnerRef(route, owner) - util.AddHCPRouteLabel(route) + netutil.AddHCPRouteLabel(route) route.Spec.Host = hostname route.Spec.To = routev1.RouteTargetReference{ Kind: "Service", @@ -256,7 +257,7 @@ func ReconcileInternalRoute(route *routev1.Route, owner *metav1.OwnerReference) util.EnsureOwnerRef(route, owner) route.Spec.Host = fmt.Sprintf("api.%s.hypershift.local", owner.Name) // Assumes owner is the HCP - return util.ReconcileInternalRoute(route, "", manifests.KubeAPIServerService("").Name) + return netutil.ReconcileInternalRoute(route, "", manifests.KubeAPIServerService("").Name) } func ReconcileKonnectivityServerLocalService(svc *corev1.Service, ownerRef config.OwnerRef) error { @@ -315,7 +316,7 @@ func ReconcileKonnectivityServerService(svc *corev1.Service, ownerRef config.Own func ReconcileKonnectivityExternalRoute(route *routev1.Route, ownerRef config.OwnerRef, hostname string, defaultIngressDomain string, labelHCPRoutes bool) error { ownerRef.ApplyTo(route) - if err := util.ReconcileExternalRoute(route, hostname, defaultIngressDomain, manifests.KonnectivityServerService(route.Namespace).Name, labelHCPRoutes); err != nil { + if err := netutil.ReconcileExternalRoute(route, hostname, defaultIngressDomain, manifests.KonnectivityServerService(route.Namespace).Name, labelHCPRoutes); err != nil { return err } if route.Annotations == nil { @@ -328,7 +329,7 @@ func ReconcileKonnectivityExternalRoute(route *routev1.Route, ownerRef config.Ow func ReconcileKonnectivityInternalRoute(route *routev1.Route, ownerRef config.OwnerRef) error { ownerRef.ApplyTo(route) // Assumes ownerRef is the HCP - if err := util.ReconcileInternalRoute(route, ownerRef.Reference.Name, manifests.KonnectivityServerService(route.Namespace).Name); err != nil { + if err := netutil.ReconcileInternalRoute(route, ownerRef.Reference.Name, manifests.KonnectivityServerService(route.Namespace).Name); err != nil { return err } if route.Annotations == nil { diff --git a/control-plane-operator/controllers/hostedcontrolplane/multus_disable_test.go b/control-plane-operator/controllers/hostedcontrolplane/multus_disable_test.go index 51a0d32a7e8d..78bda40a98ff 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/multus_disable_test.go +++ b/control-plane-operator/controllers/hostedcontrolplane/multus_disable_test.go @@ -4,7 +4,7 @@ import ( "testing" hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" "k8s.io/utils/ptr" @@ -94,7 +94,7 @@ func TestDisableMultiNetworkDefaultBehavior(t *testing.T) { } // Test that the reconciler logic would make the correct decision - shouldProcessMultus := !util.IsDisableMultiNetwork(hcp) + shouldProcessMultus := !netutil.IsDisableMultiNetwork(hcp) expectedDisableMultiNetwork := false if test.expectedDisableMultiNetwork != nil { @@ -149,7 +149,7 @@ func TestDisableMultiNetworkRestartLogic(t *testing.T) { } // Test the restart logic: restart when hasRestartAnnotation && !DisableMultiNetwork - shouldRestart := test.hasRestartAnnotation && !util.IsDisableMultiNetwork(hcp) + shouldRestart := test.hasRestartAnnotation && !netutil.IsDisableMultiNetwork(hcp) assert.Equal(t, test.expectedRestart, shouldRestart, "Restart logic test failed") }) } diff --git a/control-plane-operator/controllers/hostedcontrolplane/oauth/route.go b/control-plane-operator/controllers/hostedcontrolplane/oauth/route.go index 82c7d93492aa..6371d47bc378 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/oauth/route.go +++ b/control-plane-operator/controllers/hostedcontrolplane/oauth/route.go @@ -4,31 +4,31 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests" "github.com/openshift/hypershift/support/config" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" routev1 "github.com/openshift/api/route/v1" ) func ReconcileExternalPublicRoute(route *routev1.Route, ownerRef config.OwnerRef, hostname string, defaultIngressDomain string, labelHCPRoutes bool) error { ownerRef.ApplyTo(route) - return util.ReconcileExternalRoute(route, hostname, defaultIngressDomain, manifests.OauthServerService(route.Namespace).Name, labelHCPRoutes) + return netutil.ReconcileExternalRoute(route, hostname, defaultIngressDomain, manifests.OauthServerService(route.Namespace).Name, labelHCPRoutes) } func ReconcileExternalPrivateRoute(route *routev1.Route, ownerRef config.OwnerRef, hostname string, defaultIngressDomain string, labelHCPRoutes bool) error { ownerRef.ApplyTo(route) - if err := util.ReconcileExternalRoute(route, hostname, defaultIngressDomain, manifests.OauthServerService(route.Namespace).Name, labelHCPRoutes); err != nil { + if err := netutil.ReconcileExternalRoute(route, hostname, defaultIngressDomain, manifests.OauthServerService(route.Namespace).Name, labelHCPRoutes); err != nil { return err } if route.Labels == nil { route.Labels = map[string]string{} } route.Labels[hyperv1.RouteVisibilityLabel] = hyperv1.RouteVisibilityPrivate - util.AddInternalRouteLabel(route) + netutil.AddInternalRouteLabel(route) return nil } func ReconcileInternalRoute(route *routev1.Route, ownerRef config.OwnerRef) error { ownerRef.ApplyTo(route) // Assumes ownerRef is the HCP - return util.ReconcileInternalRoute(route, ownerRef.Reference.Name, manifests.OauthServerService(route.Namespace).Name) + return netutil.ReconcileInternalRoute(route, ownerRef.Reference.Name, manifests.OauthServerService(route.Namespace).Name) } diff --git a/control-plane-operator/controllers/hostedcontrolplane/pki/params.go b/control-plane-operator/controllers/hostedcontrolplane/pki/params.go index ceef721bec5b..a074af604f74 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/pki/params.go +++ b/control-plane-operator/controllers/hostedcontrolplane/pki/params.go @@ -6,7 +6,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/support/config" "github.com/openshift/hypershift/support/globalconfig" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" ) type PKIParams struct { @@ -83,11 +83,11 @@ func NewPKIParams(hcp *hyperv1.HostedControlPlane, // Even with that, we cannot set more than one AdvertiseAddress so both // are not supported at the same time. // Check this for more info: https://github.com/kubernetes/enhancements/issues/2438 - ipv4, err := util.IsIPv4CIDR(p.ServiceCIDR[0]) + ipv4, err := netutil.IsIPv4CIDR(p.ServiceCIDR[0]) if err != nil || ipv4 { - p.NodeInternalAPIServerIP = util.AdvertiseAddressWithDefault(hcp, config.DefaultAdvertiseIPv4Address) + p.NodeInternalAPIServerIP = netutil.AdvertiseAddressWithDefault(hcp, config.DefaultAdvertiseIPv4Address) } else { - p.NodeInternalAPIServerIP = util.AdvertiseAddressWithDefault(hcp, config.DefaultAdvertiseIPv6Address) + p.NodeInternalAPIServerIP = netutil.AdvertiseAddressWithDefault(hcp, config.DefaultAdvertiseIPv6Address) } return p diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/openstack/config.go b/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/openstack/config.go index 2280f48deacb..24601b0c3559 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/openstack/config.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/cloud_controller_manager/openstack/config.go @@ -5,7 +5,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" component "github.com/openshift/hypershift/support/controlplane-component" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -84,7 +84,7 @@ func getCloudConfig(hcpSpec hyperv1.HostedControlPlaneSpec, credentialsSecret *c } } config += "\n[Networking]\n" - config += "address-sort-order = " + util.MachineNetworksToList(hcpSpec.Networking.MachineNetwork) + "\n" + config += "address-sort-order = " + netutil.MachineNetworksToList(hcpSpec.Networking.MachineNetwork) + "\n" return config } diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/cno/component.go b/control-plane-operator/controllers/hostedcontrolplane/v2/cno/component.go index b62440594afb..f6f884301e00 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/cno/component.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/cno/component.go @@ -9,8 +9,8 @@ import ( oapiv2 "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/v2/oapi" "github.com/openshift/hypershift/support/azureutil" component "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/podspec" - "github.com/openshift/hypershift/support/util" appsv1 "k8s.io/api/apps/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -155,7 +155,7 @@ func checkOperandsRolloutStatus(cpContext component.WorkloadContext) (bool, erro } // multus-admission-controller is needed for all network types when multi-network is enabled - if !util.IsDisableMultiNetwork(cpContext.HCP) { + if !netutil.IsDisableMultiNetwork(cpContext.HCP) { operandsDeploymentsList = append(operandsDeploymentsList, operand{ DeploymentName: "multus-admission-controller", ContainerName: "multus-admission-controller", diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/cno/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/cno/deployment.go index a9c568e81c15..986c930145e3 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/cno/deployment.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/cno/deployment.go @@ -9,6 +9,7 @@ import ( "github.com/openshift/hypershift/support/azureutil" "github.com/openshift/hypershift/support/config" component "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/podspec" "github.com/openshift/hypershift/support/proxy" "github.com/openshift/hypershift/support/rhobsmonitoring" @@ -74,9 +75,9 @@ func buildCNOEnvVars(cpContext component.WorkloadContext) []corev1.EnvVar { apiServerAddress := hcp.Status.ControlPlaneEndpoint.Host apiServerPort := hcp.Status.ControlPlaneEndpoint.Port - if util.IsPrivateHCP(hcp) { + if netutil.IsPrivateHCP(hcp) { apiServerAddress = fmt.Sprintf("api.%s.hypershift.local", hcp.Name) - apiServerPort = util.APIPortForLocalZone(util.IsLBKAS(hcp)) + apiServerPort = netutil.APIPortForLocalZone(netutil.IsLBKAS(hcp)) } else if hcp.Spec.Platform.Type == hyperv1.IBMCloudPlatform { apiServerAddress = *hcp.Spec.Networking.APIServer.AdvertiseAddress apiServerPort = *hcp.Spec.Networking.APIServer.Port @@ -116,7 +117,7 @@ func buildCNOEnvVars(cpContext component.WorkloadContext) []corev1.EnvVar { {Name: "FRR_K8S_IMAGE", Value: userReleaseImageProvider.GetImage("metallb-frr")}, } - if !util.IsPrivateHCP(hcp) { + if !netutil.IsPrivateHCP(hcp) { cnoEnv = append(cnoEnv, corev1.EnvVar{ Name: "PROXY_INTERNAL_APISERVER_ADDRESS", Value: "true", }) diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/etcd/statefulset.go b/control-plane-operator/controllers/hostedcontrolplane/v2/etcd/statefulset.go index 204872fb38ce..49de8fc17d35 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/etcd/statefulset.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/etcd/statefulset.go @@ -8,8 +8,8 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests" component "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/podspec" - "github.com/openshift/hypershift/support/util" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -21,7 +21,7 @@ func adaptStatefulSet(cpContext component.WorkloadContext, sts *appsv1.StatefulS hcp := cpContext.HCP managedEtcdSpec := hcp.Spec.Etcd.Managed - ipv4, err := util.IsIPv4CIDR(hcp.Spec.Networking.ClusterNetwork[0].CIDR.String()) + ipv4, err := netutil.IsIPv4CIDR(hcp.Spec.Networking.ClusterNetwork[0].CIDR.String()) if err != nil { return fmt.Errorf("error checking the ClusterNetworkCIDR: %v", err) } diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/pki.go b/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/pki.go index 5098e14d668c..79bf570f4f78 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/pki.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/pki.go @@ -8,7 +8,7 @@ import ( "github.com/openshift/hypershift/hypershift-operator/controllers/manifests/ignitionserver" "github.com/openshift/hypershift/support/certs" component "github.com/openshift/hypershift/support/controlplane-component" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" routev1 "github.com/openshift/api/route/v1" @@ -48,7 +48,7 @@ func adaptServingCertSecret(cpContext component.WorkloadContext, secret *corev1. return fmt.Errorf("failed to get ignition ca-cert secret: %v", err) } - serviceStrategy := util.ServicePublishingStrategyByTypeForHCP(cpContext.HCP, hyperv1.Ignition) + serviceStrategy := netutil.ServicePublishingStrategyByTypeForHCP(cpContext.HCP, hyperv1.Ignition) if serviceStrategy == nil { return fmt.Errorf("ignition service strategy not specified") } diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/route.go b/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/route.go index 8f55ec93552b..c43e8fb94c0b 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/route.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/route.go @@ -5,13 +5,13 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" component "github.com/openshift/hypershift/support/controlplane-component" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" routev1 "github.com/openshift/api/route/v1" ) func routePredicate(cpContext component.WorkloadContext) bool { - strategy := util.ServicePublishingStrategyByTypeForHCP(cpContext.HCP, hyperv1.Ignition) + strategy := netutil.ServicePublishingStrategyByTypeForHCP(cpContext.HCP, hyperv1.Ignition) if strategy == nil { return false } @@ -27,11 +27,11 @@ func (ign *ignitionServer) adaptRoute(cpContext component.WorkloadContext, route } hcp := cpContext.HCP - if util.IsPrivateHCP(hcp) { - return util.ReconcileInternalRoute(route, hcp.Name, serviceName) + if netutil.IsPrivateHCP(hcp) { + return netutil.ReconcileInternalRoute(route, hcp.Name, serviceName) } - strategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.Ignition) + strategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.Ignition) if strategy == nil { return fmt.Errorf("ignition service strategy not specified") } @@ -41,8 +41,8 @@ func (ign *ignitionServer) adaptRoute(cpContext component.WorkloadContext, route hostname = strategy.Route.Hostname } - labelHCPRoutes := util.LabelHCPRoutes(hcp) - if err := util.ReconcileExternalRoute(route, hostname, ign.defaultIngressDomain, serviceName, labelHCPRoutes); err != nil { + labelHCPRoutes := netutil.LabelHCPRoutes(hcp) + if err := netutil.ReconcileExternalRoute(route, hostname, ign.defaultIngressDomain, serviceName, labelHCPRoutes); err != nil { return err } @@ -51,7 +51,7 @@ func (ign *ignitionServer) adaptRoute(cpContext component.WorkloadContext, route // ReconcileExternalRoute works on the manifest object (no existing label), so we mark // it for removal here to ensure preserveOriginalMetadata deletes it from the cluster object. if !labelHCPRoutes { - util.MarkHCPRouteLabelForRemoval(route) + netutil.MarkHCPRouteLabelForRemoval(route) } return nil diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/route_test.go b/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/route_test.go index da35b87ff6c4..6a2c45d03487 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/route_test.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/route_test.go @@ -7,7 +7,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" component "github.com/openshift/hypershift/support/controlplane-component" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" routev1 "github.com/openshift/api/route/v1" @@ -97,15 +97,15 @@ func TestIgnitionRouteAdapt(t *testing.T) { g.Expect(tc.route.Spec.Host).To(Equal(tc.expectedHost)) if tc.expectHCPRouteLabel { - g.Expect(tc.route.Labels).To(HaveKeyWithValue(util.HCPRouteLabel, tc.route.Namespace)) + g.Expect(tc.route.Labels).To(HaveKeyWithValue(netutil.HCPRouteLabel, tc.route.Namespace)) } else { - g.Expect(tc.route.Labels).ToNot(HaveKeyWithValue(util.HCPRouteLabel, tc.route.Namespace)) + g.Expect(tc.route.Labels).ToNot(HaveKeyWithValue(netutil.HCPRouteLabel, tc.route.Namespace)) } if tc.expectInternalLabel { - g.Expect(tc.route.Labels).To(HaveKeyWithValue(util.InternalRouteLabel, "true")) + g.Expect(tc.route.Labels).To(HaveKeyWithValue(netutil.InternalRouteLabel, "true")) } else { - g.Expect(tc.route.Labels).ToNot(HaveKey(util.InternalRouteLabel)) + g.Expect(tc.route.Labels).ToNot(HaveKey(netutil.InternalRouteLabel)) } }) } diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/service.go b/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/service.go index 5de606574eea..4f4f3f9ca5d2 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/service.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver/service.go @@ -5,7 +5,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" component "github.com/openshift/hypershift/support/controlplane-component" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -28,7 +28,7 @@ func adaptService(cpContext component.WorkloadContext, svc *corev1.Service) erro existingServiceUsesNodePort = (existingService.Spec.Type == corev1.ServiceTypeNodePort) && (len(existingService.Spec.Ports) == 1) } - strategy := util.ServicePublishingStrategyByTypeForHCP(cpContext.HCP, hyperv1.Ignition) + strategy := netutil.ServicePublishingStrategyByTypeForHCP(cpContext.HCP, hyperv1.Ignition) if strategy == nil { return fmt.Errorf("ignition service strategy not specified") } diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver_proxy/service.go b/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver_proxy/service.go index 8dbe337a7be7..7427dd48f676 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver_proxy/service.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/ignitionserver_proxy/service.go @@ -5,13 +5,13 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" component "github.com/openshift/hypershift/support/controlplane-component" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" corev1 "k8s.io/api/core/v1" ) func adaptService(cpContext component.WorkloadContext, svc *corev1.Service) error { - strategy := util.ServicePublishingStrategyByTypeForHCP(cpContext.HCP, hyperv1.Ignition) + strategy := netutil.ServicePublishingStrategyByTypeForHCP(cpContext.HCP, hyperv1.Ignition) if strategy == nil { return fmt.Errorf("ignition service strategy not specified") } diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go index 32a4f2857697..9664f02d7da9 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/deployment.go @@ -14,6 +14,7 @@ import ( "github.com/openshift/hypershift/support/azureutil" "github.com/openshift/hypershift/support/config" component "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/podspec" "github.com/openshift/hypershift/support/proxy" "github.com/openshift/hypershift/support/util" @@ -165,7 +166,7 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep func updateMainContainer(podSpec *corev1.PodSpec, hcp *hyperv1.HostedControlPlane) { podspec.UpdateContainer(ComponentName, podSpec.Containers, func(c *corev1.Container) { - c.Ports[0].ContainerPort = util.KASPodPort(hcp) + c.Ports[0].ContainerPort = netutil.KASPodPort(hcp) kasVerbosityLevel := 2 if hcp.Annotations[hyperv1.KubeAPIServerVerbosityLevelAnnotation] != "" { @@ -183,8 +184,8 @@ func updateMainContainer(podSpec *corev1.PodSpec, hcp *hyperv1.HostedControlPlan // Using a CIDR is not supported by Go's default ProxyFunc, but Kube uses a custom one by default that does support it: // https://github.com/kubernetes/kubernetes/blob/ab13c85316015cf9f115e29923ba9740bd1564fd/staging/src/k8s.io/apimachinery/pkg/util/net/http.go#L112-L114 var additionalNoProxyCIDRS []string - additionalNoProxyCIDRS = append(additionalNoProxyCIDRS, util.ClusterCIDRs(hcp.Spec.Networking.ClusterNetwork)...) - additionalNoProxyCIDRS = append(additionalNoProxyCIDRS, util.ServiceCIDRs(hcp.Spec.Networking.ServiceNetwork)...) + additionalNoProxyCIDRS = append(additionalNoProxyCIDRS, netutil.ClusterCIDRs(hcp.Spec.Networking.ClusterNetwork)...) + additionalNoProxyCIDRS = append(additionalNoProxyCIDRS, netutil.ServiceCIDRs(hcp.Spec.Networking.ServiceNetwork)...) proxy.SetEnvVars(&c.Env, additionalNoProxyCIDRS...) if hcp.Annotations[hyperv1.KubeAPIServerGOGCAnnotation] != "" { @@ -343,7 +344,7 @@ func applyAWSPodIdentityWebhookContainer(podSpec *corev1.PodSpec, hcp *hyperv1.H } func applyAzureWorkloadIdentityWebhookContainer(podSpec *corev1.PodSpec, hcp *hyperv1.HostedControlPlane) { - waitForKASScript := fmt.Sprintf(azureWorkloadIdentityWebhookWaitForKASVersionTemplate, util.KASPodPort(hcp)) + waitForKASScript := fmt.Sprintf(azureWorkloadIdentityWebhookWaitForKASVersionTemplate, netutil.KASPodPort(hcp)) podSpec.Containers = append(podSpec.Containers, corev1.Container{ Name: "azure-workload-identity-webhook", diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kubeconfig.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kubeconfig.go index 1d4ce0da2fb2..25dedd9fbb6f 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kubeconfig.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kubeconfig.go @@ -11,8 +11,8 @@ import ( "github.com/openshift/hypershift/support/certs" "github.com/openshift/hypershift/support/config" component "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/podspec" - "github.com/openshift/hypershift/support/util" corev1 "k8s.io/api/core/v1" clientcmd "k8s.io/client-go/tools/clientcmd" @@ -83,7 +83,7 @@ func adaptHCCOKubeconfigSecret(cpContext component.WorkloadContext, secret *core } func adaptLocalhostKubeconfigSecret(cpContext component.WorkloadContext, secret *corev1.Secret) error { - apiServerPort := util.KASPodPort(cpContext.HCP) + apiServerPort := netutil.KASPodPort(cpContext.HCP) localhostURL := fmt.Sprintf("https://localhost:%d", apiServerPort) kubeconfig, err := GenerateKubeConfig(cpContext, manifests.SystemAdminClientCertSecret(cpContext.HCP.Namespace), localhostURL) if err != nil { @@ -98,7 +98,7 @@ func adaptLocalhostKubeconfigSecret(cpContext component.WorkloadContext, secret } func adaptKASBootstrapContainerKubeconfigSecret(cpContext component.WorkloadContext, secret *corev1.Secret) error { - apiServerPort := util.KASPodPort(cpContext.HCP) + apiServerPort := netutil.KASPodPort(cpContext.HCP) localhostURL := fmt.Sprintf("https://localhost:%d", apiServerPort) kubeconfig, err := GenerateKubeConfig(cpContext, manifests.KASBootstrapContainerClientCertSecret(cpContext.HCP.Namespace), localhostURL) if err != nil { @@ -119,7 +119,7 @@ func adapExternalAdminKubeconfigSecret(cpContext component.WorkloadContext, secr url := externalURL(cpContext.InfraStatus) - if !util.IsPublicHCP(cpContext.HCP) && !util.IsRouteKAS(cpContext.HCP) { + if !netutil.IsPublicHCP(cpContext.HCP) && !netutil.IsRouteKAS(cpContext.HCP) { url = internalURL(cpContext.InfraStatus, cpContext.HCP.Name) } kubeconfig, err := GenerateKubeConfig(cpContext, manifests.SystemAdminClientCertSecret(cpContext.HCP.Namespace), url) @@ -163,7 +163,7 @@ func adaptCustomAdminKubeconfigSecret(cpContext component.WorkloadContext, secre func adaptBootstrapKubeconfigSecret(cpContext component.WorkloadContext, secret *corev1.Secret) error { url := externalURL(cpContext.InfraStatus) - if util.IsPrivateHCP(cpContext.HCP) { + if netutil.IsPrivateHCP(cpContext.HCP) { url = internalURL(cpContext.InfraStatus, cpContext.HCP.Name) } kubeconfig, err := GenerateKubeConfig(cpContext, manifests.KASMachineBootstrapClientCertSecret(cpContext.HCP.Namespace), url) @@ -215,7 +215,7 @@ func adaptAzureWorkloadIdentityWebhookKubeconfigSecret(cpContext component.Workl } if !cpContext.SkipCertificateSigning { - apiServerPort := util.KASPodPort(cpContext.HCP) + apiServerPort := netutil.KASPodPort(cpContext.HCP) localhostURL := fmt.Sprintf("https://localhost:%d", apiServerPort) return pki.ReconcileServiceAccountKubeconfigWithURL(secret, csrSigner, rootCACM, "openshift-authentication", "azure-workload-identity-webhook", localhostURL) } diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/params.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/params.go index ce3c0aa5ba3a..09fff274e85c 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/params.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/params.go @@ -9,6 +9,7 @@ import ( "github.com/openshift/hypershift/support/capabilities" "github.com/openshift/hypershift/support/config" "github.com/openshift/hypershift/support/globalconfig" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/util" configv1 "github.com/openshift/api/config/v1" @@ -59,15 +60,15 @@ func NewConfigParams(hcp *hyperv1.HostedControlPlane, featureGates []string) Kub kasConfig := KubeAPIServerConfigParams{ ExternalIPConfig: externalIPConfig(hcp.Spec.Configuration), - ClusterNetwork: util.ClusterCIDRs(hcp.Spec.Networking.ClusterNetwork), - ServiceNetwork: util.ServiceCIDRs(hcp.Spec.Networking.ServiceNetwork), + ClusterNetwork: netutil.ClusterCIDRs(hcp.Spec.Networking.ClusterNetwork), + ServiceNetwork: netutil.ServiceCIDRs(hcp.Spec.Networking.ServiceNetwork), NamedCertificates: hcp.Spec.Configuration.GetNamedCertificates(), - KASPodPort: util.KASPodPort(hcp), + KASPodPort: netutil.KASPodPort(hcp), TLSSecurityProfile: tlsSecurityProfile(hcp.Spec.Configuration), AdditionalCORSAllowedOrigins: additionalCORSAllowedOrigins(hcp.Spec.Configuration), ExternalRegistryHostNames: externalRegistryHostNames(hcp.Spec.Configuration), DefaultNodeSelector: defaultNodeSelector(hcp.Spec.Configuration), - AdvertiseAddress: util.GetAdvertiseAddress(hcp, config.DefaultAdvertiseIPv4Address, config.DefaultAdvertiseIPv6Address), + AdvertiseAddress: netutil.GetAdvertiseAddress(hcp, config.DefaultAdvertiseIPv4Address, config.DefaultAdvertiseIPv6Address), ServiceAccountIssuerURL: serviceAccountIssuerURL(hcp), FeatureGates: featureGates, NodePortRange: serviceNodePortRange(hcp.Spec.Configuration), diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kcm/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kcm/deployment.go index 89b849546488..3f67a65e1a8d 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/kcm/deployment.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kcm/deployment.go @@ -8,6 +8,7 @@ import ( "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests" "github.com/openshift/hypershift/support/config" component "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/podspec" "github.com/openshift/hypershift/support/proxy" "github.com/openshift/hypershift/support/util" @@ -33,8 +34,8 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep podspec.UpdateContainer(ComponentName, deployment.Spec.Template.Spec.Containers, func(c *corev1.Container) { c.Args = append(c.Args, - fmt.Sprintf("--cluster-cidr=%s", util.FirstClusterCIDR(hcp.Spec.Networking.ClusterNetwork)), - fmt.Sprintf("--service-cluster-ip-range=%s", util.FirstServiceCIDR(hcp.Spec.Networking.ServiceNetwork)), + fmt.Sprintf("--cluster-cidr=%s", netutil.FirstClusterCIDR(hcp.Spec.Networking.ClusterNetwork)), + fmt.Sprintf("--service-cluster-ip-range=%s", netutil.FirstServiceCIDR(hcp.Spec.Networking.ServiceNetwork)), ) // This value comes from the Cloud Provider Azure documentation: https://cloud-provider-azure.sigs.k8s.io/install/azure-ccm/#kube-controller-manager if hcp.Spec.Platform.Type == hyperv1.AzurePlatform { diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/metrics_proxy/route.go b/control-plane-operator/controllers/hostedcontrolplane/v2/metrics_proxy/route.go index b3a74b3a4c12..d0c0df253b53 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/metrics_proxy/route.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/metrics_proxy/route.go @@ -6,7 +6,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" component "github.com/openshift/hypershift/support/controlplane-component" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" routev1 "github.com/openshift/api/route/v1" ) @@ -15,8 +15,8 @@ func (mp *metricsProxy) adaptRoute(cpContext component.WorkloadContext, route *r hcp := cpContext.HCP serviceName := ComponentName - if util.IsPrivateHCP(hcp) { - return util.ReconcileInternalRoute(route, hcp.Name, serviceName) + if netutil.IsPrivateHCP(hcp) { + return netutil.ReconcileInternalRoute(route, hcp.Name, serviceName) } // Derive hostname from the Ignition route's domain when an explicit hostname @@ -24,7 +24,7 @@ func (mp *metricsProxy) adaptRoute(cpContext component.WorkloadContext, route *r // explicit hostnames on service publishing strategies. Since metrics-proxy has // no strategy entry, derive from the Ignition strategy's domain. hostname := "" - ignitionStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.Ignition) + ignitionStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.Ignition) if ignitionStrategy != nil && ignitionStrategy.Route != nil && ignitionStrategy.Route.Hostname != "" { parts := strings.SplitN(ignitionStrategy.Route.Hostname, ".", 2) if len(parts) == 2 { @@ -32,8 +32,8 @@ func (mp *metricsProxy) adaptRoute(cpContext component.WorkloadContext, route *r } } - labelHCPRoutes := util.LabelHCPRoutes(hcp) - if err := util.ReconcileExternalRoute(route, hostname, mp.defaultIngressDomain, serviceName, labelHCPRoutes); err != nil { + labelHCPRoutes := netutil.LabelHCPRoutes(hcp) + if err := netutil.ReconcileExternalRoute(route, hostname, mp.defaultIngressDomain, serviceName, labelHCPRoutes); err != nil { return err } @@ -42,7 +42,7 @@ func (mp *metricsProxy) adaptRoute(cpContext component.WorkloadContext, route *r // ReconcileExternalRoute works on the manifest object (no existing label), so we mark // it for removal here to ensure preserveOriginalMetadata deletes it from the cluster object. if !labelHCPRoutes { - util.MarkHCPRouteLabelForRemoval(route) + netutil.MarkHCPRouteLabelForRemoval(route) } return nil diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/oapi/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/oapi/deployment.go index 7f3d32cf6dfe..93d817083598 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/oapi/deployment.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/oapi/deployment.go @@ -10,6 +10,7 @@ import ( "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests" "github.com/openshift/hypershift/support/config" component "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/podspec" "github.com/openshift/hypershift/support/util" @@ -45,7 +46,7 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep etcdHostname := "etcd-client" if cpContext.HCP.Spec.Etcd.ManagementType == hyperv1.Unmanaged { - etcdHostname, err = util.HostFromURL(cpContext.HCP.Spec.Etcd.Unmanaged.Endpoint) + etcdHostname, err = netutil.HostFromURL(cpContext.HCP.Spec.Etcd.Unmanaged.Endpoint) if err != nil { return err } diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/oauth_apiserver/deployment.go b/control-plane-operator/controllers/hostedcontrolplane/v2/oauth_apiserver/deployment.go index ca190ae6de29..1d25593d8373 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/oauth_apiserver/deployment.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/oauth_apiserver/deployment.go @@ -10,8 +10,8 @@ import ( "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests" "github.com/openshift/hypershift/support/config" component "github.com/openshift/hypershift/support/controlplane-component" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/podspec" - "github.com/openshift/hypershift/support/util" configv1 "github.com/openshift/api/config/v1" @@ -28,7 +28,7 @@ func adaptDeployment(cpContext component.WorkloadContext, deployment *appsv1.Dep var err error etcdHostname := "etcd-client" if cpContext.HCP.Spec.Etcd.ManagementType == hyperv1.Unmanaged { - etcdHostname, err = util.HostFromURL(cpContext.HCP.Spec.Etcd.Unmanaged.Endpoint) + etcdHostname, err = netutil.HostFromURL(cpContext.HCP.Spec.Etcd.Unmanaged.Endpoint) if err != nil { return err } diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/router/config.go b/control-plane-operator/controllers/hostedcontrolplane/v2/router/config.go index dea8a7520532..674f9021e5b4 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/router/config.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/router/config.go @@ -12,7 +12,7 @@ import ( "github.com/openshift/hypershift/support/azureutil" "github.com/openshift/hypershift/support/config" component "github.com/openshift/hypershift/support/controlplane-component" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" routev1 "github.com/openshift/api/route/v1" @@ -106,7 +106,7 @@ func generateRouterConfig(routeList *routev1.RouteList, svcsNameToIP map[string] } sort.Sort(byRouteName(routeList.Items)) for _, route := range routeList.Items { - if _, hasHCPLabel := route.Labels[util.HCPRouteLabel]; !hasHCPLabel { + if _, hasHCPLabel := route.Labels[netutil.HCPRouteLabel]; !hasHCPLabel { // If the hypershift.openshift.io/hosted-control-plane label is not present, // then it means the route should be fulfilled by the management cluster's router. continue diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/router/config_test.go b/control-plane-operator/controllers/hostedcontrolplane/v2/router/config_test.go index a8be44f373f9..11f9ba71b531 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/router/config_test.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/router/config_test.go @@ -6,8 +6,8 @@ import ( "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests" "github.com/openshift/hypershift/hypershift-operator/controllers/manifests/ignitionserver" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/testutil" - "github.com/openshift/hypershift/support/util" routev1 "github.com/openshift/api/route/v1" @@ -19,7 +19,7 @@ func TestGenerateRouterConfig(t *testing.T) { namedRoute := func(r *routev1.Route, mods ...func(*routev1.Route)) *routev1.Route { r.Labels = map[string]string{ - util.HCPRouteLabel: "test-ns-clustername", + netutil.HCPRouteLabel: "test-ns-clustername", } for _, m := range mods { m(r) diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/router/util/util.go b/control-plane-operator/controllers/hostedcontrolplane/v2/router/util/util.go index d5d97e1e88b7..0caa883956b5 100644 --- a/control-plane-operator/controllers/hostedcontrolplane/v2/router/util/util.go +++ b/control-plane-operator/controllers/hostedcontrolplane/v2/router/util/util.go @@ -3,7 +3,7 @@ package util import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/support/azureutil" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" ) // UseHCPRouter returns true when the HCP routes should be served by a dedicated @@ -21,10 +21,10 @@ func UseHCPRouter(hcp *hyperv1.HostedControlPlane) bool { // (Swift enabled). LabelHCPRoutes returns true for all ARO to support the // SharedIngressReconciler, but that doesn't mean a dedicated router deployment is needed. if azureutil.IsAroHCP() { - return util.IsPrivateHCP(hcp) + return netutil.IsPrivateHCP(hcp) } // Router infrastructure is needed when: // 1. Cluster has private access (Private or PublicAndPrivate) - for internal routes, OR // 2. External routes are labeled for HCP router (Public with KAS DNS) - return util.IsPrivateHCP(hcp) || util.LabelHCPRoutes(hcp) + return netutil.IsPrivateHCP(hcp) || netutil.LabelHCPRoutes(hcp) } diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/kas/reconcile.go b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/kas/reconcile.go index e89afafdbad8..1dbaec6cc100 100644 --- a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/kas/reconcile.go +++ b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/kas/reconcile.go @@ -1,7 +1,7 @@ package kas import ( - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" corev1 "k8s.io/api/core/v1" discoveryv1 "k8s.io/api/discovery/v1" @@ -32,7 +32,7 @@ func ReconcileKASEndpointSlice(endpointSlice *discoveryv1.EndpointSlice, address endpointSlice.Labels = map[string]string{} } endpointSlice.Labels[discoveryv1.LabelServiceName] = "kubernetes" - ipv4, err := util.IsIPv4Address(address) + ipv4, err := netutil.IsIPv4Address(address) if err != nil || ipv4 { endpointSlice.AddressType = discoveryv1.AddressTypeIPv4 } else { diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go index c6c8334b5e44..fb2957d232e5 100644 --- a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go +++ b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go @@ -49,6 +49,7 @@ import ( "github.com/openshift/hypershift/support/capabilities" "github.com/openshift/hypershift/support/config" "github.com/openshift/hypershift/support/globalconfig" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/releaseinfo" "github.com/openshift/hypershift/support/upsert" "github.com/openshift/hypershift/support/util" @@ -655,7 +656,7 @@ func (r *reconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result ovnConfig = hcp.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig } if _, err := r.CreateOrUpdate(ctx, r.client, networkOperator, func() error { - networkoperator.ReconcileNetworkOperator(networkOperator, hcp.Spec.Networking.NetworkType, hcp.Spec.Platform.Type, util.IsDisableMultiNetwork(hcp), ovnConfig) + networkoperator.ReconcileNetworkOperator(networkOperator, hcp.Spec.Networking.NetworkType, hcp.Spec.Platform.Type, netutil.IsDisableMultiNetwork(hcp), ovnConfig) return nil }); err != nil { errs = append(errs, fmt.Errorf("failed to reconcile network operator: %w", err)) @@ -1856,8 +1857,8 @@ func (r *reconciler) reconcileOpenshiftOAuthAPIServerAPIServices(ctx context.Con func (r *reconciler) reconcileKASEndpoints(ctx context.Context, hcp *hyperv1.HostedControlPlane) error { var errs []error - kasAdvertiseAddress := util.GetAdvertiseAddress(hcp, config.DefaultAdvertiseIPv4Address, config.DefaultAdvertiseIPv6Address) - kasEndpointsPort := util.KASPodPort(hcp) + kasAdvertiseAddress := netutil.GetAdvertiseAddress(hcp, config.DefaultAdvertiseIPv4Address, config.DefaultAdvertiseIPv6Address) + kasEndpointsPort := netutil.KASPodPort(hcp) // We only keep reconciling the endpoint for existing clusters that are relying on this for nodes haproxy to work. // Otherwise, changing the haproxy config to !=443 would result in a NodePool rollout which want to avoid for existing clusters. diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go index 67225afb258f..0ab2c9075a99 100644 --- a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go +++ b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources_test.go @@ -18,6 +18,7 @@ import ( "github.com/openshift/hypershift/hypershift-operator/controllers/nodepool" "github.com/openshift/hypershift/support/azureutil" "github.com/openshift/hypershift/support/globalconfig" + "github.com/openshift/hypershift/support/netutil" fakereleaseprovider "github.com/openshift/hypershift/support/releaseinfo/fake" supportutil "github.com/openshift/hypershift/support/util" "github.com/openshift/hypershift/support/util/fakeimagemetadataprovider" @@ -1525,37 +1526,37 @@ func TestReconcileKubeletConfig(t *testing.T) { { name: "copy kubelet config from control plane NS", hostedControlPlaneObjects: []client.Object{ - makeKubeletConfigConfigMap(supportutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcpNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcpNamespace, kubeletConfig1), }, expectedHostedClusterObjects: []client.Object{ - makeKubeletConfigConfigMap(supportutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), }, }, { name: "some CM already exist and some are not, expect HCCO to catch up", hostedControlPlaneObjects: []client.Object{ - makeKubeletConfigConfigMap(supportutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcpNamespace, kubeletConfig1), - makeKubeletConfigConfigMap(supportutil.ShortenName("foo", npName2, validation.LabelValueMaxLength), hcpNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcpNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("foo", npName2, validation.LabelValueMaxLength), hcpNamespace, kubeletConfig1), }, existHostedControlPlaneObjects: []client.Object{ - makeKubeletConfigConfigMap(supportutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), }, expectedHostedClusterObjects: []client.Object{ - makeKubeletConfigConfigMap(supportutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), - makeKubeletConfigConfigMap(supportutil.ShortenName("foo", npName2, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("foo", npName2, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), }, }, { name: "CM need to be deleted", hostedControlPlaneObjects: []client.Object{ - makeKubeletConfigConfigMap(supportutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcpNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcpNamespace, kubeletConfig1), }, existHostedControlPlaneObjects: []client.Object{ - makeKubeletConfigConfigMap(supportutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), - makeKubeletConfigConfigMap(supportutil.ShortenName("foo", npName2, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("foo", npName2, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), }, expectedHostedClusterObjects: []client.Object{ - makeKubeletConfigConfigMap(supportutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), + makeKubeletConfigConfigMap(netutil.ShortenName("bar", npName1, validation.LabelValueMaxLength), hcNamespace, kubeletConfig1), }, }, } diff --git a/control-plane-operator/main.go b/control-plane-operator/main.go index abf2e67a9a35..fed537fe29c6 100644 --- a/control-plane-operator/main.go +++ b/control-plane-operator/main.go @@ -38,6 +38,7 @@ import ( component "github.com/openshift/hypershift/support/controlplane-component" "github.com/openshift/hypershift/support/events" "github.com/openshift/hypershift/support/metrics" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/podspec" "github.com/openshift/hypershift/support/releaseinfo" "github.com/openshift/hypershift/support/supportedversion" @@ -525,7 +526,7 @@ func NewStartCommand() *cobra.Command { os.Exit(1) } - if hcp.Spec.Platform.Type == hyperv1.AWSPlatform && util.IsPrivateHCP(hcp) && mgmtClusterCaps.Has(capabilities.CapabilityRoute) { + if hcp.Spec.Platform.Type == hyperv1.AWSPlatform && netutil.IsPrivateHCP(hcp) && mgmtClusterCaps.Has(capabilities.CapabilityRoute) { controllerName := "PrivateKubeAPIServerServiceObserver" if err := (&awsprivatelink.PrivateServiceObserver{ Client: mgr.GetClient(), @@ -562,7 +563,7 @@ func NewStartCommand() *cobra.Command { } } - if hcp.Spec.Platform.Type == hyperv1.GCPPlatform && util.IsPrivateHCP(hcp) && mgmtClusterCaps.Has(capabilities.CapabilityRoute) { + if hcp.Spec.Platform.Type == hyperv1.GCPPlatform && netutil.IsPrivateHCP(hcp) && mgmtClusterCaps.Has(capabilities.CapabilityRoute) { observerControllerName := "GCPPrivateServiceObserver" if err = (&gcpprivateserviceconnect.GCPPrivateServiceObserver{ @@ -590,7 +591,7 @@ func NewStartCommand() *cobra.Command { } } - if hcp.Spec.Platform.Type == hyperv1.AzurePlatform && util.IsPrivateHCP(hcp) && mgmtClusterCaps.Has(capabilities.CapabilityRoute) && !azureutil.IsAroHCP() { + if hcp.Spec.Platform.Type == hyperv1.AzurePlatform && netutil.IsPrivateHCP(hcp) && mgmtClusterCaps.Has(capabilities.CapabilityRoute) && !azureutil.IsAroHCP() { if hcp.Spec.Platform.Azure == nil || hcp.Spec.Platform.Azure.Private.Type == "" { setupLog.Error(fmt.Errorf("azure platform or private connectivity is not configured"), "skipping Azure Private Link observer setup") } else { @@ -608,7 +609,7 @@ func NewStartCommand() *cobra.Command { os.Exit(1) } - if oauthStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.OAuthServer); oauthStrategy != nil && oauthStrategy.Type == hyperv1.LoadBalancer { + if oauthStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.OAuthServer); oauthStrategy != nil && oauthStrategy.Type == hyperv1.LoadBalancer { azureOAuthObserverName := "AzurePrivateLinkServiceOAuthObserver" if err = (&azureprivatelinkservice.AzurePrivateLinkServiceObserver{ diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go index 08b66c8b359b..e470abd09f56 100644 --- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go +++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go @@ -62,6 +62,7 @@ import ( "github.com/openshift/hypershift/support/globalconfig" "github.com/openshift/hypershift/support/infraid" "github.com/openshift/hypershift/support/metrics" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/oidc" "github.com/openshift/hypershift/support/podspec" "github.com/openshift/hypershift/support/releaseinfo" @@ -3847,7 +3848,7 @@ func (r *HostedClusterReconciler) validateAWSConfig(hc *hyperv1.HostedCluster) e hyperv1.OAuthServer, hyperv1.Ignition, } { - servicePublishingStrategy := hyperutil.ServicePublishingStrategyByTypeByHC(hc, serviceType) + servicePublishingStrategy := netutil.ServicePublishingStrategyByTypeByHC(hc, serviceType) if servicePublishingStrategy == nil { errs = append(errs, fmt.Errorf("service type %v not found", serviceType)) } @@ -3857,13 +3858,13 @@ func (r *HostedClusterReconciler) validateAWSConfig(hc *hyperv1.HostedCluster) e } } - kasPublishingStrategy := hyperutil.ServicePublishingStrategyByTypeByHC(hc, hyperv1.APIServer) + kasPublishingStrategy := netutil.ServicePublishingStrategyByTypeByHC(hc, hyperv1.APIServer) if kasPublishingStrategy == nil { errs = append(errs, fmt.Errorf("service type %v not found", hyperv1.APIServer)) return utilerrors.NewAggregate(errs) } - if kasPublishingStrategy.Type == hyperv1.Route && !hyperutil.UseDedicatedDNSForKASByHC(hc) { + if kasPublishingStrategy.Type == hyperv1.Route && !netutil.UseDedicatedDNSForKASByHC(hc) { errs = append(errs, fmt.Errorf("if serviceType is 'APIServer' and publishing strategy is 'Route', then hostname must be set")) return utilerrors.NewAggregate(errs) } @@ -3873,7 +3874,7 @@ func (r *HostedClusterReconciler) validateAWSConfig(hc *hyperv1.HostedCluster) e errs = append(errs, fmt.Errorf("service type %v with publishing strategy %v is not supported, use Route", hyperv1.APIServer, kasPublishingStrategy.Type)) } } else { - if !hyperutil.UseDedicatedDNSForKASByHC(hc) && kasPublishingStrategy.Type != hyperv1.LoadBalancer { + if !netutil.UseDedicatedDNSForKASByHC(hc) && kasPublishingStrategy.Type != hyperv1.LoadBalancer { errs = append(errs, fmt.Errorf("service type %v with publishing strategy %v is not supported, use Route or LoadBalancer", hyperv1.APIServer, kasPublishingStrategy.Type)) } } diff --git a/hypershift-operator/controllers/hostedcluster/network_policies.go b/hypershift-operator/controllers/hostedcluster/network_policies.go index 54c53809fa04..0ed3c8411599 100644 --- a/hypershift-operator/controllers/hostedcluster/network_policies.go +++ b/hypershift-operator/controllers/hostedcluster/network_policies.go @@ -15,6 +15,7 @@ import ( "github.com/openshift/hypershift/support/awsutil" "github.com/openshift/hypershift/support/capabilities" "github.com/openshift/hypershift/support/config" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/rhobsmonitoring" "github.com/openshift/hypershift/support/upsert" hyperutil "github.com/openshift/hypershift/support/util" @@ -47,7 +48,7 @@ func (r *HostedClusterReconciler) reconcileNetworkPolicies(ctx context.Context, // Only needed when routes are served by the management cluster's default ingress controller, // i.e., when routes are NOT labeled for the HCP router. policy := networkpolicy.OpenshiftIngressNetworkPolicy(controlPlaneNamespaceName) - if !hyperutil.LabelHCPRoutes(hcp) { + if !netutil.LabelHCPRoutes(hcp) { if _, err := createOrUpdate(ctx, r.Client, policy, func() error { return reconcileOpenshiftIngressNetworkPolicy(policy) }); err != nil { diff --git a/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy.go b/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy.go index b7e2c32a0073..c68b1e2919db 100644 --- a/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy.go +++ b/hypershift-operator/controllers/nodepool/apiserver-haproxy/haproxy.go @@ -18,6 +18,7 @@ import ( sharedingress "github.com/openshift/hypershift/hypershift-operator/controllers/sharedingress" api "github.com/openshift/hypershift/support/api" "github.com/openshift/hypershift/support/config" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/releaseinfo" "github.com/openshift/hypershift/support/util" @@ -82,9 +83,9 @@ func (r *HAProxy) reconcileHAProxyIgnitionConfig(ctx context.Context, hcluster * var apiServerExternalPort int32 var apiServerInternalAddress string - if util.IsPrivateHC(hcluster) { + if netutil.IsPrivateHC(hcluster) { apiServerExternalAddress = fmt.Sprintf("api.%s.hypershift.local", hcluster.Name) - apiServerExternalPort = util.APIPortForLocalZone(util.IsLBKASByHC(hcluster)) + apiServerExternalPort = netutil.APIPortForLocalZone(netutil.IsLBKASByHC(hcluster)) } else { if hcluster.Status.KubeConfig == nil { return "", fmt.Errorf("waiting on hcluster.Status.KubeConfig to be set") @@ -113,7 +114,7 @@ func (r *HAProxy) reconcileHAProxyIgnitionConfig(ctx context.Context, hcluster * } // This provides support for HTTP Proxy on IPv6 scenarios - ipv4, err := util.IsIPv4CIDR(hcluster.Spec.Networking.ServiceNetwork[0].CIDR.String()) + ipv4, err := netutil.IsIPv4CIDR(hcluster.Spec.Networking.ServiceNetwork[0].CIDR.String()) if err != nil { return "", fmt.Errorf("error checking the stack in the first ServiceNetworkCIDR %s: %w", hcluster.Spec.Networking.ServiceNetwork[0].CIDR.String(), err) } @@ -135,7 +136,7 @@ func (r *HAProxy) reconcileHAProxyIgnitionConfig(ctx context.Context, hcluster * } var apiserverProxy string var noProxy string - if hcluster.Spec.Configuration != nil && hcluster.Spec.Configuration.Proxy != nil && hcluster.Spec.Configuration.Proxy.HTTPSProxy != "" && util.ConnectsThroughInternetToControlplane(hcluster.Spec.Platform) { + if hcluster.Spec.Configuration != nil && hcluster.Spec.Configuration.Proxy != nil && hcluster.Spec.Configuration.Proxy.HTTPSProxy != "" && netutil.ConnectsThroughInternetToControlplane(hcluster.Spec.Platform) { apiserverProxy, err = joinDefaultPortIfMissing(hcluster.Spec.Configuration.Proxy.HTTPSProxy) if err != nil { return "", fmt.Errorf("failed to parse .Spec.Configuration.Proxy.HTTPSProxy: %v", err) @@ -156,7 +157,7 @@ func (r *HAProxy) reconcileHAProxyIgnitionConfig(ctx context.Context, hcluster * } // This is true for ARO in CI while swift is not available. - if sharedingress.UseSharedIngress() && !util.IsPrivateHC(hcluster) { + if sharedingress.UseSharedIngress() && !netutil.IsPrivateHC(hcluster) { sharedIngressRouteSVC := &corev1.Service{ TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ @@ -174,7 +175,7 @@ func (r *HAProxy) reconcileHAProxyIgnitionConfig(ctx context.Context, hcluster * apiServerExternalPort = sharedingress.KASSVCLBPort } - useProxyProtocol := sharedingress.UseSharedIngress() && !util.IsPrivateHC(hcluster) + useProxyProtocol := sharedingress.UseSharedIngress() && !netutil.IsPrivateHC(hcluster) serializedConfig, err := apiServerProxyConfig(r.HAProxyImage, controlPlaneOperatorImage, hcluster.Spec.ClusterID, apiServerExternalAddress, apiServerInternalAddress, apiServerExternalPort, apiServerInternalPort, diff --git a/hypershift-operator/controllers/nodepool/manifests.go b/hypershift-operator/controllers/nodepool/manifests.go index 6fbfd74041b1..f61d2685022c 100644 --- a/hypershift-operator/controllers/nodepool/manifests.go +++ b/hypershift-operator/controllers/nodepool/manifests.go @@ -3,7 +3,7 @@ package nodepool import ( "fmt" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -31,7 +31,7 @@ func PerformanceProfileConfigMap(namespace, name, nodePoolName string) *corev1.C return &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: namespace, - Name: util.ShortenName(name, nodePoolName, QualifiedNameMaxLength), + Name: netutil.ShortenName(name, nodePoolName, QualifiedNameMaxLength), }, } } diff --git a/hypershift-operator/controllers/nodepool/nto.go b/hypershift-operator/controllers/nodepool/nto.go index 1b1c4945915d..3b175c8acc7e 100644 --- a/hypershift-operator/controllers/nodepool/nto.go +++ b/hypershift-operator/controllers/nodepool/nto.go @@ -13,6 +13,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/support/backwardcompat" + "github.com/openshift/hypershift/support/netutil" supportutil "github.com/openshift/hypershift/support/util" configv1 "github.com/openshift/api/config/v1" @@ -62,7 +63,7 @@ func (r *NodePoolReconciler) reconcileMirroredConfigs(ctx context.Context, logr want := set.Set[string]{} for _, mirroredConfig := range mirroredConfigs { - want.Insert(supportutil.ShortenName(mirroredConfig.Name, nodePool.Name, validation.LabelValueMaxLength)) + want.Insert(netutil.ShortenName(mirroredConfig.Name, nodePool.Name, validation.LabelValueMaxLength)) } have := set.Set[string]{} for _, configMap := range existingConfigsList.Items { @@ -112,7 +113,7 @@ func (r *NodePoolReconciler) reconcileMirroredConfigs(ctx context.Context, logr for _, mirroredConfig := range mirroredConfigs { cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: supportutil.ShortenName(mirroredConfig.Name, nodePool.Name, validation.LabelValueMaxLength), + Name: netutil.ShortenName(mirroredConfig.Name, nodePool.Name, validation.LabelValueMaxLength), Namespace: controlPlaneNamespace}, } if result, err := r.CreateOrUpdate(ctx, r.Client, cm, func() error { diff --git a/hypershift-operator/controllers/nodepool/nto_test.go b/hypershift-operator/controllers/nodepool/nto_test.go index 16cc409fa5e5..c277bf72529c 100644 --- a/hypershift-operator/controllers/nodepool/nto_test.go +++ b/hypershift-operator/controllers/nodepool/nto_test.go @@ -6,8 +6,8 @@ import ( . "github.com/onsi/gomega" hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/upsert" - supportutil "github.com/openshift/hypershift/support/util" performanceprofilev2 "github.com/openshift/cluster-node-tuning-operator/pkg/apis/performanceprofile/v2" crconditionsv1 "github.com/openshift/custom-resource-status/conditions/v1" @@ -555,7 +555,7 @@ func TestReconcileMirroredConfigs(t *testing.T) { { Immutable: ptr.To(true), ObjectMeta: metav1.ObjectMeta{ - Name: supportutil.ShortenName("foo", npName, validation.LabelValueMaxLength), + Name: netutil.ShortenName("foo", npName, validation.LabelValueMaxLength), Namespace: hcpNamespace, Labels: map[string]string{ NTOMirroredConfigLabel: "true", @@ -604,7 +604,7 @@ func TestReconcileMirroredConfigs(t *testing.T) { { Immutable: ptr.To(true), ObjectMeta: metav1.ObjectMeta{ - Name: supportutil.ShortenName("foo", npName, validation.LabelValueMaxLength), + Name: netutil.ShortenName("foo", npName, validation.LabelValueMaxLength), Namespace: hcpNamespace, Labels: map[string]string{ NTOMirroredConfigLabel: "true", @@ -620,7 +620,7 @@ func TestReconcileMirroredConfigs(t *testing.T) { configsForDeletion: []corev1.ConfigMap{ { ObjectMeta: metav1.ObjectMeta{ - Name: supportutil.ShortenName("bar", npName, validation.LabelValueMaxLength), + Name: netutil.ShortenName("bar", npName, validation.LabelValueMaxLength), Namespace: hcpNamespace, }, Data: map[string]string{ @@ -654,7 +654,7 @@ func TestReconcileMirroredConfigs(t *testing.T) { { Immutable: ptr.To(true), ObjectMeta: metav1.ObjectMeta{ - Name: supportutil.ShortenName("bar", npName, validation.LabelValueMaxLength), + Name: netutil.ShortenName("bar", npName, validation.LabelValueMaxLength), Namespace: hcpNamespace, Labels: map[string]string{ NTOMirroredConfigLabel: "true", @@ -692,7 +692,7 @@ func TestReconcileMirroredConfigs(t *testing.T) { &corev1.ConfigMap{ Immutable: ptr.To(true), ObjectMeta: metav1.ObjectMeta{ - Name: supportutil.ShortenName("bar-2", npName, validation.LabelValueMaxLength), + Name: netutil.ShortenName("bar-2", npName, validation.LabelValueMaxLength), Namespace: hcpNamespace, Labels: map[string]string{ nodeTuningGeneratedConfigLabel: "true", diff --git a/hypershift-operator/controllers/sharedingress/sharedingress_controller.go b/hypershift-operator/controllers/sharedingress/sharedingress_controller.go index dd0050b4b0b5..08a4dac9b0af 100644 --- a/hypershift-operator/controllers/sharedingress/sharedingress_controller.go +++ b/hypershift-operator/controllers/sharedingress/sharedingress_controller.go @@ -13,6 +13,7 @@ import ( "github.com/openshift/hypershift/support/azureutil" "github.com/openshift/hypershift/support/capabilities" supportconfig "github.com/openshift/hypershift/support/config" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/upsert" "github.com/openshift/hypershift/support/util" @@ -123,7 +124,7 @@ func (r *SharedIngressReconciler) SetupWithManager(mgr ctrl.Manager, createOrUpd Watches( &routev1.Route{}, handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []ctrl.Request { - if _, hasHCPLabel := obj.GetLabels()[util.HCPRouteLabel]; !hasHCPLabel { + if _, hasHCPLabel := obj.GetLabels()[netutil.HCPRouteLabel]; !hasHCPLabel { return nil } return []ctrl.Request{{NamespacedName: client.ObjectKey{ @@ -219,7 +220,7 @@ func (r *SharedIngressReconciler) reconcileRouter(ctx context.Context, pullSecre routeList := &routev1.RouteList{} // If the hypershift.openshift.io/hosted-control-plane label is not present, // then it means the route should be fulfilled by the management cluster's router. - if err := r.Client.List(ctx, routeList, client.HasLabels{util.HCPRouteLabel}); err != nil { + if err := r.Client.List(ctx, routeList, client.HasLabels{netutil.HCPRouteLabel}); err != nil { return fmt.Errorf("failed to list routes: %w", err) } @@ -386,7 +387,7 @@ func UseSharedIngress() bool { } func KasRouteHostname(hcp *hyperv1.HostedControlPlane) string { - kasPublishStrategy := util.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) + kasPublishStrategy := netutil.ServicePublishingStrategyByTypeForHCP(hcp, hyperv1.APIServer) if kasPublishStrategy.Route == nil { return "" } diff --git a/hypershift-operator/main.go b/hypershift-operator/main.go index 77bafec522f9..2e3a13d88170 100644 --- a/hypershift-operator/main.go +++ b/hypershift-operator/main.go @@ -56,9 +56,9 @@ import ( "github.com/openshift/hypershift/support/config" "github.com/openshift/hypershift/support/globalconfig" "github.com/openshift/hypershift/support/metrics" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/supportedversion" "github.com/openshift/hypershift/support/upsert" - hyperutil "github.com/openshift/hypershift/support/util" operatorv1 "github.com/openshift/api/operator/v1" configv1 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1" @@ -752,14 +752,14 @@ func run(ctx context.Context, opts *StartOptions, log logr.Logger) error { ic.Spec.RouteSelector.MatchExpressions = []metav1.LabelSelectorRequirement{} } for i, requirement := range ic.Spec.RouteSelector.MatchExpressions { - if requirement.Key != hyperutil.HCPRouteLabel { + if requirement.Key != netutil.HCPRouteLabel { continue } ic.Spec.RouteSelector.MatchExpressions[i].Operator = metav1.LabelSelectorOpDoesNotExist return nil } ic.Spec.RouteSelector.MatchExpressions = append(ic.Spec.RouteSelector.MatchExpressions, metav1.LabelSelectorRequirement{ - Key: hyperutil.HCPRouteLabel, + Key: netutil.HCPRouteLabel, Operator: metav1.LabelSelectorOpDoesNotExist, }) return nil diff --git a/konnectivity-https-proxy/cmd.go b/konnectivity-https-proxy/cmd.go index 11a798bee734..dbdb62485294 100644 --- a/konnectivity-https-proxy/cmd.go +++ b/konnectivity-https-proxy/cmd.go @@ -10,8 +10,8 @@ import ( "os" "github.com/openshift/hypershift/support/konnectivityproxy" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/supportedversion" - "github.com/openshift/hypershift/support/util" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" @@ -190,7 +190,7 @@ func dialThroughProxyFunc(httpProxy *goproxy.ProxyHttpServer, proxyURL string, p func shouldDialDirectFunc(connectDirectlyToCloudAPIs bool, isCloudAPI func(string) bool, userProxyFunc func(*url.URL) (*url.URL, error)) func(*url.URL) (bool, error) { return func(u *url.URL) (bool, error) { if connectDirectlyToCloudAPIs { - hostName, err := util.HostFromURL(u.String()) + hostName, err := netutil.HostFromURL(u.String()) if err != nil { return false, err } diff --git a/sharedingress-config-generator/config.go b/sharedingress-config-generator/config.go index bf79a48b289a..6810c004e99e 100644 --- a/sharedingress-config-generator/config.go +++ b/sharedingress-config-generator/config.go @@ -13,7 +13,7 @@ import ( "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/manifests" "github.com/openshift/hypershift/hypershift-operator/controllers/manifests/ignitionserver" "github.com/openshift/hypershift/support/config" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" routev1 "github.com/openshift/api/route/v1" @@ -123,7 +123,7 @@ func getBackendsForHostedCluster(ctx context.Context, hc hyperv1.HostedCluster, } // When is private (ARO with Swift), we don't need to create a backend for the dataplane-kas-svc frontend. - if !util.IsPrivateHC(&hc) { + if !netutil.IsPrivateHC(&hc) { backends = append(backends, backendDesc{ Name: kasService.Namespace + "-" + kasService.Name, SVCIP: kasService.Spec.ClusterIP, @@ -135,7 +135,7 @@ func getBackendsForHostedCluster(ctx context.Context, hc hyperv1.HostedCluster, // This enables traffic from external DNS to exposed endpoints (KAS, oauth, ignition and konnectivity). routeList := &routev1.RouteList{} - if err := client.List(ctx, routeList, crclient.InNamespace(hcpNamespace), crclient.HasLabels{util.HCPRouteLabel}); err != nil { + if err := client.List(ctx, routeList, crclient.InNamespace(hcpNamespace), crclient.HasLabels{netutil.HCPRouteLabel}); err != nil { return nil, nil, fmt.Errorf("failed to list routes: %w", err) } diff --git a/sharedingress-config-generator/config_test.go b/sharedingress-config-generator/config_test.go index 512cdc1f61f4..53bd460f05cd 100644 --- a/sharedingress-config-generator/config_test.go +++ b/sharedingress-config-generator/config_test.go @@ -12,8 +12,8 @@ import ( "github.com/openshift/hypershift/hypershift-operator/controllers/manifests/ignitionserver" api "github.com/openshift/hypershift/support/api" "github.com/openshift/hypershift/support/azureutil" + "github.com/openshift/hypershift/support/netutil" testutil "github.com/openshift/hypershift/support/testutil" - "github.com/openshift/hypershift/support/util" routev1 "github.com/openshift/api/route/v1" @@ -28,7 +28,7 @@ func TestGenerateConfig(t *testing.T) { // Library to create Routes and SVCs. namedRoute := func(r *routev1.Route, mods ...func(*routev1.Route)) *routev1.Route { r.Labels = map[string]string{ - util.HCPRouteLabel: "test-ns-clustername", + netutil.HCPRouteLabel: "test-ns-clustername", } for _, m := range mods { m(r) diff --git a/sharedingress-config-generator/controller.go b/sharedingress-config-generator/controller.go index 715626dc51b6..4d3f8ea61e49 100644 --- a/sharedingress-config-generator/controller.go +++ b/sharedingress-config-generator/controller.go @@ -12,7 +12,7 @@ import ( "time" hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" routev1 "github.com/openshift/api/route/v1" @@ -69,7 +69,7 @@ func (r *SharedIngressConfigReconciler) SetupWithManager(mgr ctrl.Manager) error Watches( &routev1.Route{}, handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []ctrl.Request { - if _, hasHCPLabel := obj.GetLabels()[util.HCPRouteLabel]; !hasHCPLabel { + if _, hasHCPLabel := obj.GetLabels()[netutil.HCPRouteLabel]; !hasHCPLabel { return nil } return []ctrl.Request{{NamespacedName: client.ObjectKey{ diff --git a/support/conditions/conditions.go b/support/conditions/conditions.go index 2d13f01bed8f..fa95a2fdc14e 100644 --- a/support/conditions/conditions.go +++ b/support/conditions/conditions.go @@ -2,7 +2,7 @@ package conditions import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" - support "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" @@ -97,7 +97,7 @@ func ExpectedHCConditions(hostedCluster *hyperv1.HostedCluster) map[hyperv1.Cond conditions[hyperv1.UnmanagedEtcdAvailable] = metav1.ConditionTrue } - kasExternalHostname := support.ServiceExternalDNSHostnameByHC(hostedCluster, hyperv1.APIServer) + kasExternalHostname := netutil.ServiceExternalDNSHostnameByHC(hostedCluster, hyperv1.APIServer) if kasExternalHostname == "" { // ExternalDNS is not configured conditions[hyperv1.ExternalDNSReachable] = metav1.ConditionUnknown diff --git a/support/globalconfig/infrastructure.go b/support/globalconfig/infrastructure.go index 3d2b92cb8d08..7c892d7e5f76 100644 --- a/support/globalconfig/infrastructure.go +++ b/support/globalconfig/infrastructure.go @@ -6,7 +6,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/control-plane-operator/controllers/hostedcontrolplane/cloud/openstack" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" configv1 "github.com/openshift/api/config/v1" @@ -31,7 +31,7 @@ func ReconcileInfrastructure(infra *configv1.Infrastructure, hcp *hyperv1.Hosted infra.Spec.PlatformSpec.Type = configv1.PlatformType(platformType) infra.Status.APIServerInternalURL = fmt.Sprintf("https://%s:%d", apiServerAddress, apiServerPort) - if util.IsPrivateHCP(hcp) { + if netutil.IsPrivateHCP(hcp) { infra.Status.APIServerInternalURL = fmt.Sprintf("https://api.%s.hypershift.local:%d", hcp.Name, apiServerPort) } diff --git a/support/globalconfig/installconfig.go b/support/globalconfig/installconfig.go index 943a9b5632bc..d1efea4cbd2f 100644 --- a/support/globalconfig/installconfig.go +++ b/support/globalconfig/installconfig.go @@ -6,7 +6,7 @@ import ( "text/template" hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" ) // Abbreviated version of the installer's InstallConfig type @@ -20,7 +20,7 @@ type InstallConfig struct { func NewInstallConfig(hcp *hyperv1.HostedControlPlane) *InstallConfig { cfg := &InstallConfig{ - MachineCIDRs: util.MachineCIDRs(hcp.Spec.Networking.MachineNetwork), + MachineCIDRs: netutil.MachineCIDRs(hcp.Spec.Networking.MachineNetwork), Platform: string(hcp.Spec.Platform.Type), } switch hcp.Spec.Platform.Type { diff --git a/support/globalconfig/network.go b/support/globalconfig/network.go index c90a1d6a2d69..7de0940021d8 100644 --- a/support/globalconfig/network.go +++ b/support/globalconfig/network.go @@ -4,7 +4,7 @@ import ( "fmt" hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" configv1 "github.com/openshift/api/config/v1" @@ -33,7 +33,7 @@ func ReconcileNetworkConfig(cfg *configv1.Network, hcp *hyperv1.HostedControlPla for _, entry := range hcp.Spec.Networking.ClusterNetwork { hostPrefix := uint32(entry.HostPrefix) if hostPrefix == 0 { - ipv4, err := util.IsIPv4CIDR(entry.CIDR.String()) + ipv4, err := netutil.IsIPv4CIDR(entry.CIDR.String()) if err != nil { return fmt.Errorf("the CIDR %s included in the cluster network spec is not valid: %w", entry.CIDR.String(), err) } @@ -51,7 +51,7 @@ func ReconcileNetworkConfig(cfg *configv1.Network, hcp *hyperv1.HostedControlPla } cfg.Spec.ClusterNetwork = clusterNetwork cfg.Spec.NetworkType = string(hcp.Spec.Networking.NetworkType) - cfg.Spec.ServiceNetwork = util.ServiceCIDRs(hcp.Spec.Networking.ServiceNetwork) + cfg.Spec.ServiceNetwork = netutil.ServiceCIDRs(hcp.Spec.Networking.ServiceNetwork) if hcp.Spec.Configuration != nil && hcp.Spec.Configuration.Network != nil { cfg.Spec.ExternalIP = hcp.Spec.Configuration.Network.ExternalIP cfg.Spec.ServiceNodePortRange = hcp.Spec.Configuration.Network.ServiceNodePortRange diff --git a/support/util/expose.go b/support/netutil/expose.go similarity index 99% rename from support/util/expose.go rename to support/netutil/expose.go index 485fae4c7c93..4b95639933f8 100644 --- a/support/util/expose.go +++ b/support/netutil/expose.go @@ -1,4 +1,4 @@ -package util +package netutil import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" diff --git a/support/util/expose_test.go b/support/netutil/expose_test.go similarity index 99% rename from support/util/expose_test.go rename to support/netutil/expose_test.go index 090a26a31b56..e60b7f0e66c9 100644 --- a/support/util/expose_test.go +++ b/support/netutil/expose_test.go @@ -1,4 +1,4 @@ -package util +package netutil import ( "testing" diff --git a/support/netutil/iputil.go b/support/netutil/iputil.go new file mode 100644 index 000000000000..6545e32270a2 --- /dev/null +++ b/support/netutil/iputil.go @@ -0,0 +1,86 @@ +package netutil + +import ( + "context" + "fmt" + "net" + "net/url" + "regexp" + "time" +) + +// IsIPv4CIDR checks if the input string is an IPv4 CIDR. +func IsIPv4CIDR(input string) (bool, error) { + _, ipnet, err := net.ParseCIDR(input) + if err != nil { + return false, fmt.Errorf("error parsing input '%s': not a valid CIDR", input) + } + if ipnet.IP.To4() != nil { + return true, nil + } + return false, nil +} + +// IsIPv4Address checks if the input string is an IPv4 address. +func IsIPv4Address(input string) (bool, error) { + ip := net.ParseIP(input) + if ip == nil { + return false, fmt.Errorf("error parsing input '%s': not a valid IP address", input) + } + if ip.To4() != nil { + return true, nil + } + return false, nil +} + +// FirstUsableIP returns the first usable IP in both, IPv4 and IPv6 stacks. +func FirstUsableIP(cidr string) (string, error) { + _, ipNet, err := net.ParseCIDR(cidr) + if err != nil { + return "", fmt.Errorf("error validating the incoming CIDR %s: %w", cidr, err) + } + ip := ipNet.IP + ip[len(ipNet.IP)-1]++ + return ip.String(), nil +} + +// ResolveDNSHostname receives a hostname string and tries to resolve it. +// Returns error if the host can't be resolved. +func ResolveDNSHostname(ctx context.Context, hostName string) error { + timeoutCtx, cancel := context.WithTimeout(ctx, time.Second) + defer cancel() + + ips, err := net.DefaultResolver.LookupIPAddr(timeoutCtx, hostName) + if err == nil && len(ips) == 0 { + err = fmt.Errorf("couldn't resolve %s", hostName) + } + + return err +} + +var ( + hasPortRegex = regexp.MustCompile(`:\d{1,5}$`) +) + +func HostFromURL(addr string) (string, error) { + parsedURL, err := url.Parse(addr) + if err != nil { + return "", fmt.Errorf("failed to parse URL(%s): %w", addr, err) + } + hostPort := parsedURL.Host + if hostPort == "" { + return "", fmt.Errorf("missing host/port name in URL(%s)", addr) + } + if !hasPortRegex.MatchString(hostPort) { + return hostPort, nil + } + hostName, _, err := net.SplitHostPort(hostPort) + if err != nil { + return "", fmt.Errorf("failed to split host/port from (%s): %w", hostPort, err) + } + if hostName == "" { + return "", fmt.Errorf("missing host name in URL(%s)", addr) + } + return hostName, nil + +} diff --git a/support/netutil/iputil_test.go b/support/netutil/iputil_test.go new file mode 100644 index 000000000000..601a70ca3e21 --- /dev/null +++ b/support/netutil/iputil_test.go @@ -0,0 +1,164 @@ +package netutil + +import ( + "testing" + + . "github.com/onsi/gomega" +) + +func TestFirstUsableIP(t *testing.T) { + tests := []struct { + name string + cidr string + want string + wantErr bool + }{ + { + name: "Given IPv4 CIDR, it should return the first ip of the network range", + cidr: "192.168.1.0/24", + want: "192.168.1.1", + wantErr: false, + }, + { + name: "Given IPv6 CIDR, it should return the first ip of the network range", + cidr: "2000::/3", + want: "2000::1", + wantErr: false, + }, + { + name: "Given a malformed IPv4 CIDR, it should return empty string and err", + cidr: "192.168.1.35.53/24", + want: "", + wantErr: true, + }, + { + name: "Given a malformed IPv6 CIDR, it should return empty string and err", + cidr: "2001::44444444444444/17", + want: "", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := FirstUsableIP(tt.cidr) + if (err != nil) != tt.wantErr { + t.Errorf("FirstUsableIP() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("FirstUsableIP() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestIsIPv4CIDR(t *testing.T) { + tests := []struct { + input string + expected bool + expectError bool + }{ + // Valid IPv4 CIDRs + {"192.168.1.0/24", true, false}, + {"10.0.0.0/8", true, false}, + + // Valid IPv6 CIDRs + {"2001:db8::/32", false, false}, + {"fd00::/8", false, false}, + + // Invalid inputs + {"invalid", false, true}, + {"192.168.1.1/33", false, true}, // Invalid CIDR prefix + {"", false, true}, // Empty input + {"1234::5678::/64", false, true}, // Malformed IP + + // Edge cases + {"0.0.0.0/0", true, false}, + {"255.255.255.255/32", true, false}, + } + + for _, test := range tests { + t.Run(test.input, func(t *testing.T) { + g := NewWithT(t) + result, err := IsIPv4CIDR(test.input) + if test.expectError { + g.Expect(err).To(HaveOccurred(), "Expected an error for input '%s'", test.input) + } else { + g.Expect(err).ToNot(HaveOccurred(), "Did not expect an error for input '%s'", test.input) + } + + g.Expect(result).To(Equal(test.expected), "Unexpected result for input '%s'", test.input) + }) + } +} + +func TestIsIPv4Address(t *testing.T) { + tests := []struct { + input string + expected bool + expectError bool + }{ + // Valid IPv4 addresses + {"192.168.1.1", true, false}, + {"10.0.0.1", true, false}, + + // Valid IPv6 addresses + {"2001:db8::1", false, false}, + {"fd00::1", false, false}, + + // Invalid inputs + {"invalid", false, true}, + {"192.168.1.256", false, true}, // Invalid IPv4 address + {"", false, true}, // Empty input + {"1234::5678::1", false, true}, // Malformed IP + + // Edge cases + {"0.0.0.0", true, false}, + {"255.255.255.255", true, false}, + } + + for _, test := range tests { + t.Run(test.input, func(t *testing.T) { + g := NewWithT(t) + result, err := IsIPv4Address(test.input) + if test.expectError { + g.Expect(err).To(HaveOccurred(), "Expected an error for input '%s'", test.input) + } else { + g.Expect(err).ToNot(HaveOccurred(), "Did not expect an error for input '%s'", test.input) + } + + g.Expect(result).To(Equal(test.expected), "Unexpected result for input '%s'", test.input) + }) + } +} + +func TestHostFromURL(t *testing.T) { + tests := []struct { + input string + expected string + wantErr bool + }{ + {"http://example.com", "example.com", false}, + {"https://example.com:443", "example.com", false}, + {"http://localhost:8080", "localhost", false}, + {"https://127.0.0.1:9000", "127.0.0.1", false}, + {"ftp://example.org:21", "example.org", false}, + {"http://[::1]:8080", "::1", false}, // IPv6 localhost + {"http://[2001:db8::1]:443", "2001:db8::1", false}, // IPv6 example + {"??", "", true}, // Invalid URL + {"http://:8080", "", true}, // Missing hostname + } + + for _, tt := range tests { + t.Run(tt.input, func(t *testing.T) { + g := NewWithT(t) + result, err := HostFromURL(tt.input) + if tt.wantErr { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).ToNot(HaveOccurred()) + } + g.Expect(result).To(Equal(tt.expected)) + }) + } +} diff --git a/support/util/networking.go b/support/netutil/networking.go similarity index 99% rename from support/util/networking.go rename to support/netutil/networking.go index 5629c351c8cc..00466a1a614a 100644 --- a/support/util/networking.go +++ b/support/netutil/networking.go @@ -1,4 +1,4 @@ -package util +package netutil import ( "strings" diff --git a/support/util/networking_test.go b/support/netutil/networking_test.go similarity index 99% rename from support/util/networking_test.go rename to support/netutil/networking_test.go index a0dba08231e3..7061b1212dc8 100644 --- a/support/util/networking_test.go +++ b/support/netutil/networking_test.go @@ -1,4 +1,4 @@ -package util +package netutil import ( "reflect" diff --git a/support/util/public.go b/support/netutil/public.go similarity index 97% rename from support/util/public.go rename to support/netutil/public.go index c6fedbb97491..ba2b3e3af67e 100644 --- a/support/util/public.go +++ b/support/netutil/public.go @@ -1,4 +1,4 @@ -package util +package netutil import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" diff --git a/support/util/public_test.go b/support/netutil/public_test.go similarity index 99% rename from support/util/public_test.go rename to support/netutil/public_test.go index 5627afd4c781..8de104b33a18 100644 --- a/support/util/public_test.go +++ b/support/netutil/public_test.go @@ -1,4 +1,4 @@ -package util +package netutil import ( "testing" diff --git a/support/util/route.go b/support/netutil/route.go similarity index 99% rename from support/util/route.go rename to support/netutil/route.go index 541858ac98b7..880a231dc8dd 100644 --- a/support/util/route.go +++ b/support/netutil/route.go @@ -1,4 +1,4 @@ -package util +package netutil import ( "fmt" diff --git a/support/util/route_test.go b/support/netutil/route_test.go similarity index 99% rename from support/util/route_test.go rename to support/netutil/route_test.go index ff9d4f7c4220..950407efa9a2 100644 --- a/support/util/route_test.go +++ b/support/netutil/route_test.go @@ -1,4 +1,4 @@ -package util +package netutil import ( "fmt" diff --git a/support/util/visibility.go b/support/netutil/visibility.go similarity index 99% rename from support/util/visibility.go rename to support/netutil/visibility.go index c19b3e20cec7..ddaa41ef3377 100644 --- a/support/util/visibility.go +++ b/support/netutil/visibility.go @@ -1,4 +1,4 @@ -package util +package netutil import ( "os" diff --git a/support/util/visibility_test.go b/support/netutil/visibility_test.go similarity index 99% rename from support/util/visibility_test.go rename to support/netutil/visibility_test.go index 52fab5967c20..1ae90a60d70b 100644 --- a/support/util/visibility_test.go +++ b/support/netutil/visibility_test.go @@ -1,4 +1,4 @@ -package util +package netutil import ( "testing" diff --git a/support/pki/kas.go b/support/pki/kas.go index 0001bbf4969d..23253d80fd40 100644 --- a/support/pki/kas.go +++ b/support/pki/kas.go @@ -5,14 +5,14 @@ import ( "fmt" "net" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" ) func GetKASServerCertificatesSANs(externalAPIAddress, internalAPIAddress string, serviceCIDRs []string, nodeInternalAPIServerIP string) ([]string, []string, error) { svcAddresses := make([]string, 0) for _, serviceCIDR := range serviceCIDRs { - serviceIP, err := util.FirstUsableIP(serviceCIDR) + serviceIP, err := netutil.FirstUsableIP(serviceCIDR) if err != nil { return nil, nil, fmt.Errorf("cannot get the first usable IP from CIDR %s: %w", serviceIP, err) } diff --git a/support/upsert/apply.go b/support/upsert/apply.go index d356f0906f08..99c8b1d86423 100644 --- a/support/upsert/apply.go +++ b/support/upsert/apply.go @@ -5,6 +5,7 @@ import ( "fmt" "maps" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/util" appsv1 "k8s.io/api/apps/v1" @@ -179,7 +180,7 @@ func cleanupRemovalMarkers(obj crclient.Object) { } filteredLabels := make(map[string]string) for k, v := range labels { - if v != util.RemoveLabelMarker { + if v != netutil.RemoveLabelMarker { filteredLabels[k] = v } } @@ -198,7 +199,7 @@ func preserveOriginalMetadata(original, mutated crclient.Object) { // Process mutated labels: add/update new labels, remove labels marked with RemoveLabelMarker for k, v := range mutated.GetLabels() { - if v == util.RemoveLabelMarker { + if v == netutil.RemoveLabelMarker { delete(labels, k) } else { labels[k] = v diff --git a/support/upsert/apply_test.go b/support/upsert/apply_test.go index a9d0e406bb9a..e3a5b54940a1 100644 --- a/support/upsert/apply_test.go +++ b/support/upsert/apply_test.go @@ -5,7 +5,7 @@ import ( "time" "github.com/openshift/hypershift/support/api" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" routev1 "github.com/openshift/api/route/v1" @@ -106,8 +106,8 @@ func TestApplyManifestLabelRemoval(t *testing.T) { Name: routeName, Namespace: namespace, Labels: map[string]string{ - util.HCPRouteLabel: namespace, - "other-label": "keep-me", + netutil.HCPRouteLabel: namespace, + "other-label": "keep-me", }, }, Spec: routev1.RouteSpec{ @@ -126,8 +126,8 @@ func TestApplyManifestLabelRemoval(t *testing.T) { Name: routeName, Namespace: namespace, Labels: map[string]string{ - util.HCPRouteLabel: util.RemoveLabelMarker, // Mark for removal - "other-label": "keep-me", // Keep this label + netutil.HCPRouteLabel: netutil.RemoveLabelMarker, // Mark for removal + "other-label": "keep-me", // Keep this label }, }, Spec: routev1.RouteSpec{ @@ -162,7 +162,7 @@ func TestApplyManifestLabelRemoval(t *testing.T) { } // HCPRouteLabel should be removed - if _, exists := updatedRoute.Labels[util.HCPRouteLabel]; exists { + if _, exists := updatedRoute.Labels[netutil.HCPRouteLabel]; exists { t.Errorf("expected HCPRouteLabel to be removed, but it still exists") } @@ -191,7 +191,7 @@ func TestApplyManifestLabelRemovalWithEmptyLabels(t *testing.T) { Name: routeName, Namespace: namespace, Labels: map[string]string{ - util.HCPRouteLabel: namespace, + netutil.HCPRouteLabel: namespace, }, }, Spec: routev1.RouteSpec{ @@ -208,7 +208,7 @@ func TestApplyManifestLabelRemovalWithEmptyLabels(t *testing.T) { Name: routeName, Namespace: namespace, Labels: map[string]string{ - util.HCPRouteLabel: util.RemoveLabelMarker, + netutil.HCPRouteLabel: netutil.RemoveLabelMarker, }, }, Spec: routev1.RouteSpec{ @@ -244,7 +244,7 @@ func TestApplyManifestLabelRemovalWithEmptyLabels(t *testing.T) { } // HCPRouteLabel should be removed - if _, exists := updatedRoute.Labels[util.HCPRouteLabel]; exists { + if _, exists := updatedRoute.Labels[netutil.HCPRouteLabel]; exists { t.Errorf("expected HCPRouteLabel to be removed, but it still exists") } @@ -270,8 +270,8 @@ func TestApplyManifestLabelRemovalOnCreate(t *testing.T) { Name: routeName, Namespace: namespace, Labels: map[string]string{ - util.HCPRouteLabel: util.RemoveLabelMarker, // Mark for removal - "other-label": "keep-me", // Keep this label + netutil.HCPRouteLabel: netutil.RemoveLabelMarker, // Mark for removal + "other-label": "keep-me", // Keep this label }, }, Spec: routev1.RouteSpec{ @@ -306,7 +306,7 @@ func TestApplyManifestLabelRemovalOnCreate(t *testing.T) { } // HCPRouteLabel should not exist (removal marker was cleaned up before creation) - if _, exists := createdRoute.Labels[util.HCPRouteLabel]; exists { + if _, exists := createdRoute.Labels[netutil.HCPRouteLabel]; exists { t.Errorf("expected HCPRouteLabel to be removed before creation, but it still exists") } diff --git a/support/util/util.go b/support/util/util.go index b4916fdc3f23..c459980b9d10 100644 --- a/support/util/util.go +++ b/support/util/util.go @@ -11,14 +11,11 @@ import ( "fmt" "hash/fnv" "io" - "net" "net/http" - "net/url" "os" "regexp" "sort" "strings" - "time" hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" cmdutil "github.com/openshift/hypershift/cmd/util" @@ -267,20 +264,6 @@ func decompress(r io.Reader) (*bytes.Buffer, error) { return bytes.NewBuffer(data), nil } -// ResolveDNSHostname receives a hostname string and tries to resolve it. -// Returns error if the host can't be resolved. -func ResolveDNSHostname(ctx context.Context, hostName string) error { - timeoutCtx, cancel := context.WithTimeout(ctx, time.Second) - defer cancel() - - ips, err := net.DefaultResolver.LookupIPAddr(timeoutCtx, hostName) - if err == nil && len(ips) == 0 { - err = fmt.Errorf("couldn't resolve %s", hostName) - } - - return err -} - // InsecureHTTPClient return a http.Client which skips server certificate verification func InsecureHTTPClient() *http.Client { return &http.Client{ @@ -411,41 +394,6 @@ func ConvertImageRegistryOverrideStringToMap(envVar string) map[string][]string return imageRegistryOverrides } -// IsIPv4CIDR checks if the input string is an IPv4 CIDR. -func IsIPv4CIDR(input string) (bool, error) { - _, ipnet, err := net.ParseCIDR(input) - if err != nil { - return false, fmt.Errorf("error parsing input '%s': not a valid CIDR", input) - } - if ipnet.IP.To4() != nil { - return true, nil - } - return false, nil -} - -// IsIPv4Address checks if the input string is an IPv4 address. -func IsIPv4Address(input string) (bool, error) { - ip := net.ParseIP(input) - if ip == nil { - return false, fmt.Errorf("error parsing input '%s': not a valid IP address", input) - } - if ip.To4() != nil { - return true, nil - } - return false, nil -} - -// FirstUsableIP returns the first usable IP in both, IPv4 and IPv6 stacks. -func FirstUsableIP(cidr string) (string, error) { - _, ipNet, err := net.ParseCIDR(cidr) - if err != nil { - return "", fmt.Errorf("error validating the incoming CIDR %s: %w", cidr, err) - } - ip := ipNet.IP - ip[len(ipNet.IP)-1]++ - return ip.String(), nil -} - // ParseNodeSelector parses a comma separated string of key=value pairs into a map func ParseNodeSelector(str string) map[string]string { if len(str) == 0 { @@ -718,33 +666,6 @@ func GetControlPlaneOperatorImageLabels(ctx context.Context, hc *hyperv1.HostedC return ImageLabels(controlPlaneOperatorImageMetadata), nil } -var ( - hasPortRegex = regexp.MustCompile(`:\d{1,5}$`) -) - -func HostFromURL(addr string) (string, error) { - parsedURL, err := url.Parse(addr) - if err != nil { - return "", fmt.Errorf("failed to parse URL(%s): %w", addr, err) - } - hostPort := parsedURL.Host - if hostPort == "" { - return "", fmt.Errorf("missing host/port name in URL(%s)", addr) - } - if !hasPortRegex.MatchString(hostPort) { - return hostPort, nil - } - hostName, _, err := net.SplitHostPort(hostPort) - if err != nil { - return "", fmt.Errorf("failed to split host/port from (%s): %w", hostPort, err) - } - if hostName == "" { - return "", fmt.Errorf("missing host name in URL(%s)", addr) - } - return hostName, nil - -} - // EnableIfCustomKubeconfig returns true if the hosted control plane has a custom kubeconfig defined func EnableIfCustomKubeconfig(hcp *hyperv1.HostedControlPlane) bool { return len(hcp.Spec.KubeAPIServerDNSName) > 0 diff --git a/support/util/util_test.go b/support/util/util_test.go index b0c8c08d3ab8..c12c6a3fe442 100644 --- a/support/util/util_test.go +++ b/support/util/util_test.go @@ -264,52 +264,6 @@ func testDecompressFuncErr(t *testing.T, payload []byte) { g.Expect(out.String()).To(BeEmpty(), "should be an empty string") } -func TestFirstUsableIP(t *testing.T) { - tests := []struct { - name string - cidr string - want string - wantErr bool - }{ - { - name: "Given IPv4 CIDR, it should return the first ip of the network range", - cidr: "192.168.1.0/24", - want: "192.168.1.1", - wantErr: false, - }, - { - name: "Given IPv6 CIDR, it should return the first ip of the network range", - cidr: "2000::/3", - want: "2000::1", - wantErr: false, - }, - { - name: "Given a malformed IPv4 CIDR, it should return empty string and err", - cidr: "192.168.1.35.53/24", - want: "", - wantErr: true, - }, - { - name: "Given a malformed IPv6 CIDR, it should return empty string and err", - cidr: "2001::44444444444444/17", - want: "", - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := FirstUsableIP(tt.cidr) - if (err != nil) != tt.wantErr { - t.Errorf("FirstUsableIP() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("FirstUsableIP() = %v, want %v", got, tt.want) - } - }) - } -} - func TestParseNodeSelector(t *testing.T) { tests := []struct { name string @@ -694,86 +648,6 @@ func TestDetermineHostedClusterPayloadArch(t *testing.T) { } } -func TestIsIPv4CIDR(t *testing.T) { - tests := []struct { - input string - expected bool - expectError bool - }{ - // Valid IPv4 CIDRs - {"192.168.1.0/24", true, false}, - {"10.0.0.0/8", true, false}, - - // Valid IPv6 CIDRs - {"2001:db8::/32", false, false}, - {"fd00::/8", false, false}, - - // Invalid inputs - {"invalid", false, true}, - {"192.168.1.1/33", false, true}, // Invalid CIDR prefix - {"", false, true}, // Empty input - {"1234::5678::/64", false, true}, // Malformed IP - - // Edge cases - {"0.0.0.0/0", true, false}, - {"255.255.255.255/32", true, false}, - } - - for _, test := range tests { - t.Run(test.input, func(t *testing.T) { - g := NewWithT(t) - result, err := IsIPv4CIDR(test.input) - if test.expectError { - g.Expect(err).To(HaveOccurred(), "Expected an error for input '%s'", test.input) - } else { - g.Expect(err).ToNot(HaveOccurred(), "Did not expect an error for input '%s'", test.input) - } - - g.Expect(result).To(Equal(test.expected), "Unexpected result for input '%s'", test.input) - }) - } -} - -func TestIsIPv4Address(t *testing.T) { - tests := []struct { - input string - expected bool - expectError bool - }{ - // Valid IPv4 addresses - {"192.168.1.1", true, false}, - {"10.0.0.1", true, false}, - - // Valid IPv6 addresses - {"2001:db8::1", false, false}, - {"fd00::1", false, false}, - - // Invalid inputs - {"invalid", false, true}, - {"192.168.1.256", false, true}, // Invalid IPv4 address - {"", false, true}, // Empty input - {"1234::5678::1", false, true}, // Malformed IP - - // Edge cases - {"0.0.0.0", true, false}, - {"255.255.255.255", true, false}, - } - - for _, test := range tests { - t.Run(test.input, func(t *testing.T) { - g := NewWithT(t) - result, err := IsIPv4Address(test.input) - if test.expectError { - g.Expect(err).To(HaveOccurred(), "Expected an error for input '%s'", test.input) - } else { - g.Expect(err).ToNot(HaveOccurred(), "Did not expect an error for input '%s'", test.input) - } - - g.Expect(result).To(Equal(test.expected), "Unexpected result for input '%s'", test.input) - }) - } -} - func TestRemoveEmptyJSONField(t *testing.T) { tests := []struct { name string @@ -865,37 +739,6 @@ func TestRemoveEmptyJSONField(t *testing.T) { } } -func TestHostFromURL(t *testing.T) { - tests := []struct { - input string - expected string - wantErr bool - }{ - {"http://example.com", "example.com", false}, - {"https://example.com:443", "example.com", false}, - {"http://localhost:8080", "localhost", false}, - {"https://127.0.0.1:9000", "127.0.0.1", false}, - {"ftp://example.org:21", "example.org", false}, - {"http://[::1]:8080", "::1", false}, // IPv6 localhost - {"http://[2001:db8::1]:443", "2001:db8::1", false}, // IPv6 example - {"??", "", true}, // Invalid URL - {"http://:8080", "", true}, // Missing hostname - } - - for _, tt := range tests { - t.Run(tt.input, func(t *testing.T) { - g := NewWithT(t) - result, err := HostFromURL(tt.input) - if tt.wantErr { - g.Expect(err).To(HaveOccurred()) - } else { - g.Expect(err).ToNot(HaveOccurred()) - } - g.Expect(result).To(Equal(tt.expected)) - }) - } -} - func TestCountAvailableNodes(t *testing.T) { scheme := runtime.NewScheme() _ = corev1.AddToScheme(scheme) diff --git a/test/e2e/nodepool_mirrorconfigs_test.go b/test/e2e/nodepool_mirrorconfigs_test.go index 29a85d99f968..d8f93cf5eee4 100644 --- a/test/e2e/nodepool_mirrorconfigs_test.go +++ b/test/e2e/nodepool_mirrorconfigs_test.go @@ -18,7 +18,7 @@ import ( hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1" "github.com/openshift/hypershift/hypershift-operator/controllers/manifests" "github.com/openshift/hypershift/hypershift-operator/controllers/nodepool" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" e2eutil "github.com/openshift/hypershift/test/e2e/util" ) @@ -132,7 +132,7 @@ func (mc *MirrorConfigsTest) Run(t *testing.T, nodePool hyperv1.NodePool, nodes }, []e2eutil.Predicate[*corev1.ConfigMap]{ func(configMap *corev1.ConfigMap) (done bool, reasons string, err error) { - if want, got := util.ShortenName(KubeletConfigMap.Name, nodePool.Name, nodepool.QualifiedNameMaxLength), configMap.Name; want != got { + if want, got := netutil.ShortenName(KubeletConfigMap.Name, nodePool.Name, nodepool.QualifiedNameMaxLength), configMap.Name; want != got { return false, fmt.Sprintf("expected kubelet config ConfigMap name to be '%s', got '%s'", want, got), nil } return true, fmt.Sprintf("kubelet config ConfigMap name is as expected"), nil diff --git a/test/e2e/nodepool_nto_performanceprofile_test.go b/test/e2e/nodepool_nto_performanceprofile_test.go index 38e8ef16ef7f..399481710929 100644 --- a/test/e2e/nodepool_nto_performanceprofile_test.go +++ b/test/e2e/nodepool_nto_performanceprofile_test.go @@ -7,7 +7,7 @@ import ( "fmt" "testing" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" "github.com/google/go-cmp/cmp" "github.com/openshift/hypershift/hypershift-operator/controllers/nodepool" @@ -129,7 +129,7 @@ func (mc *NTOPerformanceProfileTest) Run(t *testing.T, nodePool hyperv1.NodePool }, []e2eutil.Predicate[*corev1.ConfigMap]{ func(configMap *corev1.ConfigMap) (done bool, reasons string, err error) { - if want, got := util.ShortenName(performanceProfileConfigMap.Name, nodePool.Name, nodepool.QualifiedNameMaxLength), configMap.Name; want != got { + if want, got := netutil.ShortenName(performanceProfileConfigMap.Name, nodePool.Name, nodepool.QualifiedNameMaxLength), configMap.Name; want != got { return false, fmt.Sprintf("expected performance profile ConfigMap name to be '%s', got '%s'", want, got), nil } return true, fmt.Sprintf("performance profile ConfigMap name is as expected"), nil @@ -176,7 +176,7 @@ func (mc *NTOPerformanceProfileTest) Run(t *testing.T, nodePool hyperv1.NodePool }, []e2eutil.Predicate[*corev1.ConfigMap]{ func(configMap *corev1.ConfigMap) (done bool, reasons string, err error) { - if want, got := fmt.Sprintf("status-%s", util.ShortenName(performanceProfileConfigMap.Name, nodePool.Name, nodepool.QualifiedNameMaxLength)), configMap.Name; want != got { + if want, got := fmt.Sprintf("status-%s", netutil.ShortenName(performanceProfileConfigMap.Name, nodePool.Name, nodepool.QualifiedNameMaxLength)), configMap.Name; want != got { return false, fmt.Sprintf("expected performance profile status ConfigMap name to be '%s', got '%s'", want, got), nil } return true, fmt.Sprintf("performance profile status ConfigMap name is as expected"), nil diff --git a/test/e2e/util/hypershift_framework.go b/test/e2e/util/hypershift_framework.go index 6cb687e06810..3b629a0882d8 100644 --- a/test/e2e/util/hypershift_framework.go +++ b/test/e2e/util/hypershift_framework.go @@ -30,7 +30,7 @@ import ( "github.com/openshift/hypershift/support/assets" "github.com/openshift/hypershift/support/azureutil" "github.com/openshift/hypershift/support/capabilities" - "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" configv1 "github.com/openshift/api/config/v1" @@ -188,7 +188,7 @@ func (h *hypershiftTest) before(hostedCluster *hyperv1.HostedCluster, opts *Plat // Use !IsPublicHC to detect strictly private clusters (no public API endpoint). // IsPrivateHC includes PublicAndPrivate, which has a reachable API server // and should use ValidatePublicCluster. - if !util.IsPublicHC(hostedCluster) { + if !netutil.IsPublicHC(hostedCluster) { ValidatePrivateCluster(t, h.ctx, h.client, hostedCluster, opts, h.upgradeContext) } else { ValidatePublicCluster(t, h.ctx, h.client, hostedCluster, opts, h.upgradeContext) @@ -205,7 +205,7 @@ func (h *hypershiftTest) before(hostedCluster *hyperv1.HostedCluster, opts *Plat // The cilium-olm deployment requires worker nodes to schedule its pods. // TestNodePool sets NodePoolReplicas=0 and creates NodePools later in individual tests, // so we skip Cilium installation during the initial cluster validation phase. - if !util.IsPrivateHC(hostedCluster) { + if !netutil.IsPrivateHC(hostedCluster) { if opts.NodePoolReplicas == 0 { t.Fatal("NodePool replicas must be positive for Cilium to install.") } @@ -291,7 +291,7 @@ func (h *hypershiftTest) after(hostedCluster *hyperv1.HostedCluster, platform hy if hostedCluster.Spec.Platform.Type != hyperv1.NonePlatform { // Private clusters may won't be reachable from the test runner; assume workers exist. hasWorkerNodes := true - if !util.IsPrivateHC(hostedCluster) { + if !netutil.IsPrivateHC(hostedCluster) { guestClient := WaitForGuestClient(t, t.Context(), h.client, hostedCluster) var nodeList corev1.NodeList if err := guestClient.List(t.Context(), &nodeList); err != nil { diff --git a/test/e2e/util/oauth.go b/test/e2e/util/oauth.go index ad0be3c64c2d..f515810508c7 100644 --- a/test/e2e/util/oauth.go +++ b/test/e2e/util/oauth.go @@ -17,7 +17,7 @@ import ( configmanifests "github.com/openshift/hypershift/control-plane-operator/hostedclusterconfigoperator/controllers/resources/manifests" "github.com/openshift/hypershift/hypershift-operator/controllers/manifests" "github.com/openshift/hypershift/support/api" - supportutil "github.com/openshift/hypershift/support/util" + "github.com/openshift/hypershift/support/netutil" v1 "github.com/openshift/api/config/v1" osinv1 "github.com/openshift/api/osin/v1" @@ -312,7 +312,7 @@ func WaitForOAuthLoadBalancerReady(t *testing.T, ctx context.Context, client crc // Get the OAuth hostname from the HostedCluster's service publishing strategy. // This is the hostname that the TLS certificate is issued for and that ExternalDNS // creates a DNS record for, so it must be used for TLS connections. - oauthStrategy := supportutil.ServicePublishingStrategyByTypeByHC(hostedCluster, hyperv1.OAuthServer) + oauthStrategy := netutil.ServicePublishingStrategyByTypeByHC(hostedCluster, hyperv1.OAuthServer) g.Expect(oauthStrategy).ToNot(BeNil(), "OAuth service publishing strategy not found in HostedCluster spec") g.Expect(oauthStrategy.LoadBalancer).ToNot(BeNil(), "OAuth LoadBalancer strategy not found") oauthHost := oauthStrategy.LoadBalancer.Hostname diff --git a/test/e2e/util/util.go b/test/e2e/util/util.go index 9de1167cda10..8fbc6f2c1696 100644 --- a/test/e2e/util/util.go +++ b/test/e2e/util/util.go @@ -34,6 +34,7 @@ import ( "github.com/openshift/hypershift/support/certs" "github.com/openshift/hypershift/support/conditions" suppconfig "github.com/openshift/hypershift/support/config" + "github.com/openshift/hypershift/support/netutil" "github.com/openshift/hypershift/support/podspec" "github.com/openshift/hypershift/support/releaseinfo" hyperutil "github.com/openshift/hypershift/support/util" @@ -1202,7 +1203,7 @@ func EnsureAllRoutesUseHCPRouter(t *testing.T, ctx context.Context, hostClient c } for _, route := range routes.Items { original := route.DeepCopy() - hyperutil.AddHCPRouteLabel(&route) + netutil.AddHCPRouteLabel(&route) if diff := cmp.Diff(route.GetLabels(), original.GetLabels()); diff != "" { t.Errorf("route %s is missing the label to use the per-HCP router: %s", route.Name, diff) } @@ -1933,7 +1934,7 @@ func EnsureGlobalPullSecret(t *testing.T, ctx context.Context, mgmtClient crclie t.Skip("Skip GlobalPullSecret test for TestCreateClusterCustomConfig to avoid issues with OVN") } - if !hyperutil.IsPublicHC(entryHostedCluster) { + if !netutil.IsPublicHC(entryHostedCluster) { t.Skip("test only supported on public clusters") } @@ -2235,7 +2236,7 @@ func EnsureKubeAPIDNSNameCustomCert(t *testing.T, ctx context.Context, mgmtClien } g := NewWithT(t) - if !hyperutil.IsPublicHC(entryHostedCluster) { + if !netutil.IsPublicHC(entryHostedCluster) { return } @@ -2567,7 +2568,7 @@ func EnsureKubeAPIDNSNameCustomCert(t *testing.T, ctx context.Context, mgmtClien } func EnsureAdmissionPolicies(t *testing.T, ctx context.Context, mgmtClient crclient.Client, hc *hyperv1.HostedCluster) { - if !hyperutil.IsPublicHC(hc) { + if !netutil.IsPublicHC(hc) { return // Admission policies are only validated in public clusters does not worth to test it in private ones. } guestClient := WaitForGuestClient(t, ctx, mgmtClient, hc) @@ -2897,7 +2898,7 @@ func ValidatePublicCluster(t *testing.T, ctx context.Context, client crclient.Cl err := client.Get(ctx, crclient.ObjectKeyFromObject(hostedCluster), hostedCluster) g.Expect(err).NotTo(HaveOccurred(), "failed to get hostedcluster") - serviceStrategy := hyperutil.ServicePublishingStrategyByTypeByHC(hostedCluster, hyperv1.APIServer) + serviceStrategy := netutil.ServicePublishingStrategyByTypeByHC(hostedCluster, hyperv1.APIServer) g.Expect(serviceStrategy).ToNot(BeNil()) if serviceStrategy.Type == hyperv1.Route && serviceStrategy.Route != nil && serviceStrategy.Route.Hostname != "" { g.Expect(hostedCluster.Status.ControlPlaneEndpoint.Host).To(Equal(serviceStrategy.Route.Hostname)) @@ -2948,7 +2949,7 @@ func ValidatePrivateCluster(t *testing.T, ctx context.Context, client crclient.C err := client.Get(ctx, crclient.ObjectKeyFromObject(hostedCluster), hostedCluster) g.Expect(err).NotTo(HaveOccurred(), "failed to get hostedcluster") - serviceStrategy := hyperutil.ServicePublishingStrategyByTypeByHC(hostedCluster, hyperv1.APIServer) + serviceStrategy := netutil.ServicePublishingStrategyByTypeByHC(hostedCluster, hyperv1.APIServer) g.Expect(serviceStrategy).ToNot(BeNil()) if serviceStrategy.Route != nil && serviceStrategy.Route.Hostname != "" { g.Expect(hostedCluster.Status.ControlPlaneEndpoint.Host).To(Equal(serviceStrategy.Route.Hostname))