Change:
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks! If the matter is security related, please disclose it privately via --What happened: When the specified internal LB uses a subnet with longer name, the LB configuration will fail with following error: What you expected to happen: When constructing the frontend IP configuration name and the load balancing rules name, the subnet name should be truncated if too long. How to reproduce it (as minimally and precisely as possible): Use a subnet that has long name (70 charactors) and create ILB service. Anything else we need to know?: Environment: Kubernetes version (use ): 1.15 Cloud provider or hardware configuration: azure OS (e.g: ): Ubuntu 16.04 Kernel (e.g. ): Install tools: Network plugin and version (if this is a network-related bug): Others:
/sig cloud-provider /area provider/azure /assign

Discussion:
return nil, nil } isInternal := requiresInternalLoadBalancer(service) <del> lbFrontendIPConfigName := az.getFrontendIPConfigName(service, subnet(service)) </del> <ins> lbFrontendIPConfigName := az.getFrontendIPConfigName(service) </ins> serviceName := getServiceName(service) for _, ipConfiguration := range *lb.FrontendIPConfigurations { if lbFrontendIPConfigName == *ipConfiguration.Name {

} lbName := *lb.Name klog.V(2).Infof("reconcileLoadBalancer for service(%s): lb(%s) wantLb(%t) resolved load balancer name", serviceName, lbName, wantLb) <del> lbFrontendIPConfigName := az.getFrontendIPConfigName(service, subnet(service)) </del> <ins> lbFrontendIPConfigName := az.getFrontendIPConfigName(service) </ins> lbFrontendIPConfigID := az.getFrontendIPConfigID(lbName, lbFrontendIPConfigName) lbBackendPoolName := getBackendPoolName(az.ipv6DualStackEnabled, clusterName, service) lbBackendPoolID := az.getBackendPoolID(lbName, lbBackendPoolName)

} for _, protocol := range protocols { <del> lbRuleName := az.getLoadBalancerRuleName(service, protocol, port.Port, subnet(service)) </del> <ins> lbRuleName := az.getLoadBalancerRuleName(service, protocol, port.Port) </ins> klog.V(2).Infof("reconcileLoadBalancerRule lb name (%s) rule name (%s)", lbName, lbRuleName) transportProto, _, probeProto, err := getProtocolsFromKubernetesProtocol(protocol)

}, { desc: "getServiceLoadBalancerStatus shall return nil if lb.FrontendIPConfigurations.name != " + <del> "az.getFrontendIPConfigName(service, subnet(service))", </del> <ins> "az.getFrontendIPConfigName(service)", </ins> service: &internalService, lb:      &lb3, },

nodeLabelRole  = "kubernetes.io/role" nicFailedState = "Failed" <del> storageAccountNameMaxLength = 24 </del> <ins> storageAccountNameMaxLength   = 24 frontendIPConfigNameMaxLength = 80 loadBalancerRuleNameMaxLength = 80 </ins> ) var errNotInVMSet = errors.New("vm is not in the vmset")

