Skip to content

Commit

Permalink
feat: switched to seperate tag resource and datasource model
Browse files Browse the repository at this point in the history
  • Loading branch information
akhilmhdh committed Jun 17, 2024
1 parent d333037 commit 33f3934
Show file tree
Hide file tree
Showing 8 changed files with 574 additions and 75 deletions.
24 changes: 24 additions & 0 deletions examples/data-sources/infisical_secret_tag/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
terraform {
required_providers {
infisical = {
# version = <latest version>
source = "infisical/infisical"
}
}
}

provider "infisical" {
host = "https://app.infisical.com" # Only required if using self hosted instance of Infisical, default is https://app.infisical.com
client_id = "<>"
client_secret = "<>"
}

data "infisical_secret_tag" "terraform" {
slug = "terraform"
project_id = "PROJECT_ID"
}

output "secret-tag" {
value = data.infisical_secret_tag.terraform
}

9 changes: 9 additions & 0 deletions examples/resources/infisical_secret/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,19 @@ resource "infisical_secret" "smtp_secret" {
folder_path = "/mail-service"
}


resource "infisical_secret_tag" "terraform" {
name = "terraform"
slug = "terraform"
color = "#fff"
project_id = "PROJECT_ID"
}

resource "infisical_secret" "github_action_secret" {
name = "GITHUB_ACTION"
value = "<some value>"
env_slug = "dev"
workspace_id = "PROJECT_ID"
folder_path = "/"
tag_ids = [infisical_secret_tag.terraform.id]
}
39 changes: 39 additions & 0 deletions internal/client/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,3 +658,42 @@ type CreateProjectTagRequest struct {
type CreateProjectTagResponse struct {
Tag ProjectTag `json:"workspaceTag"`
}

type UpdateProjectTagRequest struct {
Name string `json:"name,omitempty"`
Color string `json:"color,omitempty"`
Slug string `json:"slug,omitempty"`
ProjectID string `json:"projectId"`
TagID string `json:"tagId"`
}

type UpdateProjectTagResponse struct {
Tag ProjectTag `json:"workspaceTag"`
}

type DeleteProjectTagRequest struct {
ProjectID string `json:"projectId"`
TagID string `json:"tagId"`
}

type DeleteProjectTagResponse struct {
Tag ProjectTag `json:"workspaceTag"`
}

type GetProjectTagByIDRequest struct {
ProjectID string `json:"projectId"`
TagID string `json:"tagId"`
}

type GetProjectTagByIDResponse struct {
Tag ProjectTag `json:"workspaceTag"`
}

type GetProjectTagBySlugRequest struct {
ProjectID string `json:"projectId"`
TagSlug string `json:"tagSlug"`
}

type GetProjectTagBySlugResponse struct {
Tag ProjectTag `json:"workspaceTag"`
}
96 changes: 95 additions & 1 deletion internal/client/project_tags.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package infisicalclient

import (
"errors"
"fmt"
"net/http"
)

var (
ErrNotFound = errors.New("Resource not found")
)

func (client Client) GetProjectTags(request GetProjectTagsRequest) (GetProjectTagsResponse, error) {
Expand All @@ -25,7 +31,7 @@ func (client Client) GetProjectTags(request GetProjectTagsRequest) (GetProjectTa
return body, nil
}

func (client Client) CreateProjectTags(request CreateProjectTagRequest) (CreateProjectTagResponse, error) {
func (client Client) CreateProjectTag(request CreateProjectTagRequest) (CreateProjectTagResponse, error) {
var body CreateProjectTagResponse
response, err := client.Config.HttpClient.
R().
Expand All @@ -44,3 +50,91 @@ func (client Client) CreateProjectTags(request CreateProjectTagRequest) (CreateP

return body, nil
}

func (client Client) UpdateProjectTag(request UpdateProjectTagRequest) (UpdateProjectTagResponse, error) {
var body UpdateProjectTagResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
SetBody(request).
Patch("api/v1/workspace/" + request.ProjectID + "/tags/" + request.TagID)

if err != nil {
return UpdateProjectTagResponse{}, fmt.Errorf("CallUpdateProjectTag: Unable to complete api request [err=%s]", err)
}

if response.IsError() {
return UpdateProjectTagResponse{}, fmt.Errorf("CallUpdateProjectTag: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body, nil
}

func (client Client) GetProjectTagByID(request GetProjectTagByIDRequest) (GetProjectTagByIDResponse, error) {
var body GetProjectTagByIDResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
SetBody(request).
Get("api/v1/workspace/" + request.ProjectID + "/tags/" + request.TagID)

if response.StatusCode() == http.StatusNotFound {
return GetProjectTagByIDResponse{}, ErrNotFound
}

if err != nil {
return GetProjectTagByIDResponse{}, fmt.Errorf("CallGetProjectTag: Unable to complete api request [err=%s]", err)
}

if response.IsError() {
return GetProjectTagByIDResponse{}, fmt.Errorf("CallGetProjectTag: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body, nil
}

func (client Client) GetProjectTagBySlug(request GetProjectTagBySlugRequest) (GetProjectTagBySlugResponse, error) {
var body GetProjectTagBySlugResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
SetBody(request).
Get("api/v1/workspace/" + request.ProjectID + "/tags/slug/" + request.TagSlug)

if response.StatusCode() == http.StatusNotFound {
return GetProjectTagBySlugResponse{}, ErrNotFound
}

if err != nil {
return GetProjectTagBySlugResponse{}, fmt.Errorf("CallGetProjectTagBySlug: Unable to complete api request [err=%s]", err)
}

if response.IsError() {
return GetProjectTagBySlugResponse{}, fmt.Errorf("CallGetProjectTagBySlug: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body, nil
}

func (client Client) DeleteProjectTag(request DeleteProjectTagRequest) (DeleteProjectTagResponse, error) {
var body DeleteProjectTagResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
SetBody(request).
Delete("api/v1/workspace/" + request.ProjectID + "/tags/" + request.TagID)

if err != nil {
return DeleteProjectTagResponse{}, fmt.Errorf("CallDeleteProjectTag: Unable to complete api request [err=%s]", err)
}

if response.IsError() {
return DeleteProjectTagResponse{}, fmt.Errorf("CallDeleteProjectTag: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body, nil
}
131 changes: 131 additions & 0 deletions internal/provider/datasource/secret_tag_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package datasource

import (
"context"
"fmt"

infisical "terraform-provider-infisical/internal/client"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

// Ensure provider defined types fully satisfy framework interfaces.
var _ datasource.DataSource = &SecretTagsDataSource{}

func NewSecretTagDataSource() datasource.DataSource {
return &SecretTagsDataSource{}
}

// SecretDataSource defines the data source implementation.
type SecretTagsDataSource struct {
client *infisical.Client
}

// ExampleDataSourceModel describes the data source data model.
type SecretTagDataSourceModel struct {
ID types.String `tfsdk:"id"`
ProjectID types.String `tfsdk:"project_id"`
Name types.String `tfsdk:"name"`
Slug types.String `tfsdk:"slug"`
Color types.String `tfsdk:"color"`
}

func (d *SecretTagsDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_secret_tag"
}

func (d *SecretTagsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Interact with Infisical secretTag secret tag.",
Attributes: map[string]schema.Attribute{
"slug": schema.StringAttribute{
Description: "The slug of the tag to fetch",
Required: true,
},
"project_id": schema.StringAttribute{
Description: "The secretTag ID of the tag to fetch",
Required: true,
},

"id": schema.StringAttribute{
Description: "The ID of the secret tag",
Computed: true,
},
"name": schema.StringAttribute{
Description: "The name of the secret tag",
Computed: true,
},
"color": schema.StringAttribute{
Description: "The color of the secret tag",
Computed: true,
},
},
}
}

func (d *SecretTagsDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*infisical.Client)

if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *http.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)

return
}

d.client = client
}

func (d *SecretTagsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {

if d.client.Config.AuthStrategy != infisical.AuthStrategy.UNIVERSAL_MACHINE_IDENTITY {
resp.Diagnostics.AddError(
"Unable to create secretTag tag",
"Only Machine Identity authentication is supported for this operation",
)
return
}

var data SecretTagDataSourceModel

// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)

if resp.Diagnostics.HasError() {
return
}

secretTag, err := d.client.GetProjectTagBySlug(infisical.GetProjectTagBySlugRequest{
TagSlug: data.Slug.ValueString(),
ProjectID: data.ProjectID.ValueString(),
})
if err != nil {
resp.Diagnostics.AddError(
"Something went wrong while fetching the secret tag",
"If the error is not clear, please get in touch at infisical.com/slack\n\n"+
"Infisical Client Error: "+err.Error(),
)
}

data = SecretTagDataSourceModel{
ID: types.StringValue(secretTag.Tag.ID),
Name: types.StringValue(secretTag.Tag.Name),
Slug: types.StringValue(secretTag.Tag.Slug),
ProjectID: data.ProjectID,
}

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
2 changes: 2 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func (p *infisicalProvider) DataSources(_ context.Context) []func() datasource.D
return []func() datasource.DataSource{
infisicalDatasource.NewSecretDataSource,
infisicalDatasource.NewProjectDataSource,
infisicalDatasource.NewSecretTagDataSource,
}
}

Expand All @@ -165,5 +166,6 @@ func (p *infisicalProvider) Resources(_ context.Context) []func() resource.Resou
infisicalResource.NewProjectIdentityResource,
infisicalResource.NewProjectRoleResource,
infisicalResource.NewProjectIdentitySpecificPrivilegeResource,
infisicalResource.NewProjectSecretTagResource,
}
}
Loading

0 comments on commit 33f3934

Please sign in to comment.