Skip to content

Commit 9f5fd59

Browse files
committed
Add data sources
1 parent 4ba0418 commit 9f5fd59

5 files changed

+312
-1
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
"github.com/xanzy/go-gitlab"
9+
)
10+
11+
var _ = registerDataSource("gitlab_project_milestone", func() *schema.Resource {
12+
return &schema.Resource{
13+
Description: `The ` + "`gitlab_project_milestone`" + ` data source allows details of a project milestone.
14+
15+
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/milestones.html)`,
16+
17+
ReadContext: dataSourceGitlabProjectMilestoneRead,
18+
Schema: datasourceSchemaFromResourceSchema(gitlabProjectMilestoneGetSchema(), []string{"project_id", "milestone_id"}, nil),
19+
}
20+
})
21+
22+
func dataSourceGitlabProjectMilestoneRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
23+
client := meta.(*gitlab.Client)
24+
project := d.Get("project_id").(string)
25+
milestoneID := d.Get("milestone_id").(int)
26+
27+
milestone, _, err := client.Milestones.GetMilestone(project, milestoneID, gitlab.WithContext(ctx))
28+
if err != nil {
29+
return diag.FromErr(err)
30+
}
31+
d.SetId(resourceGitLabProjectMilestoneBuildId(project, milestoneID))
32+
stateMap := gitlabProjectMilestoneToStateMap(milestone)
33+
34+
if err := setStateMapInResourceData(stateMap, d); err != nil {
35+
return diag.FromErr(err)
36+
}
37+
return nil
38+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package provider
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
9+
)
10+
11+
func TestAccDataSourceGitlabProjectMilestone_basic(t *testing.T) {
12+
testAccCheck(t)
13+
14+
testProject := testAccCreateProject(t)
15+
16+
resource.Test(t, resource.TestCase{
17+
PreCheck: func() { testAccPreCheck(t) },
18+
ProviderFactories: providerFactories,
19+
Steps: []resource.TestStep{
20+
{
21+
Config: testAccDataGitlabProjectMilestoneConfig(testProject.ID),
22+
Check: resource.ComposeTestCheckFunc(
23+
testAccDataSourceGitlabProjectMilestone("gitlab_project_milestone.this", "data.gitlab_project_milestone.this"),
24+
),
25+
},
26+
},
27+
})
28+
}
29+
30+
func testAccDataSourceGitlabProjectMilestone(src, n string) resource.TestCheckFunc {
31+
return func(s *terraform.State) error {
32+
33+
resource := s.RootModule().Resources[src]
34+
resourceAttributes := resource.Primary.Attributes
35+
36+
datasource := s.RootModule().Resources[n]
37+
datasourceAttributes := datasource.Primary.Attributes
38+
39+
testAttributes := attributeNamesFromSchema(gitlabProjectMilestoneGetSchema())
40+
41+
for _, attribute := range testAttributes {
42+
if datasourceAttributes[attribute] != resourceAttributes[attribute] {
43+
return fmt.Errorf("Expected issue's attribute `%s` to be: %s, but got: `%s`", attribute, resourceAttributes[attribute], datasourceAttributes[attribute])
44+
}
45+
}
46+
47+
return nil
48+
}
49+
}
50+
51+
func testAccDataGitlabProjectMilestoneConfig(projectID int) string {
52+
return fmt.Sprintf(`
53+
resource "gitlab_project_milestone" "this" {
54+
project_id = %[1]d
55+
title = "Terraform acceptance tests"
56+
description = "Some description"
57+
start_date = "1994-02-21"
58+
due_date = "1994-02-25"
59+
}
60+
data "gitlab_project_milestone" "this" {
61+
project_id = %[1]d
62+
milestone_id = gitlab_project_milestone.this.milestone_id
63+
}
64+
`, projectID)
65+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
11+
"github.com/mitchellh/hashstructure"
12+
"github.com/xanzy/go-gitlab"
13+
)
14+
15+
var _ = registerDataSource("gitlab_project_milestones", func() *schema.Resource {
16+
validMilestoneStates := []string{"active", "closed"}
17+
18+
return &schema.Resource{
19+
Description: `The ` + "`gitlab_project_milestones`" + ` data source allows details of a project milestones.
20+
21+
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/milestones.html)`,
22+
23+
ReadContext: dataSourceGitlabProjectMilestonesRead,
24+
Schema: map[string]*schema.Schema{
25+
"project_id": {
26+
Description: "The ID or URL-encoded path of the project owned by the authenticated user.",
27+
Type: schema.TypeString,
28+
Required: true,
29+
},
30+
"iids": {
31+
Description: "Return only the milestones having the given `iid` (Note: ignored if `include_parent_milestones` is set as `true`).",
32+
Type: schema.TypeList,
33+
Elem: &schema.Schema{Type: schema.TypeInt},
34+
Optional: true,
35+
},
36+
"state": {
37+
Description: "Return only `active` or `closed` milestones.",
38+
Type: schema.TypeString,
39+
Optional: true,
40+
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice(validMilestoneStates, false)),
41+
},
42+
"title": {
43+
Description: "Return only the milestones having the given `title`.",
44+
Type: schema.TypeString,
45+
Optional: true,
46+
},
47+
"search": {
48+
Description: "Return only milestones with a title or description matching the provided string.",
49+
Type: schema.TypeString,
50+
Optional: true,
51+
},
52+
"include_parent_milestones": {
53+
Description: "Include group milestones from parent group and its ancestors. Introduced in GitLab 13.4.",
54+
Type: schema.TypeBool,
55+
Optional: true,
56+
},
57+
"milestones": {
58+
Description: "List of milestones from a project.",
59+
Type: schema.TypeList,
60+
Computed: true,
61+
Elem: &schema.Resource{
62+
Schema: datasourceSchemaFromResourceSchema(gitlabProjectMilestoneGetSchema(), nil, nil),
63+
},
64+
},
65+
},
66+
}
67+
})
68+
69+
func dataSourceGitlabProjectMilestonesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
70+
client := meta.(*gitlab.Client)
71+
72+
project := d.Get("project_id").(string)
73+
options := gitlab.ListMilestonesOptions{
74+
ListOptions: gitlab.ListOptions{
75+
PerPage: 20,
76+
Page: 1,
77+
},
78+
}
79+
80+
if v, ok := d.GetOk("iids"); ok {
81+
options.IIDs = intSetToIntSlice(v.(*schema.Set))
82+
}
83+
84+
if v, ok := d.GetOk("title"); ok {
85+
options.Title = gitlab.String(v.(string))
86+
}
87+
88+
if v, ok := d.GetOk("state"); ok {
89+
options.State = gitlab.String(v.(string))
90+
}
91+
92+
if v, ok := d.GetOk("search"); ok {
93+
options.Search = gitlab.String(v.(string))
94+
}
95+
96+
if v, ok := d.GetOk("include_parent_milestones"); ok {
97+
options.IncludeParentMilestones = gitlab.Bool(v.(bool))
98+
}
99+
100+
optionsHash, err := hashstructure.Hash(&options, nil)
101+
if err != nil {
102+
return diag.FromErr(err)
103+
}
104+
105+
var milestones []*gitlab.Milestone
106+
for options.Page != 0 {
107+
paginatedMilestones, resp, err := client.Milestones.ListMilestones(project, &options, gitlab.WithContext(ctx))
108+
if err != nil {
109+
return diag.FromErr(err)
110+
}
111+
112+
milestones = append(milestones, paginatedMilestones...)
113+
options.Page = resp.NextPage
114+
}
115+
116+
log.Printf("[DEBUG] get gitlab milestones from project: %s", project)
117+
d.SetId(fmt.Sprintf("%s:%d", project, optionsHash))
118+
if err = d.Set("milestones", flattenGitlabProjectMilestones(milestones)); err != nil {
119+
return diag.Errorf("Failed to set milestones to state: %v", err)
120+
}
121+
122+
return nil
123+
}
124+
125+
func flattenGitlabProjectMilestones(milestones []*gitlab.Milestone) (values []map[string]interface{}) {
126+
for _, milestone := range milestones {
127+
values = append(values, gitlabProjectMilestoneToStateMap(milestone))
128+
}
129+
return values
130+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package provider
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
9+
)
10+
11+
func TestAccDataGitlabProjectMilestones_basic(t *testing.T) {
12+
testAccCheck(t)
13+
countMilestones := 2
14+
project := testAccCreateProject(t)
15+
16+
resource.Test(t, resource.TestCase{
17+
PreCheck: func() { testAccPreCheck(t) },
18+
ProviderFactories: providerFactories,
19+
Steps: []resource.TestStep{
20+
{
21+
Config: testAccDataGitlabProjectMilestones(countMilestones, project.ID),
22+
Check: resource.ComposeTestCheckFunc(
23+
testAccDataSourceGitlabProjectMilestones("gitlab_project_milestone.this", "data.gitlab_project_milestones.this", countMilestones),
24+
),
25+
},
26+
},
27+
})
28+
}
29+
30+
func testAccDataSourceGitlabProjectMilestones(src string, n string, countMilestones int) resource.TestCheckFunc {
31+
return func(s *terraform.State) error {
32+
testAttributes := attributeNamesFromSchema(gitlabProjectMilestoneGetSchema())
33+
34+
for numberMilestone := range make([]int, countMilestones) {
35+
search := s.RootModule().Resources[n]
36+
searchAttrs := search.Primary.Attributes
37+
38+
milestone := s.RootModule().Resources[fmt.Sprintf("%s.%d", src, numberMilestone)]
39+
milestoneAttrs := milestone.Primary.Attributes
40+
41+
for _, attribute := range testAttributes {
42+
milestoneAttr := milestoneAttrs[attribute]
43+
searchAttr := searchAttrs[fmt.Sprintf("milestones.%d.%s", numberMilestone, attribute)]
44+
if searchAttr != milestoneAttr {
45+
return fmt.Errorf("Expected the milestone `%s` with parameter `%s` to be: `%s`, but got: `%s`", milestoneAttrs["id"], attribute, milestoneAttr, searchAttr)
46+
}
47+
}
48+
}
49+
50+
return nil
51+
}
52+
}
53+
54+
func testAccDataGitlabProjectMilestones(countTags int, project int) string {
55+
return fmt.Sprintf(`
56+
%s
57+
data "gitlab_project_milestones" "this" {
58+
project_id = "%d"
59+
state = "active"
60+
search = "test"
61+
depends_on = [
62+
gitlab_project_milestone.this,
63+
]
64+
}
65+
`, testAccDataGitlabProjectMilestonesSetup(countTags, project), project)
66+
}
67+
68+
func testAccDataGitlabProjectMilestonesSetup(countTags int, project int) string {
69+
return fmt.Sprintf(`
70+
resource "gitlab_project_milestone" "this" {
71+
count = "%d"
72+
73+
project_id = "%d"
74+
title = "test-${count.index}"
75+
description = "test-${count.index}"
76+
}
77+
`, countTags, project)
78+
}

internal/provider/resource_gitlab_project_milestone.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ var milestoneStateToStateEvent = map[string]string{
1818

1919
var _ = registerResource("gitlab_project_milestone", func() *schema.Resource {
2020
return &schema.Resource{
21-
Description: `The ` + "`gitlab_project_milestome`" + ` resource allows to manage the lifecycle of a milestone (project).
21+
Description: `The ` + "`gitlab_project_milestone`" + ` resource allows to manage the lifecycle of a milestone (project).
2222
2323
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/milestones.html)`,
2424

0 commit comments

Comments
 (0)