Skip to content

Commit a6433fe

Browse files
Adding support for optional watchlist_id in google_chronicle_watchlist resource (#12673) (#8988)
[upstream:8dbff0637f0876d23eb58ff4634df7406f990d94] Signed-off-by: Modular Magician <magic-modules@google.com>
1 parent 68f1a03 commit a6433fe

File tree

4 files changed

+127
-19
lines changed

4 files changed

+127
-19
lines changed

.changelog/12673.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note: note
2+
chronicle: added support for optional `watchlist_id` in `google_chronicle_watchlist` resource.
3+
```

google-beta/services/chronicle/resource_chronicle_watchlist.go

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,6 @@ Note that it must be at least one character and less than 63 characters
9393
ForceNew: true,
9494
Description: `The location of the resource. This is the geographical region where the Chronicle instance resides, such as "us" or "europe-west2".`,
9595
},
96-
"watchlist_id": {
97-
Type: schema.TypeString,
98-
Required: true,
99-
ForceNew: true,
100-
Description: `Optional. The ID to use for the watchlist,
101-
which will become the final component of the watchlist's resource name.
102-
This value should be 4-63 characters, and valid characters
103-
are /a-z-/.`,
104-
},
10596
"description": {
10697
Type: schema.TypeString,
10798
Optional: true,
@@ -113,6 +104,16 @@ are /a-z-/.`,
113104
Description: `Optional. Weight applied to the risk score for entities
114105
in this watchlist.
115106
The default is 1.0 if it is not specified.`,
107+
},
108+
"watchlist_id": {
109+
Type: schema.TypeString,
110+
Computed: true,
111+
Optional: true,
112+
ForceNew: true,
113+
Description: `Optional. The ID to use for the watchlist,
114+
which will become the final component of the watchlist's resource name.
115+
This value should be 4-63 characters, and valid characters
116+
are /a-z-/.`,
116117
},
117118
"watchlist_user_preferences": {
118119
Type: schema.TypeList,
@@ -215,6 +216,17 @@ func resourceChronicleWatchlistCreate(d *schema.ResourceData, meta interface{})
215216
} else if v, ok := d.GetOkExists("watchlist_user_preferences"); !tpgresource.IsEmptyValue(reflect.ValueOf(watchlistUserPreferencesProp)) && (ok || !reflect.DeepEqual(v, watchlistUserPreferencesProp)) {
216217
obj["watchlistUserPreferences"] = watchlistUserPreferencesProp
217218
}
219+
watchlistIdProp, err := expandChronicleWatchlistWatchlistId(d.Get("watchlist_id"), d, config)
220+
if err != nil {
221+
return err
222+
} else if v, ok := d.GetOkExists("watchlist_id"); !tpgresource.IsEmptyValue(reflect.ValueOf(watchlistIdProp)) && (ok || !reflect.DeepEqual(v, watchlistIdProp)) {
223+
obj["watchlistId"] = watchlistIdProp
224+
}
225+
226+
obj, err = resourceChronicleWatchlistEncoder(d, meta, obj)
227+
if err != nil {
228+
return err
229+
}
218230

219231
url, err := tpgresource.ReplaceVars(d, config, "{{ChronicleBasePath}}projects/{{project}}/locations/{{location}}/instances/{{instance}}/watchlists?watchlistId={{watchlist_id}}")
220232
if err != nil {
@@ -260,6 +272,14 @@ func resourceChronicleWatchlistCreate(d *schema.ResourceData, meta interface{})
260272
}
261273
d.SetId(id)
262274

275+
if tpgresource.IsEmptyValue(reflect.ValueOf(d.Get("watchlist_id"))) {
276+
// watchlist id is set by API when unset and required to GET the connection
277+
// it is set by reading the "name" field rather than a field in the response
278+
if err := d.Set("watchlist_id", flattenChronicleWatchlistWatchlistId("", d, config)); err != nil {
279+
return fmt.Errorf("Error reading Watchlist ID: %s", err)
280+
}
281+
}
282+
263283
log.Printf("[DEBUG] Finished creating Watchlist %q: %#v", d.Id(), res)
264284

265285
return resourceChronicleWatchlistRead(d, meta)
@@ -334,6 +354,9 @@ func resourceChronicleWatchlistRead(d *schema.ResourceData, meta interface{}) er
334354
if err := d.Set("watchlist_user_preferences", flattenChronicleWatchlistWatchlistUserPreferences(res["watchlistUserPreferences"], d, config)); err != nil {
335355
return fmt.Errorf("Error reading Watchlist: %s", err)
336356
}
357+
if err := d.Set("watchlist_id", flattenChronicleWatchlistWatchlistId(res["watchlistId"], d, config)); err != nil {
358+
return fmt.Errorf("Error reading Watchlist: %s", err)
359+
}
337360

338361
return nil
339362
}
@@ -385,6 +408,11 @@ func resourceChronicleWatchlistUpdate(d *schema.ResourceData, meta interface{})
385408
obj["watchlistUserPreferences"] = watchlistUserPreferencesProp
386409
}
387410

