kubesphere.io/api@v0.0.0-20231107125330-c9a03957060c/network/v1alpha1/ippool_types.go (about) 1 /* 2 Copyright 2020 The KubeSphere authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package v1alpha1 18 19 import ( 20 "fmt" 21 "math/big" 22 23 cnet "github.com/projectcalico/calico/libcalico-go/lib/net" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 ) 26 27 const ( 28 ResourceKindIPPool = "IPPool" 29 ResourceSingularIPPool = "ippool" 30 ResourcePluralIPPool = "ippools" 31 32 // scope type > id > name 33 // id used to detect cidr overlap 34 IPPoolTypeLabel = "ippool.network.kubesphere.io/type" 35 IPPoolNameLabel = "ippool.network.kubesphere.io/name" 36 IPPoolIDLabel = "ippool.network.kubesphere.io/id" 37 IPPoolDefaultLabel = "ippool.network.kubesphere.io/default" 38 39 IPPoolTypeNone = "none" 40 IPPoolTypeLocal = "local" 41 IPPoolTypeCalico = "calico" 42 ) 43 44 // +genclient 45 // +genclient:nonNamespaced 46 // +kubebuilder:object:root=true 47 // +k8s:openapi-gen=true 48 // +kubebuilder:subresource:status 49 // +kubebuilder:resource:scope=Cluster 50 type IPPool struct { 51 metav1.TypeMeta `json:",inline"` 52 metav1.ObjectMeta `json:"metadata,omitempty"` 53 54 // +optional 55 Spec IPPoolSpec `json:"spec,omitempty"` 56 // +optional 57 Status IPPoolStatus `json:"status,omitempty"` 58 } 59 60 type VLANConfig struct { 61 VlanId uint32 `json:"vlanId"` 62 Master string `json:"master"` 63 } 64 65 type Route struct { 66 Dst string `json:"dst,omitempty"` 67 GW string `json:"gateway,omitempty"` 68 } 69 70 // DNS contains values interesting for DNS resolvers 71 type DNS struct { 72 Nameservers []string `json:"nameservers,omitempty"` 73 Domain string `json:"domain,omitempty"` 74 Search []string `json:"search,omitempty"` 75 Options []string `json:"options,omitempty"` 76 } 77 78 type WorkspaceStatus struct { 79 Allocations int `json:"allocations"` 80 } 81 82 type IPPoolStatus struct { 83 Unallocated int `json:"unallocated"` 84 Allocations int `json:"allocations"` 85 Capacity int `json:"capacity"` 86 Reserved int `json:"reserved,omitempty"` 87 Synced bool `json:"synced,omitempty"` 88 Workspaces map[string]WorkspaceStatus `json:"workspaces,omitempty"` 89 } 90 91 type IPPoolSpec struct { 92 Type string `json:"type"` 93 94 // The pool CIDR. 95 CIDR string `json:"cidr"` 96 97 // The first ip, inclusive 98 RangeStart string `json:"rangeStart,omitempty"` 99 100 // The last ip, inclusive 101 RangeEnd string `json:"rangeEnd,omitempty"` 102 103 // When disabled is true, IPAM will not assign addresses from this pool. 104 Disabled bool `json:"disabled,omitempty"` 105 106 // The block size to use for IP address assignments from this pool. Defaults to 26 for IPv4 and 112 for IPv6. 107 BlockSize int `json:"blockSize,omitempty"` 108 109 VLAN VLANConfig `json:"vlanConfig,omitempty"` 110 111 Gateway string `json:"gateway,omitempty"` 112 Routes []Route `json:"routes,omitempty"` 113 DNS DNS `json:"dns,omitempty"` 114 } 115 116 // +kubebuilder:object:root=true 117 // +genclient:nonNamespaced 118 type IPPoolList struct { 119 metav1.TypeMeta `json:",inline"` 120 metav1.ListMeta `json:"metadata,omitempty"` 121 Items []IPPool `json:"items"` 122 } 123 124 const ( 125 VLAN = "vlan" 126 Calico = "calico" 127 Porter = "porter" 128 Pod = "pod" 129 VLANIDStart = 1 130 VLANIDEnd = 4097 131 PorterID = 4098 132 CalicoID = 4099 133 PodID = 0 134 ) 135 136 // Find the ordinal (i.e. how far into the block) a given IP lies. Returns an error if the IP is outside the block. 137 func (b IPPool) IPToOrdinal(ip cnet.IP) (int, error) { 138 _, cidr, _ := cnet.ParseCIDR(b.Spec.CIDR) 139 ipAsInt := cnet.IPToBigInt(ip) 140 baseInt := cnet.IPToBigInt(cnet.IP{IP: cidr.IP}) 141 ord := big.NewInt(0).Sub(ipAsInt, baseInt).Int64() 142 if ord < 0 || ord >= int64(b.NumAddresses()) { 143 return 0, fmt.Errorf("IP %s not in pool %s", ip, b.Spec.CIDR) 144 } 145 return int(ord), nil 146 } 147 148 // Get number of addresses covered by the block 149 func (b IPPool) NumAddresses() int { 150 _, cidr, _ := cnet.ParseCIDR(b.Spec.CIDR) 151 ones, size := cidr.Mask.Size() 152 numAddresses := 1 << uint(size-ones) 153 return numAddresses 154 } 155 156 func (b IPPool) Type() string { 157 if b.Spec.Type == VLAN { 158 return IPPoolTypeLocal 159 } 160 161 return b.Spec.Type 162 } 163 164 func (b IPPool) NumReservedAddresses() int { 165 return b.StartReservedAddressed() + b.EndReservedAddressed() 166 } 167 168 func (b IPPool) StartReservedAddressed() int { 169 if b.Spec.RangeStart == "" { 170 return 0 171 } 172 start, _ := b.IPToOrdinal(*cnet.ParseIP(b.Spec.RangeStart)) 173 return start 174 } 175 176 func (b IPPool) EndReservedAddressed() int { 177 if b.Spec.RangeEnd == "" { 178 return 0 179 } 180 total := b.NumAddresses() 181 end, _ := b.IPToOrdinal(*cnet.ParseIP(b.Spec.RangeEnd)) 182 return total - end - 1 183 } 184 185 func (b IPPool) Overlapped(dst IPPool) bool { 186 if b.ID() != dst.ID() { 187 return false 188 } 189 190 _, cidr, _ := cnet.ParseCIDR(b.Spec.CIDR) 191 _, cidrDst, _ := cnet.ParseCIDR(dst.Spec.CIDR) 192 193 return cidr.IsNetOverlap(cidrDst.IPNet) 194 } 195 196 func (pool IPPool) ID() uint32 { 197 switch pool.Spec.Type { 198 case VLAN: 199 return pool.Spec.VLAN.VlanId + VLANIDStart 200 case Porter: 201 return PorterID 202 case Calico: 203 return CalicoID 204 } 205 206 return PodID 207 } 208 209 func (p IPPool) TypeInvalid() bool { 210 typeStr := p.Spec.Type 211 if typeStr == VLAN || typeStr == Porter || typeStr == Pod { 212 return false 213 } 214 215 return true 216 } 217 218 func (p IPPool) Disabled() bool { 219 return p.Spec.Disabled 220 } 221 222 func (p IPPool) V4() bool { 223 ip, _, _ := cnet.ParseCIDR(p.Spec.CIDR) 224 if ip.To4() != nil { 225 return true 226 } 227 return false 228 } 229 230 const IPPoolFinalizer = "finalizers.network.kubesphere.io/ippool"