sigs.k8s.io/cluster-api-provider-azure@v1.14.3/api/v1beta1/azurecluster_default.go (about) 1 /* 2 Copyright 2021 The Kubernetes 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 v1beta1 18 19 import ( 20 "fmt" 21 22 "k8s.io/utils/ptr" 23 ) 24 25 const ( 26 // DefaultVnetCIDR is the default Vnet CIDR. 27 DefaultVnetCIDR = "10.0.0.0/8" 28 // DefaultControlPlaneSubnetCIDR is the default Control Plane Subnet CIDR. 29 DefaultControlPlaneSubnetCIDR = "10.0.0.0/16" 30 // DefaultNodeSubnetCIDR is the default Node Subnet CIDR. 31 DefaultNodeSubnetCIDR = "10.1.0.0/16" 32 // DefaultClusterSubnetCIDR is the default Cluster Subnet CIDR. 33 DefaultClusterSubnetCIDR = "10.0.0.0/16" 34 // DefaultNodeSubnetCIDRPattern is the pattern that will be used to generate the default subnets CIDRs. 35 DefaultNodeSubnetCIDRPattern = "10.%d.0.0/16" 36 // DefaultAzureBastionSubnetCIDR is the default Subnet CIDR for AzureBastion. 37 DefaultAzureBastionSubnetCIDR = "10.255.255.224/27" 38 // DefaultAzureBastionSubnetName is the default Subnet Name for AzureBastion. 39 DefaultAzureBastionSubnetName = "AzureBastionSubnet" 40 // DefaultAzureBastionSubnetRole is the default Subnet role for AzureBastion. 41 DefaultAzureBastionSubnetRole = SubnetBastion 42 // DefaultInternalLBIPAddress is the default internal load balancer ip address. 43 DefaultInternalLBIPAddress = "10.0.0.100" 44 // DefaultOutboundRuleIdleTimeoutInMinutes is the default for IdleTimeoutInMinutes for the load balancer. 45 DefaultOutboundRuleIdleTimeoutInMinutes = 4 46 // DefaultAzureCloud is the public cloud that will be used by most users. 47 DefaultAzureCloud = "AzurePublicCloud" 48 ) 49 50 func (c *AzureCluster) setDefaults() { 51 c.Spec.AzureClusterClassSpec.setDefaults() 52 c.setResourceGroupDefault() 53 c.setNetworkSpecDefaults() 54 } 55 56 func (c *AzureCluster) setNetworkSpecDefaults() { 57 c.setVnetDefaults() 58 c.setBastionDefaults() 59 c.setSubnetDefaults() 60 c.setVnetPeeringDefaults() 61 c.setAPIServerLBDefaults() 62 c.SetNodeOutboundLBDefaults() 63 c.SetControlPlaneOutboundLBDefaults() 64 } 65 66 func (c *AzureCluster) setResourceGroupDefault() { 67 if c.Spec.ResourceGroup == "" { 68 c.Spec.ResourceGroup = c.Name 69 } 70 } 71 72 func (c *AzureCluster) setAzureEnvironmentDefault() { 73 if c.Spec.AzureEnvironment == "" { 74 c.Spec.AzureEnvironment = DefaultAzureCloud 75 } 76 } 77 78 func (c *AzureCluster) setVnetDefaults() { 79 if c.Spec.NetworkSpec.Vnet.ResourceGroup == "" { 80 c.Spec.NetworkSpec.Vnet.ResourceGroup = c.Spec.ResourceGroup 81 } 82 if c.Spec.NetworkSpec.Vnet.Name == "" { 83 c.Spec.NetworkSpec.Vnet.Name = generateVnetName(c.ObjectMeta.Name) 84 } 85 c.Spec.NetworkSpec.Vnet.VnetClassSpec.setDefaults() 86 } 87 88 func (c *AzureCluster) setSubnetDefaults() { 89 clusterSubnet, err := c.Spec.NetworkSpec.GetSubnet(SubnetCluster) 90 clusterSubnetExists := err == nil 91 if clusterSubnetExists { 92 clusterSubnet.setClusterSubnetDefaults(c.ObjectMeta.Name) 93 c.Spec.NetworkSpec.UpdateSubnet(clusterSubnet, SubnetCluster) 94 } 95 96 /* if there is a cp subnet set defaults 97 if no cp subnet and cluster subnet create a default cp subnet */ 98 cpSubnet, errcp := c.Spec.NetworkSpec.GetSubnet(SubnetControlPlane) 99 if errcp == nil { 100 cpSubnet.setControlPlaneSubnetDefaults(c.ObjectMeta.Name) 101 c.Spec.NetworkSpec.UpdateSubnet(cpSubnet, SubnetControlPlane) 102 } else if !clusterSubnetExists { 103 cpSubnet = SubnetSpec{SubnetClassSpec: SubnetClassSpec{Role: SubnetControlPlane}} 104 cpSubnet.setControlPlaneSubnetDefaults(c.ObjectMeta.Name) 105 c.Spec.NetworkSpec.Subnets = append(c.Spec.NetworkSpec.Subnets, cpSubnet) 106 } 107 108 var nodeSubnetFound bool 109 var nodeSubnetCounter int 110 for i, subnet := range c.Spec.NetworkSpec.Subnets { 111 if subnet.Role != SubnetNode { 112 continue 113 } 114 nodeSubnetCounter++ 115 nodeSubnetFound = true 116 subnet.setNodeSubnetDefaults(c.ObjectMeta.Name, nodeSubnetCounter) 117 c.Spec.NetworkSpec.Subnets[i] = subnet 118 } 119 120 if !nodeSubnetFound && !clusterSubnetExists { 121 nodeSubnet := SubnetSpec{ 122 SubnetClassSpec: SubnetClassSpec{ 123 Role: SubnetNode, 124 CIDRBlocks: []string{DefaultNodeSubnetCIDR}, 125 Name: generateNodeSubnetName(c.ObjectMeta.Name), 126 }, 127 SecurityGroup: SecurityGroup{ 128 Name: generateNodeSecurityGroupName(c.ObjectMeta.Name), 129 }, 130 RouteTable: RouteTable{ 131 Name: generateNodeRouteTableName(c.ObjectMeta.Name), 132 }, 133 NatGateway: NatGateway{ 134 NatGatewayClassSpec: NatGatewayClassSpec{ 135 Name: generateNatGatewayName(c.ObjectMeta.Name), 136 }, 137 }, 138 } 139 c.Spec.NetworkSpec.Subnets = append(c.Spec.NetworkSpec.Subnets, nodeSubnet) 140 } 141 } 142 143 func (s *SubnetSpec) setNodeSubnetDefaults(clusterName string, index int) { 144 if s.Name == "" { 145 s.Name = withIndex(generateNodeSubnetName(clusterName), index) 146 } 147 s.SubnetClassSpec.setDefaults(fmt.Sprintf(DefaultNodeSubnetCIDRPattern, index)) 148 149 if s.SecurityGroup.Name == "" { 150 s.SecurityGroup.Name = generateNodeSecurityGroupName(clusterName) 151 } 152 s.SecurityGroup.SecurityGroupClass.setDefaults() 153 154 if s.RouteTable.Name == "" { 155 s.RouteTable.Name = generateNodeRouteTableName(clusterName) 156 } 157 158 // NAT gateway only supports the use of IPv4 public IP addresses for outbound connectivity. 159 // So default use the NAT gateway for outbound traffic in IPv4 cluster instead of loadbalancer. 160 // We assume that if the ID is set, the subnet already exists so we shouldn't add a NAT gateway. 161 if !s.IsIPv6Enabled() && s.ID == "" { 162 if s.NatGateway.Name == "" { 163 s.NatGateway.Name = withIndex(generateNatGatewayName(clusterName), index) 164 } 165 if s.NatGateway.NatGatewayIP.Name == "" { 166 s.NatGateway.NatGatewayIP.Name = generateNatGatewayIPName(s.NatGateway.Name) 167 } 168 } 169 } 170 171 func (s *SubnetSpec) setControlPlaneSubnetDefaults(clusterName string) { 172 if s.Name == "" { 173 s.Name = generateControlPlaneSubnetName(clusterName) 174 } 175 176 s.SubnetClassSpec.setDefaults(DefaultControlPlaneSubnetCIDR) 177 178 if s.SecurityGroup.Name == "" { 179 s.SecurityGroup.Name = generateControlPlaneSecurityGroupName(clusterName) 180 } 181 s.SecurityGroup.SecurityGroupClass.setDefaults() 182 } 183 184 func (s *SubnetSpec) setClusterSubnetDefaults(clusterName string) { 185 if s.Name == "" { 186 s.Name = generateClusterSubnetSubnetName(clusterName) 187 } 188 if s.SecurityGroup.Name == "" { 189 s.SecurityGroup.Name = generateClusterSecurityGroupName(clusterName) 190 } 191 if s.RouteTable.Name == "" { 192 s.RouteTable.Name = generateClustereRouteTableName(clusterName) 193 } 194 if s.NatGateway.Name == "" { 195 s.NatGateway.Name = generateClusterNatGatewayName(clusterName) 196 } 197 if !s.IsIPv6Enabled() && s.ID == "" && s.NatGateway.NatGatewayIP.Name == "" { 198 s.NatGateway.NatGatewayIP.Name = generateNatGatewayIPName(s.NatGateway.Name) 199 } 200 s.setDefaults(DefaultClusterSubnetCIDR) 201 s.SecurityGroup.SecurityGroupClass.setDefaults() 202 } 203 204 func (c *AzureCluster) setVnetPeeringDefaults() { 205 for i, peering := range c.Spec.NetworkSpec.Vnet.Peerings { 206 if peering.ResourceGroup == "" { 207 c.Spec.NetworkSpec.Vnet.Peerings[i].ResourceGroup = c.Spec.ResourceGroup 208 } 209 } 210 } 211 212 func (c *AzureCluster) setAPIServerLBDefaults() { 213 lb := &c.Spec.NetworkSpec.APIServerLB 214 215 lb.LoadBalancerClassSpec.setAPIServerLBDefaults() 216 217 if lb.Type == Public { 218 if lb.Name == "" { 219 lb.Name = generatePublicLBName(c.ObjectMeta.Name) 220 } 221 if len(lb.FrontendIPs) == 0 { 222 lb.FrontendIPs = []FrontendIP{ 223 { 224 Name: generateFrontendIPConfigName(lb.Name), 225 PublicIP: &PublicIPSpec{ 226 Name: generatePublicIPName(c.ObjectMeta.Name), 227 }, 228 }, 229 } 230 } 231 } else if lb.Type == Internal { 232 if lb.Name == "" { 233 lb.Name = generateInternalLBName(c.ObjectMeta.Name) 234 } 235 if len(lb.FrontendIPs) == 0 { 236 lb.FrontendIPs = []FrontendIP{ 237 { 238 Name: generateFrontendIPConfigName(lb.Name), 239 FrontendIPClass: FrontendIPClass{ 240 PrivateIPAddress: DefaultInternalLBIPAddress, 241 }, 242 }, 243 } 244 } 245 } 246 c.SetAPIServerLBBackendPoolNameDefault() 247 } 248 249 // SetNodeOutboundLBDefaults sets the default values for the NodeOutboundLB. 250 func (c *AzureCluster) SetNodeOutboundLBDefaults() { 251 if c.Spec.NetworkSpec.NodeOutboundLB == nil { 252 if c.Spec.NetworkSpec.APIServerLB.Type == Internal { 253 return 254 } 255 256 var needsOutboundLB bool 257 for _, subnet := range c.Spec.NetworkSpec.Subnets { 258 if (subnet.Role == SubnetNode || subnet.Role == SubnetCluster) && subnet.IsIPv6Enabled() { 259 needsOutboundLB = true 260 break 261 } 262 } 263 264 // If we don't default the outbound LB when there are some subnets with NAT gateway, 265 // and some without, those without wouldn't have outbound traffic. So taking the 266 // safer route, we configure the outbound LB in that scenario. 267 if !needsOutboundLB { 268 return 269 } 270 271 c.Spec.NetworkSpec.NodeOutboundLB = &LoadBalancerSpec{} 272 } 273 274 lb := c.Spec.NetworkSpec.NodeOutboundLB 275 lb.LoadBalancerClassSpec.setNodeOutboundLBDefaults() 276 277 if lb.Name == "" { 278 lb.Name = c.ObjectMeta.Name 279 } 280 281 if lb.FrontendIPsCount == nil { 282 lb.FrontendIPsCount = ptr.To[int32](1) 283 } 284 285 c.setOutboundLBFrontendIPs(lb, generateNodeOutboundIPName) 286 c.SetNodeOutboundLBBackendPoolNameDefault() 287 } 288 289 // SetControlPlaneOutboundLBDefaults sets the default values for the control plane's outbound LB. 290 func (c *AzureCluster) SetControlPlaneOutboundLBDefaults() { 291 lb := c.Spec.NetworkSpec.ControlPlaneOutboundLB 292 293 if lb == nil { 294 return 295 } 296 297 lb.LoadBalancerClassSpec.setControlPlaneOutboundLBDefaults() 298 if lb.Name == "" { 299 lb.Name = generateControlPlaneOutboundLBName(c.ObjectMeta.Name) 300 } 301 if lb.FrontendIPsCount == nil { 302 lb.FrontendIPsCount = ptr.To[int32](1) 303 } 304 c.setOutboundLBFrontendIPs(lb, generateControlPlaneOutboundIPName) 305 c.SetControlPlaneOutboundLBBackendPoolNameDefault() 306 } 307 308 // SetBackendPoolNameDefault defaults the backend pool name of the LBs. 309 func (c *AzureCluster) SetBackendPoolNameDefault() { 310 c.SetAPIServerLBBackendPoolNameDefault() 311 c.SetNodeOutboundLBBackendPoolNameDefault() 312 c.SetControlPlaneOutboundLBBackendPoolNameDefault() 313 } 314 315 // SetAPIServerLBBackendPoolNameDefault defaults the name of the backend pool for apiserver LB. 316 func (c *AzureCluster) SetAPIServerLBBackendPoolNameDefault() { 317 apiServerLB := &c.Spec.NetworkSpec.APIServerLB 318 if apiServerLB.BackendPool.Name == "" { 319 apiServerLB.BackendPool.Name = generateBackendAddressPoolName(apiServerLB.Name) 320 } 321 } 322 323 // SetNodeOutboundLBBackendPoolNameDefault defaults the name of the backend pool for node outbound LB. 324 func (c *AzureCluster) SetNodeOutboundLBBackendPoolNameDefault() { 325 nodeOutboundLB := c.Spec.NetworkSpec.NodeOutboundLB 326 if nodeOutboundLB != nil && nodeOutboundLB.BackendPool.Name == "" { 327 nodeOutboundLB.BackendPool.Name = generateOutboundBackendAddressPoolName(nodeOutboundLB.Name) 328 } 329 } 330 331 // SetControlPlaneOutboundLBBackendPoolNameDefault defaults the name of the backend pool for control plane outbound LB. 332 func (c *AzureCluster) SetControlPlaneOutboundLBBackendPoolNameDefault() { 333 controlPlaneOutboundLB := c.Spec.NetworkSpec.ControlPlaneOutboundLB 334 if controlPlaneOutboundLB != nil && controlPlaneOutboundLB.BackendPool.Name == "" { 335 controlPlaneOutboundLB.BackendPool.Name = generateOutboundBackendAddressPoolName(generateControlPlaneOutboundLBName(c.ObjectMeta.Name)) 336 } 337 } 338 339 // setOutboundLBFrontendIPs sets the frontend ips for the given load balancer. 340 // The name of the frontend ip is generated using generatePublicIPName function. 341 func (c *AzureCluster) setOutboundLBFrontendIPs(lb *LoadBalancerSpec, generatePublicIPName func(string) string) { 342 switch *lb.FrontendIPsCount { 343 case 0: 344 lb.FrontendIPs = []FrontendIP{} 345 case 1: 346 lb.FrontendIPs = []FrontendIP{ 347 { 348 Name: generateFrontendIPConfigName(lb.Name), 349 PublicIP: &PublicIPSpec{ 350 Name: generatePublicIPName(c.ObjectMeta.Name), 351 }, 352 }, 353 } 354 default: 355 lb.FrontendIPs = make([]FrontendIP, *lb.FrontendIPsCount) 356 for i := 0; i < int(*lb.FrontendIPsCount); i++ { 357 lb.FrontendIPs[i] = FrontendIP{ 358 Name: withIndex(generateFrontendIPConfigName(lb.Name), i+1), 359 PublicIP: &PublicIPSpec{ 360 Name: withIndex(generatePublicIPName(c.ObjectMeta.Name), i+1), 361 }, 362 } 363 } 364 } 365 } 366 367 func (c *AzureCluster) setBastionDefaults() { 368 if c.Spec.BastionSpec.AzureBastion != nil { 369 if c.Spec.BastionSpec.AzureBastion.Name == "" { 370 c.Spec.BastionSpec.AzureBastion.Name = generateAzureBastionName(c.ObjectMeta.Name) 371 } 372 // Ensure defaults for the Subnet settings. 373 if c.Spec.BastionSpec.AzureBastion.Subnet.Name == "" { 374 c.Spec.BastionSpec.AzureBastion.Subnet.Name = DefaultAzureBastionSubnetName 375 } 376 if len(c.Spec.BastionSpec.AzureBastion.Subnet.CIDRBlocks) == 0 { 377 c.Spec.BastionSpec.AzureBastion.Subnet.CIDRBlocks = []string{DefaultAzureBastionSubnetCIDR} 378 } 379 if c.Spec.BastionSpec.AzureBastion.Subnet.Role == "" { 380 c.Spec.BastionSpec.AzureBastion.Subnet.Role = DefaultAzureBastionSubnetRole 381 } 382 // Ensure defaults for the PublicIP settings. 383 if c.Spec.BastionSpec.AzureBastion.PublicIP.Name == "" { 384 c.Spec.BastionSpec.AzureBastion.PublicIP.Name = generateAzureBastionPublicIPName(c.ObjectMeta.Name) 385 } 386 } 387 } 388 389 func (lb *LoadBalancerClassSpec) setAPIServerLBDefaults() { 390 if lb.Type == "" { 391 lb.Type = Public 392 } 393 if lb.SKU == "" { 394 lb.SKU = SKUStandard 395 } 396 if lb.IdleTimeoutInMinutes == nil { 397 lb.IdleTimeoutInMinutes = ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes) 398 } 399 } 400 401 func (lb *LoadBalancerClassSpec) setNodeOutboundLBDefaults() { 402 lb.setOutboundLBDefaults() 403 } 404 405 func (lb *LoadBalancerClassSpec) setControlPlaneOutboundLBDefaults() { 406 lb.setOutboundLBDefaults() 407 } 408 409 func (lb *LoadBalancerClassSpec) setOutboundLBDefaults() { 410 lb.Type = Public 411 lb.SKU = SKUStandard 412 if lb.IdleTimeoutInMinutes == nil { 413 lb.IdleTimeoutInMinutes = ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes) 414 } 415 } 416 417 func setControlPlaneOutboundLBDefaults(lb *LoadBalancerClassSpec, apiserverLBType LBType) { 418 // public clusters don't need control plane outbound lb 419 if apiserverLBType == Public { 420 return 421 } 422 423 // private clusters can disable control plane outbound lb by setting it to nil. 424 if lb == nil { 425 return 426 } 427 428 lb.Type = Public 429 lb.SKU = SKUStandard 430 431 if lb.IdleTimeoutInMinutes == nil { 432 lb.IdleTimeoutInMinutes = ptr.To[int32](DefaultOutboundRuleIdleTimeoutInMinutes) 433 } 434 } 435 436 // generateVnetName generates a virtual network name, based on the cluster name. 437 func generateVnetName(clusterName string) string { 438 return fmt.Sprintf("%s-%s", clusterName, "vnet") 439 } 440 441 // generateClusterSubnetSubnetName generates a subnet name, based on the cluster name. 442 func generateClusterSubnetSubnetName(clusterName string) string { 443 return fmt.Sprintf("%s-%s", clusterName, "subnet") 444 } 445 446 // generateControlPlaneSubnetName generates a node subnet name, based on the cluster name. 447 func generateControlPlaneSubnetName(clusterName string) string { 448 return fmt.Sprintf("%s-%s", clusterName, "controlplane-subnet") 449 } 450 451 // generateNodeSubnetName generates a node subnet name, based on the cluster name. 452 func generateNodeSubnetName(clusterName string) string { 453 return fmt.Sprintf("%s-%s", clusterName, "node-subnet") 454 } 455 456 // generateAzureBastionName generates an azure bastion name. 457 func generateAzureBastionName(clusterName string) string { 458 return fmt.Sprintf("%s-azure-bastion", clusterName) 459 } 460 461 // generateAzureBastionPublicIPName generates an azure bastion public ip name. 462 func generateAzureBastionPublicIPName(clusterName string) string { 463 return fmt.Sprintf("%s-azure-bastion-pip", clusterName) 464 } 465 466 // generateClusterSecurityGroupName generates a security group name, based on the cluster name. 467 func generateClusterSecurityGroupName(clusterName string) string { 468 return fmt.Sprintf("%s-%s", clusterName, "nsg") 469 } 470 471 // generateControlPlaneSecurityGroupName generates a control plane security group name, based on the cluster name. 472 func generateControlPlaneSecurityGroupName(clusterName string) string { 473 return fmt.Sprintf("%s-%s", clusterName, "controlplane-nsg") 474 } 475 476 // generateNodeSecurityGroupName generates a node security group name, based on the cluster name. 477 func generateNodeSecurityGroupName(clusterName string) string { 478 return fmt.Sprintf("%s-%s", clusterName, "node-nsg") 479 } 480 481 // generateClustereRouteTableName generates a route table name, based on the cluster name. 482 func generateClustereRouteTableName(clusterName string) string { 483 return fmt.Sprintf("%s-%s", clusterName, "routetable") 484 } 485 486 // generateNodeRouteTableName generates a node route table name, based on the cluster name. 487 func generateNodeRouteTableName(clusterName string) string { 488 return fmt.Sprintf("%s-%s", clusterName, "node-routetable") 489 } 490 491 // generateInternalLBName generates a internal load balancer name, based on the cluster name. 492 func generateInternalLBName(clusterName string) string { 493 return fmt.Sprintf("%s-%s", clusterName, "internal-lb") 494 } 495 496 // generatePublicLBName generates a public load balancer name, based on the cluster name. 497 func generatePublicLBName(clusterName string) string { 498 return fmt.Sprintf("%s-%s", clusterName, "public-lb") 499 } 500 501 // generateControlPlaneOutboundLBName generates the name of the control plane outbound LB. 502 func generateControlPlaneOutboundLBName(clusterName string) string { 503 return fmt.Sprintf("%s-outbound-lb", clusterName) 504 } 505 506 // generatePublicIPName generates a public IP name, based on the cluster name and a hash. 507 func generatePublicIPName(clusterName string) string { 508 return fmt.Sprintf("pip-%s-apiserver", clusterName) 509 } 510 511 // generateFrontendIPConfigName generates a load balancer frontend IP config name. 512 func generateFrontendIPConfigName(lbName string) string { 513 return fmt.Sprintf("%s-%s", lbName, "frontEnd") 514 } 515 516 // generateNodeOutboundIPName generates a public IP name, based on the cluster name. 517 func generateNodeOutboundIPName(clusterName string) string { 518 return fmt.Sprintf("pip-%s-node-outbound", clusterName) 519 } 520 521 // generateControlPlaneOutboundIPName generates a public IP name, based on the cluster name. 522 func generateControlPlaneOutboundIPName(clusterName string) string { 523 return fmt.Sprintf("pip-%s-controlplane-outbound", clusterName) 524 } 525 526 // generateClusterNatGatewayName generates a NAT gateway name. 527 func generateClusterNatGatewayName(clusterName string) string { 528 return fmt.Sprintf("%s-%s", clusterName, "natgw") 529 } 530 531 // generateNatGatewayName generates a NAT gateway name. 532 func generateNatGatewayName(clusterName string) string { 533 return fmt.Sprintf("%s-%s", clusterName, "node-natgw") 534 } 535 536 // generateNatGatewayIPName generates a NAT gateway IP name. 537 func generateNatGatewayIPName(natGatewayName string) string { 538 return fmt.Sprintf("pip-%s", natGatewayName) 539 } 540 541 // withIndex appends the index as suffix to a generated name. 542 func withIndex(name string, n int) string { 543 return fmt.Sprintf("%s-%d", name, n) 544 } 545 546 // generateBackendAddressPoolName generates a load balancer backend address pool name. 547 func generateBackendAddressPoolName(lbName string) string { 548 return fmt.Sprintf("%s-%s", lbName, "backendPool") 549 } 550 551 // generateOutboundBackendAddressPoolName generates a load balancer outbound backend address pool name. 552 func generateOutboundBackendAddressPoolName(lbName string) string { 553 return fmt.Sprintf("%s-%s", lbName, "outboundBackendPool") 554 }