Merge pull request #36696 from brendandburns/azure

Automatic merge from submit-queue

Add support for service load balancer source ranges to Azure load balancers.

@colemickens @kubernetes/sig-network
This commit is contained in:
Kubernetes Submit Queue 2016-11-13 21:00:38 -08:00 committed by GitHub
commit d5014c3f21
2 changed files with 82 additions and 32 deletions

View File

@ -474,25 +474,41 @@ func (az *Cloud) reconcileLoadBalancer(lb network.LoadBalancer, pip *network.Pub
func (az *Cloud) reconcileSecurityGroup(sg network.SecurityGroup, clusterName string, service *api.Service) (network.SecurityGroup, bool, error) { func (az *Cloud) reconcileSecurityGroup(sg network.SecurityGroup, clusterName string, service *api.Service) (network.SecurityGroup, bool, error) {
serviceName := getServiceName(service) serviceName := getServiceName(service)
wantLb := len(service.Spec.Ports) > 0 wantLb := len(service.Spec.Ports) > 0
expectedSecurityRules := make([]network.SecurityRule, len(service.Spec.Ports))
sourceRanges, err := serviceapi.GetLoadBalancerSourceRanges(service)
if err != nil {
return sg, false, err
}
var sourceAddressPrefixes []string
if sourceRanges == nil || serviceapi.IsAllowAll(sourceRanges) {
sourceAddressPrefixes = []string{"Internet"}
} else {
for _, ip := range sourceRanges {
sourceAddressPrefixes = append(sourceAddressPrefixes, ip.String())
}
}
expectedSecurityRules := make([]network.SecurityRule, len(service.Spec.Ports)*len(sourceAddressPrefixes))
for i, port := range service.Spec.Ports { for i, port := range service.Spec.Ports {
securityRuleName := getRuleName(service, port) securityRuleName := getRuleName(service, port)
_, securityProto, _, err := getProtocolsFromKubernetesProtocol(port.Protocol) _, securityProto, _, err := getProtocolsFromKubernetesProtocol(port.Protocol)
if err != nil { if err != nil {
return sg, false, err return sg, false, err
} }
for j := range sourceAddressPrefixes {
expectedSecurityRules[i] = network.SecurityRule{ ix := i*len(sourceAddressPrefixes) + j
Name: to.StringPtr(securityRuleName), expectedSecurityRules[ix] = network.SecurityRule{
Properties: &network.SecurityRulePropertiesFormat{ Name: to.StringPtr(securityRuleName),
Protocol: securityProto, Properties: &network.SecurityRulePropertiesFormat{
SourcePortRange: to.StringPtr("*"), Protocol: securityProto,
DestinationPortRange: to.StringPtr(strconv.Itoa(int(port.Port))), SourcePortRange: to.StringPtr("*"),
SourceAddressPrefix: to.StringPtr("Internet"), DestinationPortRange: to.StringPtr(strconv.Itoa(int(port.Port))),
DestinationAddressPrefix: to.StringPtr("*"), SourceAddressPrefix: to.StringPtr(sourceAddressPrefixes[j]),
Access: network.Allow, DestinationAddressPrefix: to.StringPtr("*"),
Direction: network.Inbound, Access: network.Allow,
}, Direction: network.Inbound,
},
}
} }
} }

View File

@ -187,6 +187,23 @@ func TestReconcileSecurityGroupRemoveServiceRemovesPort(t *testing.T) {
validateSecurityGroup(t, sg, svcUpdated) validateSecurityGroup(t, sg, svcUpdated)
} }
func TestReconcileSecurityWithSourceRanges(t *testing.T) {
az := getTestCloud()
svc := getTestService("servicea", 80, 443)
svc.Spec.LoadBalancerSourceRanges = []string{
"192.168.0.1/24",
"10.0.0.1/32",
}
sg := getTestSecurityGroup(svc)
sg, _, err := az.reconcileSecurityGroup(sg, testClusterName, &svc)
if err != nil {
t.Errorf("Unexpected error: %q", err)
}
validateSecurityGroup(t, sg, svc)
}
func getTestCloud() *Cloud { func getTestCloud() *Cloud {
return &Cloud{ return &Cloud{
Config: Config{ Config: Config{
@ -269,18 +286,30 @@ func getTestLoadBalancer(services ...api.Service) network.LoadBalancer {
return lb return lb
} }
func getServiceSourceRanges(service *api.Service) []string {
if len(service.Spec.LoadBalancerSourceRanges) == 0 {
return []string{"Internet"}
}
return service.Spec.LoadBalancerSourceRanges
}
func getTestSecurityGroup(services ...api.Service) network.SecurityGroup { func getTestSecurityGroup(services ...api.Service) network.SecurityGroup {
rules := []network.SecurityRule{} rules := []network.SecurityRule{}
for _, service := range services { for _, service := range services {
for _, port := range service.Spec.Ports { for _, port := range service.Spec.Ports {
ruleName := getRuleName(&service, port) ruleName := getRuleName(&service, port)
rules = append(rules, network.SecurityRule{
Name: to.StringPtr(ruleName), sources := getServiceSourceRanges(&service)
Properties: &network.SecurityRulePropertiesFormat{ for _, src := range sources {
DestinationPortRange: to.StringPtr(fmt.Sprintf("%d", port.Port)), rules = append(rules, network.SecurityRule{
}, Name: to.StringPtr(ruleName),
}) Properties: &network.SecurityRulePropertiesFormat{
SourceAddressPrefix: to.StringPtr(src),
DestinationPortRange: to.StringPtr(fmt.Sprintf("%d", port.Port)),
},
})
}
} }
} }
@ -344,7 +373,7 @@ func validateLoadBalancer(t *testing.T, loadBalancer network.LoadBalancer, servi
lenRules := len(*loadBalancer.Properties.LoadBalancingRules) lenRules := len(*loadBalancer.Properties.LoadBalancingRules)
if lenRules != expectedRuleCount { if lenRules != expectedRuleCount {
t.Errorf("Expected the loadbalancer to have %d rules. Found %d.", expectedRuleCount, lenRules) t.Errorf("Expected the loadbalancer to have %d rules. Found %d.\n%v", expectedRuleCount, lenRules, loadBalancer.Properties.LoadBalancingRules)
} }
lenProbes := len(*loadBalancer.Properties.Probes) lenProbes := len(*loadBalancer.Properties.Probes)
if lenProbes != expectedRuleCount { if lenProbes != expectedRuleCount {
@ -356,25 +385,30 @@ func validateSecurityGroup(t *testing.T, securityGroup network.SecurityGroup, se
expectedRuleCount := 0 expectedRuleCount := 0
for _, svc := range services { for _, svc := range services {
for _, wantedRule := range svc.Spec.Ports { for _, wantedRule := range svc.Spec.Ports {
expectedRuleCount++ sources := getServiceSourceRanges(&svc)
wantedRuleName := getRuleName(&svc, wantedRule)
foundRule := false for _, source := range sources {
for _, actualRule := range *securityGroup.Properties.SecurityRules { expectedRuleCount++
if strings.EqualFold(*actualRule.Name, wantedRuleName) && wantedRuleName := getRuleName(&svc, wantedRule)
*actualRule.Properties.DestinationPortRange == fmt.Sprintf("%d", wantedRule.Port) { foundRule := false
foundRule = true for _, actualRule := range *securityGroup.Properties.SecurityRules {
break if strings.EqualFold(*actualRule.Name, wantedRuleName) &&
*actualRule.Properties.SourceAddressPrefix == source &&
*actualRule.Properties.DestinationPortRange == fmt.Sprintf("%d", wantedRule.Port) {
foundRule = true
break
}
}
if !foundRule {
t.Errorf("Expected security group rule but didn't find it: %q", wantedRuleName)
} }
}
if !foundRule {
t.Errorf("Expected security group rule but didn't find it: %q", wantedRuleName)
} }
} }
} }
lenRules := len(*securityGroup.Properties.SecurityRules) lenRules := len(*securityGroup.Properties.SecurityRules)
if lenRules != expectedRuleCount { if lenRules != expectedRuleCount {
t.Errorf("Expected the loadbalancer to have %d rules. Found %d.", expectedRuleCount, lenRules) t.Errorf("Expected the loadbalancer to have %d rules. Found %d.\n", expectedRuleCount, lenRules)
} }
} }