return clusterName } <del> func (az *Cloud) getLoadBalancerRuleName(service *v1.Service, protocol v1.Protocol, port int32, subnetName *string) string { </del> <ins> func (az *Cloud) getLoadBalancerRuleName(service *v1.Service, protocol v1.Protocol, port int32) string { </ins> prefix := az.getRulePrefix(service) <del> if subnetName == nil { return fmt.Sprintf("%s-%s-%d", prefix, protocol, port) </del> <ins> ruleName := fmt.Sprintf("%s-%s-%d", prefix, protocol, port) subnet := subnet(service) if subnet == nil { return ruleName </ins> } <del> return fmt.Sprintf("%s-%s-%s-%d", prefix, *subnetName, protocol, port) </del> <ins> // Load balancer rule name must be less or equal to 80 characters, so excluding the hyphen two segments cannot exceed 79 subnetSegment := *subnet if len(ruleName)+len(subnetSegment)+1 > loadBalancerRuleNameMaxLength { subnetSegment = subnetSegment[:loadBalancerRuleNameMaxLength-len(ruleName)-1] } return fmt.Sprintf("%s-%s-%s-%d", prefix, subnetSegment, protocol, port) </ins> } func (az *Cloud) getSecurityRuleName(service *v1.Service, port v1.ServicePort, sourceAddrPrefix string) string {

return strings.HasPrefix(*fip.Name, baseName) } <del> func (az *Cloud) getFrontendIPConfigName(service *v1.Service, subnetName *string) string { </del> <ins> func (az *Cloud) getFrontendIPConfigName(service *v1.Service) string { </ins> baseName := az.GetLoadBalancerName(context.TODO(), "", service) <ins> subnetName := subnet(service) </ins> if subnetName != nil { <del> return fmt.Sprintf("%s-%s", baseName, *subnetName) </del> <ins> ipcName := fmt.Sprintf("%s-%s", baseName, *subnetName) // Azure lb front end configuration name must not exceed 80 characters if len(ipcName) > frontendIPConfigNameMaxLength { ipcName = ipcName[:frontendIPConfigNameMaxLength] } return ipcName </ins> } return baseName }

package azure import ( <ins> "strconv" </ins> "testing" "github.com/stretchr/testify/assert"

assert.Equal(t, c.expected, loadbalancerName, c.description) } } <ins> func TestGetLoadBalancingRuleName(t *testing.T) { az := getTestCloud() az.PrimaryAvailabilitySetName = "primary" svc := &v1.Service{ ObjectMeta: meta.ObjectMeta{ Annotations: map[string]string{}, UID:         "257b9655-5137-4ad2-b091-ef3f07043ad3", }, } cases := []struct { description   string subnetName    string isInternal    bool useStandardLB bool protocol      v1.Protocol port          int32 expected      string }{ { description:   "internal lb should have subnet name on the rule name", subnetName:    "shortsubnet", isInternal:    true, useStandardLB: true, protocol:      v1.ProtocolTCP, port:          9000, expected:      "a257b965551374ad2b091ef3f07043ad-shortsubnet-TCP-9000", }, { description:   "internal standard lb should have subnet name on the rule name but truncated to 80 characters", subnetName:    "averylonnnngggnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggggggggggggggggggggggsubet", isInternal:    true, useStandardLB: true, protocol:      v1.ProtocolTCP, port:          9000, expected:      "a257b965551374ad2b091ef3f07043ad-averylonnnngggnnnnnnnnnnnnnnnnnnnnnngg-TCP-9000", }, { description:   "internal basic lb should have subnet name on the rule name but truncated to 80 characters", subnetName:    "averylonnnngggnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggggggggggggggggggggggsubet", isInternal:    true, useStandardLB: false, protocol:      v1.ProtocolTCP, port:          9000, expected:      "a257b965551374ad2b091ef3f07043ad-averylonnnngggnnnnnnnnnnnnnnnnnnnnnngg-TCP-9000", }, { description:   "external standard lb should not have subnet name on the rule name", subnetName:    "shortsubnet", isInternal:    false, useStandardLB: true, protocol:      v1.ProtocolTCP, port:          9000, expected:      "a257b965551374ad2b091ef3f07043ad-TCP-9000", }, { description:   "external basic lb should not have subnet name on the rule name", subnetName:    "shortsubnet", isInternal:    false, useStandardLB: false, protocol:      v1.ProtocolTCP, port:          9000, expected:      "a257b965551374ad2b091ef3f07043ad-TCP-9000", }, } for _, c := range cases { if c.useStandardLB { az.Config.LoadBalancerSku = loadBalancerSkuStandard } else { az.Config.LoadBalancerSku = loadBalancerSkuBasic } svc.Annotations[ServiceAnnotationLoadBalancerInternalSubnet] = c.subnetName svc.Annotations[ServiceAnnotationLoadBalancerInternal] = strconv.FormatBool(c.isInternal) loadbalancerRuleName := az.getLoadBalancerRuleName(svc, c.protocol, c.port) assert.Equal(t, c.expected, loadbalancerRuleName, c.description) } } func TestGetFrontendIPConfigName(t *testing.T) { az := getTestCloud() az.PrimaryAvailabilitySetName = "primary" svc := &v1.Service{ ObjectMeta: meta.ObjectMeta{ Annotations: map[string]string{ ServiceAnnotationLoadBalancerInternalSubnet: "subnet", ServiceAnnotationLoadBalancerInternal:       "true", }, UID: "257b9655-5137-4ad2-b091-ef3f07043ad3", }, } cases := []struct { description   string subnetName    string isInternal    bool useStandardLB bool expected      string }{ { description:   "internal lb should have subnet name on the frontend ip configuration name", subnetName:    "shortsubnet", isInternal:    true, useStandardLB: true, expected:      "a257b965551374ad2b091ef3f07043ad-shortsubnet", }, { description:   "internal standard lb should have subnet name on the frontend ip configuration name but truncated to 80 characters", subnetName:    "averylonnnngggnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggggggggggggggggggggggsubet", isInternal:    true, useStandardLB: true, expected:      "a257b965551374ad2b091ef3f07043ad-averylonnnngggnnnnnnnnnnnnnnnnnnnnnnggggggggggg", }, { description:   "internal basic lb should have subnet name on the frontend ip configuration name but truncated to 80 characters", subnetName:    "averylonnnngggnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggggggggggggggggggggggsubet", isInternal:    true, useStandardLB: false, expected:      "a257b965551374ad2b091ef3f07043ad-averylonnnngggnnnnnnnnnnnnnnnnnnnnnnggggggggggg", }, { description:   "external standard lb should not have subnet name on the frontend ip configuration name", subnetName:    "shortsubnet", isInternal:    false, useStandardLB: true, expected:      "a257b965551374ad2b091ef3f07043ad", }, { description:   "external basic lb should not have subnet name on the frontend ip configuration name", subnetName:    "shortsubnet", isInternal:    false, useStandardLB: false, expected:      "a257b965551374ad2b091ef3f07043ad", }, } for _, c := range cases { if c.useStandardLB { az.Config.LoadBalancerSku = loadBalancerSkuStandard } else { az.Config.LoadBalancerSku = loadBalancerSkuBasic } svc.Annotations[ServiceAnnotationLoadBalancerInternalSubnet] = c.subnetName svc.Annotations[ServiceAnnotationLoadBalancerInternal] = strconv.FormatBool(c.isInternal) ipconfigName := az.getFrontendIPConfigName(svc) assert.Equal(t, c.expected, ipconfigName, c.description) } } </ins>

if len(svc.Spec.Ports) > 0 { expectedFrontendIPCount++ expectedFrontendIP := ExpectedFrontendIPInfo{ <del> Name:   az.getFrontendIPConfigName(&svc, subnet(&svc)), </del> <ins> Name:   az.getFrontendIPConfigName(&svc), </ins> Subnet: subnet(&svc), } expectedFrontendIPs = append(expectedFrontendIPs, expectedFrontendIP) } for _, wantedRule := range svc.Spec.Ports { expectedRuleCount++ <del> wantedRuleName := az.getLoadBalancerRuleName(&svc, wantedRule.Protocol, wantedRule.Port, subnet(&svc)) </del> <ins> wantedRuleName := az.getLoadBalancerRuleName(&svc, wantedRule.Protocol, wantedRule.Port) </ins> foundRule := false for _, actualRule := range *loadBalancer.LoadBalancingRules { if strings.EqualFold(*actualRule.Name, wantedRuleName) &&