Skip to content

Commit b991b9d

Browse files
committed
resource/gitlab_project_approval_rule: fix potential accidential destroy of resource if not in first page
This fixes a potential bug that the resource is marked for destroy after a read, because it was not found on the first page. Pagination was not implemented. However, there exist a specific API to get a single project-level approval rule. I have implemented it in go-gitlab: * xanzy/go-gitlab#1410 After it is released, we should be able to just rebase and LGTM ;)
1 parent 65c03ea commit b991b9d

File tree

1 file changed

+11
-33
lines changed

1 file changed

+11
-33
lines changed

internal/provider/resource_gitlab_project_approval_rule.go

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -115,21 +115,28 @@ func resourceGitlabProjectApprovalRuleCreate(ctx context.Context, d *schema.Reso
115115
func resourceGitlabProjectApprovalRuleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
116116
log.Printf("[DEBUG] read gitlab project-level rule %s", d.Id())
117117

118-
projectID, _, err := parseTwoPartID(d.Id())
118+
projectID, parsedRuleID, err := parseTwoPartID(d.Id())
119119
if err != nil {
120120
return diag.FromErr(err)
121121
}
122-
d.Set("project", projectID)
122+
ruleID, err := strconv.Atoi(parsedRuleID)
123+
if err != nil {
124+
return diag.FromErr(err)
125+
}
126+
127+
client := meta.(*gitlab.Client)
123128

124-
rule, err := getApprovalRuleByID(ctx, meta.(*gitlab.Client), d.Id())
129+
rule, _, err := client.Projects.GetProjectApprovalRule(projectID, ruleID, gitlab.WithContext(ctx))
125130
if err != nil {
126-
if errors.Is(err, errApprovalRuleNotFound) {
131+
if is404(err) {
132+
log.Printf("[DEBUG] no project-level rule %s found, removing from state", d.Id())
127133
d.SetId("")
128134
return nil
129135
}
130136
return diag.FromErr(err)
131137
}
132138

139+
d.Set("project", projectID)
133140
d.Set("name", rule.Name)
134141
d.Set("approvals_required", rule.ApprovalsRequired)
135142
d.Set("rule_type", rule.RuleType)
@@ -203,35 +210,6 @@ func resourceGitlabProjectApprovalRuleDelete(ctx context.Context, d *schema.Reso
203210
return nil
204211
}
205212

206-
// getApprovalRuleByID checks the list of rules and finds the one that matches our rule ID.
207-
func getApprovalRuleByID(ctx context.Context, client *gitlab.Client, id string) (*gitlab.ProjectApprovalRule, error) {
208-
projectID, ruleID, err := parseTwoPartID(id)
209-
if err != nil {
210-
return nil, err
211-
}
212-
213-
ruleIDInt, err := strconv.Atoi(ruleID)
214-
if err != nil {
215-
return nil, err
216-
}
217-
218-
log.Printf("[DEBUG] read approval rules for project %s", projectID)
219-
220-
rules, _, err := client.Projects.GetProjectApprovalRules(projectID, gitlab.WithContext(ctx))
221-
if err != nil {
222-
return nil, err
223-
}
224-
225-
for _, r := range rules {
226-
if r.ID == ruleIDInt {
227-
log.Printf("[DEBUG] found project-level rule %+v", r)
228-
return r, nil
229-
}
230-
}
231-
232-
return nil, errApprovalRuleNotFound
233-
}
234-
235213
// flattenApprovalRuleUserIDs flattens a list of approval user ids into a list
236214
// of ints for storage in state.
237215
func flattenApprovalRuleUserIDs(users []*gitlab.BasicUser) []int {

0 commit comments

Comments
 (0)