Skip to content

Commit 8dc11db

Browse files
feat: Add support for suppression rules in Aqua Security Terraform provider
Implementation: Adds suppression rule CRUD resource and listing data source, wires them into the provider with new client endpoints and constants, plus docs, examples, tests, and refined credential handling. - **Suppression Rules**: - **Resource**: New `aquasec_suppression_rule` with CRUD, schema validations, and import (`aquasec/resource_suppression_rules.go`). - **Data Source**: New `aquasec_suppression_rules` for listing/pagination (`aquasec/data_suppression_rules.go`). - **Provider Wiring**: Registers resource/data source in `provider.go`. - **Client**: - Adds `SuppressionRule` models, enums, and helpers; implements `Get/List/Create/Update/Delete` via Supply Chain API (`client/suppression_rules.go`). - Extends client init with `saasScpUrl`; adds supply-chain URLs and adjusts API-key auth mapping (`client/client.go`, `consts/consts.go`). - **Utils**: New flatten/expand helpers for suppression rules (`aquasec/utils.go`). - **Provider Config**: Trims/merges creds from file/env, prefers API key flow, updates validation paths (`aquasec/provider.go`). - **Docs & Examples**: Adds docs for resource/data source and Terraform examples. - **Tests**: Acceptance tests for resource and data source.
1 parent 0a6066f commit 8dc11db

File tree

13 files changed

+2164
-28
lines changed

13 files changed

+2164
-28
lines changed

aquasec/data_suppression_rules.go

Lines changed: 407 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package aquasec
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
9+
)
10+
11+
func TestDataSourceSuppressionRule(t *testing.T) {
12+
t.Parallel()
13+
14+
resource.Test(t, resource.TestCase{
15+
PreCheck: func() { testAccPreCheck(t) },
16+
Providers: testAccProviders,
17+
Steps: []resource.TestStep{
18+
{
19+
Config: testAccDataSourceSuppressionRuleConfig(),
20+
Check: testAccDataSourceSuppressionRuleExists("data.aquasec_suppression_rules.all"),
21+
},
22+
},
23+
})
24+
}
25+
26+
func testAccDataSourceSuppressionRuleConfig() string {
27+
return `
28+
data "aquasec_suppression_rules" "all" {
29+
}
30+
`
31+
}
32+
33+
func testAccDataSourceSuppressionRuleExists(resourceName string) resource.TestCheckFunc {
34+
return func(s *terraform.State) error {
35+
rs, ok := s.RootModule().Resources[resourceName]
36+
if !ok {
37+
return fmt.Errorf("not found: %s", resourceName)
38+
}
39+
40+
if rs.Primary.ID == "" {
41+
return fmt.Errorf("no ID is set")
42+
}
43+
44+
return nil
45+
}
46+
}

aquasec/provider.go

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io"
88
"log"
99
"os"
10+
"strings"
1011

1112
"github.com/aquasecurity/terraform-provider-aquasec/client"
1213
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -146,6 +147,7 @@ func Provider(v string) *schema.Provider {
146147
"aquasec_log_management": resourceLogManagement(),
147148
"aquasec_serverless_application": resourceServerlessApplication(),
148149
"aquasec_monitoring_system": resourceMonitoringSystem(),
150+
"aquasec_suppression_rule": resourceSuppressionRule(),
149151
},
150152
DataSourcesMap: map[string]*schema.Resource{
151153
"aquasec_users": dataSourceUsers(),
@@ -184,6 +186,7 @@ func Provider(v string) *schema.Provider {
184186
"aquasec_log_managements": dataLogManagement(),
185187
"aquasec_serverless_applications": dataSourceServerlessApplication(),
186188
"aquasec_monitoring_systems": dataSourceMonitoringSystem(),
189+
"aquasec_suppression_rules": dataSourceSuppressionRule(),
187190
},
188191
ConfigureContextFunc: providerConfigure,
189192
}
@@ -235,31 +238,54 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}
235238
caCertPath := d.Get("ca_certificate_path").(string)
236239
validate := d.Get("validate").(bool)
237240

