diff --git a/README.md b/README.md index f23e6d34..acfdd737 100644 --- a/README.md +++ b/README.md @@ -294,12 +294,14 @@ sessionAffinityConfig: ## Additional environment variables To tweak CCM based on needs, one can overwrite the default values set for caches and requests by setting appropriate environment variables when applying the manifest or helm chart. -| 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` | +| 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` | +| `BGP_CUSTOM_ID_MAP` | | Use your own map instead of default region map for BGP | +| `BGP_PEER_PREFIX` | `2600:3c0f` | Use your own BGP peer prefix instead of default one | ## 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. diff --git a/cloud/linode/cilium_loadbalancers.go b/cloud/linode/cilium_loadbalancers.go index 5ee9d279..f301c286 100644 --- a/cloud/linode/cilium_loadbalancers.go +++ b/cloud/linode/cilium_loadbalancers.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "net/http" + "os" "slices" "strings" @@ -28,8 +29,8 @@ const ( ciliumLBClass = "io.cilium/bgp-control-plane" ipHolderLabelPrefix = "linode-ccm-ip-holder" ciliumBGPPeeringPolicyName = "linode-ccm-bgp-peering" - - commonControlPlaneLabel = "node-role.kubernetes.io/control-plane" + defaultBGPPeerPrefix = "2600:3c0f" + commonControlPlaneLabel = "node-role.kubernetes.io/control-plane" ) // This mapping is unfortunately necessary since there is no way to get the @@ -481,6 +482,12 @@ func (l *loadbalancers) getCiliumLBIPPool(ctx context.Context, service *v1.Servi // NOTE: Cilium CRDs must be installed for this to work func (l *loadbalancers) ensureCiliumBGPPeeringPolicy(ctx context.Context) error { + if raw, ok := os.LookupEnv("BGP_CUSTOM_ID_MAP"); ok { + klog.Info("BGP_CUSTOM_ID_MAP env variable specified, using it instead of the default region map") + if err := json.Unmarshal([]byte(raw), ®ionIDMap); err != nil { + return err + } + } regionID, ok := regionIDMap[l.zone] if !ok { return fmt.Errorf("unsupported region for BGP: %s", l.zone) @@ -543,10 +550,15 @@ func (l *loadbalancers) ensureCiliumBGPPeeringPolicy(ctx context.Context) error }}, }, } + bgpPeerPrefix := defaultBGPPeerPrefix + if raw, ok := os.LookupEnv("BGP_PEER_PREFIX"); ok { + klog.Info("BGP_PEER_PREFIX env variable specified, using it instead of the default bgpPeer prefix") + bgpPeerPrefix = raw + } // As in https://github.com/linode/lelastic, there are 4 peers per DC for i := 1; i <= 4; i++ { neighbor := v2alpha1.CiliumBGPNeighbor{ - PeerAddress: fmt.Sprintf("2600:3c0f:%d:34::%d/64", regionID, i), + PeerAddress: fmt.Sprintf("%s:%d:34::%d/64", bgpPeerPrefix, regionID, i), PeerASN: 65000, EBGPMultihopTTL: ptr.To(int32(10)), ConnectRetryTimeSeconds: ptr.To(int32(5)), diff --git a/cloud/linode/cilium_loadbalancers_test.go b/cloud/linode/cilium_loadbalancers_test.go index 1fdace1c..f03bfaeb 100644 --- a/cloud/linode/cilium_loadbalancers_test.go +++ b/cloud/linode/cilium_loadbalancers_test.go @@ -201,6 +201,7 @@ func createNewIpHolderInstance() linodego.Instance { func testNoBGPNodeLabel(t *testing.T, mc *mocks.MockClient) { Options.BGPNodeSelector = "" Options.IpHolderSuffix = "linodelb" + t.Setenv("BGP_PEER_PREFIX", "2600:3cef") svc := createTestService() newIpHolderInstance = createNewIpHolderInstance() @@ -257,7 +258,18 @@ func testUnsupportedRegion(t *testing.T, mc *mocks.MockClient) { lbStatus, err := lb.EnsureLoadBalancer(context.TODO(), "linodelb", svc, nodes) if err == nil { - t.Fatal("expected nil error") + t.Fatal("expected not nil error") + } + if lbStatus != nil { + t.Fatalf("expected a nil lbStatus, got %v", lbStatus) + } + + // Use BGP custom id map + t.Setenv("BGP_CUSTOM_ID_MAP", "{'us-foobar': 2}") + lb = &loadbalancers{mc, zone, kubeClient, ciliumClient, ciliumLBType} + lbStatus, err = lb.EnsureLoadBalancer(context.TODO(), "linodelb", svc, nodes) + if err == nil { + t.Fatal("expected not nil error") } if lbStatus != nil { t.Fatalf("expected a nil lbStatus, got %v", lbStatus)