internal/provider/sdk/resource_gitlab_topic.go (139 lines of code) (raw):

package sdk import ( "context" "fmt" "strconv" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" gitlab "gitlab.com/gitlab-org/api/client-go" "gitlab.com/gitlab-org/terraform-provider-gitlab/internal/provider/api" ) var _ = registerResource("gitlab_topic", func() *schema.Resource { return &schema.Resource{ Description: `The ` + "`gitlab_topic`" + ` resource allows to manage the lifecycle of topics that are then assignable to projects. -> Topics are the successors for project tags. Aside from avoiding terminology collisions with Git tags, they are more descriptive and better searchable. **Upstream API**: [GitLab REST API docs for topics](https://docs.gitlab.com/api/topics/) `, CreateContext: resourceGitlabTopicCreate, ReadContext: resourceGitlabTopicRead, UpdateContext: resourceGitlabTopicUpdate, DeleteContext: resourceGitlabTopicDelete, Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, Schema: constructSchema(map[string]*schema.Schema{ "name": { Description: "The topic's name.", Type: schema.TypeString, Required: true, }, "title": { Description: "The topic's description.", Type: schema.TypeString, Required: true, }, "description": { Description: "A text describing the topic.", Type: schema.TypeString, Optional: true, }, }, avatarableSchema()), CustomizeDiff: avatarableDiff, } }) func resourceGitlabTopicCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*gitlab.Client) options := &gitlab.CreateTopicOptions{ Name: gitlab.Ptr(d.Get("name").(string)), Title: gitlab.Ptr(d.Get("title").(string)), } if v, ok := d.GetOk("description"); ok { options.Description = gitlab.Ptr(v.(string)) } avatar, err := handleAvatarOnCreate(d) if err != nil { return diag.FromErr(err) } if avatar != nil { options.Avatar = &gitlab.TopicAvatar{ Filename: avatar.Filename, Image: avatar.Image, } } tflog.Debug(ctx, fmt.Sprintf("[DEBUG] create gitlab topic %s", *options.Name)) topic, _, err := client.Topics.CreateTopic(options, gitlab.WithContext(ctx)) if err != nil { return diag.Errorf("Failed to create topic %q: %s", *options.Name, err) } d.SetId(fmt.Sprintf("%d", topic.ID)) return resourceGitlabTopicRead(ctx, d, meta) } func resourceGitlabTopicRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*gitlab.Client) topicID, err := strconv.Atoi(d.Id()) if err != nil { return diag.Errorf("Failed to convert topic id %s to int: %s", d.Id(), err) } tflog.Debug(ctx, fmt.Sprintf("[DEBUG] read gitlab topic %d", topicID)) topic, _, err := client.Topics.GetTopic(topicID, gitlab.WithContext(ctx)) if err != nil { if api.Is404(err) { tflog.Debug(ctx, fmt.Sprintf("[DEBUG] gitlab group %s not found so removing from state", d.Id())) d.SetId("") return nil } return diag.Errorf("Failed to read topic %d: %s", topicID, err) } d.SetId(fmt.Sprintf("%d", topic.ID)) d.Set("name", topic.Name) d.Set("title", topic.Title) d.Set("description", topic.Description) d.Set("avatar_url", topic.AvatarURL) return nil } func resourceGitlabTopicUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*gitlab.Client) options := &gitlab.UpdateTopicOptions{} if d.HasChange("name") { options.Name = gitlab.Ptr(d.Get("name").(string)) } if d.HasChange("title") { options.Title = gitlab.Ptr(d.Get("title").(string)) } if d.HasChange("description") { options.Description = gitlab.Ptr(d.Get("description").(string)) } avatar, err := handleAvatarOnUpdate(d) if err != nil { return diag.FromErr(err) } if avatar != nil { options.Avatar = &gitlab.TopicAvatar{ Filename: avatar.Filename, Image: avatar.Image, } } tflog.Debug(ctx, fmt.Sprintf("[DEBUG] update gitlab topic %s", d.Id())) topicID, err := strconv.Atoi(d.Id()) if err != nil { return diag.Errorf("Failed to convert topic id %s to int: %s", d.Id(), err) } _, _, err = client.Topics.UpdateTopic(topicID, options, gitlab.WithContext(ctx)) if err != nil { return diag.Errorf("Failed to update topic %d: %s", topicID, err) } return resourceGitlabTopicRead(ctx, d, meta) } func resourceGitlabTopicDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*gitlab.Client) topicID, err := strconv.Atoi(d.Id()) if err != nil { return diag.Errorf("Failed to convert topic id %s to int: %s", d.Id(), err) } tflog.Debug(ctx, fmt.Sprintf("[DEBUG] delete gitlab topic %s", d.Id())) if _, err = client.Topics.DeleteTopic(topicID, gitlab.WithContext(ctx)); err != nil { return diag.Errorf("Failed to delete topic %d: %s", topicID, err) } return nil }