Skip to content

Commit bfd0121

Browse files
feat(CIS): Add support for managed and custom lists (IBM-Cloud#6310)
* feat(CIS): Add support for managed and custom lists * fix typo * add custom list * add custom list example * add get custom list items * add list items * add acceptance test for data files * add acceptance test for resource files * sync go sdk version * add example * add documentation * Update cis_custom_list_items.html.markdown * Update cis_custom_list_items.html.markdown * Update cis_custom_list_items.html.markdown * Update cis_custom_lists.html.markdown * Update cis_managed_lists.html.markdown * Update cis_custom_list.html.markdown * Update cis_custom_list_items.copy.markdown * fix error toolchain issue * fix name issue --------- Co-authored-by: austinmama <[email protected]>
1 parent be7c2ca commit bfd0121

18 files changed

+1464
-1
lines changed

examples/ibm-cis/main.tf

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,4 +855,42 @@ data ibm_cis_origin_certificates "test" {
855855
cis_id = ibm_cis.instance.id
856856
domain_id = ibm_cis_domain.example.id
857857
certificate_id = "25392180178235735583993116186144990011711092749"
858-
}
858+
}
859+
860+
# Get Managed lists
861+
data ibm_cis_managed_lists managed_lists {
862+
cis_id = ibm_cis.instance.id
863+
}
864+
865+
# Get custom lists
866+
data ibm_cis_custom_lists custom_lists {
867+
cis_id = ibm_cis.instance.id
868+
list_id = ibm_cis.lists.list_id
869+
}
870+
871+
# create custom list
872+
resource ibm_cis_custom_list custom_list {
873+
cis_id = ibm_cis.instance.id
874+
kind = var.list.kind
875+
name = var.list.name
876+
description = var.list.description
877+
}
878+
879+
# Get custom list items
880+
data ibm_cis_custom_list_items custom_list_items {
881+
cis_id = ibm_cis.instance.id
882+
list_id = ibm_cis.lists.list_id
883+
item_id = ibm_cis.lists.item.item_id
884+
}
885+
886+
# Create custom list items
887+
resource ibm_cis_custom_list_items items {
888+
cis_id = ibm_cis.instance.id
889+
list_id = ibm_cis.lists.list_id
890+
items {
891+
ip = var.ip1
892+
}
893+
items {
894+
ip = var.ip2
895+
}
896+
}

