Skip to content

Commit 291e46f

Browse files
authored
Merge pull request #235 from linode/external-network-definition
Allow to mark internal network as external
2 parents 76dea77 + fab127d commit 291e46f

File tree

7 files changed

+52
-8
lines changed

7 files changed

+52
-8
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ Environment Variable | Default | Description
294294
`LINODE_INSTANCE_CACHE_TTL` | `15` | Default timeout of instance cache in seconds
295295
`LINODE_ROUTES_CACHE_TTL_SECONDS` | `60` | Default timeout of route cache in seconds
296296
`LINODE_REQUEST_TIMEOUT_SECONDS` | `120` | Default timeout in seconds for http requests to linode API
297+
`LINODE_EXTERNAL_SUBNET` | | Mark private network as external. Example - `172.24.0.0/16`
297298

298299
## Generating a Manifest for Deployment
299300
Use the script located at `./deploy/generate-manifest.sh` to generate a self-contained deployment manifest for the Linode CCM. Two arguments are required.

cloud/linode/cloud.go

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package linode
33
import (
44
"fmt"
55
"io"
6+
"net"
67
"os"
78
"strconv"
89
"sync"
@@ -37,6 +38,7 @@ var Options struct {
3738
VPCName string
3839
LoadBalancerType string
3940
BGPNodeSelector string
41+
LinodeExternalNetwork *net.IPNet
4042
}
4143

4244
// vpcDetails is set when VPCName options flag is set.

cloud/linode/common.go

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package linode
22

33
import (
44
"fmt"
5+
"net"
56
"strconv"
67
"strings"
78

@@ -42,3 +43,11 @@ func IgnoreLinodeAPIError(err error, code int) error {
4243

4344
return err
4445
}
46+
47+
func isPrivate(ip *net.IP) bool {
48+
if Options.LinodeExternalNetwork == nil {
49+
return ip.IsPrivate()
50+
}
51+
52+
return ip.IsPrivate() && !Options.LinodeExternalNetwork.Contains(*ip)
53+
}

cloud/linode/instances.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func (nc *nodeCache) getInstanceAddresses(instance linodego.Instance, vpcips []s
4949

5050
for _, ip := range instance.IPv4 {
5151
ipType := v1.NodeExternalIP
52-
if ip.IsPrivate() {
52+
if isPrivate(ip) {
5353
ipType = v1.NodeInternalIP
5454
}
5555
ips = append(ips, nodeIP{ip: ip.String(), ipType: ipType})
@@ -155,7 +155,7 @@ func (i *instances) linodeByIP(kNode *v1.Node) (*linodego.Instance, error) {
155155
}
156156
for _, node := range i.nodeCache.nodes {
157157
for _, nodeIP := range node.instance.IPv4 {
158-
if !nodeIP.IsPrivate() && slices.Contains(kNodeAddresses, nodeIP.String()) {
158+
if !isPrivate(nodeIP) && slices.Contains(kNodeAddresses, nodeIP.String()) {
159159
return node.instance, nil
160160
}
161161
}

cloud/linode/instances_test.go

+21-2
Original file line numberDiff line numberDiff line change
@@ -146,52 +146,67 @@ func TestMetadataRetrieval(t *testing.T) {
146146
name string
147147
inputIPv4s []string
148148
inputIPv6 string
149+
externalNetwork string
149150
outputAddresses []v1.NodeAddress
150151
expectedErr error
151152
}{
152-
{"no IPs", nil, "", nil, instanceNoIPAddressesError{192910}},
153+
{"no IPs", nil, "", "", nil, instanceNoIPAddressesError{192910}},
153154
{
154155
"one public, one private",
155156
[]string{"32.74.121.25", "192.168.121.42"},
156157
"",
158+
"",
157159
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}, {Type: v1.NodeInternalIP, Address: "192.168.121.42"}},
158160
nil,
159161
},
160162
{
161163
"one public ipv4, one public ipv6",
162164
[]string{"32.74.121.25"},
163165
"2600:3c06::f03c:94ff:fe1e:e072",
166+
"",
164167
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}, {Type: v1.NodeExternalIP, Address: "2600:3c06::f03c:94ff:fe1e:e072"}},
165168
nil,
166169
},
167170
{
168171
"one public, no private",
169172
[]string{"32.74.121.25"},
170173
"",
174+
"",
171175
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}},
172176
nil,
173177
},
174178
{
175179
"one private, no public",
176180
[]string{"192.168.121.42"},
177181
"",
182+
"",
178183
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "192.168.121.42"}},
179184
nil,
180185
},
181186
{
182187
"two public addresses",
183188
[]string{"32.74.121.25", "32.74.121.22"},
184189
"",
190+
"",
185191
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}, {Type: v1.NodeExternalIP, Address: "32.74.121.22"}},
186192
nil,
187193
},
188194
{
189195
"two private addresses",
190196
[]string{"192.168.121.42", "10.0.2.15"},
191197
"",
198+
"",
192199
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "192.168.121.42"}, {Type: v1.NodeInternalIP, Address: "10.0.2.15"}},
193200
nil,
194201
},
202+
{
203+
"two private addresses - one in network marked as external",
204+
[]string{"192.168.121.42", "10.0.2.15"},
205+
"",
206+
"10.0.2.0/16",
207+
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "192.168.121.42"}, {Type: v1.NodeExternalIP, Address: "10.0.2.15"}},
208+
nil,
209+
},
195210
}
196211

