Skip to content

Commit 20cddc2

Browse files
authored
feat: make plugin version optional - installs latest version (#2315)
* feat: make plugin version optional - installs latest version * docs: version won't auto-update * ref: check plugin catalog latest version in read * ref: only fetch catalog plugin version when desired version is the latest
1 parent 228213d commit 20cddc2

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

docs/resources/cloud_plugin_installation.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ resource "grafana_cloud_plugin_installation" "test" {
3838

3939
- `slug` (String) Slug of the plugin to be installed.
4040
- `stack_slug` (String) The stack id to which the plugin should be installed.
41-
- `version` (String) Version of the plugin to be installed.
41+
42+
### Optional
43+
44+
- `version` (String) Version of the plugin to be installed. Defaults to 'latest' and installs the most recent version. Terraform will detect new version as drift for plan/apply. Defaults to `latest`.
4245

4346
### Read-Only
4447

internal/resources/cloud/resource_cloud_plugin_installation.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ var (
1919
)
2020
)
2121

22+
const LatestVersion = "latest"
23+
2224
func resourcePluginInstallation() *common.Resource {
2325
schema := &schema.Resource{
2426
Description: `
@@ -46,9 +48,10 @@ Required access policy scopes:
4648
ForceNew: true,
4749
},
4850
"version": {
49-
Description: "Version of the plugin to be installed.",
51+
Description: "Version of the plugin to be installed. Defaults to 'latest' and installs the most recent version. Terraform will detect new version as drift for plan/apply.",
5052
Type: schema.TypeString,
51-
Required: true,
53+
Optional: true,
54+
Default: LatestVersion,
5255
ForceNew: true,
5356
},
5457
},
@@ -92,10 +95,11 @@ func listStackPlugins(ctx context.Context, client *gcom.APIClient, data *ListerD
9295
func resourcePluginInstallationCreate(ctx context.Context, d *schema.ResourceData, client *gcom.APIClient) diag.Diagnostics {
9396
stackSlug := d.Get("stack_slug").(string)
9497
pluginSlug := d.Get("slug").(string)
98+
version := d.Get("version").(string)
9599

96100
req := gcom.PostInstancePluginsRequest{
97101
Plugin: pluginSlug,
98-
Version: common.Ref(d.Get("version").(string)),
102+
Version: common.Ref(version),
99103
}
100104

101105
err := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError {
@@ -133,10 +137,24 @@ func resourcePluginInstallationRead(ctx context.Context, d *schema.ResourceData,
133137
if err, shouldReturn := common.CheckReadError("plugin", d, err); shouldReturn {
134138
return err
135139
}
140+
desiredVersion := d.Get("version").(string)
141+
catalogVersion := ""
142+
if desiredVersion == LatestVersion {
143+
catalogPlugin, _, err := client.PluginsAPI.GetPlugin(ctx, pluginSlug.(string)).Execute()
144+
if err, shouldReturn := common.CheckReadError("plugin", d, err); shouldReturn {
145+
return err
146+
}
147+
catalogVersion = catalogPlugin.Version
148+
}
136149

137150
d.Set("stack_slug", installation.InstanceSlug)
138151
d.Set("slug", installation.PluginSlug)
139-
d.Set("version", installation.Version)
152+
153+
if desiredVersion == LatestVersion && installation.Version == catalogVersion {
154+
d.Set("version", LatestVersion)
155+
} else {
156+
d.Set("version", installation.Version)
157+
}
140158
d.SetId(resourcePluginInstallationID.Make(stackSlug, pluginSlug))
141159

142160
return nil

internal/resources/cloud/resource_cloud_plugin_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,17 @@ func TestAccResourcePluginInstallation(t *testing.T) {
3636
resource.TestCheckResourceAttr("grafana_cloud_plugin_installation.test-installation", "slug", "grafana-googlesheets-datasource"),
3737
resource.TestCheckResourceAttr("grafana_cloud_plugin_installation.test-installation", "version", "1.2.5")),
3838
},
39+
{
40+
Config: testAccGrafanaCloudPluginInstallationLatest(stackSlug, "grafana-clock-panel"),
41+
Check: resource.ComposeTestCheckFunc(
42+
testAccStackCheckExists("grafana_cloud_stack.test", &stack),
43+
testAccCloudPluginInstallationCheckExists(stackSlug, "grafana-clock-panel"),
44+
resource.TestCheckResourceAttrSet("grafana_cloud_plugin_installation.test-installation-no-version", "id"),
45+
resource.TestCheckResourceAttr("grafana_cloud_plugin_installation.test-installation-no-version", "stack_slug", stackSlug),
46+
resource.TestCheckResourceAttr("grafana_cloud_plugin_installation.test-installation-no-version", "slug", pluginSlug),
47+
resource.TestCheckResourceAttr("grafana_cloud_plugin_installation.test-installation-no-version", "version", "latest"),
48+
),
49+
},
3950
{
4051
ResourceName: "grafana_cloud_plugin_installation.test-installation",
4152
ImportState: true,
@@ -95,6 +106,7 @@ func testAccGrafanaCloudPluginInstallation(stackSlug, name, version string) stri
95106
resource "grafana_cloud_stack" "test" {
96107
name = "%[1]s"
97108
slug = "%[1]s"
109+
delete_protection = false
98110
wait_for_readiness = false
99111
}
100112
@@ -105,3 +117,18 @@ func testAccGrafanaCloudPluginInstallation(stackSlug, name, version string) stri
105117
}
106118
`, stackSlug, name, version)
107119
}
120+
121+
func testAccGrafanaCloudPluginInstallationLatest(stackSlug, name string) string {
122+
return fmt.Sprintf(`
123+
resource "grafana_cloud_stack" "test" {
124+
name = "%[1]s"
125+
slug = "%[1]s"
126+
delete_protection = false
127+
wait_for_readiness = false
128+
}
129+
resource "grafana_cloud_plugin_installation" "test-installation-no-version" {
130+
stack_slug = grafana_cloud_stack.test.slug
131+
slug = "%[2]s"
132+
}
133+
`, stackSlug, name)
134+
}

0 commit comments

Comments
 (0)