238-
if username == "" && password == "" && aquaURL == "" && apiKey == "" && secretkey == "" {
239-
username, password, aquaURL, apiKey, secretkey, err = getProviderConfigurationFromFile(d)
240-
if err != nil && validate {
241-
return nil, diag.FromErr(err)
241+
if username == "" || password == "" || apiKey == "" || secretkey == "" {
242+
uF, pF, fileURL, akF, skF, ferr := getProviderConfigurationFromFile(d)
243+
if ferr != nil && validate {
244+
return nil, diag.FromErr(ferr)
245+
}
246+
if username == "" {
247+
username = uF
248+
}
249+
if password == "" {
250+
password = pF
251+
}
252+
if aquaURL == "" && fileURL != "" {
253+
aquaURL = fileURL
254+
}
255+
if apiKey == "" {
256+
apiKey = akF
257+
}
258+
if secretkey == "" {
259+
secretkey = skF
242260
}
243261
}
244262

263+
username = strings.TrimSpace(username)
264+
password = strings.TrimSpace(password)
265+
apiKey = strings.TrimSpace(apiKey)
266+
secretkey = strings.TrimSpace(secretkey)
267+
aquaURL = strings.TrimSpace(aquaURL)
268+
245269
if validate {
246270
if aquaURL == "" {
247271
diags = append(diags, diag.Diagnostic{
248272
Severity: diag.Error,
249273
Summary: "Initializing provider, aqua_url parameter is missing.",
250274
})
251275
}
252-
if username == "" {
253-
diags = append(diags, diag.Diagnostic{
254-
Severity: diag.Error,
255-
Summary: "Initializing provider, username parameter is missing.",
256-
})
257-
}
258-
if password == "" {
259-
diags = append(diags, diag.Diagnostic{
260-
Severity: diag.Error,
261-
Summary: "Initializing provider, password parameter is missing.",
262-
})
276+
if apiKey == "" && secretkey == "" {
277+
if username == "" {
278+
diags = append(diags, diag.Diagnostic{
279+
Severity: diag.Error,
280+
Summary: "Initializing provider, username parameter is missing.",
281+
})
282+
}
283+
if password == "" {
284+
diags = append(diags, diag.Diagnostic{
285+
Severity: diag.Error,
286+
Summary: "Initializing provider, password parameter is missing.",
287+
})
288+
}
263289
}
264290
}
265291

@@ -282,16 +308,7 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}
282308
}
283309

284310
var aquaClient *client.Client
285-
if username != "" && password != "" {
286-
aquaClient, err = client.NewClientWithTokenAuth(aquaURL, username, password, verifyTLS, caCertByte)
287-
if err != nil {
288-
return nil, diag.Diagnostics{diag.Diagnostic{
289-
Severity: diag.Error,
290-
Summary: "Error creating Aqua client with token authentication",
291-
Detail: err.Error(),
292-
}}
293-
}
294-
} else if apiKey != "" {
311+
if apiKey != "" {
295312
aquaClient, err = client.NewClientWithAPIKey(aquaURL, apiKey, secretkey, verifyTLS, caCertByte)
296313
if err != nil {
297314
return nil, diag.Diagnostics{diag.Diagnostic{
@@ -309,6 +326,15 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}
309326
if v, ok := d.GetOk("csp_roles"); ok {
310327
aquaClient.CSPRoles = convertStringArr(v.([]interface{}))
311328
}
329+
} else if username != "" && password != "" {
330+
aquaClient, err = client.NewClientWithTokenAuth(aquaURL, username, password, verifyTLS, caCertByte)
331+
if err != nil {
332+
return nil, diag.Diagnostics{diag.Diagnostic{
333+
Severity: diag.Error,
334+
Summary: "Error creating Aqua client with token authentication",
335+
Detail: err.Error(),
336+
}}
337+
}
312338
} else {
313339
return nil, diag.Diagnostics{diag.Diagnostic{
314340
Severity: diag.Error,

0 commit comments

Comments
 (0)