Implemented project resource
This commit is contained in:
parent
3d60272592
commit
64ac1f44e0
3 changed files with 162 additions and 16 deletions
145
internal/provider/project_resource.go
Normal file
145
internal/provider/project_resource.go
Normal file
|
@ -0,0 +1,145 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.adyxax.org/adyxax/terraform-eventline/internal/evcli"
|
||||
"github.com/exograd/eventline/pkg/eventline"
|
||||
"github.com/exograd/go-daemon/ksuid"
|
||||
"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"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
)
|
||||
|
||||
type ProjectResource struct {
|
||||
client *evcli.Client
|
||||
}
|
||||
|
||||
var _ resource.Resource = &ProjectResource{} // Ensure provider defined types fully satisfy framework interfaces
|
||||
var _ resource.ResourceWithImportState = &ProjectResource{} // Ensure provider defined types fully satisfy framework interfaces
|
||||
func NewProjectResource() resource.Resource {
|
||||
return &ProjectResource{}
|
||||
}
|
||||
|
||||
type ProjectResourceModel struct {
|
||||
Id types.String `tfsdk:"id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
}
|
||||
|
||||
func (r *ProjectResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_project"
|
||||
}
|
||||
|
||||
func (r *ProjectResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"id": schema.StringAttribute{
|
||||
Computed: true,
|
||||
MarkdownDescription: "Project Id",
|
||||
PlanModifiers: []planmodifier.String{
|
||||
stringplanmodifier.UseStateForUnknown(),
|
||||
},
|
||||
},
|
||||
"name": schema.StringAttribute{
|
||||
MarkdownDescription: "Project name",
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
MarkdownDescription: "Eventline project resource",
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ProjectResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
|
||||
r.client, _ = req.ProviderData.(*evcli.Client)
|
||||
}
|
||||
|
||||
func (r *ProjectResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
var data *ProjectResourceModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
project := eventline.Project{Name: data.Name.ValueString()}
|
||||
if err := r.client.CreateProject(&project); err != nil {
|
||||
resp.Diagnostics.AddError("CreateProject", fmt.Sprintf("Unable to create project, got error: %s\nTry importing the resource instead?", err))
|
||||
return
|
||||
}
|
||||
data.Id = types.StringValue(project.Id.String())
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
}
|
||||
|
||||
func (r *ProjectResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var data *ProjectResourceModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
var id ksuid.KSUID
|
||||
if err := id.Parse(data.Id.ValueString()); err != nil {
|
||||
resp.Diagnostics.AddError("KsuidParse", fmt.Sprintf("Unable to parse project id, got error: %s", err))
|
||||
return
|
||||
}
|
||||
project, err := r.client.FetchProjectById(id)
|
||||
if err != nil {
|
||||
var e *evcli.APIError
|
||||
if errors.As(err, &e) && e.Code == "unknown_project" {
|
||||
resp.State.RemoveResource(ctx) // The project does not exist
|
||||
return
|
||||
}
|
||||
resp.Diagnostics.AddError("FetchProjectById", fmt.Sprintf("Unable to fetch project by id, got error: %s", err))
|
||||
return
|
||||
}
|
||||
data.Id = types.StringValue(project.Id.String())
|
||||
data.Name = types.StringValue(project.Name)
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
}
|
||||
|
||||
func (r *ProjectResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
var data *ProjectResourceModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
var id ksuid.KSUID
|
||||
if err := id.Parse(data.Id.ValueString()); err != nil {
|
||||
resp.Diagnostics.AddError("KsuidParse", fmt.Sprintf("Unable to parse project id, got error: %s", err))
|
||||
return
|
||||
}
|
||||
project := eventline.Project{Id: id, Name: data.Name.ValueString()}
|
||||
if err := r.client.UpdateProject(&project); err != nil {
|
||||
resp.Diagnostics.AddError("UpdateProject", fmt.Sprintf("Unable to update project, got error: %s", err))
|
||||
return
|
||||
}
|
||||
data.Id = types.StringValue(project.Id.String())
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
}
|
||||
|
||||
func (r *ProjectResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
var data *ProjectResourceModel
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
var id ksuid.KSUID
|
||||
if err := id.Parse(data.Id.ValueString()); err != nil {
|
||||
resp.Diagnostics.AddError("KsuidParse", fmt.Sprintf("Unable to parse project id, got error: %s", err))
|
||||
return
|
||||
}
|
||||
if err := r.client.DeleteProject(id); err != nil {
|
||||
var e *evcli.APIError
|
||||
if errors.As(err, &e) && e.Code == "unknown_project" {
|
||||
return // the project does not exist, that is what we want
|
||||
}
|
||||
resp.Diagnostics.AddError("DeleteProject", fmt.Sprintf("Unable to delete project by id, got error: %s", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ProjectResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
|
||||
}
|
|
@ -9,33 +9,31 @@ import (
|
|||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
)
|
||||
|
||||
type projectsDataSource struct {
|
||||
type ProjectsDataSource struct {
|
||||
client *evcli.Client
|
||||
}
|
||||
|
||||
var _ datasource.DataSource = &projectsDataSource{} // Ensure provider defined types fully satisfy framework interfaces.
|
||||
var _ datasource.DataSource = &ProjectsDataSource{} // Ensure provider defined types fully satisfy framework interfaces
|
||||
func NewProjectsDataSource() datasource.DataSource {
|
||||
return &projectsDataSource{}
|
||||
return &ProjectsDataSource{}
|
||||
}
|
||||
|
||||
type ProjectsModel struct {
|
||||
Elements []ProjectModel `tfsdk:"elements"`
|
||||
type ProjectsDataSourceModel struct {
|
||||
Elements []ProjectDataSourceModel `tfsdk:"elements"`
|
||||
}
|
||||
type ProjectModel struct {
|
||||
type ProjectDataSourceModel struct {
|
||||
Id types.String `tfsdk:"id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
}
|
||||
|
||||
func (d *projectsDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
||||
func (d *ProjectsDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_projects"
|
||||
}
|
||||
|
||||
func (d *projectsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||
func (d *ProjectsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
MarkdownDescription: "Eventline projects data source",
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"elements": schema.ListAttribute{
|
||||
Computed: true,
|
||||
|
@ -48,15 +46,16 @@ func (d *projectsDataSource) Schema(ctx context.Context, req datasource.SchemaRe
|
|||
MarkdownDescription: "Projects list",
|
||||
},
|
||||
},
|
||||
MarkdownDescription: "Eventline projects data source",
|
||||
}
|
||||
}
|
||||
|
||||
func (d *projectsDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||
func (d *ProjectsDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||
d.client, _ = req.ProviderData.(*evcli.Client)
|
||||
}
|
||||
|
||||
func (d *projectsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
var data ProjectsModel
|
||||
func (d *ProjectsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
var data ProjectsDataSourceModel
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
|
@ -66,9 +65,9 @@ func (d *projectsDataSource) Read(ctx context.Context, req datasource.ReadReques
|
|||
resp.Diagnostics.AddError("FetchProjects", fmt.Sprintf("Unable to fetch projects, got error: %s", err))
|
||||
return
|
||||
}
|
||||
projectList := make([]ProjectModel, len(projects))
|
||||
projectList := make([]ProjectDataSourceModel, len(projects))
|
||||
for i, project := range projects {
|
||||
projectList[i] = ProjectModel{Id: basetypes.NewStringValue(project.Id.String()), Name: basetypes.NewStringValue(project.Name)}
|
||||
projectList[i] = ProjectDataSourceModel{Id: types.StringValue(project.Id.String()), Name: types.StringValue(project.Name)}
|
||||
}
|
||||
data.Elements = projectList
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
|
|
|
@ -70,7 +70,9 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest,
|
|||
}
|
||||
|
||||
func (p *Provider) Resources(ctx context.Context) []func() resource.Resource {
|
||||
return []func() resource.Resource{}
|
||||
return []func() resource.Resource{
|
||||
NewProjectResource,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provider) DataSources(ctx context.Context) []func() datasource.DataSource {
|
||||
|
|
Loading…
Add table
Reference in a new issue