diff --git a/examples/resources/team_role/resource.tf b/examples/resources/team_role/resource.tf new file mode 100644 index 0000000..e49aab7 --- /dev/null +++ b/examples/resources/team_role/resource.tf @@ -0,0 +1,6 @@ +resource "cortex_team_role" "engineer" { + tag = "se-1" + name = "Software Engineer 1" + description = "A first-level engineer" + notifcations_enabled = true +} diff --git a/go.mod b/go.mod index 4331af7..b92dfdf 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/hashicorp/terraform-plugin-testing v1.5.1 github.com/life4/genesis v1.8.1 github.com/motemen/go-loghttp v0.0.0-20170804080138-974ac5ceac27 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.10.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index 840a625..de29a64 100644 --- a/go.sum +++ b/go.sum @@ -305,8 +305,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= diff --git a/internal/cortex/http_client.go b/internal/cortex/http_client.go index 29a0724..6245ebe 100644 --- a/internal/cortex/http_client.go +++ b/internal/cortex/http_client.go @@ -4,12 +4,13 @@ import ( "context" "errors" "fmt" - "github.com/dghubble/sling" - "github.com/motemen/go-loghttp" - _ "github.com/motemen/go-loghttp/global" // Just this line! "net/http" "net/url" "os" + + "github.com/dghubble/sling" + "github.com/motemen/go-loghttp" + _ "github.com/motemen/go-loghttp/global" // Just this line! ) const ( @@ -19,6 +20,7 @@ const ( var BaseUris = map[string]string{ "teams": "/api/v1/teams/", + "teams_roles": "/api/v1/teams/roles/", "departments": "/api/v1/teams/departments/", "scorecards": "/api/v1/scorecards/", "catalog_entities": "/api/v1/catalog/", @@ -157,6 +159,8 @@ func (c *HttpClient) Teams() TeamsClientInterface { return &TeamsClient{client: c} } +func (c *HttpClient) TeamRoles() TeamRolesClientInterface { return &TeamRolesClient{client: c} } + func (c *HttpClient) Departments() DepartmentsClientInterface { return &DepartmentsClient{client: c} } diff --git a/internal/cortex/team_roles.go b/internal/cortex/team_roles.go new file mode 100644 index 0000000..4f3ca26 --- /dev/null +++ b/internal/cortex/team_roles.go @@ -0,0 +1,204 @@ +package cortex + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "log" + + "github.com/dghubble/sling" +) + +type TeamRolesClientInterface interface { + Get(ctx context.Context, id int64) (*TeamRole, error) + List(ctx context.Context, params *TeamRolesListParams) (*TeamRolesListResponse, error) + Create(ctx context.Context, req CreateTeamRoleRequest) (*TeamRole, error) + Update(ctx context.Context, req UpdateTeamRoleRequest) (*TeamRole, error) + Delete(ctx context.Context, id int64) error +} + +type TeamRolesClient struct { + client *HttpClient +} + +var _ TeamRolesClientInterface = &TeamRolesClient{} + +func (c *TeamRolesClient) Client() *sling.Sling { + return c.client.Client() +} + +/*********************************************************************************************************************** + * Types + **********************************************************************************************************************/ + +type TeamRole struct { + ID int64 `json:"id"` + Name string `json:"name"` + Tag string `json:"tag"` + Description string `json:"description,omitempty"` + NotificationsEnabled bool `json:"notificationsEnabled,omitempty"` +} + +/*********************************************************************************************************************** + * GET /api/v1/teams/roles/:id + **********************************************************************************************************************/ + +func (c *TeamRolesClient) Get(_ context.Context, id int64) (*TeamRole, error) { + apiResponse := &TeamRole{} + apiError := &ApiError{} + response, err := c.Client().Get(Route("teams_roles", fmt.Sprintf("%d", id))).Receive(apiResponse, apiError) + if err != nil { + return apiResponse, errors.New("could not get team role: " + err.Error()) + } + + err = c.client.handleResponseStatus(response, apiError) + if err != nil { + return apiResponse, errors.Join(errors.New("Failed getting team role: "), err) + } + + return apiResponse, nil +} + +/*********************************************************************************************************************** + * GET /api/v1/teams/roles + **********************************************************************************************************************/ + +// TeamRolesListParams are the query parameters for the GET /v1/teams/roles endpoint. +type TeamRolesListParams struct { + Page int `url:"page,omitempty"` + PerPage int `url:"size,omitempty"` + Query string `url:"query,omitempty"` +} + +// TeamRolesListResponse is the response from the GET /v1/teams/roles endpoint. +type TeamRolesListResponse struct { + Roles []TeamRole `json:"items"` +} + +func (c *TeamRolesClient) List(_ context.Context, params *TeamRolesListParams) (*TeamRolesListResponse, error) { + apiResponse := &TeamRolesListResponse{} + apiError := &ApiError{} + + response, err := c.Client().Get(Route("teams_roles", "")).QueryStruct(¶ms).Receive(apiResponse, apiError) + if err != nil { + return nil, errors.New("could not get team roles: " + err.Error()) + } + + err = c.client.handleResponseStatus(response, apiError) + if err != nil { + return nil, err + } + + return apiResponse, nil +} + +/*********************************************************************************************************************** + * POST /api/v1/teams/roles + **********************************************************************************************************************/ + +type CreateTeamRoleRequest struct { + Tag string `json:"tag"` + Name string `json:"name"` + Description string `json:"description,omitempty"` + NotificationsEnabled bool `json:"notificationsEnabled,omitempty"` +} + +// ToCreateRequest converts a TeamRole to a CreateTeamRoleRequest. +func (r *TeamRole) ToCreateRequest() CreateTeamRoleRequest { + return CreateTeamRoleRequest{ + Tag: r.Tag, + Name: r.Name, + Description: r.Description, + NotificationsEnabled: r.NotificationsEnabled, + } +} + +func (c *TeamRolesClient) Create(_ context.Context, req CreateTeamRoleRequest) (*TeamRole, error) { + apiResponse := &TeamRole{} + apiError := &ApiError{} + + response, err := c.Client().Post(Route("teams_roles", "")).BodyJSON(&req).Receive(apiResponse, apiError) + if err != nil { + return apiResponse, errors.New("could not create team role: " + err.Error()) + } + + err = c.client.handleResponseStatus(response, apiError) + if err != nil { + reqJson, _ := json.Marshal(req) + log.Printf("Failed creating team role: %+v\n\nRequest:\n%+v", err, string(reqJson)) + return apiResponse, err + } + + return apiResponse, nil +} + +/*********************************************************************************************************************** + * PUT /api/v1/teams/roles/:id + **********************************************************************************************************************/ + +type UpdateTeamRoleRequest struct { + ID int64 `json:"id"` + Tag string `json:"tag"` + Name string `json:"name"` + Description string `json:"description,omitempty"` + NotificationsEnabled bool `json:"notificationsEnabled,omitempty"` +} + +// ToUpdateRequest converts a TeamRole to an UpdateTeamRoleRequest. +func (r *TeamRole) ToUpdateRequest() UpdateTeamRoleRequest { + return UpdateTeamRoleRequest{ + ID: r.ID, + Tag: r.Tag, + Name: r.Name, + Description: r.Description, + NotificationsEnabled: r.NotificationsEnabled, + } +} + +func (c *TeamRolesClient) Update(_ context.Context, req UpdateTeamRoleRequest) (*TeamRole, error) { + apiResponse := &TeamRole{} + apiError := &ApiError{} + + response, err := c.Client().Put(Route("teams_roles", fmt.Sprintf("%d", req.ID))).BodyJSON(&req).Receive(apiResponse, apiError) + if err != nil { + return apiResponse, errors.New("could not update team role: " + err.Error()) + } + + err = c.client.handleResponseStatus(response, apiError) + if err != nil { + reqJson, _ := json.Marshal(req) + log.Printf("Failed updating team role: %+v\n\nRequest:\n%+v\n%+v", err, string(reqJson), apiError.String()) + return apiResponse, err + } + + return apiResponse, nil +} + +/*********************************************************************************************************************** + * DELETE /api/v1/teams/roles/:id + **********************************************************************************************************************/ + +type DeleteTeamRoleResponse struct{} +type DeleteTeamRoleRequest struct { + ID int64 `json:"id"` +} + +func (c *TeamRolesClient) Delete(_ context.Context, id int64) error { + apiError := &ApiError{} + apiResponse := &DeleteTeamRoleResponse{} + + req := DeleteTeamRoleRequest{ID: id} + resp, err := c.Client().Delete(Route("teams_roles", fmt.Sprintf("%d", id))).QueryStruct(req).Receive(apiResponse, apiError) + if err != nil { + return fmt.Errorf("could not delete team role %d:\n\n%+v", id, err.Error()) + } + + err = c.client.handleResponseStatus(resp, apiError) + if err != nil { + log.Printf("Could not delete team role %d:\n\n%+v", id, err.Error()) + return err + } + + return nil +} diff --git a/internal/cortex/team_roles_test.go b/internal/cortex/team_roles_test.go new file mode 100644 index 0000000..7ae6a0b --- /dev/null +++ b/internal/cortex/team_roles_test.go @@ -0,0 +1,117 @@ +package cortex_test + +import ( + "context" + "fmt" + "testing" + + "github.com/cortexapps/terraform-provider-cortex/internal/cortex" + "github.com/stretchr/testify/suite" +) + +/** Suite *************************************************************************************************************/ + +type teamRolesSuite struct { + suite.Suite +} + +func TestCortexTeamRoles(t *testing.T) { + suite.Run(t, new(teamRolesSuite)) +} + +func (s *teamRolesSuite) newTeamRole() *cortex.TeamRole { + return &cortex.TeamRole{ + ID: 1, + Tag: "engineer", + Name: "Engineer", + Description: "A team role", + NotificationsEnabled: true, + } +} + +func (s *teamRolesSuite) TestGet() { + id := int64(1) + expectedResp := s.newTeamRole() + ctx := context.Background() + c, teardown, err := setupClient(cortex.Route("teams_roles", fmt.Sprintf("%d", id)), expectedResp, AssertRequestMethod(s.T(), "GET")) + defer teardown() + s.NoError(err) + + actualResp, err := c.TeamRoles().Get(ctx, id) + s.NoError(err) + s.Equal(expectedResp, actualResp) +} + +func (s *teamRolesSuite) TestList() { + expectedResp := &cortex.TeamRolesListResponse{ + Roles: []cortex.TeamRole{ + *s.newTeamRole(), + }, + } + ctx := context.Background() + c, teardown, err := setupClient(cortex.Route("teams_roles", ""), expectedResp, AssertRequestMethod(s.T(), "GET")) + defer teardown() + s.NoError(err) + + actualResp, err := c.TeamRoles().List(ctx, &cortex.TeamRolesListParams{}) + s.NoError(err) + s.Equal(expectedResp, actualResp) +} + +func (s *teamRolesSuite) TestCreate() { + req := cortex.CreateTeamRoleRequest{ + Name: "Engineer", + Tag: "engineer", + Description: "A team role", + NotificationsEnabled: true, + } + expectedResp := s.newTeamRole() + ctx := context.Background() + c, teardown, err := setupClient( + cortex.Route("teams_roles", ""), + expectedResp, + AssertRequestMethod(s.T(), "POST"), + AssertRequestBody(s.T(), req), + ) + defer teardown() + s.NoError(err) + + actualResp, err := c.TeamRoles().Create(ctx, req) + s.NoError(err) + s.Equal(expectedResp, actualResp) +} + +func (s *teamRolesSuite) TestUpdate() { + id := int64(1) + req := cortex.UpdateTeamRoleRequest{ + ID: id, + Name: "Engineer", + Description: "A team role", + NotificationsEnabled: true, + } + expectedResp := s.newTeamRole() + ctx := context.Background() + c, teardown, err := setupClient( + cortex.Route("teams_roles", fmt.Sprintf("%d", id)), + expectedResp, + AssertRequestMethod(s.T(), "PUT"), + AssertRequestBody(s.T(), req), + ) + defer teardown() + s.NoError(err) + + actualResp, err := c.TeamRoles().Update(ctx, req) + s.NoError(err) + s.Equal(expectedResp, actualResp) +} + +func (s *teamRolesSuite) TestDelete() { + id := int64(2) + ctx := context.Background() + c, teardown, err := setupClient(cortex.Route("teams_roles", fmt.Sprintf("%d", id)), nil, AssertRequestMethod(s.T(), "DELETE")) + defer teardown() + s.NoError(err) + + err = c.TeamRoles().Delete(ctx, id) + s.NoError(err) +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 797839e..0df0aa9 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -3,6 +3,8 @@ package provider import ( "context" "fmt" + "os" + "github.com/cortexapps/terraform-provider-cortex/internal/cortex" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/path" @@ -10,7 +12,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/provider/schema" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" - "os" ) // Ensure CortexProvider satisfies various provider interfaces. @@ -106,6 +107,7 @@ func (p *CortexProvider) Resources(ctx context.Context) []func() resource.Resour NewScorecardResource, NewResourceDefinitionResource, NewCatalogEntityCustomDataResource, + NewTeamRoleResource, } } diff --git a/internal/provider/team_role_resource.go b/internal/provider/team_role_resource.go new file mode 100644 index 0000000..eb0054c --- /dev/null +++ b/internal/provider/team_role_resource.go @@ -0,0 +1,203 @@ +package provider + +import ( + "context" + "fmt" + + "github.com/cortexapps/terraform-provider-cortex/internal/cortex" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" +) + +// Ensure provider defined types fully satisfy framework interfaces. +var _ resource.Resource = &TeamRoleResource{} +var _ resource.ResourceWithImportState = &TeamRoleResource{} + +func NewTeamRoleResource() resource.Resource { + return &TeamRoleResource{} +} + +func NewTeamRoleResourceModel() TeamRoleResourceModel { + return TeamRoleResourceModel{} +} + +/*********************************************************************************************************************** + * Types + **********************************************************************************************************************/ + +// TeamRoleResource defines the resource implementation. +type TeamRoleResource struct { + client *cortex.HttpClient +} + +/*********************************************************************************************************************** + * Schema + **********************************************************************************************************************/ + +func (r *TeamRoleResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + // This description is used by the documentation generator and the language server. + MarkdownDescription: "Team Role Entity", + + Attributes: map[string]schema.Attribute{ + // Required attributes + "tag": schema.StringAttribute{ + MarkdownDescription: "Unique identifier for the team role.", + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "Name of the team role.", + Required: true, + }, + + // Optional attributes + "description": schema.StringAttribute{ + MarkdownDescription: "Description of the team role.", + Optional: true, + }, + "notifications_enabled": schema.BoolAttribute{ + MarkdownDescription: "Indicates if notifications are enabled for the team role.", + Optional: true, + }, + + // Computed attributes + "id": schema.Int64Attribute{ + Description: "The ID of the team role.", + Computed: true, + }, + }, + } +} + +/*********************************************************************************************************************** + * Methods + **********************************************************************************************************************/ + +func (r *TeamRoleResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_team_role" +} + +func (r *TeamRoleResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*cortex.HttpClient) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *http.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + r.client = client +} + +func (r *TeamRoleResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + data := NewTeamRoleResourceModel() + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Issue API request + entity, err := r.client.TeamRoles().Get(ctx, data.ID.ValueInt64()) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read team role %d, got error: %s", data.ID.ValueInt64(), err)) + return + } + + // Map entity to resource model + data.FromApiModel(*entity) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +// Create Creates a new team. +func (r *TeamRoleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + data := NewTeamRoleResourceModel() + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + clientEntity := data.ToApiModel() + if resp.Diagnostics.HasError() { + return + } + + entity, err := r.client.TeamRoles().Create(ctx, clientEntity.ToCreateRequest()) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create team role, got error: %s", err)) + return + } + + // Map entity to resource model + data.FromApiModel(*entity) + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *TeamRoleResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + data := NewTeamRoleResourceModel() + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + clientEntity := data.ToApiModel() + if resp.Diagnostics.HasError() { + return + } + entity, err := r.client.TeamRoles().Update(ctx, clientEntity.ToUpdateRequest()) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update team role, got error: %s", err)) + return + } + + // Map entity to resource model + data.FromApiModel(*entity) + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *TeamRoleResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + data := NewTeamRoleResourceModel() + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + err := r.client.TeamRoles().Delete(ctx, data.ID.ValueInt64()) + if err != nil { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete team role, got error: %s", err)) + return + } +} + +func (r *TeamRoleResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} diff --git a/internal/provider/team_role_resource_models.go b/internal/provider/team_role_resource_models.go new file mode 100644 index 0000000..3c4588e --- /dev/null +++ b/internal/provider/team_role_resource_models.go @@ -0,0 +1,67 @@ +package provider + +import ( + "github.com/cortexapps/terraform-provider-cortex/internal/cortex" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +/*********************************************************************************************************************** + * Models + **********************************************************************************************************************/ + +// TeamRoleResourceModel describes the team role data model within Terraform. +type TeamRoleResourceModel struct { + ID types.Int64 `tfsdk:"id"` + Tag types.String `tfsdk:"tag"` + Name types.String `tfsdk:"name"` + Description types.String `tfsdk:"description"` + NotificationsEnabled types.Bool `tfsdk:"notifications_enabled"` +} + +func (r *TeamRoleResourceModel) FromApiModel(entity cortex.TeamRole) { + r.ID = types.Int64Value(entity.ID) + r.Tag = types.StringValue(entity.Tag) + r.Name = types.StringValue(entity.Name) + if entity.Description != "" { + r.Description = types.StringValue(entity.Description) + } else { + r.Description = types.StringNull() + } + if entity.NotificationsEnabled { + r.NotificationsEnabled = types.BoolValue(true) + } else { + r.NotificationsEnabled = types.BoolValue(false) + } +} + +func (r *TeamRoleResourceModel) ToApiModel() cortex.TeamRole { + entity := cortex.TeamRole{ + ID: r.ID.ValueInt64(), + Tag: r.Tag.ValueString(), + Name: r.Name.ValueString(), + Description: r.Description.ValueString(), + NotificationsEnabled: r.NotificationsEnabled.ValueBool(), + } + return entity +} + +/*********************************************************************************************************************** + * Data Source + **********************************************************************************************************************/ + +// TeamRoleDataSourceModel describes the data source data model. +type TeamRoleDataSourceModel struct { + ID types.Int64 `tfsdk:"id"` + Tag types.String `tfsdk:"tag"` + Name types.String `tfsdk:"name"` + Description types.String `tfsdk:"description"` + NotificationsEnabled types.Bool `tfsdk:"notifications_enabled"` +} + +func (o *TeamRoleDataSourceModel) FromApiModel(entity cortex.TeamRole) { + o.ID = types.Int64Value(entity.ID) + o.Tag = types.StringValue(entity.Tag) + o.Name = types.StringValue(entity.Name) + o.Description = types.StringValue(entity.Description) + o.NotificationsEnabled = types.BoolValue(entity.NotificationsEnabled) +} diff --git a/internal/provider/team_role_resource_test.go b/internal/provider/team_role_resource_test.go new file mode 100644 index 0000000..260e4e6 --- /dev/null +++ b/internal/provider/team_role_resource_test.go @@ -0,0 +1,75 @@ +package provider_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccTeamRoleMinimalResource(t *testing.T) { + tag := "test-team-role-minimal" + resourceType := "cortex_team_role" + resourceName := resourceType + "." + tag + stub := tFactoryBuildTeamRoleMinimalResource(tag) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read testing + { + Config: testAccTeamRoleMinimalResourceConfig(resourceType, stub), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "tag", stub.Tag), + resource.TestCheckResourceAttr(resourceName, "name", stub.Name), + resource.TestCheckResourceAttr(resourceName, "description", stub.Description), + resource.TestCheckResourceAttr(resourceName, "notifications_enabled", "true"), + ), + }, + // ImportState testing + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + // Update and Read testing + { + Config: testAccTeamRoleMinimalResourceConfig(resourceType, stub), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "tag", stub.Tag), + resource.TestCheckResourceAttr(resourceName, "name", stub.Name), + resource.TestCheckResourceAttr(resourceName, "description", stub.Description), + resource.TestCheckResourceAttr(resourceName, "notifications_enabled", "true"), + ), + }, + // Delete testing automatically occurs in TestCase + }, + }) +} + +func testAccTeamRoleMinimalResourceConfig(resourceType string, stub TestTeamRoleResource) string { + return fmt.Sprintf(` +resource %[1]q %[2]q { + tag = %[3]q + name = %[4]q + description = %[5]q + notifications_enabled = true +} +`, resourceType, stub.Tag, stub.Tag, stub.Name, stub.Description) +} + +type TestTeamRoleResource struct { + Tag string + Name string + Description string + NotificationsEnabled bool +} + +func tFactoryBuildTeamRoleMinimalResource(tag string) TestTeamRoleResource { + return TestTeamRoleResource{ + Tag: tag, + Name: "Test Role", + Description: "A test role", + NotificationsEnabled: true, + } +}