Skip to content

Commit

Permalink
Add optional flags for DOKS control plane firewall feature (#1540)
Browse files Browse the repository at this point in the history
* Add control plane permission flags

* Check if flag is set

* Update godo to v0.118.0 and update control plane firewall structs

* Fix LBs tests

---------

Co-authored-by: Oliver Love <[email protected]>
  • Loading branch information
llDrLove and llDrLove authored Jun 20, 2024
1 parent 4a9d43c commit 5b24b23
Show file tree
Hide file tree
Showing 16 changed files with 150 additions and 42 deletions.
4 changes: 4 additions & 0 deletions args.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ const (
ArgAutoUpgrade = "auto-upgrade"
// ArgHA is a cluster's highly available control plane argument.
ArgHA = "ha"
// ArgEnableControlPlaneFirewall enable control plane firewall.
ArgEnableControlPlaneFirewall = "enable-control-plane-firewall"
// ArgControlPlaneFirewallAllowedAddresses list of allowed addresses that can access the control plane.
ArgControlPlaneFirewallAllowedAddresses = "control-plane-firewall-allowed-addresses"
// ArgSurgeUpgrade is a cluster's surge-upgrade argument.
ArgSurgeUpgrade = "surge-upgrade"
// ArgCommandUpsert is an upsert for a resource to be created or updated argument.
Expand Down
66 changes: 63 additions & 3 deletions commands/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ import (
"time"

"github.com/blang/semver"
"github.com/digitalocean/doctl"
"github.com/digitalocean/doctl/commands/displayers"
"github.com/digitalocean/doctl/do"
"github.com/digitalocean/godo"
"github.com/google/uuid"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/digitalocean/doctl"
"github.com/digitalocean/doctl/commands/displayers"
"github.com/digitalocean/doctl/do"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeerrors "k8s.io/apimachinery/pkg/util/errors"
clientauthentication "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
Expand Down Expand Up @@ -282,6 +283,10 @@ After creating a cluster, a configuration context is added to kubectl and made a
"Enables surge-upgrade for the cluster")
AddBoolFlag(cmdKubeClusterCreate, doctl.ArgHA, "", false,
"Creates the cluster with a highly-available control plane. Defaults to false. To enable the HA control plane, supply --ha=true.")
AddStringFlag(cmdKubeClusterCreate, doctl.ArgEnableControlPlaneFirewall, "", "",
"Creates the cluster with control plane firewall enabled. Defaults to false. To enable the control plane firewall, supply --enable-control-plane-firewall=true.")
AddStringSliceFlag(cmdKubeClusterCreate, doctl.ArgControlPlaneFirewallAllowedAddresses, "", nil,
"A comma-separated list of allowed addresses that can access the control plane.")
AddStringSliceFlag(cmdKubeClusterCreate, doctl.ArgTag, "", nil,
"A comma-separated list of `tags` to apply to the cluster, in addition to the default tags of `k8s` and `k8s:$K8S_CLUSTER_ID`.")
AddStringFlag(cmdKubeClusterCreate, doctl.ArgSizeSlug, "",
Expand Down Expand Up @@ -328,6 +333,10 @@ Updates the configuration values for a Kubernetes cluster. The cluster must be r
"Enables surge-upgrade for the cluster")
AddBoolFlag(cmdKubeClusterUpdate, doctl.ArgHA, "", false,
"Enables the highly-available control plane for the cluster")
AddStringFlag(cmdKubeClusterUpdate, doctl.ArgEnableControlPlaneFirewall, "", "",
"Creates the cluster with control plane firewall enabled. Defaults to false. To enable the control plane firewall, supply --enable-control-plane-firewall=true.")
AddStringSliceFlag(cmdKubeClusterUpdate, doctl.ArgControlPlaneFirewallAllowedAddresses, "", nil,
"A comma-separated list of allowed addresses that can access the control plane.")
AddBoolFlag(cmdKubeClusterUpdate, doctl.ArgClusterUpdateKubeconfig, "",
true, "Updates the cluster in your kubeconfig")
AddBoolFlag(cmdKubeClusterUpdate, doctl.ArgSetCurrentContext, "", true,
Expand Down Expand Up @@ -1648,6 +1657,31 @@ func buildClusterCreateRequestFromArgs(c *CmdConfig, r *godo.KubernetesClusterCr
}
r.HA = ha

enableControlPlaneFirewall, err := c.Doit.GetString(c.NS, doctl.ArgEnableControlPlaneFirewall)
if err != nil {
return err
}
if enableControlPlaneFirewall != "" {
enableControlPlaneFirewallBool, err := strconv.ParseBool(enableControlPlaneFirewall)
if err != nil {
return err
}
r.ControlPlaneFirewall = &godo.KubernetesControlPlaneFirewall{
Enabled: &enableControlPlaneFirewallBool,
}
}

controlPlaneFirewallAllowedAddresses, isSet, err := c.Doit.GetStringSliceIsFlagSet(c.NS, doctl.ArgControlPlaneFirewallAllowedAddresses)
if err != nil {
return err
}
if isSet {
if r.ControlPlaneFirewall == nil {
r.ControlPlaneFirewall = &godo.KubernetesControlPlaneFirewall{}
}
r.ControlPlaneFirewall.AllowedAddresses = controlPlaneFirewallAllowedAddresses
}

tags, err := c.Doit.GetStringSlice(c.NS, doctl.ArgTag)
if err != nil {
return err
Expand Down Expand Up @@ -1737,6 +1771,32 @@ func buildClusterUpdateRequestFromArgs(c *CmdConfig, r *godo.KubernetesClusterUp
return err
}
r.HA = ha

enableControlPlaneFirewall, err := c.Doit.GetString(c.NS, doctl.ArgEnableControlPlaneFirewall)
if err != nil {
return err
}
if enableControlPlaneFirewall != "" {
enableControlPlaneFirewallBool, err := strconv.ParseBool(enableControlPlaneFirewall)
if err != nil {
return err
}
r.ControlPlaneFirewall = &godo.KubernetesControlPlaneFirewall{
Enabled: &enableControlPlaneFirewallBool,
}
}

controlPlaneFirewallAllowedAddresses, isSet, err := c.Doit.GetStringSliceIsFlagSet(c.NS, doctl.ArgControlPlaneFirewallAllowedAddresses)
if err != nil {
return err
}
if isSet {
if r.ControlPlaneFirewall == nil {
r.ControlPlaneFirewall = &godo.KubernetesControlPlaneFirewall{}
}
r.ControlPlaneFirewall.AllowedAddresses = controlPlaneFirewallAllowedAddresses
}

return nil
}

Expand Down
40 changes: 38 additions & 2 deletions commands/kubernetes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import (
"sort"
"testing"

"github.com/digitalocean/doctl"
"github.com/digitalocean/doctl/do"
"github.com/digitalocean/godo"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"

"github.com/digitalocean/doctl"
"github.com/digitalocean/doctl/do"
)

var (
Expand All @@ -30,6 +31,13 @@ var (
},
AutoUpgrade: true,
HA: true,
ControlPlaneFirewall: &godo.KubernetesControlPlaneFirewall{
Enabled: boolPtr(true),
AllowedAddresses: []string{
"1.2.3.4",
"4.3.2.1/32",
},
},
},
}

Expand Down Expand Up @@ -497,6 +505,13 @@ func TestKubernetesCreate(t *testing.T) {
},
AutoUpgrade: true,
HA: true,
ControlPlaneFirewall: &godo.KubernetesControlPlaneFirewall{
Enabled: boolPtr(true),
AllowedAddresses: []string{
"1.2.3.4",
"4.3.2.1/32",
},
},
}
tm.kubernetes.EXPECT().Create(&r).Return(&testCluster, nil)

Expand All @@ -517,6 +532,9 @@ func TestKubernetesCreate(t *testing.T) {
config.Doit.Set(config.NS, doctl.ArgAutoUpgrade, testCluster.AutoUpgrade)
config.Doit.Set(config.NS, doctl.ArgHA, testCluster.HA)

config.Doit.Set(config.NS, doctl.ArgEnableControlPlaneFirewall, testCluster.ControlPlaneFirewall.Enabled)
config.Doit.Set(config.NS, doctl.ArgControlPlaneFirewallAllowedAddresses, testCluster.ControlPlaneFirewall.AllowedAddresses)

// Test with no vpc-uuid specified
err := testK8sCmdService().RunKubernetesClusterCreate("c-8", 3)(config)
assert.NoError(t, err)
Expand Down Expand Up @@ -550,6 +568,13 @@ func TestKubernetesUpdate(t *testing.T) {
},
AutoUpgrade: boolPtr(false),
HA: boolPtr(true),
ControlPlaneFirewall: &godo.KubernetesControlPlaneFirewall{
Enabled: boolPtr(true),
AllowedAddresses: []string{
"1.2.3.4",
"4.3.2.1/32",
},
},
}
tm.kubernetes.EXPECT().Update(testCluster.ID, &r).Return(&testCluster, nil)

Expand All @@ -559,6 +584,8 @@ func TestKubernetesUpdate(t *testing.T) {
config.Doit.Set(config.NS, doctl.ArgMaintenanceWindow, "any=00:00")
config.Doit.Set(config.NS, doctl.ArgAutoUpgrade, false)
config.Doit.Set(config.NS, doctl.ArgHA, true)
config.Doit.Set(config.NS, doctl.ArgEnableControlPlaneFirewall, testCluster.ControlPlaneFirewall.Enabled)
config.Doit.Set(config.NS, doctl.ArgControlPlaneFirewallAllowedAddresses, testCluster.ControlPlaneFirewall.AllowedAddresses)

err := testK8sCmdService().RunKubernetesClusterUpdate(config)
assert.NoError(t, err)
Expand All @@ -574,6 +601,13 @@ func TestKubernetesUpdate(t *testing.T) {
Day: godo.KubernetesMaintenanceDayAny,
},
AutoUpgrade: boolPtr(false),
ControlPlaneFirewall: &godo.KubernetesControlPlaneFirewall{
Enabled: boolPtr(true),
AllowedAddresses: []string{
"1.2.3.4",
"4.3.2.1/32",
},
},
}
tm.kubernetes.EXPECT().List().Return(testClusterList, nil)
tm.kubernetes.EXPECT().Update(testCluster.ID, &r).Return(&testCluster, nil)
Expand All @@ -583,6 +617,8 @@ func TestKubernetesUpdate(t *testing.T) {
config.Doit.Set(config.NS, doctl.ArgTag, testCluster.Tags)
config.Doit.Set(config.NS, doctl.ArgMaintenanceWindow, "any=00:00")
config.Doit.Set(config.NS, doctl.ArgAutoUpgrade, false)
config.Doit.Set(config.NS, doctl.ArgEnableControlPlaneFirewall, testCluster.ControlPlaneFirewall.Enabled)
config.Doit.Set(config.NS, doctl.ArgControlPlaneFirewallAllowedAddresses, testCluster.ControlPlaneFirewall.AllowedAddresses)

err := testK8sCmdService().RunKubernetesClusterUpdate(config)
assert.NoError(t, err)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.21
require (
github.com/blang/semver v3.5.1+incompatible
github.com/creack/pty v1.1.21
github.com/digitalocean/godo v1.117.0
github.com/digitalocean/godo v1.118.0
github.com/docker/cli v24.0.5+incompatible
github.com/docker/docker v24.0.9+incompatible
github.com/docker/docker-credential-helpers v0.7.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/digitalocean/godo v1.117.0 h1:WVlTe09melDYTd7VCVyvHcNWbgB+uI1O115+5LOtdSw=
github.com/digitalocean/godo v1.117.0/go.mod h1:Vk0vpCot2HOAJwc5WE8wljZGtJ3ZtWIc8MQ8rF38sdo=
github.com/digitalocean/godo v1.118.0 h1:lkzGFQmACrVCp7UqH1sAi4JK/PWwlc5aaxubgorKmC4=
github.com/digitalocean/godo v1.118.0/go.mod h1:Vk0vpCot2HOAJwc5WE8wljZGtJ3ZtWIc8MQ8rF38sdo=
github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc=
github.com/docker/cli v24.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
Expand Down
4 changes: 2 additions & 2 deletions integration/glb_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ const (
}`
glbCreateOutput = `
Notice: Load balancer created
ID IP Name Status Created At Region Size Size Unit VPC UUID Tag Droplet IDs SSL Sticky Sessions Health Check Forwarding Rules Disable Lets Encrypt DNS Records
cf9f1aa1-e1f8-4f3a-ad71-124c45e204b8 my-glb-name new 2024-04-09T16:10:11Z <nil> lb-small 1 false type:none,cookie_name:,cookie_ttl_seconds:0 protocol:http,port:80,path:/,check_interval_seconds:10,response_timeout_seconds:5,healthy_threshold:5,unhealthy_threshold:3 false
ID IP Name Status Created At Region Size Size Unit VPC UUID Tag Droplet IDs SSL Sticky Sessions Health Check Forwarding Rules Disable Lets Encrypt DNS Records
cf9f1aa1-e1f8-4f3a-ad71-124c45e204b8 my-glb-name new 2024-04-09T16:10:11Z <nil> lb-small 1 false type:none,cookie_name:,cookie_ttl_seconds:0 protocol:http,port:80,path:/,check_interval_seconds:10,response_timeout_seconds:5,healthy_threshold:5,unhealthy_threshold:3,proxy_protocol:<nil> false
`
)
4 changes: 2 additions & 2 deletions integration/glb_update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,6 @@ const (
}
}`
glbUpdateOutput = `
ID IP Name Status Created At Region Size Size Unit VPC UUID Tag Droplet IDs SSL Sticky Sessions Health Check Forwarding Rules Disable Lets Encrypt DNS Records
updated-lb-id my-glb-name new 2024-04-09T16:10:11Z <nil> lb-small 1 false type:none,cookie_name:,cookie_ttl_seconds:0 protocol:http,port:80,path:/,check_interval_seconds:10,response_timeout_seconds:5,healthy_threshold:5,unhealthy_threshold:3 false`
ID IP Name Status Created At Region Size Size Unit VPC UUID Tag Droplet IDs SSL Sticky Sessions Health Check Forwarding Rules Disable Lets Encrypt DNS Records
updated-lb-id my-glb-name new 2024-04-09T16:10:11Z <nil> lb-small 1 false type:none,cookie_name:,cookie_ttl_seconds:0 protocol:http,port:80,path:/,check_interval_seconds:10,response_timeout_seconds:5,healthy_threshold:5,unhealthy_threshold:3,proxy_protocol:<nil> false`
)
8 changes: 4 additions & 4 deletions integration/lb_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ var _ = suite("compute/load-balancer/create", func(t *testing.T, when spec.G, it
const (
lbCreateOutput = `
Notice: Load balancer created
ID IP Name Status Created At Region Size Size Unit VPC UUID Tag Droplet IDs SSL Sticky Sessions Health Check Forwarding Rules Disable Lets Encrypt DNS Records
4de7ac8b-495b-4884-9a69-1050c6793cd6 example-lb-01 new 2017-02-01T22:22:58Z nyc3 lb-small <nil> 00000000-0000-4000-8000-000000000000 3164444,3164445 true type:none,cookie_name:,cookie_ttl_seconds:0 protocol:,port:0,path:,check_interval_seconds:0,response_timeout_seconds:0,healthy_threshold:0,unhealthy_threshold:0 true
ID IP Name Status Created At Region Size Size Unit VPC UUID Tag Droplet IDs SSL Sticky Sessions Health Check Forwarding Rules Disable Lets Encrypt DNS Records
4de7ac8b-495b-4884-9a69-1050c6793cd6 example-lb-01 new 2017-02-01T22:22:58Z nyc3 lb-small <nil> 00000000-0000-4000-8000-000000000000 3164444,3164445 true type:none,cookie_name:,cookie_ttl_seconds:0 protocol:,port:0,path:,check_interval_seconds:0,response_timeout_seconds:0,healthy_threshold:0,unhealthy_threshold:0,proxy_protocol:<nil> true
`

lbWaitCreateOutput = `
Notice: Load balancer creation is in progress, waiting for load balancer to become active
Notice: Load balancer created
ID IP Name Status Created At Region Size Size Unit VPC UUID Tag Droplet IDs SSL Sticky Sessions Health Check Forwarding Rules Disable Lets Encrypt DNS Records
4de7ac8b-495b-4884-9a69-1050c6793cd6 example-lb-01 active 2017-02-01T22:22:58Z nyc3 lb-small <nil> 00000000-0000-4000-8000-000000000000 3164444,3164445 true type:none,cookie_name:,cookie_ttl_seconds:0 protocol:,port:0,path:,check_interval_seconds:0,response_timeout_seconds:0,healthy_threshold:0,unhealthy_threshold:0 true
ID IP Name Status Created At Region Size Size Unit VPC UUID Tag Droplet IDs SSL Sticky Sessions Health Check Forwarding Rules Disable Lets Encrypt DNS Records
4de7ac8b-495b-4884-9a69-1050c6793cd6 example-lb-01 active 2017-02-01T22:22:58Z nyc3 lb-small <nil> 00000000-0000-4000-8000-000000000000 3164444,3164445 true type:none,cookie_name:,cookie_ttl_seconds:0 protocol:,port:0,path:,check_interval_seconds:0,response_timeout_seconds:0,healthy_threshold:0,unhealthy_threshold:0,proxy_protocol:<nil> true
`

lbCreateResponse = `
Expand Down
4 changes: 2 additions & 2 deletions integration/lb_get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ var _ = suite("compute/load-balancer/get", func(t *testing.T, when spec.G, it sp

const (
lbGetOutput = `
ID IP Name Status Created At Region Size Size Unit VPC UUID Tag Droplet IDs SSL Sticky Sessions Health Check Forwarding Rules Disable Lets Encrypt DNS Records
find-lb-id 104.131.186.241 example-lb-01 new 2017-02-01T22:22:58Z nyc3 lb-small <nil> 00000000-0000-4000-8000-000000000000 3164445 false type:none,cookie_name:,cookie_ttl_seconds:0 protocol:,port:0,path:,check_interval_seconds:0,response_timeout_seconds:0,healthy_threshold:0,unhealthy_threshold:0 false
ID IP Name Status Created At Region Size Size Unit VPC UUID Tag Droplet IDs SSL Sticky Sessions Health Check Forwarding Rules Disable Lets Encrypt DNS Records
find-lb-id 104.131.186.241 example-lb-01 new 2017-02-01T22:22:58Z nyc3 lb-small <nil> 00000000-0000-4000-8000-000000000000 3164445 false type:none,cookie_name:,cookie_ttl_seconds:0 protocol:,port:0,path:,check_interval_seconds:0,response_timeout_seconds:0,healthy_threshold:0,unhealthy_threshold:0,proxy_protocol:<nil> false
`
lbGetResponse = `
{
Expand Down
Loading

0 comments on commit 5b24b23

Please sign in to comment.