Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion source/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ type serviceSource struct {
nodeInformer coreinformers.NodeInformer
serviceTypeFilter *serviceTypes
exposeInternalIPv6 bool
excludeUnschedulable bool

// process Services with legacy annotations
compatibility string
Expand All @@ -98,7 +99,7 @@ func NewServiceSource(
ignoreHostnameAnnotation bool,
labelSelector labels.Selector,
resolveLoadBalancerHostname,
listenEndpointEvents, exposeInternalIPv6 bool,
listenEndpointEvents, exposeInternalIPv6, excludeUnschedulable bool,
) (Source, error) {
tmpl, err := fqdn.ParseTemplate(fqdnTemplate)
if err != nil {
Expand Down Expand Up @@ -224,6 +225,7 @@ func NewServiceSource(
resolveLoadBalancerHostname: resolveLoadBalancerHostname,
listenEndpointEvents: listenEndpointEvents,
exposeInternalIPv6: exposeInternalIPv6,
excludeUnschedulable: excludeUnschedulable,
}, nil
}

Expand Down Expand Up @@ -812,6 +814,10 @@ func (sc *serviceSource) extractNodePortTargets(svc *v1.Service) (endpoint.Targe
}

for _, node := range nodes {
if node.Spec.Unschedulable && sc.excludeUnschedulable {
log.Debugf("Skipping node %s - unschedulable", node.Name)
continue
}
for _, address := range node.Status.Addresses {
switch address.Type {
case v1.NodeExternalIP:
Expand Down
1 change: 1 addition & 0 deletions source/service_fqdn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ func TestServiceSourceFqdnTemplatingExamples(t *testing.T) {
false,
false,
true,
true,
)
require.NoError(t, err)

Expand Down
66 changes: 66 additions & 0 deletions source/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ func (suite *ServiceSuite) SetupTest() {
false,
false,
false,
false,
)
suite.NoError(err, "should initialize service source")
}
Expand Down Expand Up @@ -181,6 +182,7 @@ func testServiceSourceNewServiceSource(t *testing.T) {
false,
false,
false,
false,
)

if ti.expectError {
Expand Down Expand Up @@ -1165,6 +1167,7 @@ func testServiceSourceEndpoints(t *testing.T) {
tc.resolveLoadBalancerHostname,
false,
false,
false,
)

require.NoError(t, err)
Expand Down Expand Up @@ -1381,6 +1384,7 @@ func testMultipleServicesEndpoints(t *testing.T) {
false,
false,
false,
false,
)
require.NoError(t, err)

Expand Down Expand Up @@ -1686,6 +1690,7 @@ func TestClusterIpServices(t *testing.T) {
false,
false,
false,
false,
)
require.NoError(t, err)

Expand Down Expand Up @@ -1718,6 +1723,7 @@ func TestServiceSourceNodePortServices(t *testing.T) {
fqdnTemplate string
ignoreHostnameAnnotation bool
exposeInternalIPv6 bool
ignoreUnscheduledNodes bool
labels map[string]string
annotations map[string]string
lbs []string
Expand Down Expand Up @@ -2383,6 +2389,55 @@ func TestServiceSourceNodePortServices(t *testing.T) {
},
}},
},
{
title: "NodePort services ignore unschedulable node",
ignoreUnscheduledNodes: true,
svcNamespace: "testing",
svcName: "foo",
svcType: v1.ServiceTypeNodePort,
svcTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeCluster,
labels: map[string]string{},
annotations: map[string]string{
annotations.HostnameKey: "foo.example.org.",
annotations.AccessKey: "public",
},
expected: []*endpoint.Endpoint{
{DNSName: "_foo._tcp.foo.example.org", Targets: endpoint.Targets{"0 50 30192 foo.example.org."}, RecordType: endpoint.RecordTypeSRV},
{DNSName: "foo.example.org", Targets: endpoint.Targets{"54.10.11.2"}, RecordType: endpoint.RecordTypeA},
{DNSName: "foo.example.org", Targets: endpoint.Targets{"2001:DB8::3"}, RecordType: endpoint.RecordTypeAAAA},
},
nodes: []*v1.Node{{
ObjectMeta: metav1.ObjectMeta{
Name: "node1",
},
Spec: v1.NodeSpec{
Unschedulable: true,
},
Status: v1.NodeStatus{
Addresses: []v1.NodeAddress{
{Type: v1.NodeExternalIP, Address: "54.10.11.1"},
{Type: v1.NodeInternalIP, Address: "10.0.1.1"},
{Type: v1.NodeExternalIP, Address: "2001:DB8::1"},
{Type: v1.NodeInternalIP, Address: "2001:DB8::2"},
},
},
}, {
ObjectMeta: metav1.ObjectMeta{
Name: "node2",
},
Spec: v1.NodeSpec{
Unschedulable: false,
},
Status: v1.NodeStatus{
Addresses: []v1.NodeAddress{
{Type: v1.NodeExternalIP, Address: "54.10.11.2"},
{Type: v1.NodeInternalIP, Address: "10.0.1.2"},
{Type: v1.NodeExternalIP, Address: "2001:DB8::3"},
{Type: v1.NodeInternalIP, Address: "2001:DB8::4"},
},
},
}},
},
} {

t.Run(tc.title, func(t *testing.T) {
Expand Down Expand Up @@ -2463,6 +2518,7 @@ func TestServiceSourceNodePortServices(t *testing.T) {
false,
false,
tc.exposeInternalIPv6,
tc.ignoreUnscheduledNodes,
)
require.NoError(t, err)

Expand Down Expand Up @@ -3371,6 +3427,7 @@ func TestHeadlessServices(t *testing.T) {
false,
false,
tc.exposeInternalIPv6,
false,
)
require.NoError(t, err)

Expand Down Expand Up @@ -3507,6 +3564,7 @@ func TestMultipleServicesPointingToSameLoadBalancer(t *testing.T) {
false,
false,
false,
true,
)
require.NoError(t, err)
assert.NotNil(t, src)
Expand Down Expand Up @@ -3873,6 +3931,7 @@ func TestMultipleHeadlessServicesPointingToPodsOnTheSameNode(t *testing.T) {
false,
false,
false,
true,
)
require.NoError(t, err)
assert.NotNil(t, src)
Expand Down Expand Up @@ -4331,6 +4390,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
false,
false,
false,
true,
)
require.NoError(t, err)

Expand Down Expand Up @@ -4541,6 +4601,7 @@ func TestExternalServices(t *testing.T) {
false,
false,
false,
true,
)
require.NoError(t, err)

Expand Down Expand Up @@ -4603,6 +4664,7 @@ func BenchmarkServiceEndpoints(b *testing.B) {
false,
false,
false,
true,
)
require.NoError(b, err)

Expand Down Expand Up @@ -4702,6 +4764,7 @@ func TestNewServiceSourceInformersEnabled(t *testing.T) {
false,
false,
false,
false,
)
require.NoError(t, err)
svcSrc, ok := svc.(*serviceSource)
Expand Down Expand Up @@ -4733,6 +4796,7 @@ func TestNewServiceSourceWithServiceTypeFilters_Unsupported(t *testing.T) {
false,
false,
false,
false,
)
require.Errorf(t, err, "unsupported service type filter: \"UnknownType\". Supported types are: [\"ClusterIP\" \"NodePort\" \"LoadBalancer\" \"ExternalName\"]")
require.Nil(t, svc, "ServiceSource should be nil when an unsupported service type is provided")
Expand Down Expand Up @@ -4912,6 +4976,7 @@ func TestEndpointSlicesIndexer(t *testing.T) {
false,
false,
false,
true,
)
require.NoError(t, err)
ss, ok := src.(*serviceSource)
Expand Down Expand Up @@ -4999,6 +5064,7 @@ func TestPodTransformerInServiceSource(t *testing.T) {
false,
false,
false,
false,
)
require.NoError(t, err)
ss, ok := src.(*serviceSource)
Expand Down
7 changes: 6 additions & 1 deletion source/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,12 @@ func buildServiceSource(ctx context.Context, p ClientGenerator, cfg *Config) (So
if err != nil {
return nil, err
}
return NewServiceSource(ctx, client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.Compatibility, cfg.PublishInternal, cfg.PublishHostIP, cfg.AlwaysPublishNotReadyAddresses, cfg.ServiceTypeFilter, cfg.IgnoreHostnameAnnotation, cfg.LabelFilter, cfg.ResolveLoadBalancerHostname, cfg.ListenEndpointEvents, cfg.ExposeInternalIPv6)
return NewServiceSource(ctx, client, cfg.Namespace,
cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation,
cfg.Compatibility, cfg.PublishInternal, cfg.PublishHostIP,
cfg.AlwaysPublishNotReadyAddresses, cfg.ServiceTypeFilter, cfg.IgnoreHostnameAnnotation,
cfg.LabelFilter, cfg.ResolveLoadBalancerHostname, cfg.ListenEndpointEvents,
cfg.ExposeInternalIPv6, cfg.ExcludeUnschedulable)
}

// buildIngressSource creates an Ingress source for exposing Kubernetes ingresses as DNS records.
Expand Down
Loading