-
Notifications
You must be signed in to change notification settings - Fork 385
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[datadog_team] Add datadog team data sources (#1946)
* add teams datasources * add tests * update docs * apply code review suggestions * apply code review suggestions * update codeowners
- Loading branch information
Showing
15 changed files
with
895 additions
and
1 deletion.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
package fwprovider | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/DataDog/datadog-api-client-go/v2/api/datadogV2" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
|
||
"github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" | ||
) | ||
|
||
var ( | ||
_ datasource.DataSource = &DatadogTeamDataSource{} | ||
) | ||
|
||
func NewDatadogTeamDataSource() datasource.DataSource { | ||
return &DatadogTeamDataSource{} | ||
} | ||
|
||
type DatadogTeamDataSourceModel struct { | ||
// Query Parameters | ||
TeamID types.String `tfsdk:"team_id"` | ||
FilterKeyword types.String `tfsdk:"filter_keyword"` | ||
// Results | ||
ID types.String `tfsdk:"id"` | ||
Description types.String `tfsdk:"description"` | ||
Handle types.String `tfsdk:"handle"` | ||
LinkCount types.Int64 `tfsdk:"link_count"` | ||
Summary types.String `tfsdk:"summary"` | ||
UserCount types.Int64 `tfsdk:"user_count"` | ||
Name types.String `tfsdk:"name"` | ||
} | ||
|
||
type DatadogTeamDataSource struct { | ||
Api *datadogV2.TeamsApi | ||
Auth context.Context | ||
} | ||
|
||
func (r *DatadogTeamDataSource) Configure(_ context.Context, request datasource.ConfigureRequest, response *datasource.ConfigureResponse) { | ||
if request.ProviderData == nil { | ||
return | ||
} | ||
|
||
providerData, ok := request.ProviderData.(*FrameworkProvider) | ||
if !ok { | ||
response.Diagnostics.AddError("Unexpected Resource Configure Type", "") | ||
return | ||
} | ||
|
||
r.Api = providerData.DatadogApiInstances.GetTeamsApiV2() | ||
r.Auth = providerData.Auth | ||
} | ||
|
||
func (d *DatadogTeamDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "team" | ||
} | ||
|
||
func (d *DatadogTeamDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
Description: "Use this data source to retrieve information about an existing Datadog team.", | ||
Attributes: map[string]schema.Attribute{ | ||
// Datasource ID | ||
"id": utils.ResourceIDAttribute(), | ||
// Datasource Parameters | ||
"team_id": schema.StringAttribute{ | ||
Description: "The team's identifier.", | ||
Optional: true, | ||
Computed: true, | ||
}, | ||
"filter_keyword": schema.StringAttribute{ | ||
Description: "Search query. Can be team name, team handle, or email of team member.", | ||
Optional: true, | ||
}, | ||
// Computed values | ||
"description": schema.StringAttribute{ | ||
Computed: true, | ||
Description: "Free-form markdown description/content for the team's homepage.", | ||
}, | ||
"handle": schema.StringAttribute{ | ||
Computed: true, | ||
Description: "The team's handle.", | ||
}, | ||
"link_count": schema.Int64Attribute{ | ||
Description: "The number of links belonging to the team.", | ||
Computed: true, | ||
}, | ||
"summary": schema.StringAttribute{ | ||
Description: "A brief summary of the team, derived from the `description`.", | ||
Computed: true, | ||
}, | ||
"user_count": schema.Int64Attribute{ | ||
Description: "The number of users belonging to the team.", | ||
Computed: true, | ||
}, | ||
"name": schema.StringAttribute{ | ||
Computed: true, | ||
Description: "The name of the team.", | ||
}, | ||
}, | ||
} | ||
|
||
} | ||
|
||
func (d *DatadogTeamDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var state DatadogTeamDataSourceModel | ||
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
if !state.TeamID.IsNull() { | ||
teamID := state.TeamID.ValueString() | ||
ddResp, _, err := d.Api.GetTeam(d.Auth, teamID) | ||
if err != nil { | ||
resp.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error getting datadog team")) | ||
return | ||
} | ||
|
||
d.updateState(&state, ddResp.Data) | ||
} else if !state.FilterKeyword.IsNull() { | ||
filterKeyword := state.FilterKeyword.ValueString() | ||
optionalParams := datadogV2.ListTeamsOptionalParameters{ | ||
FilterKeyword: &filterKeyword, | ||
} | ||
|
||
ddResp, _, err := d.Api.ListTeams(d.Auth, optionalParams) | ||
if err != nil { | ||
resp.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error listing datadog teams")) | ||
return | ||
} | ||
|
||
if len(ddResp.Data) > 1 { | ||
resp.Diagnostics.AddError("filter keyword returned more than one result, use more specific search criteria", "") | ||
return | ||
} | ||
if len(ddResp.Data) == 0 { | ||
resp.Diagnostics.AddError("filter keyword returned no result", "") | ||
return | ||
} | ||
|
||
d.updateStateFromListResponse(&state, &ddResp.Data[0]) | ||
} | ||
|
||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) | ||
} | ||
|
||
func (r *DatadogTeamDataSource) updateState(state *DatadogTeamDataSourceModel, teamData *datadogV2.TeamData) { | ||
state.ID = types.StringValue(teamData.GetId()) | ||
attributes := teamData.GetAttributes() | ||
|
||
state.Description = types.StringValue(attributes.GetDescription()) | ||
state.Handle = types.StringValue(attributes.GetHandle()) | ||
state.LinkCount = types.Int64Value(int64(attributes.GetLinkCount())) | ||
state.Name = types.StringValue(attributes.GetName()) | ||
state.UserCount = types.Int64Value(int64(attributes.GetUserCount())) | ||
state.Summary = types.StringValue(attributes.GetSummary()) | ||
} | ||
|
||
func (r *DatadogTeamDataSource) updateStateFromListResponse(state *DatadogTeamDataSourceModel, teamData *datadogV2.Team) { | ||
state.ID = types.StringValue(teamData.GetId()) | ||
state.TeamID = types.StringValue(teamData.GetId()) | ||
|
||
attributes := teamData.GetAttributes() | ||
state.Description = types.StringValue(attributes.GetDescription()) | ||
state.Handle = types.StringValue(attributes.GetHandle()) | ||
state.LinkCount = types.Int64Value(int64(attributes.GetLinkCount())) | ||
state.Name = types.StringValue(attributes.GetName()) | ||
state.UserCount = types.Int64Value(int64(attributes.GetUserCount())) | ||
state.Summary = types.StringValue(attributes.GetSummary()) | ||
} |
146 changes: 146 additions & 0 deletions
146
datadog/fwprovider/data_source_datadog_team_memberships.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package fwprovider | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/DataDog/datadog-api-client-go/v2/api/datadogV2" | ||
"github.com/hashicorp/terraform-plugin-framework/attr" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
|
||
"github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" | ||
) | ||
|
||
var ( | ||
_ datasource.DataSource = &DatadogTeamMembershipsDataSource{} | ||
) | ||
|
||
type DatadogTeamMembershipsDataSourceModel struct { | ||
// Query Parameters | ||
TeamID types.String `tfsdk:"team_id"` | ||
FilterKeyword types.String `tfsdk:"filter_keyword"` | ||
// Results | ||
ID types.String `tfsdk:"id"` | ||
TeamMemberships []*TeamMembershipModel `tfsdk:"team_memberships"` | ||
} | ||
|
||
func NewDatadogTeamMembershipsDataSource() datasource.DataSource { | ||
return &DatadogTeamMembershipsDataSource{} | ||
} | ||
|
||
type DatadogTeamMembershipsDataSource struct { | ||
Api *datadogV2.TeamsApi | ||
Auth context.Context | ||
} | ||
|
||
func (r *DatadogTeamMembershipsDataSource) Configure(_ context.Context, request datasource.ConfigureRequest, response *datasource.ConfigureResponse) { | ||
if request.ProviderData == nil { | ||
return | ||
} | ||
|
||
providerData, ok := request.ProviderData.(*FrameworkProvider) | ||
if !ok { | ||
response.Diagnostics.AddError("Unexpected Resource Configure Type", "") | ||
return | ||
} | ||
|
||
r.Api = providerData.DatadogApiInstances.GetTeamsApiV2() | ||
r.Auth = providerData.Auth | ||
} | ||
|
||
func (d *DatadogTeamMembershipsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "team_memberships" | ||
} | ||
|
||
func (d *DatadogTeamMembershipsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
Description: "Use this data source to retrieve information about existing Datadog team memberships.", | ||
Attributes: map[string]schema.Attribute{ | ||
// Datasource ID | ||
"id": utils.ResourceIDAttribute(), | ||
// Datasource Parameters | ||
"team_id": schema.StringAttribute{ | ||
Description: "The team's identifier.", | ||
Required: true, | ||
}, | ||
"filter_keyword": schema.StringAttribute{ | ||
Description: "Search query, can be user email or name.", | ||
Optional: true, | ||
}, | ||
// Computed values | ||
"team_memberships": schema.ListAttribute{ | ||
Computed: true, | ||
Description: "List of team memberships.", | ||
ElementType: types.ObjectType{ | ||
AttrTypes: map[string]attr.Type{ | ||
"team_id": types.StringType, | ||
"user_id": types.StringType, | ||
"role": types.StringType, | ||
"id": types.StringType, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
} | ||
|
||
func (d *DatadogTeamMembershipsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var state DatadogTeamMembershipsDataSourceModel | ||
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
var optionalParams datadogV2.GetTeamMembershipsOptionalParameters | ||
teamID := state.TeamID.ValueString() | ||
|
||
if !state.FilterKeyword.IsNull() { | ||
optionalParams.FilterKeyword = state.FilterKeyword.ValueStringPointer() | ||
} | ||
|
||
pageSize := int64(100) | ||
pageNumber := int64(0) | ||
|
||
var userTeams []datadogV2.UserTeam | ||
for { | ||
optionalParams.PageNumber = &pageNumber | ||
optionalParams.PageSize = &pageSize | ||
|
||
ddResp, _, err := d.Api.GetTeamMemberships(d.Auth, teamID, optionalParams) | ||
if err != nil { | ||
resp.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error getting team memberships")) | ||
return | ||
} | ||
|
||
userTeams = append(userTeams, ddResp.GetData()...) | ||
if len(ddResp.GetData()) < 100 { | ||
break | ||
} | ||
pageNumber++ | ||
} | ||
|
||
d.updateState(&state, &userTeams) | ||
|
||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) | ||
} | ||
|
||
func (r *DatadogTeamMembershipsDataSource) updateState(state *DatadogTeamMembershipsDataSourceModel, teamData *[]datadogV2.UserTeam) { | ||
state.ID = types.StringValue(fmt.Sprintf("%s:%s", state.TeamID.ValueString(), state.FilterKeyword.ValueString())) | ||
|
||
var teamMemberships []*TeamMembershipModel | ||
for _, user := range *teamData { | ||
membership := TeamMembershipModel{ | ||
ID: types.StringValue(user.GetId()), | ||
TeamId: types.StringValue(state.TeamID.ValueString()), | ||
UserId: types.StringValue(user.Relationships.User.Data.GetId()), | ||
Role: types.StringValue(string(user.Attributes.GetRole())), | ||
} | ||
|
||
teamMemberships = append(teamMemberships, &membership) | ||
} | ||
|
||
state.TeamMemberships = teamMemberships | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
datadog/tests/cassettes/TestAccDatadogTeamDatasourceBasic.freeze
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
2023-06-01T15:26:11.394314-04:00 |
Oops, something went wrong.