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

Support enable secure-by-default #5751

Merged
merged 6 commits into from
Nov 25, 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
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.22.4
toolchain go1.22.5

require (
github.com/IBM-Cloud/bluemix-go v0.0.0-20241113164343-2c8987e9d7fc
github.com/IBM-Cloud/bluemix-go v0.0.0-20241117121028-a3be206688b3
github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240725064144-454a2ae23113
github.com/IBM-Cloud/power-go-client v1.8.3
github.com/IBM/apigateway-go-sdk v0.0.0-20210714141226-a5d5d49caaca
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3
github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/DataDog/zstd v1.4.4/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/IBM-Cloud/bluemix-go v0.0.0-20241113164343-2c8987e9d7fc h1:clhxSBYSYp1KBMfx9DJXPNeaKSpbC9Nhijnl66QlVrA=
github.com/IBM-Cloud/bluemix-go v0.0.0-20241113164343-2c8987e9d7fc/go.mod h1:/7hMjdZA6fEpd/dQAOEABxKEwN0t72P3PlpEDu0Y7bE=
github.com/IBM-Cloud/bluemix-go v0.0.0-20241117121028-a3be206688b3 h1:eIa+RXJZ188p1S5q+fu3feDiL6dtp0W2IB1LM0B/plE=
github.com/IBM-Cloud/bluemix-go v0.0.0-20241117121028-a3be206688b3/go.mod h1:/7hMjdZA6fEpd/dQAOEABxKEwN0t72P3PlpEDu0Y7bE=
github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240725064144-454a2ae23113 h1:f2Erqfea1dKpaTFagTJM6W/wnD3JGq/Vn9URh8nuRwk=
github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240725064144-454a2ae23113/go.mod h1:xUQL9SGAjoZFd4GNjrjjtEpjpkgU7RFXRyHesbKTjiY=
github.com/IBM-Cloud/ibm-cloud-cli-sdk v0.5.3/go.mod h1:RiUvKuHKTBmBApDMUQzBL14pQUGKcx/IioKQPIcRQjs=
Expand Down
9 changes: 9 additions & 0 deletions ibm/flex/structures.go
Original file line number Diff line number Diff line change
Expand Up @@ -2903,6 +2903,15 @@ func ResourceTagsCustomizeDiff(diff *schema.ResourceDiff) error {
return nil
}

func OnlyInUpdateDiff(resources []string, diff *schema.ResourceDiff) error {
for _, r := range resources {
if diff.HasChange(r) && diff.Id() == "" {
return fmt.Errorf("the %s can't be used at create time", r)
}
}
return nil
}

func ResourceValidateAccessTags(diff *schema.ResourceDiff, meta interface{}) error {

if value, ok := diff.GetOkExists("access_tags"); ok {
Expand Down
39 changes: 35 additions & 4 deletions ibm/service/kubernetes/resource_ibm_container_vpc_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const (

const (
DisableOutboundTrafficProtectionFlag = "disable_outbound_traffic_protection"
EnableSecureByDefaultFlag = "enable_secure_by_default"
)

func ResourceIBMContainerVpcCluster() *schema.Resource {
Expand All @@ -52,6 +53,9 @@ func ResourceIBMContainerVpcCluster() *schema.Resource {
func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error {
return flex.ResourceTagsCustomizeDiff(diff)
},
func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error {
return flex.OnlyInUpdateDiff([]string{EnableSecureByDefaultFlag}, diff)
},
),

Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -357,6 +361,22 @@ func ResourceIBMContainerVpcCluster() *schema.Resource {
Description: "Allow outbound connections to public destinations",
},

EnableSecureByDefaultFlag: {
Type: schema.TypeBool,
Optional: true,
Description: "Enable Secure-by-default on existing clusters (note: can be used on existing clusters)",
ValidateFunc: func(i interface{}, s string) (warnings []string, errors []error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we are checking if its type bool or value can be true or false since we defined it as bool type will not it implictly take only true/false

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right, the first check is not needed. I'll remove it

v := i.(bool)
if !v {
// The field can only be true
errors = append(errors, fmt.Errorf("%s can be only true", s))
return warnings, errors
}

return warnings, errors
},
},

//Get Cluster info Request
"state": {
Type: schema.TypeString,
Expand Down Expand Up @@ -746,8 +766,7 @@ func resourceIBMContainerVpcClusterUpdate(d *schema.ResourceData, meta interface
}
}

if d.HasChange(DisableOutboundTrafficProtectionFlag) {
outbound_traffic_protection := !d.Get(DisableOutboundTrafficProtectionFlag).(bool)
if d.HasChange(DisableOutboundTrafficProtectionFlag) || d.HasChange(EnableSecureByDefaultFlag) {
ClusterClient, err := meta.(conns.ClientSession).VpcContainerAPI()
if err != nil {
return err
Expand All @@ -758,9 +777,21 @@ func resourceIBMContainerVpcClusterUpdate(d *schema.ResourceData, meta interface
return err
}

if err := ClusterClient.VPCs().SetOutboundTrafficProtection(clusterID, outbound_traffic_protection, Env); err != nil {
return err
if d.HasChange(DisableOutboundTrafficProtectionFlag) {
outbound_traffic_protection := !d.Get(DisableOutboundTrafficProtectionFlag).(bool)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we are storing opposite value of DisableOutboundTrafficProtectionFlag

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a legacy stuff, I didn't change the functionality here. On the other hand if I'm right the DisableOutboundTrafficProtectionFlag was introduced first, and after that in an upcoming change the opposite value of this was needed. It's a bit wierd, but this is how it's working.

if err := ClusterClient.VPCs().SetOutboundTrafficProtection(clusterID, outbound_traffic_protection, Env); err != nil {
return err
}
}

if d.HasChange(EnableSecureByDefaultFlag) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we enable we can disable it back also?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, I can follow you.
This resource flag can be set to only true. Basically an allready created cluster where this flag was not set, it can be set to true, but after that it can't be set to any other value. The validation for the "only true" is where the flag is described:

enableSecureByDefault := d.Get(EnableSecureByDefaultFlag).(bool)
if err := ClusterClient.VPCs().EnableSecureByDefault(clusterID, enableSecureByDefault, Env); err != nil {
return err
}

}

}

if (d.HasChange("kube_version") || d.HasChange("update_all_workers") || d.HasChange("patch_version") || d.HasChange("retry_patch_version")) && !d.IsNewResource() {
Expand Down
97 changes: 97 additions & 0 deletions ibm/service/kubernetes/resource_ibm_container_vpc_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,48 @@ func TestAccIBMContainerVPCClusterUpdateDisableOutboundTrafficProtection(t *test
})
}

func TestAccIBMContainerVPCClusterEnableSecureByDefault(t *testing.T) {
name := fmt.Sprintf("tf-vpc-cluster-%d", acctest.RandIntRange(10, 100))
var conf *v2.ClusterInfo

resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckIBMContainerVpcClusterDestroy,
Steps: []resource.TestStep{
{
// First create a cluster with a version where Secure by Default is not available
Config: testAccCheckIBMContainerVpcClusterEnableSecureByDefault(name, "1.29", "null"),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMContainerVpcExists("ibm_container_vpc_cluster.cluster", conf),
resource.TestCheckResourceAttr(
"ibm_container_vpc_cluster.cluster", "name", name),
),
},
{
// Then update it to a version where Secure by Default is available, but not applied by default
Config: testAccCheckIBMContainerVpcClusterEnableSecureByDefault(name, "1.30", "null"),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMContainerVpcExists("ibm_container_vpc_cluster.cluster", conf),
resource.TestCheckResourceAttr(
"ibm_container_vpc_cluster.cluster", "name", name),
),
},
{
// Then enable it
Config: testAccCheckIBMContainerVpcClusterEnableSecureByDefault(name, "1.30", "true"),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMContainerVpcExists("ibm_container_vpc_cluster.cluster", conf),
resource.TestCheckResourceAttr(
"ibm_container_vpc_cluster.cluster", "name", name),
resource.TestCheckResourceAttr(
"ibm_container_vpc_cluster.cluster", "enable_secure_by_default", "true"),
),
},
},
})
}

func testAccCheckIBMContainerVpcClusterDestroy(s *terraform.State) error {
csClient, err := acc.TestAccProvider.Meta().(conns.ClientSession).VpcContainerAPI()
if err != nil {
Expand Down Expand Up @@ -471,6 +513,61 @@ resource "ibm_container_vpc_cluster" "cluster" {
}`, name, kubeVersion, disable_outbound_traffic_protection)
}

func testAccCheckIBMContainerVpcClusterEnableSecureByDefault(name, kubeVersion, enable_secure_by_default string) string {
return fmt.Sprintf(`
data "ibm_resource_group" "resource_group" {
is_default = "true"
//name = "Default"
}
resource "ibm_is_vpc" "vpc" {
name = "%[1]s"
}
resource "ibm_is_subnet" "subnet" {
name = "%[1]s"
vpc = ibm_is_vpc.vpc.id
zone = "us-south-1"
total_ipv4_address_count = 256
}
resource "ibm_resource_instance" "kms_instance" {
name = "%[1]s"
service = "kms"
plan = "tiered-pricing"
location = "us-south"
}

resource "ibm_kms_key" "test" {
instance_id = ibm_resource_instance.kms_instance.guid
key_name = "%[1]s"
standard_key = false
force_delete = true
}
resource "ibm_container_vpc_cluster" "cluster" {
name = "%[1]s"
vpc_id = ibm_is_vpc.vpc.id
flavor = "cx2.2x4"
worker_count = 1
kube_version = "%[2]s"
wait_till = "OneWorkerNodeReady"
resource_group_id = data.ibm_resource_group.resource_group.id
zones {
subnet_id = ibm_is_subnet.subnet.id
name = "us-south-1"
}
kms_config {
instance_id = ibm_resource_instance.kms_instance.guid
crk_id = ibm_kms_key.test.key_id
private_endpoint = false
}
worker_labels = {
"test" = "test-default-pool"
"test1" = "test-default-pool1"
"test2" = "test-default-pool2"
}
enable_secure_by_default = %[3]s

}`, name, kubeVersion, enable_secure_by_default)
}

func testAccCheckIBMContainerVpcClusterDisableOutboundTrafficProtectionUpdate(name, disable_outbound_traffic_protection string) string {
return fmt.Sprintf(`
data "ibm_resource_group" "resource_group" {
Expand Down
7 changes: 7 additions & 0 deletions metadata/provider_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -107426,6 +107426,13 @@
"description": "Allow outbound connections to public destinations",
"default_value": false,
"optional": true
},
{
"name": "enable_secure_by_default",
"type": "TypeBool",
"description": "Enable Secure-by-default security group configuration on existing cluster",
"default_value": false,
"optional": true
}
],
"ibm_container_vpc_worker": [
Expand Down
1 change: 1 addition & 0 deletions website/docs/r/container_vpc_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ Review the argument references that you can specify for your resource.
- `kms_account_id` - (Optional, String) Account ID for boot volume encryption, if other account is providing the kms.
- `security_groups` - (Optional, List) Enables users to define specific security groups for their workers.
- `disable_outbound_traffic_protection` - (Optional, Bool) Include this option to allow public outbound access from the cluster workers. By default, public outbound access is blocked in OpenShift versions 4.15 and later and Kubernetes versions 1.30 and later. This option is usable only from OpenShift versions 4.15 and later and Kubernetes versions 1.30 and later.
- `enable_secure_by_default` - (Optional, Bool) Enables Secure-by-default security group configuration. Once the upgrade begins, it cannot be undone. During the upgrade, network traffic to your cluster may temporarily be blocked. This option is usable only from OpenShift versions 4.15 and later and Kubernetes versions 1.30 and later.

**Note**

Expand Down
Loading