Skip to content

Commit

Permalink
Merge pull request #25826 from freehan/svcsourcerange
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue

promote sourceRange into service spec

@thockin  one more for your pile

I will add docs at `http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md`

cc: @justinsb 

Fixes: #20392
  • Loading branch information
k8s-merge-robot committed May 28, 2016
2 parents 3f455fb + 466bc38 commit a550cf1
Show file tree
Hide file tree
Showing 25 changed files with 533 additions and 174 deletions.
7 changes: 7 additions & 0 deletions api/swagger-spec/v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -19175,6 +19175,13 @@
"loadBalancerIP": {
"type": "string",
"description": "Only applies to Service Type: LoadBalancer LoadBalancer will get created with the IP specified in this field. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature."
},
"loadBalancerSourceRanges": {
"type": "array",
"items": {
"type": "string"
},
"description": "If specified and supported by the platform, this will restrict traffic through the cloud-provider load-balancer will be restricted to the specified client IPs. This field will be ignored if the cloud-provider does not support the feature.\" More info: http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md"
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion docs/api-reference/autoscaling/v1/definitions.html
Original file line number Diff line number Diff line change
Expand Up @@ -1320,7 +1320,7 @@ <h3 id="_any">any</h3>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-05-02 18:47:14 UTC
Last updated 2016-05-23 07:07:20 UTC
</div>
</div>
</body>
Expand Down
9 changes: 8 additions & 1 deletion docs/api-reference/v1/definitions.html
Original file line number Diff line number Diff line change
Expand Up @@ -7770,6 +7770,13 @@ <h3 id="_v1_servicespec">v1.ServiceSpec</h3>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">loadBalancerSourceRanges</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If specified and supported by the platform, this will restrict traffic through the cloud-provider load-balancer will be restricted to the specified client IPs. This field will be ignored if the cloud-provider does not support the feature." More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md">http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>

Expand Down Expand Up @@ -7984,7 +7991,7 @@ <h3 id="_any">any</h3>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-05-24 11:53:20 UTC
Last updated 2016-05-26 18:58:49 UTC
</div>
</div>
</body>
Expand Down
7 changes: 7 additions & 0 deletions pkg/api/deep_copy_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -3007,6 +3007,13 @@ func DeepCopy_api_ServiceSpec(in ServiceSpec, out *ServiceSpec, c *conversion.Cl
}
out.LoadBalancerIP = in.LoadBalancerIP
out.SessionAffinity = in.SessionAffinity
if in.LoadBalancerSourceRanges != nil {
in, out := in.LoadBalancerSourceRanges, &out.LoadBalancerSourceRanges
*out = make([]string, len(in))
copy(*out, in)
} else {
out.LoadBalancerSourceRanges = nil
}
return nil
}

Expand Down
36 changes: 25 additions & 11 deletions pkg/api/service/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"strings"

"k8s.io/kubernetes/pkg/api"
netsets "k8s.io/kubernetes/pkg/util/net/sets"
)

Expand All @@ -37,18 +38,31 @@ func IsAllowAll(ipnets netsets.IPNet) bool {
return false
}