ibm/conns/config.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import (
5252
cisglbhealthcheckv1 "github.com/IBM/networking-go-sdk/globalloadbalancermonitorv1"
5353
cisglbpoolv0 "github.com/IBM/networking-go-sdk/globalloadbalancerpoolsv0"
5454
cisglbv1 "github.com/IBM/networking-go-sdk/globalloadbalancerv1"
55+
cislistsapiv1 "github.com/IBM/networking-go-sdk/listsapiv1"
5556
cislogpushjobsapiv1 "github.com/IBM/networking-go-sdk/logpushjobsapiv1"
5657
cismtlsv1 "github.com/IBM/networking-go-sdk/mtlsv1"
5758
cispagerulev1 "github.com/IBM/networking-go-sdk/pageruleapiv1"
@@ -296,6 +297,7 @@ type ClientSession interface {
296297
CisLockdownClientSession() (*cislockdownv1.ZoneLockdownV1, error)
297298
CisRangeAppClientSession() (*cisrangeappv1.RangeApplicationsV1, error)
298299
CisWAFRuleClientSession() (*ciswafrulev1.WafRulesApiV1, error)
300+
CisListsSession() (*cislistsapiv1.ListsApiV1, error)
299301
IAMIdentityV1API() (*iamidentity.IamIdentityV1, error)
300302
IBMCloudShellV1() (*ibmcloudshellv1.IBMCloudShellV1, error)
301303
ResourceManagerV2API() (*resourcemanager.ResourceManagerV2, error)
@@ -550,6 +552,11 @@ type clientSession struct {
550552
// CIS WAF rule service options
551553
cisWAFRuleErr error
552554
cisWAFRuleClient *ciswafrulev1.WafRulesApiV1
555+
556+
// CIS LISTS
557+
cisListsClient *cislistsapiv1.ListsApiV1
558+
cisListsErr error
559+
553560
// IAM Identity Option
554561
iamIdentityErr error
555562
iamIdentityAPI *iamidentity.IamIdentityV1
@@ -1149,6 +1156,14 @@ func (sess clientSession) CisOrigAuthSession() (*cisoriginpull.AuthenticatedOrig
11491156
return sess.cisOriginAuthClient.Clone(), nil
11501157
}
11511158

1159+
// CIS Lists
1160+
func (sess clientSession) CisListsSession() (*cislistsapiv1.ListsApiV1, error) {
1161+
if sess.cisListsErr != nil {
1162+
return sess.cisListsClient, sess.cisListsErr
1163+
}
1164+
return sess.cisListsClient.Clone(), nil
1165+
}
1166+
11521167
// IAM Identity Session
11531168
func (sess clientSession) IAMIdentityV1API() (*iamidentity.IamIdentityV1, error) {
11541169
return sess.iamIdentityAPI, sess.iamIdentityErr
@@ -3165,6 +3180,27 @@ func (c *Config) ClientSession() (interface{}, error) {
31653180
})
31663181
}
31673182

3183+
// IBM Network CIS Lists
3184+
cisListsOpt := &cislistsapiv1.ListsApiV1Options{
3185+
URL: cisEndPoint,
3186+
Crn: core.StringPtr(""),
3187+
Authenticator: authenticator,
3188+
ItemID: core.StringPtr(""),
3189+
ListID: core.StringPtr(""),
3190+
OperationID: core.StringPtr(""),
3191+
}
3192+
session.cisListsClient, session.cisListsErr = cislistsapiv1.NewListsApiV1(cisListsOpt)
3193+
if session.cisListsErr != nil {
3194+
session.cisListsErr = fmt.Errorf("[ERROR] Error occured while configuring CIS Lists : %s",
3195+
session.cisListsErr)
3196+
}
3197+
if session.cisListsClient != nil && session.cisListsClient.Service != nil {
3198+
session.cisListsClient.Service.EnableRetries(c.RetryCount, c.RetryDelay)
3199+
session.cisListsClient.SetDefaultHeaders(gohttp.Header{
3200+
"X-Original-User-Agent": {fmt.Sprintf("terraform-provider-ibm/%s", version.Version)},
3201+
})
3202+
}
3203+
31683204
// IAM IDENTITY Service
31693205
// iamIdenityURL := fmt.Sprintf("https://%s.iam.cloud.ibm.com/v1", c.Region)
31703206
iamIdenityURL := iamidentity.DefaultServiceURL

ibm/provider/provider.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ func Provider() *schema.Provider {
343343
"ibm_cis_filters": cis.DataSourceIBMCISFilters(),
344344
"ibm_cis_firewall_rules": cis.DataSourceIBMCISFirewallRules(),
345345
"ibm_cis_origin_certificates": cis.DataSourceIBMCISOriginCertificateOrder(),
346+
"ibm_cis_managed_lists": cis.DataSourceIBMCISManagedLists(),
347+
"ibm_cis_custom_lists": cis.DataSourceIBMCISCustomLists(),
348+
"ibm_cis_custom_list_items": cis.DataSourceIBMCISCustomListItems(),
346349
"ibm_cloudant": cloudant.DataSourceIBMCloudant(),
347350
"ibm_cloudant_database": cloudant.DataSourceIBMCloudantDatabase(),
348351
"ibm_database": database.DataSourceIBMDatabaseInstance(),
@@ -1179,6 +1182,8 @@ func Provider() *schema.Provider {
11791182
"ibm_cis_ruleset_entrypoint_version": cis.ResourceIBMCISRulesetEntryPointVersion(),
11801183
"ibm_cis_advanced_certificate_pack_order": cis.ResourceIBMCISAdvancedCertificatePackOrder(),
11811184
"ibm_cis_origin_certificate_order": cis.ResourceIBMCISOriginCertificateOrder(),
1185+
"ibm_cis_custom_list": cis.ResourceIBMCISCustomList(),
1186+
"ibm_cis_custom_list_items": cis.ResourceIBMCISCustomListItems(),
11821187

11831188
"ibm_cloudant": cloudant.ResourceIBMCloudant(),
11841189
"ibm_cloudant_database": cloudant.ResourceIBMCloudantDatabase(),
@@ -1969,6 +1974,8 @@ func Validator() validate.ValidatorDict {
19691974
"ibm_cis_ruleset_version_detach": cis.ResourceIBMCISRulesetVersionDetachValidator(),
19701975
"ibm_cis_advanced_certificate_pack_order": cis.ResourceIBMCISAdvancedCertificatePackOrderValidator(),
19711976
"ibm_cis_origin_certificate_order": cis.ResourceIBMCISOriginCertificateOrderValidator(),
1977+
"ibm_cis_custom_list": cis.ResourceIBMCISCustomListValidator(),
1978+
"ibm_cis_custom_list_items": cis.ResourceIBMCISCustomListItemsValidator(),
19721979
"ibm_container_cluster": kubernetes.ResourceIBMContainerClusterValidator(),
19731980
"ibm_container_worker_pool": kubernetes.ResourceIBMContainerWorkerPoolValidator(),
19741981
"ibm_container_vpc_worker_pool": kubernetes.ResourceIBMContainerVPCWorkerPoolValidator(),
@@ -2302,6 +2309,9 @@ func Validator() validate.ValidatorDict {
23022309
"ibm_cis_waf_rules": cis.DataSourceIBMCISWAFRulesValidator(),
23032310
"ibm_cis_logpush_jobs": cis.DataSourceIBMCISLogPushJobsValidator(),
23042311
"ibm_cis_origin_certificates": cis.DataIBMCISOriginCertificateOrderValidator(),
2312+
"ibm_cis_managed_lists": cis.DataSourceIBMCISManagedListsValidator(),
2313+
"ibm_cis_custom_lists": cis.DataSourceIBMCISCustomListsValidator(),
2314+
"ibm_cis_custom_list_items": cis.DataSourceIBMCISCustomListItemsValidator(),
23052315

23062316
"ibm_config_aggregator_configurations": configurationaggregator.DataSourceIbmConfigAggregatorValidator(),
23072317
"ibm_cos_bucket": cos.DataSourceIBMCosBucketValidator(),
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
// Copyright IBM Corp. 2025 All Rights Reserved.
2+
// Licensed under the Mozilla Public License v2.0
3+
4+
package cis
5+
6+
import (
7+
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
8+
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
9+
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/validate"
10+
"github.com/IBM/go-sdk-core/v5/core"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
)
13+
14+
const (
15+
CISCustomListItems = "ibm_cis_custom_list_items"
16+
CISCustomListItemID = "item_id"
17+
CISCustomListItemsOutput = "items"
18+
CISCustomListItemIp = "ip"
19+
CISCustomListItemHostname = "hostname"
20+
CISCustomListItemASN = "asn"
21+
CISCustomListItemComment = "comment"
22+
CISCustomListItemCreatedOn = "created_on"
23+
CISCustomListItemModifiedOn = "modified_on"
24+
)
25+
26+
func DataSourceIBMCISCustomListItems() *schema.Resource {
27+
return &schema.Resource{
28+
Read: DataSourceIBMCISCustomListItemsRead,
29+
Schema: map[string]*schema.Schema{
30+
cisID: {
31+
Type: schema.TypeString,
32+
Description: "CIS instance crn",
33+
Required: true,
34+
ValidateFunc: validate.InvokeDataSourceValidator(
35+
"ibm_cis_ruleset_versions",
36+
"cis_id"),
37+
},
38+
CISCustomListID: {
39+
Type: schema.TypeString,
40+
Description: "Custom List ID",
41+
Required: true,
42+
},
43+
CISCustomListItemID: {
44+
Type: schema.TypeString,
45+
Description: "Custom List Item ID",
46+
Optional: true,
47+
},
48+
CISCustomListItemsOutput: {
49+
Type: schema.TypeSet,
50+
Computed: true,
51+
Description: "Container for response information.",
52+
Elem: &schema.Resource{
53+
Schema: map[string]*schema.Schema{
54+
CISCustomListItemID: {
55+
Type: schema.TypeString,
56+
Description: "Custom List Item ID",
57+
Computed: true,
58+
},
59+
CISCustomListItemIp: {
60+
Type: schema.TypeString,
61+
Computed: true,
62+
Description: "IP address of the item",
63+
},
64+
CISCustomListItemHostname: {
65+
Type: schema.TypeString,
66+
Computed: true,
67+
Description: "Hostname of the item",
68+
},
69+
CISCustomListItemASN: {
70+
Type: schema.TypeInt,
71+
Description: "ASN of the item",
72+
Computed: true,
73+
},
74+
CISCustomListItemComment: {
75+
Type: schema.TypeString,
76+
Description: "Item comment",
77+
Computed: true,
78+
},
79+
CISCustomListItemCreatedOn: {
80+
Type: schema.TypeString,
81+
Description: "Item Create date",
82+
Computed: true,
83+
},
84+
CISCustomListItemModifiedOn: {
85+
Type: schema.TypeString,
86+
Description: "Item last modified date",
87+
Computed: true,
88+
},
89+
},
90+
},
91+
},
92+
},
93+
}
94+
}
95+
96+
func DataSourceIBMCISCustomListItemsValidator() *validate.ResourceValidator {
97+
98+
validateSchema := make([]validate.ValidateSchema, 0)
99+
100+
validateSchema = append(validateSchema,
101+
validate.ValidateSchema{
102+
Identifier: "cis_id",
103+
ValidateFunctionIdentifier: validate.ValidateCloudData,
104+
Type: validate.TypeString,
105+
CloudDataType: "resource_instance",
106+
CloudDataRange: []string{"service:internet-svcs"},
107+
Required: true})
108+
109+
IBMCISCustomListsValidator := validate.ResourceValidator{
110+
ResourceName: CISCustomListItems,
111+
Schema: validateSchema}
112+
return &IBMCISCustomListsValidator
113+
}
114+
115+
func DataSourceIBMCISCustomListItemsRead(d *schema.ResourceData, meta interface{}) error {
116+
sess, err := meta.(conns.ClientSession).CisListsSession()
117+
if err != nil {
118+
return err
119+
}
120+
crn := d.Get(cisID).(string)
121+
sess.Crn = core.StringPtr(crn)
122+
123+
listId := d.Get(CISCustomListID).(string)
124+
sess.ListID = core.StringPtr(listId)
125+
126+
itemId := d.Get(CISCustomListItemID).(string)
127+
128+
listItemList := make([]map[string]interface{}, 0)
129+
if itemId != "" {
130+
sess.ItemID = core.StringPtr(itemId)
131+
opt := sess.NewGetListItemOptions()
132+
result, resp, err := sess.GetListItem(opt)
133+
134+
if err != nil {
135+
flex.FmtErrorf("[WARN] Get Custom List Item failed: %v\n", resp)
136+
return err
137+
}
138+
139+
itemObj := result.Result
140+
itemOutput := map[string]interface{}{}
141+
itemOutput[CISCustomListItemID] = itemObj.ID
142+
itemOutput[CISCustomListItemIp] = itemObj.Ip
143+
itemOutput[CISCustomListItemHostname] = itemObj.Hostname
144+
itemOutput[CISCustomListItemASN] = itemObj.Asn
145+
itemOutput[CISCustomListItemComment] = itemObj.Comment
146+
itemOutput[CISCustomListItemCreatedOn] = itemObj.CreatedOn
147+
itemOutput[CISCustomListItemModifiedOn] = itemObj.ModifiedOn
148+
listItemList = append(listItemList, itemOutput)
149+
150+
} else {
151+
opt := sess.NewGetListItemsOptions()
152+
result, resp, err := sess.GetListItems(opt)
153+
154+
if err != nil {
155+
flex.FmtErrorf("[WARN] List Custom Lists failed: %v\n", resp)
156+
return err
157+
}
158+
159+
for _, itemObj := range result.Result {
160+
itemOutput := map[string]interface{}{}
161+
itemOutput[CISCustomListItemID] = itemObj.ID
162+
itemOutput[CISCustomListItemIp] = itemObj.Ip
163+
itemOutput[CISCustomListItemHostname] = itemObj.Hostname
164+
itemOutput[CISCustomListItemASN] = itemObj.Asn
165+
itemOutput[CISCustomListItemComment] = itemObj.Comment
166+
itemOutput[CISCustomListItemCreatedOn] = itemObj.CreatedOn
167+
itemOutput[CISCustomListItemModifiedOn] = itemObj.ModifiedOn
168+
listItemList = append(listItemList, itemOutput)
169+
}
170+
171+
}
172+
173+
d.Set(CISCustomListID, listId)
174+
d.Set(CISCustomListItemID, itemId)
175+
d.SetId(dataSourceCISCustomListItemsCheckID(d))
176+
d.Set(CISCustomListItemsOutput, listItemList)
177+
d.Set(cisID, crn)
178+
179+
return nil
180+
}
181+
182+
func dataSourceCISCustomListItemsCheckID(d *schema.ResourceData) string {
183+
return "custom_list_item" + ":" + d.Get(CISCustomListID).(string) + ":" + d.Get(cisID).(string)
184+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright IBM Corp. 2025 All Rights Reserved.
2+
// Licensed under the Mozilla Public License v2.0
3+
4+
package cis_test
5+
6+
import (
7+
"fmt"
8+
"testing"
9+
10+
acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest"
11+
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
13+
)
14+
15+
func TestAccIBMCisCustomListItemsDataSource_Basic(t *testing.T) {
16+
name := "data.ibm_cis_custom_list_items.test"
17+
resource.Test(t, resource.TestCase{
18+
PreCheck: func() { acc.TestAccPreCheckCis(t) },
19+
Providers: acc.TestAccProviders,
20+
Steps: []resource.TestStep{
21+
{
22+
Config: testAccCheckCisCustomListItemsDataSource_basic("test"),
23+
Check: resource.ComposeTestCheckFunc(
24+
resource.TestCheckResourceAttrSet(name, "items.#"),
25+
),
26+
},
27+
},
28+
})
29+
}
30+
func testAccCheckCisCustomListItemsDataSource_basic(id string) string {
31+
return testAccCheckIBMCisDomainDataSourceConfigBasic1() + fmt.Sprintf(`
32+
data ibm_cis_custom_lists custom_lists {
33+
cis_id = data.ibm_cis.cis.id
34+
}
35+
36+
data "ibm_cis_custom_list_items" "%[1]s" {
37+
cis_id = data.ibm_cis.cis.id
38+
list_id = data.ibm_cis_custom_lists.custom_lists.lists[0].list_id
39+
}
40+
`, id)
41+
}

0 commit comments

Comments
 (0)