411+
obj, err = resourceChronicleWatchlistEncoder(d, meta, obj)
412+
if err != nil {
413+
return err
414+
}
415+
388416
url, err := tpgresource.ReplaceVars(d, config, "{{ChronicleBasePath}}projects/{{project}}/locations/{{location}}/instances/{{instance}}/watchlists/{{watchlist_id}}")
389417
if err != nil {
390418
return err
@@ -628,6 +656,11 @@ func flattenChronicleWatchlistWatchlistUserPreferencesPinned(v interface{}, d *s
628656
return v
629657
}
630658

659+
func flattenChronicleWatchlistWatchlistId(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
660+
parts := strings.Split(d.Get("name").(string), "/")
661+
return parts[len(parts)-1]
662+
}
663+
631664
func expandChronicleWatchlistMultiplyingFactor(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
632665
return v, nil
633666
}
@@ -696,3 +729,13 @@ func expandChronicleWatchlistWatchlistUserPreferences(v interface{}, d tpgresour
696729
func expandChronicleWatchlistWatchlistUserPreferencesPinned(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
697730
return v, nil
698731
}
732+
733+
func expandChronicleWatchlistWatchlistId(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
734+
return v, nil
735+
}
736+
737+
func resourceChronicleWatchlistEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
738+
// watchlist_id is needed to qualify the URL but cannot be sent in the body
739+
delete(obj, "watchlistId")
740+
return obj, nil
741+
}

google-beta/services/chronicle/resource_chronicle_watchlist_generated_test.go

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func TestAccChronicleWatchlist_chronicleWatchlistBasicExample(t *testing.T) {
5151
ResourceName: "google_chronicle_watchlist.example",
5252
ImportState: true,
5353
ImportStateVerify: true,
54-
ImportStateVerifyIgnore: []string{"instance", "location", "watchlist_id"},
54+
ImportStateVerifyIgnore: []string{"instance", "location"},
5555
},
5656
},
5757
})
@@ -63,7 +63,48 @@ resource "google_chronicle_watchlist" "example" {
6363
provider = "google-beta"
6464
location = "us"
6565
instance = "%{chronicle_id}"
66-
watchlist_id = "tf-test-watchlist-name%{random_suffix}"
66+
watchlist_id = "tf-test-watchlist-id%{random_suffix}"
67+
description = "tf-test-watchlist-description%{random_suffix}"
68+
display_name = "tf_test_watchlist_name%{random_suffix}"
69+
multiplying_factor = 1
70+
entity_population_mechanism {
71+
manual {
72+
73+
}
74+
}
75+
watchlist_user_preferences {
76+
pinned = true
77+
}
78+
}
79+
`, context)
80+
}
81+
82+
func TestAccChronicleWatchlist_chronicleWatchlistWithoutIdExample(t *testing.T) {
83+
t.Parallel()
84+
85+
context := map[string]interface{}{
86+
"chronicle_id": envvar.GetTestChronicleInstanceIdFromEnv(t),
87+
"random_suffix": acctest.RandString(t, 10),
88+
}
89+
90+
acctest.VcrTest(t, resource.TestCase{
91+
PreCheck: func() { acctest.AccTestPreCheck(t) },
92+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
93+
CheckDestroy: testAccCheckChronicleWatchlistDestroyProducer(t),
94+
Steps: []resource.TestStep{
95+
{
96+
Config: testAccChronicleWatchlist_chronicleWatchlistWithoutIdExample(context),
97+
},
98+
},
99+
})
100+
}
101+
102+
func testAccChronicleWatchlist_chronicleWatchlistWithoutIdExample(context map[string]interface{}) string {
103+
return acctest.Nprintf(`
104+
resource "google_chronicle_watchlist" "example" {
105+
provider = "google-beta"
106+
location = "us"
107+
instance = "%{chronicle_id}"
67108
description = "tf-test-watchlist-description%{random_suffix}"
68109
display_name = "tf-test-watchlist-name%{random_suffix}"
69110
multiplying_factor = 1

website/docs/r/chronicle_watchlist.html.markdown

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,28 @@ resource "google_chronicle_watchlist" "example" {
3838
provider = "google-beta"
3939
location = "us"
4040
instance = "00000000-0000-0000-0000-000000000000"
41-
watchlist_id = "watchlist-name"
41+
watchlist_id = "watchlist-id"
42+
description = "watchlist-description"
43+
display_name = "watchlist_name"
44+
multiplying_factor = 1
45+
entity_population_mechanism {
46+
manual {
47+
48+
}
49+
}
50+
watchlist_user_preferences {
51+
pinned = true
52+
}
53+
}
54+
```
55+
## Example Usage - Chronicle Watchlist Without Id
56+
57+
58+
```hcl
59+
resource "google_chronicle_watchlist" "example" {
60+
provider = "google-beta"
61+
location = "us"
62+
instance = "00000000-0000-0000-0000-000000000000"
4263
description = "watchlist-description"
4364
display_name = "watchlist-name"
4465
multiplying_factor = 1
@@ -77,13 +98,6 @@ The following arguments are supported:
7798
(Required)
7899
The unique identifier for the Chronicle instance, which is the same as the customer ID.
79100

80-
* `watchlist_id` -
81-
(Required)
82-
Optional. The ID to use for the watchlist,
83-
which will become the final component of the watchlist's resource name.
84-
This value should be 4-63 characters, and valid characters
85-
are /a-z-/.
86-
87101

88102
<a name="nested_entity_population_mechanism"></a>The `entity_population_mechanism` block supports:
89103

@@ -109,6 +123,13 @@ The following arguments are supported:
109123
A collection of user preferences for watchlist UI configuration.
110124
Structure is [documented below](#nested_watchlist_user_preferences).
111125

126+
* `watchlist_id` -
127+
(Optional)
128+
Optional. The ID to use for the watchlist,
129+
which will become the final component of the watchlist's resource name.
130+
This value should be 4-63 characters, and valid characters
131+
are /a-z-/.
132+
112133
* `project` - (Optional) The ID of the project in which the resource belongs.
113134
If it is not provided, the provider project is used.
114135

0 commit comments

Comments
 (0)