// GetLoadBalancerSourceRanges verifies and parses the AnnotationLoadBalancerSourceRangesKey annotation from a service,
// GetLoadBalancerSourceRanges first try to parse and verify LoadBalancerSourceRanges field from a service.
// If the field is not specified, turn to parse and verify the AnnotationLoadBalancerSourceRangesKey annotation from a service,
// extracting the source ranges to allow, and if not present returns a default (allow-all) value.
func GetLoadBalancerSourceRanges(annotations map[string]string) (netsets.IPNet, error) {
val := annotations[AnnotationLoadBalancerSourceRangesKey]
val = strings.TrimSpace(val)
if val == "" {
val = defaultLoadBalancerSourceRanges
}
specs := strings.Split(val, ",")
ipnets, err := netsets.ParseIPNets(specs...)
if err != nil {
return nil, fmt.Errorf("Service annotation %s:%s is not valid. Expecting a comma-separated list of source IP ranges. For example, 10.0.0.0/24,192.168.2.0/24", AnnotationLoadBalancerSourceRangesKey, val)
func GetLoadBalancerSourceRanges(service *api.Service) (netsets.IPNet, error) {
var ipnets netsets.IPNet
var err error
// if SourceRange field is specified, ignore sourceRange annotation
if len(service.Spec.LoadBalancerSourceRanges) > 0 {
specs := service.Spec.LoadBalancerSourceRanges
ipnets, err = netsets.ParseIPNets(specs...)

if err != nil {
return nil, fmt.Errorf("service.Spec.LoadBalancerSourceRanges: %v is not valid. Expecting a list of IP ranges. For example, 10.0.0.0/24. Error msg: %v", specs, err)
}
} else {
val := service.Annotations[AnnotationLoadBalancerSourceRangesKey]
val = strings.TrimSpace(val)
if val == "" {
val = defaultLoadBalancerSourceRanges
}
specs := strings.Split(val, ",")
ipnets, err = netsets.ParseIPNets(specs...)
if err != nil {
return nil, fmt.Errorf("%s: %s is not valid. Expecting a comma-separated list of source IP ranges. For example, 10.0.0.0/24,192.168.2.0/24", AnnotationLoadBalancerSourceRangesKey, val)
}
}
return ipnets, nil
}
44 changes: 41 additions & 3 deletions pkg/api/service/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,24 @@ package service
import (
"testing"

"k8s.io/kubernetes/pkg/api"
netsets "k8s.io/kubernetes/pkg/util/net/sets"
"strings"
)

func TestGetLoadBalancerSourceRanges(t *testing.T) {
checkError := func(v string) {
annotations := make(map[string]string)
annotations[AnnotationLoadBalancerSourceRangesKey] = v
_, err := GetLoadBalancerSourceRanges(annotations)
svc := api.Service{}
svc.Annotations = annotations
_, err := GetLoadBalancerSourceRanges(&svc)
if err == nil {
t.Errorf("Expected error parsing: %q", v)
}
svc = api.Service{}
svc.Spec.LoadBalancerSourceRanges = strings.Split(v, ",")
_, err = GetLoadBalancerSourceRanges(&svc)
if err == nil {
t.Errorf("Expected error parsing: %q", v)
}
Expand All @@ -41,7 +51,15 @@ func TestGetLoadBalancerSourceRanges(t *testing.T) {
checkOK := func(v string) netsets.IPNet {
annotations := make(map[string]string)
annotations[AnnotationLoadBalancerSourceRangesKey] = v
cidrs, err := GetLoadBalancerSourceRanges(annotations)
svc := api.Service{}
svc.Annotations = annotations
cidrs, err := GetLoadBalancerSourceRanges(&svc)
if err != nil {
t.Errorf("Unexpected error parsing: %q", v)
}
svc = api.Service{}
svc.Spec.LoadBalancerSourceRanges = strings.Split(v, ",")
cidrs, err = GetLoadBalancerSourceRanges(&svc)
if err != nil {
t.Errorf("Unexpected error parsing: %q", v)
}
Expand All @@ -63,7 +81,27 @@ func TestGetLoadBalancerSourceRanges(t *testing.T) {
if len(cidrs) != 2 {
t.Errorf("Expected two CIDRs: %v", cidrs.StringSlice())
}
cidrs = checkOK("")
// check LoadBalancerSourceRanges not specified
svc := api.Service{}
cidrs, err := GetLoadBalancerSourceRanges(&svc)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if len(cidrs) != 1 {
t.Errorf("Expected exactly one CIDR: %v", cidrs.StringSlice())
}
if !IsAllowAll(cidrs) {
t.Errorf("Expected default to be allow-all: %v", cidrs.StringSlice())
}
// check SourceRanges annotation is empty
annotations := make(map[string]string)
annotations[AnnotationLoadBalancerSourceRangesKey] = ""
svc = api.Service{}
svc.Annotations = annotations
cidrs, err = GetLoadBalancerSourceRanges(&svc)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if len(cidrs) != 1 {
t.Errorf("Expected exactly one CIDR: %v", cidrs.StringSlice())
}
Expand Down
Loading

0 comments on commit a550cf1

Please sign in to comment.