diff --git a/docs/data-sources/team_config.md b/docs/data-sources/team_config.md new file mode 100644 index 00000000..b7b74c8d --- /dev/null +++ b/docs/data-sources/team_config.md @@ -0,0 +1,48 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "vercel_team_config Data Source - terraform-provider-vercel" +subcategory: "" +description: |- + Retrieves the configuration of an existing Vercel Team. +--- + +# vercel_team_config (Data Source) + +Retrieves the configuration of an existing Vercel Team. + +## Example Usage + +```terraform +data "vercel_team_config" "example" { + id = "team_xxxxxxxxxxxxxxxxxxxxxxxx" // Replace with your team ID +} +``` + + +## Schema + +### Required + +- `id` (String) The ID of the existing Vercel Team. + +### Read-Only + +- `description` (String) A description of the team. +- `email_domain` (String) Hostname that'll be matched with emails on sign-up to automatically join the Team. +- `enable_preview_feedback` (String) Preview feedback configuration. +- `enable_production_feedback` (String) Production feedback configuration. +- `hide_ip_addresses` (Boolean) Indicates if ip addresses should be accessible in o11y tooling. +- `hide_ip_addresses_in_log_drains` (Boolean) Indicates if ip addresses should be accessible in log drains. +- `invite_code` (String) A code that can be used to join this team. Only visible to Team owners. +- `name` (String) The name of the team. +- `preview_deployment_suffix` (String) The hostname that is used as the preview deployment suffix. +- `remote_caching` (Attributes) Configuration for Remote Caching. (see [below for nested schema](#nestedatt--remote_caching)) +- `sensitive_environment_variable_policy` (String) The policy for sensitive environment variables. +- `slug` (String) The slug of the team. Used in the URL of the team's dashboard. + + +### Nested Schema for `remote_caching` + +Read-Only: + +- `enabled` (Boolean) Indicates if Remote Caching is enabled. diff --git a/examples/data-sources/vercel_team_config/data-source.tf b/examples/data-sources/vercel_team_config/data-source.tf new file mode 100644 index 00000000..27bc1f96 --- /dev/null +++ b/examples/data-sources/vercel_team_config/data-source.tf @@ -0,0 +1,3 @@ +data "vercel_team_config" "example" { + id = "team_xxxxxxxxxxxxxxxxxxxxxxxx" // Replace with your team ID +} diff --git a/vercel/data_source_team_config.go b/vercel/data_source_team_config.go new file mode 100644 index 00000000..244a1c2a --- /dev/null +++ b/vercel/data_source_team_config.go @@ -0,0 +1,170 @@ +package vercel + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/vercel/terraform-provider-vercel/client" +) + +var ( + _ datasource.DataSource = &teamConfigDataSource{} + _ datasource.DataSourceWithConfigure = &teamConfigDataSource{} +) + +func newTeamConfigDataSource() datasource.DataSource { + return &teamConfigDataSource{} +} + +type teamConfigDataSource struct { + client *client.Client +} + +func (d *teamConfigDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_team_config" +} + +func (d *teamConfigDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*client.Client) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + d.client = client +} + +func (d *teamConfigDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Description: "Retrieves the configuration of an existing Vercel Team.", + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "The ID of the existing Vercel Team.", + Required: true, + }, + "name": schema.StringAttribute{ + Description: "The name of the team.", + Computed: true, + }, + "invite_code": schema.StringAttribute{ + Computed: true, + Description: "A code that can be used to join this team. Only visible to Team owners.", + }, + "slug": schema.StringAttribute{ + Description: "The slug of the team. Used in the URL of the team's dashboard.", + Computed: true, + }, + "description": schema.StringAttribute{ + Computed: true, + Description: "A description of the team.", + }, + "sensitive_environment_variable_policy": schema.StringAttribute{ + Computed: true, + Description: "The policy for sensitive environment variables.", + }, + "email_domain": schema.StringAttribute{ + Computed: true, + Description: "Hostname that'll be matched with emails on sign-up to automatically join the Team.", + }, + "preview_deployment_suffix": schema.StringAttribute{ + Computed: true, + Description: "The hostname that is used as the preview deployment suffix.", + }, + "remote_caching": schema.SingleNestedAttribute{ + Computed: true, + Description: "Configuration for Remote Caching.", + Attributes: map[string]schema.Attribute{ + "enabled": schema.BoolAttribute{ + Computed: true, + Description: "Indicates if Remote Caching is enabled.", + }, + }, + }, + "enable_preview_feedback": schema.StringAttribute{ + Computed: true, + Description: "Preview feedback configuration.", + }, + "enable_production_feedback": schema.StringAttribute{ + Computed: true, + Description: "Production feedback configuration.", + }, + "hide_ip_addresses": schema.BoolAttribute{ + Computed: true, + Description: "Indicates if ip addresses should be accessible in o11y tooling.", + }, + "hide_ip_addresses_in_log_drains": schema.BoolAttribute{ + Computed: true, + Description: "Indicates if ip addresses should be accessible in log drains.", + }, + }, + } +} + +type TeamConfigData struct { + ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Slug types.String `tfsdk:"slug"` + Description types.String `tfsdk:"description"` + InviteCode types.String `tfsdk:"invite_code"` + SensitiveEnvironmentVariablePolicy types.String `tfsdk:"sensitive_environment_variable_policy"` + EmailDomain types.String `tfsdk:"email_domain"` + PreviewDeploymentSuffix types.String `tfsdk:"preview_deployment_suffix"` + RemoteCaching types.Object `tfsdk:"remote_caching"` + EnablePreviewFeedback types.String `tfsdk:"enable_preview_feedback"` + EnableProductionFeedback types.String `tfsdk:"enable_production_feedback"` + HideIPAddresses types.Bool `tfsdk:"hide_ip_addresses"` + HideIPAddressesInLogDrains types.Bool `tfsdk:"hide_ip_addresses_in_log_drains"` + // Saml types.Object `tfsdk:"saml"` +} + +func (d *teamConfigDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var config TeamConfigData + diags := req.Config.Get(ctx, &config) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + teamID := config.ID.ValueString() + team, err := d.client.GetTeam(ctx, teamID) + if err != nil { + resp.Diagnostics.AddError( + "Error reading Team Config", + fmt.Sprintf("Could not read Team Configuration with ID %s, unexpected error: %s", teamID, err), + ) + return + } + + out, diags := convertResponseToTeamConfig(ctx, team, types.MapNull(types.StringType)) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + diags = resp.State.Set(ctx, TeamConfigData{ + ID: out.ID, + Name: out.Name, + Slug: out.Slug, + Description: out.Description, + InviteCode: out.InviteCode, + SensitiveEnvironmentVariablePolicy: out.SensitiveEnvironmentVariablePolicy, + EmailDomain: out.EmailDomain, + PreviewDeploymentSuffix: out.PreviewDeploymentSuffix, + EnablePreviewFeedback: out.EnablePreviewFeedback, + EnableProductionFeedback: out.EnableProductionFeedback, + HideIPAddresses: out.HideIPAddresses, + HideIPAddressesInLogDrains: out.HideIPAddressesInLogDrains, + RemoteCaching: out.RemoteCaching, + }) + resp.Diagnostics.Append(diags...) +} diff --git a/vercel/data_source_team_config_test.go b/vercel/data_source_team_config_test.go new file mode 100644 index 00000000..1a687d35 --- /dev/null +++ b/vercel/data_source_team_config_test.go @@ -0,0 +1,42 @@ +package vercel_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAcc_TeamConfigDataSource(t *testing.T) { + resourceName := "data.vercel_team_config.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccVercelTeamConfigDataSource(testTeam()), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet(resourceName, "id"), + resource.TestCheckResourceAttrSet(resourceName, "name"), + resource.TestCheckResourceAttrSet(resourceName, "slug"), + resource.TestCheckResourceAttrSet(resourceName, "description"), + resource.TestCheckResourceAttrSet(resourceName, "sensitive_environment_variable_policy"), + resource.TestCheckResourceAttrSet(resourceName, "remote_caching.enabled"), + resource.TestCheckResourceAttrSet(resourceName, "enable_preview_feedback"), + resource.TestCheckResourceAttrSet(resourceName, "enable_production_feedback"), + resource.TestCheckResourceAttrSet(resourceName, "hide_ip_addresses"), + resource.TestCheckResourceAttrSet(resourceName, "hide_ip_addresses_in_log_drains"), + ), + }, + }, + }) +} + +func testAccVercelTeamConfigDataSource(teamID string) string { + return fmt.Sprintf(` +data "vercel_team_config" "test" { + id = "%s" // Replace with a valid team ID +} +`, teamID) +} diff --git a/vercel/provider.go b/vercel/provider.go index 075378ce..1c0ad72b 100644 --- a/vercel/provider.go +++ b/vercel/provider.go @@ -87,6 +87,7 @@ func (p *vercelProvider) DataSources(_ context.Context) []func() datasource.Data newProjectDeploymentRetentionDataSource, newProjectDirectoryDataSource, newSharedEnvironmentVariableDataSource, + newTeamConfigDataSource, } }