Skip to content

Commit 52c2830

Browse files
authored
feat(drone_crons): added new drone_crons data source (#104)
1 parent 579ecd0 commit 52c2830

File tree

4 files changed

+185
-0
lines changed

4 files changed

+185
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#retrieve all crons in a repositorie from drone instance
2+
data "drone_crons" "all" {
3+
repository = "octolab/hello-world"
4+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package drone
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"regexp"
7+
"sort"
8+
9+
"github.com/drone/drone-go/drone"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
13+
"github.com/mavimo/terraform-provider-drone/internal/provider/utils"
14+
)
15+
16+
func dataSourceCrons() *schema.Resource {
17+
return &schema.Resource{
18+
Description: "Data source for retrieving all Drone crons for a repo",
19+
ReadContext: dataSourceCronsRead,
20+
Schema: map[string]*schema.Schema{
21+
"repository": {
22+
Type: schema.TypeString,
23+
Required: true,
24+
Description: "Repository name",
25+
ValidateFunc: validation.StringMatch(
26+
regexp.MustCompile("^[^/ ]+/[^/ ]+$"),
27+
"Invalid repository (e.g. octocat/hello-world)",
28+
),
29+
},
30+
"names": {
31+
Type: schema.TypeList,
32+
Elem: &schema.Schema{
33+
Type: schema.TypeString,
34+
},
35+
Computed: true,
36+
Description: "List with cron name for a specific repository",
37+
},
38+
},
39+
}
40+
}
41+
42+
func dataSourceCronsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
43+
client := m.(drone.Client)
44+
45+
// Warning or errors can be collected in a slice type
46+
var diags diag.Diagnostics
47+
48+
owner, repo, err := utils.ParseRepo(d.Get("repository").(string))
49+
if err != nil {
50+
return diag.FromErr(err)
51+
}
52+
53+
crons, err := client.CronList(owner, repo)
54+
55+
if err != nil {
56+
diags = append(diags, diag.Diagnostic{
57+
Severity: diag.Error,
58+
Summary: fmt.Sprintf("failed to read Drone Crons for repo: %s/%ss", owner, repo),
59+
Detail: err.Error(),
60+
})
61+
62+
return diags
63+
}
64+
65+
ids := make([]string, 0)
66+
slugs := make([]string, 0)
67+
68+
for _, cron := range crons {
69+
ids = append(ids, cron.Name)
70+
slugs = append(slugs, cron.Name)
71+
}
72+
73+
sort.Strings(slugs)
74+
d.Set("names", slugs)
75+
d.Set("repository", fmt.Sprintf("%s/%s", owner, repo))
76+
77+
d.SetId(utils.BuildChecksumID(ids))
78+
79+
return diags
80+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package drone
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
9+
)
10+
11+
func TestAccDroneCronsDataSource(t *testing.T) {
12+
t.Run("check drone_crons data source with default values", func(t *testing.T) {
13+
orgName := "terraform"
14+
repoName := "repo-test-1"
15+
cronName1 := "cron-test-1"
16+
cronName2 := "cron-test-2"
17+
cronName3 := "cron-test-3"
18+
19+
configResource := fmt.Sprintf(`
20+
resource "drone_repo" "test" {
21+
repository = "%s/%s"
22+
}
23+
24+
resource "drone_cron" "test1" {
25+
repository = "${drone_repo.test.repository}"
26+
name = "%s"
27+
event = "push"
28+
expr = "@daily"
29+
}
30+
31+
resource "drone_cron" "test2" {
32+
repository = "${drone_repo.test.repository}"
33+
name = "%s"
34+
event = "push"
35+
expr = "@weekly"
36+
}
37+
38+
resource "drone_cron" "test3" {
39+
repository = "${drone_repo.test.repository}"
40+
name = "%s"
41+
event = "push"
42+
expr = "@monthly"
43+
}
44+
`, orgName, repoName, cronName1, cronName2, cronName3)
45+
46+
configData := configResource + fmt.Sprintf(`
47+
data "drone_crons" "test" {
48+
repository = "%s/%s"
49+
}
50+
`, orgName, repoName)
51+
52+
resource.Test(t, resource.TestCase{
53+
PreCheck: func() { testAccPreCheck(t) },
54+
Providers: testProviders,
55+
Steps: []resource.TestStep{
56+
{
57+
Config: configResource,
58+
Check: resource.ComposeTestCheckFunc(),
59+
},
60+
{
61+
Config: configData,
62+
Check: resource.ComposeTestCheckFunc(
63+
// We check that id is computed
64+
resource.TestCheckResourceAttrSet("data.drone_crons.test", "id"),
65+
// We check that are correctly sorted
66+
resource.TestCheckResourceAttr("data.drone_crons.test", "names.0", cronName1),
67+
resource.TestCheckResourceAttr("data.drone_crons.test", "names.1", cronName2),
68+
resource.TestCheckResourceAttr("data.drone_crons.test", "names.2", cronName3),
69+
// We check that we get only the repos we created
70+
resource.TestCheckResourceAttr("data.drone_crons.test", "names.#", "3"),
71+
),
72+
},
73+
},
74+
})
75+
})
76+
77+
t.Run("check drone_crons data source with non existing repository", func(t *testing.T) {
78+
orgName := "terraform"
79+
testMissingRepoName := "missing-repo"
80+
81+
configData := fmt.Sprintf(`
82+
data "drone_crons" "test" {
83+
repository = "%s/%s"
84+
}
85+
`, orgName, testMissingRepoName)
86+
87+
resource.Test(t, resource.TestCase{
88+
PreCheck: func() { testAccPreCheck(t) },
89+
Providers: testProviders,
90+
Steps: []resource.TestStep{
91+
{
92+
Config: configData,
93+
ExpectError: regexp.MustCompile(
94+
fmt.Sprintf("Error: failed to read Drone Crons for repo: %s/%s", orgName, testMissingRepoName),
95+
),
96+
},
97+
},
98+
})
99+
})
100+
}

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func Provider() *schema.Provider {
5454
},
5555
DataSourcesMap: map[string]*schema.Resource{
5656
"drone_cron": dataSourceCron(),
57+
"drone_crons": dataSourceCrons(),
5758
"drone_repo": dataSourceRepo(),
5859
"drone_repos": dataSourceRepos(),
5960
"drone_template": dataSourceTemplate(),

0 commit comments

Comments
 (0)