Skip to content

Commit 5ebdde9

Browse files
committed
feat(zones): support v2 expression syntax for sysdig_secure_zone
1 parent 97535da commit 5ebdde9

18 files changed

Lines changed: 2681 additions & 246 deletions

go.mod

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ require (
77
github.com/aws/aws-sdk-go v1.55.7
88
github.com/hashicorp/go-cty v1.5.0
99
github.com/hashicorp/go-retryablehttp v0.7.8
10-
github.com/hashicorp/terraform-plugin-log v0.9.0
11-
github.com/hashicorp/terraform-plugin-sdk/v2 v2.37.0
10+
github.com/hashicorp/terraform-plugin-log v0.10.0
11+
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1
12+
github.com/hashicorp/terraform-plugin-testing v1.14.0
1213
github.com/jmespath/go-jmespath v0.4.0
1314
github.com/rs/zerolog v1.34.0
1415
github.com/spf13/cast v1.9.2
1516
github.com/stretchr/testify v1.10.0
1617
github.com/sysdiglabs/agent-kilt v1.0.0
17-
google.golang.org/protobuf v1.36.6
18+
google.golang.org/protobuf v1.36.9
1819
)
1920

2021
require (
@@ -23,7 +24,7 @@ require (
2324
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
2425
github.com/cloudflare/circl v1.6.1 // indirect
2526
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
26-
github.com/davecgh/go-spew v1.1.1 // indirect
27+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
2728
github.com/docker/cli v28.3.2+incompatible // indirect
2829
github.com/docker/distribution v2.8.3+incompatible // indirect
2930
github.com/docker/docker-credential-helpers v0.9.3 // indirect
@@ -37,16 +38,16 @@ require (
3738
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
3839
github.com/hashicorp/go-hclog v1.6.3 // indirect
3940
github.com/hashicorp/go-multierror v1.1.1 // indirect
40-
github.com/hashicorp/go-plugin v1.6.3 // indirect
41+
github.com/hashicorp/go-plugin v1.7.0 // indirect
4142
github.com/hashicorp/go-uuid v1.0.3 // indirect
4243
github.com/hashicorp/go-version v1.7.0 // indirect
4344
github.com/hashicorp/hc-install v0.9.2 // indirect
4445
github.com/hashicorp/hcl/v2 v2.24.0 // indirect
4546
github.com/hashicorp/logutils v1.0.0 // indirect
46-
github.com/hashicorp/terraform-exec v0.23.0 // indirect
47-
github.com/hashicorp/terraform-json v0.25.0 // indirect
48-
github.com/hashicorp/terraform-plugin-go v0.28.0 // indirect
49-
github.com/hashicorp/terraform-registry-address v0.3.0 // indirect
47+
github.com/hashicorp/terraform-exec v0.24.0 // indirect
48+
github.com/hashicorp/terraform-json v0.27.2 // indirect
49+
github.com/hashicorp/terraform-plugin-go v0.29.0 // indirect
50+
github.com/hashicorp/terraform-registry-address v0.4.0 // indirect
5051
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
5152
github.com/hashicorp/yamux v0.1.2 // indirect
5253
github.com/klauspost/compress v1.18.0 // indirect
@@ -62,22 +63,22 @@ require (
6263
github.com/opencontainers/go-digest v1.0.0 // indirect
6364
github.com/opencontainers/image-spec v1.1.1 // indirect
6465
github.com/pkg/errors v0.9.1 // indirect
65-
github.com/pmezard/go-difflib v1.0.0 // indirect
66+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
6667
github.com/sirupsen/logrus v1.9.3 // indirect
6768
github.com/vbatts/tar-split v0.12.1 // indirect
6869
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
6970
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
7071
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
71-
github.com/zclconf/go-cty v1.16.3 // indirect
72-
golang.org/x/crypto v0.39.0 // indirect
73-
golang.org/x/mod v0.25.0 // indirect
74-
golang.org/x/net v0.41.0 // indirect
75-
golang.org/x/sync v0.16.0 // indirect
76-
golang.org/x/sys v0.34.0 // indirect
77-
golang.org/x/text v0.26.0 // indirect
78-
golang.org/x/tools v0.34.0 // indirect
72+
github.com/zclconf/go-cty v1.17.0 // indirect
73+
golang.org/x/crypto v0.45.0 // indirect
74+
golang.org/x/mod v0.29.0 // indirect
75+
golang.org/x/net v0.47.0 // indirect
76+
golang.org/x/sync v0.18.0 // indirect
77+
golang.org/x/sys v0.38.0 // indirect
78+
golang.org/x/text v0.31.0 // indirect
79+
golang.org/x/tools v0.38.0 // indirect
7980
google.golang.org/appengine v1.6.8 // indirect
8081
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
81-
google.golang.org/grpc v1.73.0 // indirect
82+
google.golang.org/grpc v1.75.1 // indirect
8283
gopkg.in/yaml.v3 v3.0.1 // indirect
8384
)

go.sum

Lines changed: 62 additions & 55 deletions
Large diffs are not rendered by default.

sysdig/common.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ const (
5252
SchemaScopeKey = "scope"
5353
SchemaScopesKey = "scopes"
5454
SchemaTargetTypeKey = "target_type"
55+
SchemaResourceTypeKey = "resource_type"
56+
SchemaExpressionKey = "expression"
57+
SchemaFieldKey = "field"
58+
SchemaOperatorKey = "operator"
59+
SchemaValueKey = "value"
60+
SchemaValuesKey = "values"
5561
SchemaRoleKey = "role"
5662
SchemaSystemRoleKey = "system_role"
5763
SchemaRulesKey = "rules"

sysdig/data_source_sysdig_secure_zone.go

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,34 @@ func dataSourceSysdigSecureZone() *schema.Resource {
5050
Type: schema.TypeString,
5151
Computed: true,
5252
},
53+
// Not marked Deprecated: rules with v2-compatible syntax are fully supported.
54+
// Only v1 syntax (labels, labelValues, agentTags) is deprecated, but since
55+
// this is a Computed field, SDK v2 has no mechanism for conditional deprecation.
56+
// The resource-side ValidateDiagFunc handles the v1-only warning.
5357
SchemaRulesKey: {
5458
Type: schema.TypeString,
5559
Computed: true,
5660
},
61+
SchemaExpressionKey: {
62+
Type: schema.TypeList,
63+
Computed: true,
64+
Elem: &schema.Resource{
65+
Schema: map[string]*schema.Schema{
66+
SchemaFieldKey: {Type: schema.TypeString, Computed: true},
67+
SchemaOperatorKey: {Type: schema.TypeString, Computed: true},
68+
SchemaValueKey: {Type: schema.TypeString, Computed: true},
69+
SchemaValuesKey: {
70+
Type: schema.TypeList,
71+
Computed: true,
72+
Elem: &schema.Schema{Type: schema.TypeString},
73+
},
74+
},
75+
},
76+
},
5777
},
5878
},
5979
},
80+
6081
"id": {
6182
Type: schema.TypeString,
6283
Optional: true,
@@ -74,52 +95,80 @@ func dataSourceSysdigSecureZone() *schema.Resource {
7495
}
7596

7697
func dataSourceSysdigSecureZoneRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
77-
client, err := getZoneClient(m.(SysdigClients))
98+
clientV2, err := getZoneV2Client(m.(SysdigClients))
7899
if err != nil {
79100
return diag.FromErr(err)
80101
}
81-
82-
var zone *v2.Zone
102+
var zoneV2 *v2.ZoneV2
83103
zoneIDRaw, hasZoneID := d.GetOk("id")
84104
if hasZoneID {
85105
zoneID, err := strconv.Atoi(zoneIDRaw.(string))
86106
if err != nil {
87-
return diag.FromErr(fmt.Errorf("invalid zone id: %s", err))
107+
return diag.FromErr(fmt.Errorf("error fetching zone by ID: %s", err))
88108
}
89-
zone, err = client.GetZoneByID(ctx, zoneID)
109+
zoneV2, err = clientV2.GetZoneV2(ctx, zoneID)
90110
if err != nil {
91-
return diag.FromErr(fmt.Errorf("error fetching zone by ID: %s", err))
111+
return diag.FromErr(fmt.Errorf("error fetching zone v2 by ID: %s", err))
92112
}
93113
} else if nameRaw, hasName := d.GetOk("name"); hasName {
94114
name := nameRaw.(string)
95-
zones, err := client.GetZones(ctx, name)
115+
zones, err := clientV2.GetZonesV2(ctx, name)
96116
if err != nil {
97117
return diag.FromErr(fmt.Errorf("error fetching zones: %s", err))
98118
}
99119
for _, z := range zones {
100120
if z.Name == name {
101-
zone = &z
121+
zoneV2 = &z
102122
break
103123
}
104124
}
105-
if zone == nil {
125+
if zoneV2 == nil {
106126
return diag.FromErr(fmt.Errorf("zone with name '%s' not found", name))
107127
}
128+
zoneV2, err = clientV2.GetZoneV2(ctx, zoneV2.ID)
129+
if err != nil {
130+
return diag.FromErr(fmt.Errorf("error fetching zones: %s", err))
131+
}
108132
} else {
109133
return diag.FromErr(fmt.Errorf("either id or name must be specified"))
110134
}
111135

112-
d.SetId(fmt.Sprintf("%d", zone.ID))
113-
_ = d.Set(SchemaNameKey, zone.Name)
114-
_ = d.Set(SchemaDescriptionKey, zone.Description)
115-
_ = d.Set(SchemaIsSystemKey, zone.IsSystem)
116-
_ = d.Set(SchemaAuthorKey, zone.Author)
117-
_ = d.Set(SchemaLastModifiedBy, zone.LastModifiedBy)
118-
_ = d.Set(SchemaLastUpdated, time.UnixMilli(zone.LastUpdated).Format(time.RFC3339))
136+
d.SetId(fmt.Sprintf("%d", zoneV2.ID))
137+
_ = d.Set(SchemaNameKey, zoneV2.Name)
138+
_ = d.Set(SchemaDescriptionKey, zoneV2.Description)
139+
_ = d.Set(SchemaIsSystemKey, zoneV2.IsSystem)
140+
_ = d.Set(SchemaAuthorKey, zoneV2.Author)
141+
_ = d.Set(SchemaLastModifiedBy, zoneV2.LastModifiedBy)
142+
_ = d.Set(SchemaLastUpdated, time.UnixMilli(zoneV2.LastUpdated).Format(time.RFC3339))
119143

120-
if err := d.Set(SchemaScopeKey, fromZoneScopesResponse(zone.Scopes)); err != nil {
144+
if err := d.Set(SchemaScopeKey, getZoneScopes(zoneV2)); err != nil {
121145
return diag.FromErr(fmt.Errorf("error setting scope: %s", err))
122146
}
123147

124148
return nil
125149
}
150+
151+
func getZoneScopes(zoneV2 *v2.ZoneV2) []any {
152+
// Build expression lookup by filter ID from the v2 response.
153+
out := make([]any, 0)
154+
if zoneV2 != nil {
155+
for _, s := range zoneV2.Scopes {
156+
for _, f := range s.Filters {
157+
if f.ID != 0 && len(f.Expressions) > 0 {
158+
var exprs []any
159+
for _, e := range f.Expressions {
160+
exprs = append(exprs, flattenExpressionV2(e))
161+
}
162+
m := map[string]any{
163+
SchemaIDKey: f.ID,
164+
SchemaTargetTypeKey: f.ResourceType,
165+
SchemaRulesKey: f.Rules,
166+
}
167+
m[SchemaExpressionKey] = exprs
168+
out = append(out, m)
169+
}
170+
}
171+
}
172+
}
173+
return out
174+
}

sysdig/data_source_sysdig_secure_zone_test.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package sysdig_test
44

55
import (
6+
"fmt"
67
"testing"
78

89
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@@ -43,6 +44,125 @@ func TestAccDataSourceSysdigSecureZone(t *testing.T) {
4344
})
4445
}
4546

47+
func TestAccDataSourceSysdigSecureZone_ByName(t *testing.T) {
48+
zoneName := "Zone_DS_" + randomText(5)
49+
50+
resource.ParallelTest(t, resource.TestCase{
51+
PreCheck: preCheckAnyEnv(t, SysdigSecureApiTokenEnv, SysdigIBMSecureAPIKeyEnv),
52+
ProviderFactories: map[string]func() (*schema.Provider, error){
53+
"sysdig": func() (*schema.Provider, error) {
54+
return sysdig.Provider(), nil
55+
},
56+
},
57+
Steps: []resource.TestStep{
58+
{
59+
Config: testAccDataSourceSecureZoneByName(zoneName),
60+
Check: resource.ComposeTestCheckFunc(
61+
resource.TestCheckResourceAttr(
62+
"data.sysdig_secure_zone.test",
63+
"name",
64+
zoneName,
65+
),
66+
resource.TestCheckResourceAttr(
67+
"data.sysdig_secure_zone.test",
68+
"scope.0.target_type",
69+
"aws",
70+
),
71+
72+
// v2 expressions
73+
resource.TestCheckResourceAttr(
74+
"data.sysdig_secure_zone.test",
75+
"scope.0.expression.#",
76+
"1",
77+
),
78+
resource.TestCheckResourceAttr(
79+
"data.sysdig_secure_zone.test",
80+
"scope.0.expression.0.field",
81+
"organization",
82+
),
83+
),
84+
},
85+
},
86+
})
87+
}
88+
89+
func TestAccDataSourceSysdigSecureZone_ByID(t *testing.T) {
90+
zoneName := "Zone_DS_ID_" + randomText(5)
91+
92+
resource.ParallelTest(t, resource.TestCase{
93+
PreCheck: preCheckAnyEnv(t, SysdigSecureApiTokenEnv, SysdigIBMSecureAPIKeyEnv),
94+
ProviderFactories: map[string]func() (*schema.Provider, error){
95+
"sysdig": func() (*schema.Provider, error) {
96+
return sysdig.Provider(), nil
97+
},
98+
},
99+
Steps: []resource.TestStep{
100+
{
101+
Config: testAccDataSourceSecureZoneByID(zoneName),
102+
Check: resource.ComposeTestCheckFunc(
103+
resource.TestCheckResourceAttrSet(
104+
"data.sysdig_secure_zone.test",
105+
"id",
106+
),
107+
resource.TestCheckResourceAttr(
108+
"data.sysdig_secure_zone.test",
109+
"scope.0.expression.#",
110+
"1",
111+
),
112+
),
113+
},
114+
},
115+
})
116+
}
117+
118+
func testAccDataSourceSecureZoneByName(name string) string {
119+
return fmt.Sprintf(`
120+
resource "sysdig_secure_zone" "test" {
121+
name = "%s"
122+
description = "ds acceptance test"
123+
124+
scope {
125+
target_type = "aws"
126+
127+
expression {
128+
field = "organization"
129+
operator = "in"
130+
values = ["o1", "o2"]
131+
}
132+
}
133+
}
134+
135+
data "sysdig_secure_zone" "test" {
136+
depends_on = [sysdig_secure_zone.test]
137+
name = "%s"
138+
}
139+
`, name, name)
140+
}
141+
142+
func testAccDataSourceSecureZoneByID(name string) string {
143+
return fmt.Sprintf(`
144+
resource "sysdig_secure_zone" "test" {
145+
name = "%s"
146+
description = "ds acceptance test"
147+
148+
scope {
149+
target_type = "aws"
150+
151+
expression {
152+
field = "organization"
153+
operator = "in"
154+
values = ["o1", "o2"]
155+
}
156+
}
157+
}
158+
159+
data "sysdig_secure_zone" "test" {
160+
depends_on = [sysdig_secure_zone.test]
161+
id = sysdig_secure_zone.test.id
162+
}
163+
`, name)
164+
}
165+
46166
func testAccDataSourceSysdigSecureZoneConfig() string {
47167
return `
48168
resource "sysdig_secure_zone" "sample" {

0 commit comments

Comments
 (0)