Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to mark internal network as external #235

Merged
merged 3 commits into from
Sep 26, 2024
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ Environment Variable | Default | Description
`LINODE_INSTANCE_CACHE_TTL` | `15` | Default timeout of instance cache in seconds
`LINODE_ROUTES_CACHE_TTL_SECONDS` | `60` | Default timeout of route cache in seconds
`LINODE_REQUEST_TIMEOUT_SECONDS` | `120` | Default timeout in seconds for http requests to linode API
`LINODE_EXTERNAL_SUBNET` | | Mark private network as external. Example - `172.24.0.0/16`

## Generating a Manifest for Deployment
Use the script located at `./deploy/generate-manifest.sh` to generate a self-contained deployment manifest for the Linode CCM. Two arguments are required.
Expand Down
2 changes: 2 additions & 0 deletions cloud/linode/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package linode
import (
"fmt"
"io"
"net"
"os"
"strconv"
"sync"
Expand Down Expand Up @@ -37,6 +38,7 @@ var Options struct {
VPCName string
LoadBalancerType string
BGPNodeSelector string
LinodeExternalNetwork *net.IPNet
}

// vpcDetails is set when VPCName options flag is set.
Expand Down
9 changes: 9 additions & 0 deletions cloud/linode/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package linode

import (
"fmt"
"net"
"strconv"
"strings"

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

return err
}

func isPrivate(ip *net.IP) bool {
if Options.LinodeExternalNetwork == nil {
return ip.IsPrivate()
}

return ip.IsPrivate() && !Options.LinodeExternalNetwork.Contains(*ip)
}
4 changes: 2 additions & 2 deletions cloud/linode/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (nc *nodeCache) getInstanceAddresses(instance linodego.Instance, vpcips []s

for _, ip := range instance.IPv4 {
ipType := v1.NodeExternalIP
if ip.IsPrivate() {
if isPrivate(ip) {
ipType = v1.NodeInternalIP
}
ips = append(ips, nodeIP{ip: ip.String(), ipType: ipType})
Expand Down Expand Up @@ -155,7 +155,7 @@ func (i *instances) linodeByIP(kNode *v1.Node) (*linodego.Instance, error) {
}
for _, node := range i.nodeCache.nodes {
for _, nodeIP := range node.instance.IPv4 {
if !nodeIP.IsPrivate() && slices.Contains(kNodeAddresses, nodeIP.String()) {
if !isPrivate(nodeIP) && slices.Contains(kNodeAddresses, nodeIP.String()) {
return node.instance, nil
}
}
Expand Down
23 changes: 21 additions & 2 deletions cloud/linode/instances_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,52 +146,67 @@ func TestMetadataRetrieval(t *testing.T) {
name string
inputIPv4s []string
inputIPv6 string
externalNetwork string
outputAddresses []v1.NodeAddress
expectedErr error
}{
{"no IPs", nil, "", nil, instanceNoIPAddressesError{192910}},
{"no IPs", nil, "", "", nil, instanceNoIPAddressesError{192910}},
{
"one public, one private",
[]string{"32.74.121.25", "192.168.121.42"},
"",
"",
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}, {Type: v1.NodeInternalIP, Address: "192.168.121.42"}},
nil,
},
{
"one public ipv4, one public ipv6",
[]string{"32.74.121.25"},
"2600:3c06::f03c:94ff:fe1e:e072",
"",
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}, {Type: v1.NodeExternalIP, Address: "2600:3c06::f03c:94ff:fe1e:e072"}},
nil,
},
{
"one public, no private",
[]string{"32.74.121.25"},
"",
"",
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}},
nil,
},
{
"one private, no public",
[]string{"192.168.121.42"},
"",
"",
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "192.168.121.42"}},
nil,
},
{
"two public addresses",
[]string{"32.74.121.25", "32.74.121.22"},
"",
"",
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}, {Type: v1.NodeExternalIP, Address: "32.74.121.22"}},
nil,
},
{
"two private addresses",
[]string{"192.168.121.42", "10.0.2.15"},
"",
"",
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "192.168.121.42"}, {Type: v1.NodeInternalIP, Address: "10.0.2.15"}},
nil,
},
{
"two private addresses - one in network marked as external",
[]string{"192.168.121.42", "10.0.2.15"},
"",
"10.0.2.0/16",
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "192.168.121.42"}, {Type: v1.NodeExternalIP, Address: "10.0.2.15"}},
nil,
},
}

for _, test := range ipTests {
Expand All @@ -201,7 +216,11 @@ func TestMetadataRetrieval(t *testing.T) {
name := "my-instance"
providerID := providerIDPrefix + strconv.Itoa(id)
node := nodeWithProviderID(providerID)

if test.externalNetwork == "" {
Options.LinodeExternalNetwork = nil
} else {
_, Options.LinodeExternalNetwork, _ = net.ParseCIDR(test.externalNetwork)
}
ips := make([]*net.IP, 0, len(test.inputIPv4s))
for _, ip := range test.inputIPv4s {
parsed := net.ParseIP(ip)
Expand Down
2 changes: 1 addition & 1 deletion cloud/linode/node_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@
// supports other subnets with nodebalancer, this logic needs to be updated.
// https://www.linode.com/docs/api/linode-instances/#linode-view
for _, addr := range linode.IPv4 {
if addr.IsPrivate() {
if isPrivate(addr) {

Check warning on line 175 in cloud/linode/node_controller.go

View check run for this annotation

Codecov / codecov/patch

cloud/linode/node_controller.go#L175

Added line #L175 was not covered by tests
expectedPrivateIP = addr.String()
break
}
Expand Down
19 changes: 16 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"flag"
"fmt"
"net"
"os"

"k8s.io/component-base/logs"
Expand All @@ -25,9 +26,10 @@ import (
)

const (
sentryDSNVariable = "SENTRY_DSN"
sentryEnvironmentVariable = "SENTRY_ENVIRONMENT"
sentryReleaseVariable = "SENTRY_RELEASE"
sentryDSNVariable = "SENTRY_DSN"
sentryEnvironmentVariable = "SENTRY_ENVIRONMENT"
sentryReleaseVariable = "SENTRY_RELEASE"
linodeExternalSubnetVariable = "LINODE_EXTERNAL_SUBNET"
)

func initializeSentry() {
Expand Down Expand Up @@ -114,6 +116,17 @@ func main() {
os.Exit(1)
}

if externalSubnet, ok := os.LookupEnv(linodeExternalSubnetVariable); ok && externalSubnet != "" {
_, network, err := net.ParseCIDR(externalSubnet)
if err != nil {
msg := fmt.Sprintf("Unable to parse %s as network subnet: %v", externalSubnet, err)
sentry.CaptureError(ctx, fmt.Errorf(msg))
fmt.Fprintf(os.Stderr, "%v\n", msg)
os.Exit(1)
}
linode.Options.LinodeExternalNetwork = network
}

pflag.CommandLine.SetNormalizeFunc(utilflag.WordSepNormalizeFunc)
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)

Expand Down
Loading