teamcity/ssh_key.go (134 lines of code) (raw):
package teamcity
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"terraform-provider-teamcity/client"
)
var (
_ resource.Resource = &sshKeyResource{}
_ resource.ResourceWithConfigure = &sshKeyResource{}
)
func NewSshKeyResource() resource.Resource {
return &sshKeyResource{}
}
type sshKeyResource struct {
client *client.Client
}
type sshKeyResourceModel struct {
Project types.String `tfsdk:"project_id"`
Name types.String `tfsdk:"name"`
Key types.String `tfsdk:"private_key"`
}
func (r *sshKeyResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_ssh_key"
}
func (r *sshKeyResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "You can upload private SSH keys into TeamCity projects. Uploaded keys can be used when configuring VCS roots, and in the SSH Agent build feature. More info [here](https://www.jetbrains.com/help/teamcity/ssh-keys-management.html)",
Attributes: map[string]schema.Attribute{
"project_id": schema.StringAttribute{
Required: true,
},
"name": schema.StringAttribute{
Required: true,
},
"private_key": schema.StringAttribute{
Required: true,
Sensitive: true,
},
},
}
}
func (r *sshKeyResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
}
r.client = req.ProviderData.(*client.Client)
}
func (r *sshKeyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var plan sshKeyResourceModel
diags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
err := r.client.NewSshKey(plan.Project.ValueString(), plan.Name.ValueString(), plan.Key.ValueString())
if err != nil {
resp.Diagnostics.AddError(
"Error adding SSH key",
err.Error(),
)
return
}
var newState sshKeyResourceModel
newState.Project = plan.Project
newState.Name = plan.Name
newState.Key = plan.Key
diags = resp.State.Set(ctx, newState)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
func (r *sshKeyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var state sshKeyResourceModel
diags := req.State.Get(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
actual, err := r.client.GetSshKeys(state.Project.ValueString())
if err != nil {
resp.Diagnostics.AddError(
"Error Reading SSH keys",
err.Error(),
)
return
}
if actual == nil {
resp.State.RemoveResource(ctx)
return
}
if !contains2(actual, state.Name.ValueString()) {
resp.State.RemoveResource(ctx)
return
}
newState := sshKeyResourceModel{
Project: state.Project,
Name: state.Name,
Key: state.Key,
}
diags = resp.State.Set(ctx, newState)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}
func (r *sshKeyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
}
func (r *sshKeyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var state sshKeyResourceModel
diags := req.State.Get(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
err := r.client.DeleteSshKey(state.Project.ValueString(), state.Name.ValueString())
if err != nil {
resp.Diagnostics.AddError(
"Error Deleting SSH key",
err.Error(),
)
return
}
}
func contains2(items []string, value string) bool {
for _, i := range items {
if i == value {
return true
}
}
return false
}