197212
for _, test := range ipTests {
@@ -201,7 +216,11 @@ func TestMetadataRetrieval(t *testing.T) {
201216
name := "my-instance"
202217
providerID := providerIDPrefix + strconv.Itoa(id)
203218
node := nodeWithProviderID(providerID)
204-
219+
if test.externalNetwork == "" {
220+
Options.LinodeExternalNetwork = nil
221+
} else {
222+
_, Options.LinodeExternalNetwork, _ = net.ParseCIDR(test.externalNetwork)
223+
}
205224
ips := make([]*net.IP, 0, len(test.inputIPv4s))
206225
for _, ip := range test.inputIPv4s {
207226
parsed := net.ParseIP(ip)

cloud/linode/node_controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ func (s *nodeController) handleNode(ctx context.Context, node *v1.Node) error {
172172
// supports other subnets with nodebalancer, this logic needs to be updated.
173173
// https://www.linode.com/docs/api/linode-instances/#linode-view
174174
for _, addr := range linode.IPv4 {
175-
if addr.IsPrivate() {
175+
if isPrivate(addr) {
176176
expectedPrivateIP = addr.String()
177177
break
178178
}

main.go

+16-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"flag"
66
"fmt"
7+
"net"
78
"os"
89

910
"k8s.io/component-base/logs"
@@ -25,9 +26,10 @@ import (
2526
)
2627

2728
const (
28-
sentryDSNVariable = "SENTRY_DSN"
29-
sentryEnvironmentVariable = "SENTRY_ENVIRONMENT"
30-
sentryReleaseVariable = "SENTRY_RELEASE"
29+
sentryDSNVariable = "SENTRY_DSN"
30+
sentryEnvironmentVariable = "SENTRY_ENVIRONMENT"
31+
sentryReleaseVariable = "SENTRY_RELEASE"
32+
linodeExternalSubnetVariable = "LINODE_EXTERNAL_SUBNET"
3133
)
3234

3335
func initializeSentry() {
@@ -114,6 +116,17 @@ func main() {
114116
os.Exit(1)
115117
}
116118

119+
if externalSubnet, ok := os.LookupEnv(linodeExternalSubnetVariable); ok && externalSubnet != "" {
120+
_, network, err := net.ParseCIDR(externalSubnet)
121+
if err != nil {
122+
msg := fmt.Sprintf("Unable to parse %s as network subnet: %v", externalSubnet, err)
123+
sentry.CaptureError(ctx, fmt.Errorf(msg))
124+
fmt.Fprintf(os.Stderr, "%v\n", msg)
125+
os.Exit(1)
126+
}
127+
linode.Options.LinodeExternalNetwork = network
128+
}
129+
117130
pflag.CommandLine.SetNormalizeFunc(utilflag.WordSepNormalizeFunc)
118131
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
119132

0 commit comments

Comments
 (0)