github.com/ironcore-dev/gardener-extension-provider-ironcore@v0.3.2-0.20240314231816-8336447fb9a0/pkg/controller/bastion/utils.go (about) 1 // SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and IronCore contributors 2 // SPDX-License-Identifier: Apache-2.0 3 4 package bastion 5 6 import ( 7 "fmt" 8 "net" 9 "strings" 10 11 extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1" 12 computev1alpha1 "github.com/ironcore-dev/ironcore/api/compute/v1alpha1" 13 ) 14 15 // generateBastionHostResourceName returns a unique name for the Bastion host in 16 // the Gardener Kubernetes cluster, based on the cluster name, Bastion name, and 17 // UID. The function concatenates these values and truncates the resulting 18 // string to 63 characters, if necessary, to comply with the Kubernetes naming 19 // convention. In rare cases, this truncation may result in non-unique names, 20 // but the likelihood of this happening is extremely low. 21 func generateBastionHostResourceName(clusterName string, bastion *extensionsv1alpha1.Bastion) (string, error) { 22 bastionName := bastion.Name 23 if bastionName == "" { 24 return "", fmt.Errorf("bastionName can not be empty") 25 } 26 if clusterName == "" { 27 return "", fmt.Errorf("clusterName can not be empty") 28 } 29 staticName := clusterName + "-" + bastionName 30 nameSuffix := strings.Split(string(bastion.UID), "-")[0] 31 name := fmt.Sprintf("%s-bastion-%s", staticName, nameSuffix) 32 if len(name) > 63 { 33 name = name[:63] 34 } 35 return name, nil 36 } 37 38 func getIgnitionNameForMachine(machineName string) string { 39 return fmt.Sprintf("%s-%s", machineName, "ignition") 40 } 41 42 // getPrivateAndVirtualIPsFromNetworkInterfaces extracts the private IPv4 and 43 // virtual IPv4 addresses from the given slice of NetworkInterfaceStatus 44 // objects. 45 // 46 // If a network interface has multiple private IPs, only the first one will be 47 // returned. If multiple network interfaces have a virtual IP, only the first 48 // one will be returned. 49 // 50 // TODO: IPv6 addresses are ignored for now and will be 51 // added in the future once Gardener extension supports IPv6. 52 func getPrivateAndVirtualIPsFromNetworkInterfaces(networkInterfaces []computev1alpha1.NetworkInterfaceStatus) (string, string, error) { 53 var privateIP, virtualIP string 54 55 for _, ni := range networkInterfaces { 56 if ni.IPs == nil { 57 return "", "", fmt.Errorf("no private ip found for network interface: %s", ni.Name) 58 } 59 for _, ip := range ni.IPs { 60 parsedIP := net.ParseIP(ip.String()) 61 if parsedIP == nil { 62 continue // skip invalid IP 63 } 64 if parsedIP.To4() != nil { 65 privateIP = parsedIP.String() 66 break 67 } else { 68 // IPv6 case 69 continue 70 } 71 } 72 if ni.VirtualIP != nil { 73 parsedIP := net.ParseIP(ni.VirtualIP.String()) 74 if parsedIP == nil { 75 continue // skip invalid IP 76 } 77 if parsedIP.To4() != nil { 78 virtualIP = parsedIP.String() 79 break 80 } else { 81 // IPv6 case 82 continue 83 } 84 } 85 } 86 if privateIP == "" { 87 return "", "", fmt.Errorf("private IPv4 address not found") 88 } 89 if virtualIP == "" { 90 return "", "", fmt.Errorf("virtual IPv4 address not found") 91 } 92 93 return privateIP, virtualIP, nil 94 }