Skip to content

Commit

Permalink
feat: add new tool versions datasource
Browse files Browse the repository at this point in the history
  • Loading branch information
Apollorion committed Oct 31, 2024
1 parent ab02d41 commit 490814f
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 0 deletions.
59 changes: 59 additions & 0 deletions docs/data-sources/tool_versions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "spacelift_tool_versions Data Source - terraform-provider-spacelift"
subcategory: ""
description: |-
Lists supported versions for a given tool.
---

# spacelift_tool_versions (Data Source)

Lists supported versions for a given tool.

## Example Usage

```terraform
data "spacelift_tool_versions" "terraform" {
tool = "terraform"
}
output "terraform" {
value = data.spacelift_tool_versions.terraform.versions
}
data "spacelift_tool_versions" "open_tofu" {
tool = "openTofu"
}
output "open_tofu" {
value = data.spacelift_tool_versions.open_tofu.versions
}
data "spacelift_tool_versions" "kubectl" {
tool = "kubectl"
}
output "kubectl" {
value = data.spacelift_tool_versions.kubectl.versions
}
data "spacelift_tool_versions" "terragrunt" {
tool = "terragrunt"
}
output "terragrunt" {
value = data.spacelift_tool_versions.terragrunt.versions
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `tool` (String) The tool to get supported versions for.

### Read-Only

- `id` (String) The ID of this resource.
- `versions` (List of String) Supported versions of the given tool.
31 changes: 31 additions & 0 deletions examples/data-sources/spacelift_tool_versions/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
data "spacelift_tool_versions" "terraform" {
tool = "terraform"
}

output "terraform" {
value = data.spacelift_tool_versions.terraform.versions
}

data "spacelift_tool_versions" "open_tofu" {
tool = "openTofu"
}

output "open_tofu" {
value = data.spacelift_tool_versions.open_tofu.versions
}

data "spacelift_tool_versions" "kubectl" {
tool = "kubectl"
}

output "kubectl" {
value = data.spacelift_tool_versions.kubectl.versions
}

data "spacelift_tool_versions" "terragrunt" {
tool = "terragrunt"
}

output "terragrunt" {
value = data.spacelift_tool_versions.terragrunt.versions
}
95 changes: 95 additions & 0 deletions spacelift/data_tool_versions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package spacelift

import (
"context"
"slices"

"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/spacelift-io/terraform-provider-spacelift/spacelift/internal"
)

func dataToolVersions() *schema.Resource {
return &schema.Resource{
Description: "Lists supported versions for a given tool.",
ReadContext: dataToolVersionsRead,
Schema: map[string]*schema.Schema{
"tool": {
Type: schema.TypeString,
Description: "The tool to get supported versions for.",
ValidateDiagFunc: dataToolVersionsValidateInput,
Required: true,
},
"versions": {
Type: schema.TypeList,
Description: "Supported versions of the given tool.",
Elem: &schema.Schema{
Type: schema.TypeString,
},
Computed: true,
},
},
}
}

func dataToolVersionsValidateInput(i interface{}, p cty.Path) diag.Diagnostics {
tool := i.(string)

validTools := []string{
"kubectl",
"openTofu",
"terraform",
"terragrunt",
}

if !slices.Contains(validTools, tool) {
return diag.Errorf("tool must be one of %v", validTools)
}

return nil
}

func dataToolVersionsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
d.SetId("spacelift-versions")
tool := d.Get("tool").(string)
switch tool {
case "kubectl":
var query struct {
Versions []string `graphql:"kubectlVersions"`
}
if err := meta.(*internal.Client).Query(ctx, "toolVersions", &query, map[string]interface{}{}); err != nil {
return diag.Errorf("could not query for tool: %v", err)
}
d.Set("versions", query.Versions)
case "openTofu":
var query struct {
Versions []string `graphql:"openTofuVersions"`
}
if err := meta.(*internal.Client).Query(ctx, "toolVersions", &query, map[string]interface{}{}); err != nil {
return diag.Errorf("could not query for tool: %v", err)
}
d.Set("versions", query.Versions)
case "terraform":
var query struct {
Versions []string `graphql:"terraformVersions"`
}
if err := meta.(*internal.Client).Query(ctx, "toolVersions", &query, map[string]interface{}{}); err != nil {
return diag.Errorf("could not query for tool: %v", err)
}
d.Set("versions", query.Versions)
case "terragrunt":
var query struct {
Versions []string `graphql:"terragruntVersions"`
}
if err := meta.(*internal.Client).Query(ctx, "toolVersions", &query, map[string]interface{}{}); err != nil {
return diag.Errorf("could not query for tool: %v", err)
}
d.Set("versions", query.Versions)
default:
return diag.Errorf("unsupported tool: %s", tool)
}

return nil
}
96 changes: 96 additions & 0 deletions spacelift/data_tool_versions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package spacelift

import (
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"

. "github.com/spacelift-io/terraform-provider-spacelift/spacelift/internal/testhelpers"
)

func TestToolVersionsData(t *testing.T) {
t.Run("reads all tool versions", func(t *testing.T) {
testSteps(t, []resource.TestStep{
{
Config: `
data "spacelift_tool_versions" "test" {
tool = "kubectl"
}
`,
Check: Resource(
"data.spacelift_tool_versions.test",
Attribute("id", Contains("spacelift-versions")),
Attribute("tool", Equals("kubectl")),
SetLengthGreaterThanZero("versions"),
),
//Check: func(state *terraform.State) error {
// resource, ok := state.Modules[0].Resources["data.spacelift_tool_versions.test"]
// if !ok {
// return errors.Errorf("resource not found")
// }
//
// fmt.Println(resource.Primary.Attributes)
//
// return nil
//},
},
{
Config: `
data "spacelift_tool_versions" "test" {
tool = "openTofu"
}
`,
Check: Resource(
"data.spacelift_tool_versions.test",
Attribute("id", Contains("spacelift-versions")),
Attribute("tool", Equals("openTofu")),
SetLengthGreaterThanZero("versions"),
),
},
{
Config: `
data "spacelift_tool_versions" "test" {
tool = "terraform"
}
`,
Check: Resource(
"data.spacelift_tool_versions.test",
Attribute("id", Contains("spacelift-versions")),
Attribute("tool", Equals("terraform")),
SetLengthGreaterThanZero("versions"),
),
},
{
Config: `
data "spacelift_tool_versions" "test" {
tool = "terragrunt"
}
`,
Check: Resource(
"data.spacelift_tool_versions.test",
Attribute("id", Contains("spacelift-versions")),
Attribute("tool", Equals("terragrunt")),
SetLengthGreaterThanZero("versions"),
),
},
})
})

t.Run("only allows specific tools", func(t *testing.T) {
re, err := regexp.Compile(`tool must be one of \[.*]`)
if err != nil {
t.Fatalf("could not compile regexp: %v", err)
}
testSteps(t, []resource.TestStep{
{
Config: `
data "spacelift_tool_versions" "test" {
tool = "this-tool-should-error"
}
`,
ExpectError: re,
},
})
})
}
18 changes: 18 additions & 0 deletions spacelift/internal/testhelpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,24 @@ func SetContains(name string, values ...string) AttributeCheck {
}
}

// SetContains checks the set contains all specified values
func SetLengthGreaterThanZero(name string) AttributeCheck {
return func(attributes map[string]string) error {

_, ok := attributes[fmt.Sprintf("%s.#", name)]
if !ok {
return errors.Errorf("%q does not appear to be a set", name)
}

_, ok = attributes[fmt.Sprintf("%s.0", name)]
if !ok {
return errors.Errorf("%q has no length", name)
}

return nil
}
}

// SetDoesNotContain checks the set does not contain any of the specified values
func SetDoesNotContain(name string, values ...string) AttributeCheck {
return func(attributes map[string]string) error {
Expand Down
1 change: 1 addition & 0 deletions spacelift/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func Provider(commit, version string) plugin.ProviderFunc {
"spacelift_scheduled_delete_stack": dataScheduledDeleteStack(),
"spacelift_stack": dataStack(),
"spacelift_stacks": dataStacks(),
"spacelift_tool_versions": dataToolVersions(),
"spacelift_webhook": dataWebhook(),
"spacelift_named_webhook": dataNamedWebhook(),
"spacelift_stack_aws_role": dataStackAWSRole(), // deprecated
Expand Down
1 change: 1 addition & 0 deletions spacelift/type_conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package spacelift
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/shurcooL/graphql"

"github.com/spacelift-io/terraform-provider-spacelift/spacelift/internal/structs"
)

Expand Down

0 comments on commit 490814f

Please sign in to comment.