Skip to content

Commit bf8ec27

Browse files
{wip} Add Audit Config data source
1 parent be9cec1 commit bf8ec27

File tree

3 files changed

+228
-0
lines changed

3 files changed

+228
-0
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package provider
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
tfe "github.com/hashicorp/go-tfe"
11+
"github.com/hashicorp/terraform-plugin-framework/datasource"
12+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
13+
"github.com/hashicorp/terraform-plugin-framework/types"
14+
)
15+
16+
// Ensure the implementation satisfies the expected interfaces.
17+
var (
18+
_ datasource.DataSource = &dataSourceOrganizationAuditConfiguration{}
19+
_ datasource.DataSourceWithConfigure = &dataSourceOrganizationAuditConfiguration{}
20+
)
21+
22+
type modelDataTFEOrganizationAuditConfigurationV0 struct {
23+
ID types.String `tfsdk:"id"`
24+
Organization types.String `tfsdk:"organization"`
25+
26+
AuditTrailsEnabled types.Bool `tfsdk:"audit_trails_enabled"`
27+
HCPAuditLogStreamingEnabled types.Bool `tfsdk:"hcp_log_streaming_enabled"`
28+
HCPOrganization types.String `tfsdk:"hcp_organization"`
29+
}
30+
31+
func dataTFEOrganizationAuditConfiguration(v *tfe.OrganizationAuditConfiguration) modelDataTFEOrganizationAuditConfigurationV0 {
32+
result := modelDataTFEOrganizationAuditConfigurationV0{
33+
ID: types.StringValue(v.ID),
34+
Organization: types.StringValue(v.Organization.Name),
35+
36+
AuditTrailsEnabled: types.BoolValue(v.AuditTrails.Enabled),
37+
HCPAuditLogStreamingEnabled: types.BoolValue(v.HCPAuditLogStreaming.Enabled),
38+
HCPOrganization: types.StringValue(v.HCPAuditLogStreaming.OrganizationID),
39+
}
40+
41+
return result
42+
}
43+
44+
// NewOrganizationAuditConfigurationDataSource is a helper function to simplify the provider implementation.
45+
func NewOrganizationAuditConfigurationDataSource() datasource.DataSource {
46+
return &dataSourceOrganizationAuditConfiguration{}
47+
}
48+
49+
// dataSourceOrganizationAuditConfiguration is the data source implementation.
50+
type dataSourceOrganizationAuditConfiguration struct {
51+
config ConfiguredClient
52+
}
53+
54+
// Metadata returns the data source type name.
55+
func (d *dataSourceOrganizationAuditConfiguration) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
56+
resp.TypeName = req.ProviderTypeName + "_organization_audit_configuration"
57+
}
58+
59+
func (d *dataSourceOrganizationAuditConfiguration) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
60+
resp.Schema = schema.Schema{
61+
62+
Attributes: map[string]schema.Attribute{
63+
"id": schema.StringAttribute{
64+
Computed: true,
65+
Description: "Service-generated identifier for the configuration.",
66+
},
67+
"organization": schema.StringAttribute{
68+
Required: true,
69+
Description: "Name of the organization.",
70+
},
71+
72+
"audit_trails_enabled": schema.BoolAttribute{
73+
Optional: true,
74+
Description: "Whether Audit Trails is enabled for the organization.",
75+
},
76+
"hcp_log_streaming_enabled": schema.BoolAttribute{
77+
Optional: true,
78+
Description: "Whether HCP Audit Log Streaming is enabled for the organization.",
79+
},
80+
"hcp_organization": schema.StringAttribute{
81+
Optional: true,
82+
Description: "The destination HCP Organization for HCP Audit Log Streaming.",
83+
},
84+
},
85+
}
86+
}
87+
88+
// Configure adds the provider configured client to the data source.
89+
func (d *dataSourceOrganizationAuditConfiguration) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
90+
if req.ProviderData == nil {
91+
return
92+
}
93+
94+
client, ok := req.ProviderData.(ConfiguredClient)
95+
if !ok {
96+
resp.Diagnostics.AddError(
97+
"Unexpected Data Source Configure Type",
98+
fmt.Sprintf("Expected tfe.ConfiguredClient, got %T. This is a bug in the tfe provider, so please report it on GitHub.", req.ProviderData),
99+
)
100+
101+
return
102+
}
103+
d.config = client
104+
}
105+
106+
// Read refreshes the Terraform state with the latest data.
107+
func (d *dataSourceOrganizationAuditConfiguration) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
108+
var data modelDataTFEOrganizationAuditConfigurationV0
109+
110+
// Read Terraform configuration data into the model
111+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
112+
if resp.Diagnostics.HasError() {
113+
return
114+
}
115+
116+
var organization string
117+
resp.Diagnostics.Append(d.config.dataOrDefaultOrganization(ctx, req.Config, &organization)...)
118+
if resp.Diagnostics.HasError() {
119+
return
120+
}
121+
122+
org, err := d.config.Client.Organizations.Read(ctx, organization)
123+
if err != nil {
124+
resp.Diagnostics.AddError("Error reading Organization Audit Configuration",
125+
fmt.Sprintf("Could not read Organization %q, unexpected error: %s", organization, err.Error()),
126+
)
127+
return
128+
}
129+
130+
if !org.Permissions.CanManageAuditing {
131+
resp.Diagnostics.AddWarning("Cannot read audit configuration",
132+
fmt.Sprintf("Cannot not read the audit configuration in organization %q due to insufficent permissions or the organization not supporting auditing", organization),
133+
)
134+
return
135+
}
136+
137+
ac, err := d.config.Client.OrganizationAuditConfigurations.Read(ctx, organization)
138+
if err != nil {
139+
resp.Diagnostics.AddError("Error reading Organization Audit Configuration",
140+
fmt.Sprintf("Could not read Audit Configuration in organization %q, unexpected error: %s", organization, err.Error()),
141+
)
142+
return
143+
}
144+
145+
result := dataTFEOrganizationAuditConfiguration(ac)
146+
147+
// Save updated data into Terraform state
148+
resp.Diagnostics.Append(resp.State.Set(ctx, &result)...)
149+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package provider
5+
6+
import (
7+
"fmt"
8+
"testing"
9+
10+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
11+
)
12+
13+
func TestAccTFEOrganizationAuditConfigurationDataSource_basic(t *testing.T) {
14+
skipUnlessBeta(t)
15+
16+
tfeClient, err := getClientUsingEnv()
17+
if err != nil {
18+
t.Fatal(err)
19+
}
20+
21+
org, orgCleanup := createBusinessOrganization(t, tfeClient)
22+
t.Cleanup(orgCleanup)
23+
24+
resource.Test(t, resource.TestCase{
25+
PreCheck: func() { testAccPreCheck(t) },
26+
ProtoV5ProviderFactories: testAccMuxedProviders,
27+
Steps: []resource.TestStep{
28+
{
29+
Config: testAccTFEOrganizationAuditConfigDataSourceConfig(org.Name),
30+
Check: resource.ComposeAggregateTestCheckFunc(
31+
resource.TestCheckResourceAttr("data.tfe_organization_audit_configuration.foobar", "organization", org.Name),
32+
resource.TestCheckResourceAttrSet("data.tfe_organization_audit_configuration.foobar", "id"),
33+
resource.TestCheckResourceAttrSet("data.tfe_organization_audit_configuration.foobar", "audit_trails_enabled"),
34+
resource.TestCheckResourceAttrSet("data.tfe_organization_audit_configuration.foobar", "hcp_log_streaming_enabled"),
35+
),
36+
},
37+
},
38+
})
39+
}
40+
41+
func TestAccTFEOrganizationAuditConfigurationDataSource_disallowed(t *testing.T) {
42+
skipUnlessBeta(t)
43+
44+
tfeClient, err := getClientUsingEnv()
45+
if err != nil {
46+
t.Fatal(err)
47+
}
48+
49+
org, orgCleanup := createTrialOrganization(t, tfeClient)
50+
t.Cleanup(orgCleanup)
51+
52+
resource.Test(t, resource.TestCase{
53+
PreCheck: func() { testAccPreCheck(t) },
54+
ProtoV5ProviderFactories: testAccMuxedProviders,
55+
Steps: []resource.TestStep{
56+
{
57+
Config: testAccTFEOrganizationAuditConfigDataSourceConfig(org.Name),
58+
Check: resource.ComposeAggregateTestCheckFunc(
59+
resource.TestCheckResourceAttr("data.tfe_organization_audit_configuration.foobar", "organization", org.Name),
60+
resource.TestCheckNoResourceAttr("data.tfe_organization_audit_configuration.foobar", "id"),
61+
resource.TestCheckNoResourceAttr("data.tfe_organization_audit_configuration.foobar", "audit_trails_enabled"),
62+
resource.TestCheckNoResourceAttr("data.tfe_organization_audit_configuration.foobar", "hcp_log_streaming_enabled"),
63+
),
64+
},
65+
},
66+
})
67+
}
68+
69+
func testAccTFEOrganizationAuditConfigDataSourceConfig(orgName string) string {
70+
return fmt.Sprintf(`
71+
locals {
72+
organization_name = "%s"
73+
}
74+
75+
data "tfe_organization_audit_configuration" "foobar" {
76+
organization = local.organization_name
77+
}`, orgName)
78+
}

internal/provider/provider_next.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ func (p *frameworkProvider) Configure(ctx context.Context, req provider.Configur
131131
func (p *frameworkProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
132132
return []func() datasource.DataSource{
133133
NewNoCodeModuleDataSource,
134+
NewOrganizationAuditConfigurationDataSource,
134135
NewOrganizationRunTaskDataSource,
135136
NewOrganizationRunTaskGlobalSettingsDataSource,
136137
NewOutputsDataSource,

0 commit comments

Comments
 (0)