Skip to content

Commit 9460f68

Browse files
[GKE Hub]: Add Fleet default cluster config (#9389) (#16630)
* [GKE Hub]: Add Fleet default cluster config * Adds SecurityPosture Config * [GKE Hub]: Retrigger review * [GKE Hub]: Retrigger review [upstream:a23d520591dcd0500bef368d33d428dce7db8fe7] Signed-off-by: Modular Magician <[email protected]>
1 parent cc6a284 commit 9460f68

File tree

4 files changed

+193
-2
lines changed

4 files changed

+193
-2
lines changed

.changelog/9389.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
GKEHub: added `defaultClusterConfig` to `Fleet` resource
3+
```

google/services/gkehub2/resource_gke_hub_fleet.go

+141
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929

3030
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
3131
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
32+
"github.com/hashicorp/terraform-provider-google/google/verify"
3233
)
3334

3435
func ResourceGKEHub2Fleet() *schema.Resource {
@@ -53,6 +54,38 @@ func ResourceGKEHub2Fleet() *schema.Resource {
5354
),
5455

5556
Schema: map[string]*schema.Schema{
57+
"default_cluster_config": {
58+
Type: schema.TypeList,
59+
Optional: true,
60+
Description: `The default cluster configurations to apply across the fleet.`,
61+
MaxItems: 1,
62+
Elem: &schema.Resource{
63+
Schema: map[string]*schema.Schema{
64+
"security_posture_config": {
65+
Type: schema.TypeList,
66+
Optional: true,
67+
Description: `Enable/Disable Security Posture features for the cluster.`,
68+
MaxItems: 1,
69+
Elem: &schema.Resource{
70+
Schema: map[string]*schema.Schema{
71+
"mode": {
72+
Type: schema.TypeString,
73+
Optional: true,
74+
ValidateFunc: verify.ValidateEnum([]string{"DISABLED", "BASIC", "ENTERPRISE", ""}),
75+
Description: `Sets which mode to use for Security Posture features. Possible values: ["DISABLED", "BASIC", "ENTERPRISE"]`,
76+
},
77+
"vulnerability_mode": {
78+
Type: schema.TypeString,
79+
Optional: true,
80+
ValidateFunc: verify.ValidateEnum([]string{"VULNERABILITY_DISABLED", "VULNERABILITY_BASIC", "VULNERABILITY_ENTERPRISE", ""}),
81+
Description: `Sets which mode to use for vulnerability scanning. Possible values: ["VULNERABILITY_DISABLED", "VULNERABILITY_BASIC", "VULNERABILITY_ENTERPRISE"]`,
82+
},
83+
},
84+
},
85+
},
86+
},
87+
},
88+
},
5689
"display_name": {
5790
Type: schema.TypeString,
5891
Optional: true,
@@ -120,6 +153,12 @@ func resourceGKEHub2FleetCreate(d *schema.ResourceData, meta interface{}) error
120153
} else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) {
121154
obj["displayName"] = displayNameProp
122155
}
156+
defaultClusterConfigProp, err := expandGKEHub2FleetDefaultClusterConfig(d.Get("default_cluster_config"), d, config)
157+
if err != nil {
158+
return err
159+
} else if v, ok := d.GetOkExists("default_cluster_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(defaultClusterConfigProp)) && (ok || !reflect.DeepEqual(v, defaultClusterConfigProp)) {
160+
obj["defaultClusterConfig"] = defaultClusterConfigProp
161+
}
123162

124163
url, err := tpgresource.ReplaceVars(d, config, "{{GKEHub2BasePath}}projects/{{project}}/locations/global/fleets")
125164
if err != nil {
@@ -233,6 +272,9 @@ func resourceGKEHub2FleetRead(d *schema.ResourceData, meta interface{}) error {
233272
if err := d.Set("state", flattenGKEHub2FleetState(res["state"], d, config)); err != nil {
234273
return fmt.Errorf("Error reading Fleet: %s", err)
235274
}
275+
if err := d.Set("default_cluster_config", flattenGKEHub2FleetDefaultClusterConfig(res["defaultClusterConfig"], d, config)); err != nil {
276+
return fmt.Errorf("Error reading Fleet: %s", err)
277+
}
236278

237279
return nil
238280
}
@@ -259,6 +301,12 @@ func resourceGKEHub2FleetUpdate(d *schema.ResourceData, meta interface{}) error
259301
} else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) {
260302
obj["displayName"] = displayNameProp
261303
}
304+
defaultClusterConfigProp, err := expandGKEHub2FleetDefaultClusterConfig(d.Get("default_cluster_config"), d, config)
305+
if err != nil {
306+
return err
307+
} else if v, ok := d.GetOkExists("default_cluster_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, defaultClusterConfigProp)) {
308+
obj["defaultClusterConfig"] = defaultClusterConfigProp
309+
}
262310

263311
url, err := tpgresource.ReplaceVars(d, config, "{{GKEHub2BasePath}}projects/{{project}}/locations/global/fleets/default")
264312
if err != nil {
@@ -271,6 +319,10 @@ func resourceGKEHub2FleetUpdate(d *schema.ResourceData, meta interface{}) error
271319
if d.HasChange("display_name") {
272320
updateMask = append(updateMask, "displayName")
273321
}
322+
323+
if d.HasChange("default_cluster_config") {
324+
updateMask = append(updateMask, "defaultClusterConfig")
325+
}
274326
// updateMask is a URL parameter but not present in the schema, so ReplaceVars
275327
// won't set it
276328
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
@@ -422,6 +474,95 @@ func flattenGKEHub2FleetStateCode(v interface{}, d *schema.ResourceData, config
422474
return v
423475
}
424476

477+
func flattenGKEHub2FleetDefaultClusterConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
478+
if v == nil {
479+
return nil
480+
}
481+
original := v.(map[string]interface{})
482+
if len(original) == 0 {
483+
return nil
484+
}
485+
transformed := make(map[string]interface{})
486+
transformed["security_posture_config"] =
487+
flattenGKEHub2FleetDefaultClusterConfigSecurityPostureConfig(original["securityPostureConfig"], d, config)
488+
return []interface{}{transformed}
489+
}
490+
func flattenGKEHub2FleetDefaultClusterConfigSecurityPostureConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
491+
if v == nil {
492+
return nil
493+
}
494+
original := v.(map[string]interface{})
495+
if len(original) == 0 {
496+
return nil
497+
}
498+
transformed := make(map[string]interface{})
499+
transformed["mode"] =
500+
flattenGKEHub2FleetDefaultClusterConfigSecurityPostureConfigMode(original["mode"], d, config)
501+
transformed["vulnerability_mode"] =
502+
flattenGKEHub2FleetDefaultClusterConfigSecurityPostureConfigVulnerabilityMode(original["vulnerabilityMode"], d, config)
503+
return []interface{}{transformed}
504+
}
505+
func flattenGKEHub2FleetDefaultClusterConfigSecurityPostureConfigMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
506+
return v
507+
}
508+
509+
func flattenGKEHub2FleetDefaultClusterConfigSecurityPostureConfigVulnerabilityMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
510+
return v
511+
}
512+
425513
func expandGKEHub2FleetDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
426514
return v, nil
427515
}
516+
517+
func expandGKEHub2FleetDefaultClusterConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
518+
l := v.([]interface{})
519+
if len(l) == 0 || l[0] == nil {
520+
return nil, nil
521+
}
522+
raw := l[0]
523+
original := raw.(map[string]interface{})
524+
transformed := make(map[string]interface{})
525+
526+
transformedSecurityPostureConfig, err := expandGKEHub2FleetDefaultClusterConfigSecurityPostureConfig(original["security_posture_config"], d, config)
527+
if err != nil {
528+
return nil, err
529+
} else if val := reflect.ValueOf(transformedSecurityPostureConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) {
530+
transformed["securityPostureConfig"] = transformedSecurityPostureConfig
531+
}
532+
533+
return transformed, nil
534+
}
535+
536+
func expandGKEHub2FleetDefaultClusterConfigSecurityPostureConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
537+
l := v.([]interface{})
538+
if len(l) == 0 || l[0] == nil {
539+
return nil, nil
540+
}
541+
raw := l[0]
542+
original := raw.(map[string]interface{})
543+
transformed := make(map[string]interface{})
544+
545+
transformedMode, err := expandGKEHub2FleetDefaultClusterConfigSecurityPostureConfigMode(original["mode"], d, config)
546+
if err != nil {
547+
return nil, err
548+
} else if val := reflect.ValueOf(transformedMode); val.IsValid() && !tpgresource.IsEmptyValue(val) {
549+
transformed["mode"] = transformedMode
550+
}
551+
552+
transformedVulnerabilityMode, err := expandGKEHub2FleetDefaultClusterConfigSecurityPostureConfigVulnerabilityMode(original["vulnerability_mode"], d, config)
553+
if err != nil {
554+
return nil, err
555+
} else if val := reflect.ValueOf(transformedVulnerabilityMode); val.IsValid() && !tpgresource.IsEmptyValue(val) {
556+
transformed["vulnerabilityMode"] = transformedVulnerabilityMode
557+
}
558+
559+
return transformed, nil
560+
}
561+
562+
func expandGKEHub2FleetDefaultClusterConfigSecurityPostureConfigMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
563+
return v, nil
564+
}
565+
566+
func expandGKEHub2FleetDefaultClusterConfigSecurityPostureConfigVulnerabilityMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
567+
return v, nil
568+
}

google/services/gkehub2/resource_gke_hub_fleet_test.go

+18-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ func testAccGKEHub2Fleet_basic(context map[string]interface{}) string {
5858
resource "google_gke_hub_fleet" "default" {
5959
project = google_project.project.project_id
6060
display_name = "my production fleet"
61-
61+
default_cluster_config {
62+
security_posture_config {
63+
mode = "DISABLED"
64+
vulnerability_mode = "VULNERABILITY_DISABLED"
65+
}
66+
}
6267
depends_on = [time_sleep.wait_for_gkehub_enablement]
6368
}
6469
`, context)
@@ -69,7 +74,12 @@ func testAccGKEHub2Fleet_update(context map[string]interface{}) string {
6974
resource "google_gke_hub_fleet" "default" {
7075
project = google_project.project.project_id
7176
display_name = "my staging fleet"
72-
77+
default_cluster_config {
78+
security_posture_config {
79+
mode = "BASIC"
80+
vulnerability_mode = "VULNERABILITY_BASIC"
81+
}
82+
}
7383
depends_on = [time_sleep.wait_for_gkehub_enablement]
7484
}
7585
`, context)
@@ -90,6 +100,12 @@ resource "google_project_service" "gkehub" {
90100
disable_on_destroy = false
91101
}
92102
103+
resource "google_project_service" "anthos" {
104+
project = google_project.project.project_id
105+
service = "anthos.googleapis.com"
106+
disable_on_destroy = false
107+
}
108+
93109
resource "time_sleep" "wait_for_gkehub_enablement" {
94110
create_duration = "150s"
95111
depends_on = [google_project_service.gkehub]

website/docs/r/gke_hub_fleet.html.markdown

+31
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ To get more information about Fleet, see:
3434
```hcl
3535
resource "google_gke_hub_fleet" "default" {
3636
display_name = "my production fleet"
37+
default_cluster_config {
38+
security_posture_config {
39+
mode = "DISABLED"
40+
vulnerability_mode = "VULNERABILITY_DISABLED"
41+
}
42+
}
3743
}
3844
```
3945

@@ -51,10 +57,35 @@ The following arguments are supported:
5157
A user-assigned display name of the Fleet. When present, it must be between 4 to 30 characters.
5258
Allowed characters are: lowercase and uppercase letters, numbers, hyphen, single-quote, double-quote, space, and exclamation point.
5359

60+
* `default_cluster_config` -
61+
(Optional)
62+
The default cluster configurations to apply across the fleet.
63+
Structure is [documented below](#nested_default_cluster_config).
64+
5465
* `project` - (Optional) The ID of the project in which the resource belongs.
5566
If it is not provided, the provider project is used.
5667

5768

69+
<a name="nested_default_cluster_config"></a>The `default_cluster_config` block supports:
70+
71+
* `security_posture_config` -
72+
(Optional)
73+
Enable/Disable Security Posture features for the cluster.
74+
Structure is [documented below](#nested_security_posture_config).
75+
76+
77+
<a name="nested_security_posture_config"></a>The `security_posture_config` block supports:
78+
79+
* `mode` -
80+
(Optional)
81+
Sets which mode to use for Security Posture features.
82+
Possible values are: `DISABLED`, `BASIC`, `ENTERPRISE`.
83+
84+
* `vulnerability_mode` -
85+
(Optional)
86+
Sets which mode to use for vulnerability scanning.
87+
Possible values are: `VULNERABILITY_DISABLED`, `VULNERABILITY_BASIC`, `VULNERABILITY_ENTERPRISE`.
88+
5889
## Attributes Reference
5990

6091
In addition to the arguments listed above, the following computed attributes are exported:

0 commit comments

Comments
 (0)