github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/controller/component/port_utils.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package component 21 22 import ( 23 "errors" 24 "fmt" 25 26 corev1 "k8s.io/api/core/v1" 27 ) 28 29 const minAvailPort = 1024 30 const maxAvailPort = 65535 31 32 func getAllContainerPorts(containers []corev1.Container) (map[int32]bool, error) { 33 set := map[int32]bool{} 34 for _, container := range containers { 35 for _, v := range container.Ports { 36 _, ok := set[v.ContainerPort] 37 if ok { 38 return nil, fmt.Errorf("containerPorts conflict: [%+v]", v.ContainerPort) 39 } 40 set[v.ContainerPort] = true 41 } 42 } 43 return set, nil 44 } 45 46 // get available container ports, increased by one if conflict with exist ports 47 // util no conflicts. 48 func getAvailableContainerPorts(containers []corev1.Container, containerPorts []int32) ([]int32, error) { 49 set, err := getAllContainerPorts(containers) 50 if err != nil { 51 return nil, err 52 } 53 54 iterAvailPort := func(p int32) (int32, error) { 55 // The TCP/IP port numbers below 1024 are privileged ports, which are special 56 // in that normal users are not allowed to run servers on them. 57 if p < minAvailPort || p > maxAvailPort { 58 p = minAvailPort 59 } 60 sentinel := p 61 for { 62 if _, ok := set[p]; !ok { 63 set[p] = true 64 return p, nil 65 } 66 p++ 67 if p == sentinel { 68 return -1, errors.New("no available port for container") 69 } 70 if p > maxAvailPort { 71 p = minAvailPort 72 } 73 } 74 } 75 76 for i, p := range containerPorts { 77 if containerPorts[i], err = iterAvailPort(p); err != nil { 78 return []int32{}, err 79 } 80 } 81 return containerPorts, nil 82 }