Skip to content

Commit

Permalink
Added linear_workspace_label resource
Browse files Browse the repository at this point in the history
  • Loading branch information
pksunkara committed Jul 5, 2022
1 parent 22fe296 commit 66bd82d
Show file tree
Hide file tree
Showing 12 changed files with 859 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/resources/team_label.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ resource "linear_team_label" "example" {

### Read-Only

- `id` (String) Identifier of the team.
- `id` (String) Identifier of the label.

## Import

Expand Down
43 changes: 43 additions & 0 deletions docs/resources/workspace_label.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "linear_workspace_label Resource - terraform-provider-linear"
subcategory: ""
description: |-
Linear workspace label.
---

# linear_workspace_label (Resource)

Linear workspace label.

## Example Usage

```terraform
resource "linear_workspace_label" "example" {
name = "Tech Debt"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `name` (String) Name of the label.

### Optional

- `color` (String) Color of the label.
- `description` (String) Description of the label.

### Read-Only

- `id` (String) Identifier of the label.

## Import

Import is supported using the following syntax:

```shell
terraform import linear_workspace_label.example Bug
```
1 change: 1 addition & 0 deletions examples/resources/linear_workspace_label/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import linear_workspace_label.example Bug
3 changes: 3 additions & 0 deletions examples/resources/linear_workspace_label/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "linear_workspace_label" "example" {
name = "Tech Debt"
}
424 changes: 423 additions & 1 deletion internal/provider/generated.go

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ func (p *provider) Configure(ctx context.Context, req tfsdk.ConfigureProviderReq

func (p *provider) GetResources(ctx context.Context) (map[string]tfsdk.ResourceType, diag.Diagnostics) {
return map[string]tfsdk.ResourceType{
"linear_team": teamResourceType{},
"linear_team_label": teamLabelResourceType{},
"linear_team": teamResourceType{},
"linear_team_label": teamLabelResourceType{},
"linear_workspace_label": workspaceLabelResourceType{},
}, nil
}

Expand Down
1 change: 1 addition & 0 deletions internal/provider/resource_team.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func (t teamResourceType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Dia
Required: true,
Validators: []tfsdk.AttributeValidator{
validators.MinLength(1),
validators.NoWhitespace(),
},
},
"name": {
Expand Down
4 changes: 1 addition & 3 deletions internal/provider/resource_team_label.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (t teamLabelResourceType) GetSchema(ctx context.Context) (tfsdk.Schema, dia
MarkdownDescription: "Linear team label.",
Attributes: map[string]tfsdk.Attribute{
"id": {
MarkdownDescription: "Identifier of the team.",
MarkdownDescription: "Identifier of the label.",
Type: types.StringType,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
Expand Down Expand Up @@ -211,8 +211,6 @@ func (r teamLabelResource) Delete(ctx context.Context, req tfsdk.DeleteResourceR
}

func (r teamLabelResource) ImportState(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) {
tfsdk.ResourceImportStatePassthroughID(ctx, tftypes.NewAttributePath().WithAttributeName("id"), req, resp)

parts := strings.Split(req.ID, ":")

if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
Expand Down
1 change: 1 addition & 0 deletions internal/provider/resource_team_label.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ query findTeamLabel($name: String!, $key: String!) {
# @genqlient(for: "IssueLabelCreateInput.id", omitempty: true)
# @genqlient(for: "IssueLabelCreateInput.description", omitempty: true)
# @genqlient(for: "IssueLabelCreateInput.color", omitempty: true)
# @genqlient(for: "IssueLabelCreateInput.teamId", omitempty: true)
mutation createTeamLabel(
$input: IssueLabelCreateInput!
) {
Expand Down
206 changes: 206 additions & 0 deletions internal/provider/resource_workspace_label.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package provider

import (
"context"
"fmt"

"github.com/frankgreco/terraform-helpers/validators"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tftypes"
"github.com/hashicorp/terraform-plugin-log/tflog"
)

// Ensure provider defined types fully satisfy framework interfaces
var _ tfsdk.ResourceType = workspaceLabelResourceType{}
var _ tfsdk.Resource = workspaceLabelResource{}
var _ tfsdk.ResourceWithImportState = workspaceLabelResource{}

type workspaceLabelResourceType struct{}

func (t workspaceLabelResourceType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
return tfsdk.Schema{
MarkdownDescription: "Linear workspace label.",
Attributes: map[string]tfsdk.Attribute{
"id": {
MarkdownDescription: "Identifier of the label.",
Type: types.StringType,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
tfsdk.UseStateForUnknown(),
},
},
"name": {
MarkdownDescription: "Name of the label.",
Type: types.StringType,
Required: true,
Validators: []tfsdk.AttributeValidator{
validators.MinLength(1),
},
},
"description": {
MarkdownDescription: "Description of the label.",
Type: types.StringType,
Optional: true,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
tfsdk.UseStateForUnknown(),
},
},
"color": {
MarkdownDescription: "Color of the label.",
Type: types.StringType,
Optional: true,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
tfsdk.UseStateForUnknown(),
},
Validators: []tfsdk.AttributeValidator{
// TODO: Color value validation
},
},
},
}, nil
}

func (t workspaceLabelResourceType) NewResource(ctx context.Context, in tfsdk.Provider) (tfsdk.Resource, diag.Diagnostics) {
provider, diags := convertProviderType(in)

return workspaceLabelResource{
provider: provider,
}, diags
}

type workspaceLabelResourceData struct {
Id types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Color types.String `tfsdk:"color"`
}

type workspaceLabelResource struct {
provider provider
}

func (r workspaceLabelResource) Create(ctx context.Context, req tfsdk.CreateResourceRequest, resp *tfsdk.CreateResourceResponse) {
var data workspaceLabelResourceData

diags := req.Config.Get(ctx, &data)
resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}

input := IssueLabelCreateInput{
Name: data.Name.Value,
Description: data.Description.Value,
Color: data.Color.Value,
}

response, err := createWorkspaceLabel(context.Background(), r.provider.client, input)

if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create workspace label, got error: %s", err))
return
}

tflog.Trace(ctx, "created a workspace label")

data.Id = types.String{Value: response.IssueLabelCreate.IssueLabel.Id}
data.Description = types.String{Value: response.IssueLabelCreate.IssueLabel.Description}
data.Color = types.String{Value: response.IssueLabelCreate.IssueLabel.Color}

diags = resp.State.Set(ctx, &data)
resp.Diagnostics.Append(diags...)
}

func (r workspaceLabelResource) Read(ctx context.Context, req tfsdk.ReadResourceRequest, resp *tfsdk.ReadResourceResponse) {
var data workspaceLabelResourceData

diags := req.State.Get(ctx, &data)
resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}

response, err := getWorkspaceLabel(context.Background(), r.provider.client, data.Id.Value)

if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read workspace label, got error: %s", err))
return
}

data.Name = types.String{Value: response.IssueLabel.Name}
data.Description = types.String{Value: response.IssueLabel.Description}
data.Color = types.String{Value: response.IssueLabel.Color}

diags = resp.State.Set(ctx, &data)
resp.Diagnostics.Append(diags...)
}

func (r workspaceLabelResource) Update(ctx context.Context, req tfsdk.UpdateResourceRequest, resp *tfsdk.UpdateResourceResponse) {
var data workspaceLabelResourceData

diags := req.Plan.Get(ctx, &data)
resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}

input := IssueLabelUpdateInput{
Name: data.Name.Value,
Description: data.Description.Value,
Color: data.Color.Value,
}

response, err := updateWorkspaceLabel(context.Background(), r.provider.client, input, data.Id.Value)

if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update workspace label, got error: %s", err))
return
}

tflog.Trace(ctx, "updated a workspace label")

data.Name = types.String{Value: response.IssueLabelUpdate.IssueLabel.Name}
data.Description = types.String{Value: response.IssueLabelUpdate.IssueLabel.Description}
data.Color = types.String{Value: response.IssueLabelUpdate.IssueLabel.Color}

diags = resp.State.Set(ctx, &data)
resp.Diagnostics.Append(diags...)
}

func (r workspaceLabelResource) Delete(ctx context.Context, req tfsdk.DeleteResourceRequest, resp *tfsdk.DeleteResourceResponse) {
var data workspaceLabelResourceData

diags := req.State.Get(ctx, &data)
resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}

_, err := deleteWorkspaceLabel(context.Background(), r.provider.client, data.Id.Value)

if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete workspace label, got error: %s", err))
return
}

tflog.Trace(ctx, "deleted a workspace label")
}

func (r workspaceLabelResource) ImportState(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) {
response, err := findWorkspaceLabel(context.Background(), r.provider.client, req.ID)

if err != nil || len(response.IssueLabels.Nodes) != 1 {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to import workspace label, got error: %s", err))
return
}

resp.Diagnostics.Append(resp.State.SetAttribute(ctx, tftypes.NewAttributePath().WithAttributeName("id"), response.IssueLabels.Nodes[0].Id)...)
}
66 changes: 66 additions & 0 deletions internal/provider/resource_workspace_label.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
query getWorkspaceLabel($id: String!) {
issueLabel(id: $id) {
id
name
description
color
}
}

query findWorkspaceLabel($name: String!) {
issueLabels(filter: {
name: {
eq: $name
},
#4
# team: {
# key: {
# eq: $key
# }
# }
}) {
nodes {
id
}
}
}

# @genqlient(for: "IssueLabelCreateInput.id", omitempty: true)
# @genqlient(for: "IssueLabelCreateInput.description", omitempty: true)
# @genqlient(for: "IssueLabelCreateInput.color", omitempty: true)
# @genqlient(for: "IssueLabelCreateInput.teamId", omitempty: true)
mutation createWorkspaceLabel(
$input: IssueLabelCreateInput!
) {
issueLabelCreate(input: $input) {
issueLabel {
id
name
description
color
}
}
}

# @genqlient(for: "IssueLabelUpdateInput.name", omitempty: true)
# @genqlient(for: "IssueLabelUpdateInput.description", omitempty: true)
# @genqlient(for: "IssueLabelUpdateInput.color", omitempty: true)
mutation updateWorkspaceLabel(
$input: IssueLabelUpdateInput!,
$id: String!
) {
issueLabelUpdate(input: $input, id: $id) {
issueLabel {
id
name
description
color
}
}
}

mutation deleteWorkspaceLabel($id: String!) {
issueLabelDelete(id: $id) {
success
}
}
Loading

0 comments on commit 66bd82d

Please sign in to comment.