internal/provider/resource_gitlab_integration_jenkins.go (212 lines of code) (raw):

package provider import ( "context" "fmt" "github.com/hashicorp/terraform-plugin-framework/diag" "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/boolplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" gitlab "gitlab.com/gitlab-org/api/client-go" "gitlab.com/gitlab-org/terraform-provider-gitlab/internal/provider/utils" ) var ( _ resource.Resource = &gitlabIntegrationJenkinsResource{} _ resource.ResourceWithConfigure = &gitlabIntegrationJenkinsResource{} _ resource.ResourceWithImportState = &gitlabIntegrationJenkinsResource{} ) func init() { registerResource(NewGitLabIntegrationJenkinsResource) } func NewGitLabIntegrationJenkinsResource() resource.Resource { return &gitlabIntegrationJenkinsResource{} } type gitlabIntegrationJenkinsResource struct { client *gitlab.Client } type gitlabIntegrationJenkinsResourceModel struct { ID types.String `tfsdk:"id"` Project types.String `tfsdk:"project"` JenkinsURL types.String `tfsdk:"jenkins_url"` EnableSSLVerification types.Bool `tfsdk:"enable_ssl_verification"` ProjectName types.String `tfsdk:"project_name"` Username types.String `tfsdk:"username"` Password types.String `tfsdk:"password"` PushEvents types.Bool `tfsdk:"push_events"` MergeRequestEvents types.Bool `tfsdk:"merge_request_events"` TagPushEvents types.Bool `tfsdk:"tag_push_events"` Active types.Bool `tfsdk:"active"` } func (r *gitlabIntegrationJenkinsResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { resp.TypeName = req.ProviderTypeName + "_integration_jenkins" } func (r *gitlabIntegrationJenkinsResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { resp.Schema = schema.Schema{ MarkdownDescription: `The ` + "`gitlab_integration_jenkins`" + ` resource allows to manage the lifecycle of a project integration with Jenkins. **Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/api/project_integrations/#jenkins)`, Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ Computed: true, MarkdownDescription: "The ID of the resource. Matches the `project` value.", PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, }, "project": schema.StringAttribute{ MarkdownDescription: "ID of the project you want to activate integration on.", Required: true, PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, "enable_ssl_verification": schema.BoolAttribute{ MarkdownDescription: "Enable SSL verification. Defaults to `true` (enabled).", Optional: true, Computed: true, PlanModifiers: []planmodifier.Bool{boolplanmodifier.UseStateForUnknown()}, }, "jenkins_url": schema.StringAttribute{ MarkdownDescription: "Jenkins URL like `http://jenkins.example.com`", Required: true, Validators: []validator.String{utils.HttpUrlValidator}, }, "project_name": schema.StringAttribute{ MarkdownDescription: "The URL-friendly project name. Example: `my_project_name`.", Required: true, }, "username": schema.StringAttribute{ MarkdownDescription: "Username for authentication with the Jenkins server, if authentication is required by the server.", Optional: true, }, "password": schema.StringAttribute{ MarkdownDescription: "Password for authentication with the Jenkins server, if authentication is required by the server.", Optional: true, Sensitive: true, }, "push_events": schema.BoolAttribute{ MarkdownDescription: "Enable notifications for push events.", Optional: true, Computed: true, PlanModifiers: []planmodifier.Bool{boolplanmodifier.UseStateForUnknown()}, }, "merge_request_events": schema.BoolAttribute{ MarkdownDescription: "Enable notifications for merge request events.", Optional: true, Computed: true, PlanModifiers: []planmodifier.Bool{boolplanmodifier.UseStateForUnknown()}, }, "tag_push_events": schema.BoolAttribute{ MarkdownDescription: "Enable notifications for tag push events.", Optional: true, Computed: true, PlanModifiers: []planmodifier.Bool{boolplanmodifier.UseStateForUnknown()}, }, "active": schema.BoolAttribute{ MarkdownDescription: "Whether the integration is active.", Computed: true, }, }, } } func (r *gitlabIntegrationJenkinsResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) { if req.ProviderData == nil { return } resourceData := req.ProviderData.(*GitLabResourceData) r.client = resourceData.Client } func (r *gitlabIntegrationJenkinsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { err := r.update(ctx, &req.Plan, &resp.State, &resp.Diagnostics) if err != nil { resp.Diagnostics.AddError("Failed to create Jenkins integration", err.Error()) } } func (r *gitlabIntegrationJenkinsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { var data gitlabIntegrationJenkinsResourceModel resp.Diagnostics.Append(req.State.Get(ctx, &data)...) if resp.Diagnostics.HasError() { return } projectID := data.ID.ValueString() jenkins, _, err := r.client.Services.GetJenkinsCIService(projectID) if err != nil { resp.Diagnostics.AddError("GitLab API error occurred", fmt.Sprintf("Unable to read gitlab jenkins integration: %s", err.Error())) return } data.modelToStateModel(jenkins, projectID) resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } func (r *gitlabIntegrationJenkinsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { err := r.update(ctx, &req.Plan, &resp.State, &resp.Diagnostics) if err != nil { resp.Diagnostics.AddError("Failed to update Jenkins integration", err.Error()) } } func (r *gitlabIntegrationJenkinsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { var data gitlabIntegrationJenkinsResourceModel resp.Diagnostics.Append(req.State.Get(ctx, &data)...) if resp.Diagnostics.HasError() { return } _, err := r.client.Services.DeleteJenkinsCIService(data.Project.ValueString()) if err != nil { resp.Diagnostics.AddError( "GitLab API Error occurred", fmt.Sprintf("Unable to delete Jenkins integration: %s", err.Error()), ) return } } func (r *gitlabIntegrationJenkinsResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) } func (r *gitlabIntegrationJenkinsResource) update(ctx context.Context, plan *tfsdk.Plan, state *tfsdk.State, diags *diag.Diagnostics) error { var data gitlabIntegrationJenkinsResourceModel diags.Append(plan.Get(ctx, &data)...) if diags.HasError() { return nil } options := &gitlab.SetJenkinsCIServiceOptions{ URL: data.JenkinsURL.ValueStringPointer(), EnableSSLVerification: data.EnableSSLVerification.ValueBoolPointer(), ProjectName: data.ProjectName.ValueStringPointer(), Username: data.Username.ValueStringPointer(), Password: data.Password.ValueStringPointer(), PushEvents: data.PushEvents.ValueBoolPointer(), MergeRequestsEvents: data.MergeRequestEvents.ValueBoolPointer(), TagPushEvents: data.TagPushEvents.ValueBoolPointer(), } tflog.Debug(ctx, "Update Gitlab Jenkins integration", map[string]any{ "options": options, }) projectID := data.Project.ValueString() _, _, err := r.client.Services.SetJenkinsCIService(projectID, options) if err != nil { return err } jenkins, _, err := r.client.Services.GetJenkinsCIService(projectID) if err != nil { return err } data.modelToStateModel(jenkins, projectID) diags.Append(state.Set(ctx, &data)...) return nil } func (d *gitlabIntegrationJenkinsResourceModel) modelToStateModel(r *gitlab.JenkinsCIService, projectID string) { d.ID = types.StringValue(projectID) d.Project = types.StringValue(projectID) d.JenkinsURL = types.StringValue(r.Properties.URL) d.ProjectName = types.StringValue(r.Properties.ProjectName) if r.Properties.Username == "" { d.Username = types.StringNull() } else { d.Username = types.StringValue(r.Properties.Username) } d.EnableSSLVerification = types.BoolValue(r.Properties.EnableSSLVerification) d.MergeRequestEvents = types.BoolValue(r.MergeRequestsEvents) d.PushEvents = types.BoolValue(r.PushEvents) d.TagPushEvents = types.BoolValue(r.TagPushEvents) d.Active = types.BoolValue(r.Active) }