Skip to content

Commit 0f7613e

Browse files
authored
add organization_preferences resource and data source (#622)
* WIP: add org preferences data source TODO: * how to uniquely ID the org preferences? * add `resource_organization_preferences` Signed-off-by: Mike Ball <[email protected]> * set ID on organization_preferences data source Signed-off-by: Mike Ball <[email protected]> * stringify org preferences resource home_dashboard_uid Signed-off-by: Mike Ball <[email protected]> * add basic resource_organization_preferences Signed-off-by: Mike Ball <[email protected]> * DRY up data_source_organization_preferences This makes use of `cloneResourceSchemaForDatasource` such that it's not necessary to redundantly declare the schema across both the resource and data source. Signed-off-by: Mike Ball <[email protected]> * 'organization_preferences' as resource/data source ID If every instance of a data source or resource has the same value, the ID can be static, as that resource or data source is a singleton. Signed-off-by: Mike Ball <[email protected]> * 'organization_preferences' as resource/data source ID If every instance of a data source or resource has the same value, the ID can be static, as that resource or data source is a singleton. Signed-off-by: Mike Ball <[email protected]> * clear org preferences on delete Signed-off-by: Mike Ball <[email protected]> * properly update org preferences Signed-off-by: Mike Ball <[email protected]> * add org prefs 'timezone' validation Signed-off-by: Mike Ball <[email protected]> * add org prefs 'theme' validation Signed-off-by: Mike Ball <[email protected]> * remove 'locale' from org prefs This does not appear to be documented: https://grafana.com/docs/grafana/latest/developers/http_api/preferences/ Signed-off-by: Mike Ball <[email protected]> * add organization preferences docs Signed-off-by: Mike Ball <[email protected]> * clarify org prefs available attr values Signed-off-by: Mike Ball <[email protected]> * document organization_preferences datasource Signed-off-by: Mike Ball <[email protected]> * add initial organization_preferences datasource test Signed-off-by: Mike Ball <[email protected]> * add check for 'id' attr in organizaiton_preferences datasource Signed-off-by: Mike Ball <[email protected]> * add basic organization_preferences resource tests Signed-off-by: Mike Ball <[email protected]> * enable organization_preferences tests on OSS Signed-off-by: Mike Ball <[email protected]> * properly cast HomeDashboardID to int64 Signed-off-by: Mike Ball <[email protected]> * correct organization_preferences test assertions Signed-off-by: Mike Ball <[email protected]> * test organization_preferences 'week_start' attr Signed-off-by: Mike Ball <[email protected]> * add additional organization_preferences tests Signed-off-by: Mike Ball <[email protected]> * test org preferences for Grafana versions >= 8 This seeks to avoid errors like: ``` === RUN TestAccResourceOrganizationPreferences resource_organization_preferences_test.go:28: Step 1/2 error: Check failed: Check 1/7 error: expected organization preferences week start 'Monday'; got '' --- FAIL: TestAccResourceOrganizationPreferences (0.49s) ``` ...as seen here: https://drone.grafana.net/grafana/terraform-provider-grafana/1742/11/4 Signed-off-by: Mike Ball <[email protected]> * add third org preferences resource.TestStep Signed-off-by: Mike Ball <[email protected]> Signed-off-by: Mike Ball <[email protected]>
1 parent 340d0ee commit 0f7613e

File tree

10 files changed

+432
-34
lines changed

10 files changed

+432
-34
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "grafana_organization_preferences Data Source - terraform-provider-grafana"
4+
subcategory: "Grafana OSS"
5+
description: |-
6+
Official documentation https://grafana.com/docs/grafana/latest/administration/manage-organizations/HTTP API https://grafana.com/docs/grafana/latest/developers/http_api/preferences/#get-current-org-prefs
7+
---
8+
9+
# grafana_organization_preferences (Data Source)
10+
11+
* [Official documentation](https://grafana.com/docs/grafana/latest/administration/manage-organizations/)
12+
* [HTTP API](https://grafana.com/docs/grafana/latest/developers/http_api/preferences/#get-current-org-prefs)
13+
14+
## Example Usage
15+
16+
```terraform
17+
data "grafana_organization_preferences" "test" {}
18+
```
19+
20+
<!-- schema generated by tfplugindocs -->
21+
## Schema
22+
23+
### Read-Only
24+
25+
- `home_dashboard_id` (Number) The Organization home dashboard ID.
26+
- `home_dashboard_uid` (String) The Organization home dashboard UID.
27+
- `id` (String) The ID of this resource.
28+
- `theme` (String) The Organization theme. Available values are `light`, `dark`, or an empty string for the default.
29+
- `timezone` (String) The Organization timezone. Available values are `utc`, `browser`, or an empty string for the default.
30+
- `week_start` (String) The Organization week start.
31+
32+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "grafana_organization_preferences Resource - terraform-provider-grafana"
4+
subcategory: "Grafana OSS"
5+
description: |-
6+
Official documentation https://grafana.com/docs/grafana/latest/administration/manage-organizations/HTTP API https://grafana.com/docs/grafana/latest/developers/http_api/preferences/#get-current-org-prefs
7+
---
8+
9+
# grafana_organization_preferences (Resource)
10+
11+
* [Official documentation](https://grafana.com/docs/grafana/latest/administration/manage-organizations/)
12+
* [HTTP API](https://grafana.com/docs/grafana/latest/developers/http_api/preferences/#get-current-org-prefs)
13+
14+
## Example Usage
15+
16+
```terraform
17+
resource "grafana_organization_preferences" "test" {
18+
theme = "light"
19+
timezone = "utc"
20+
week_start = "Tuesday"
21+
}
22+
```
23+
24+
<!-- schema generated by tfplugindocs -->
25+
## Schema
26+
27+
### Optional
28+
29+
- `home_dashboard_id` (Number) The Organization home dashboard ID.
30+
- `home_dashboard_uid` (String) The Organization home dashboard UID.
31+
- `theme` (String) The Organization theme. Available values are `light`, `dark`, or an empty string for the default.
32+
- `timezone` (String) The Organization timezone. Available values are `utc`, `browser`, or an empty string for the default.
33+
- `week_start` (String) The Organization week start.
34+
35+
### Read-Only
36+
37+
- `id` (String) The ID of this resource.
38+
39+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
data "grafana_organization_preferences" "test" {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
resource "grafana_organization_preferences" "test" {
2+
theme = "light"
3+
timezone = "utc"
4+
week_start = "Tuesday"
5+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package grafana
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+
)
9+
10+
func DatasourceOrganizationPreferences() *schema.Resource {
11+
return &schema.Resource{
12+
Description: `
13+
* [Official documentation](https://grafana.com/docs/grafana/latest/administration/manage-organizations/)
14+
* [HTTP API](https://grafana.com/docs/grafana/latest/developers/http_api/preferences/#get-current-org-prefs)
15+
`,
16+
ReadContext: dataSourceOrganizationPreferencesRead,
17+
Schema: cloneResourceSchemaForDatasource(ResourceOrganizationPreferences(), map[string]*schema.Schema{}),
18+
}
19+
}
20+
21+
func dataSourceOrganizationPreferencesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
22+
client := meta.(*client).gapi
23+
prefs, err := client.OrgPreferences()
24+
25+
if err != nil {
26+
return diag.FromErr(err)
27+
}
28+
29+
d.Set("theme", prefs.Theme)
30+
d.Set("home_dashboard_id", prefs.HomeDashboardID)
31+
d.Set("home_dashboard_uid", prefs.HomeDashboardUID)
32+
d.Set("timezone", prefs.Timezone)
33+
d.Set("week_start", prefs.WeekStart)
34+
35+
d.SetId("organization_preferences")
36+
37+
return nil
38+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package grafana
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
7+
)
8+
9+
func TestAccDatasourceOrganizationPreferences(t *testing.T) {
10+
CheckOSSTestsEnabled(t)
11+
12+
checks := []resource.TestCheckFunc{
13+
resource.TestCheckResourceAttr(
14+
"data.grafana_organization_preferences.test", "theme", "",
15+
),
16+
resource.TestCheckResourceAttr(
17+
"data.grafana_organization_preferences.test", "timezone", "",
18+
),
19+
resource.TestCheckResourceAttr(
20+
"data.grafana_organization_preferences.test", "id", "organization_preferences",
21+
),
22+
}
23+
24+
resource.Test(t, resource.TestCase{
25+
ProviderFactories: testAccProviderFactories,
26+
Steps: []resource.TestStep{
27+
{
28+
Config: testAccExample(t, "data-sources/grafana_organization_preferences/data-source.tf"),
29+
Check: resource.ComposeTestCheckFunc(checks...),
30+
},
31+
},
32+
})
33+
}

grafana/provider.go

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -48,32 +48,33 @@ func Provider(version string) func() *schema.Provider {
4848
// Resources that require the Grafana client to exist.
4949
grafanaClientResources = addResourcesMetadataValidation(grafanaClientPresent, map[string]*schema.Resource{
5050
// Grafana
51-
"grafana_annotation": ResourceAnnotation(),
52-
"grafana_alert_notification": ResourceAlertNotification(),
53-
"grafana_builtin_role_assignment": ResourceBuiltInRoleAssignment(),
54-
"grafana_contact_point": ResourceContactPoint(),
55-
"grafana_dashboard": ResourceDashboard(),
56-
"grafana_dashboard_permission": ResourceDashboardPermission(),
57-
"grafana_data_source": ResourceDataSource(),
58-
"grafana_data_source_permission": ResourceDatasourcePermission(),
59-
"grafana_folder": ResourceFolder(),
60-
"grafana_folder_permission": ResourceFolderPermission(),
61-
"grafana_library_panel": ResourceLibraryPanel(),
62-
"grafana_message_template": ResourceMessageTemplate(),
63-
"grafana_mute_timing": ResourceMuteTiming(),
64-
"grafana_notification_policy": ResourceNotificationPolicy(),
65-
"grafana_organization": ResourceOrganization(),
66-
"grafana_playlist": ResourcePlaylist(),
67-
"grafana_report": ResourceReport(),
68-
"grafana_role": ResourceRole(),
69-
"grafana_role_assignment": ResourceRoleAssignment(),
70-
"grafana_rule_group": ResourceRuleGroup(),
71-
"grafana_team": ResourceTeam(),
72-
"grafana_team_preferences": ResourceTeamPreferences(),
73-
"grafana_team_external_group": ResourceTeamExternalGroup(),
74-
"grafana_service_account_token": ResourceServiceAccountToken(),
75-
"grafana_service_account": ResourceServiceAccount(),
76-
"grafana_user": ResourceUser(),
51+
"grafana_annotation": ResourceAnnotation(),
52+
"grafana_alert_notification": ResourceAlertNotification(),
53+
"grafana_builtin_role_assignment": ResourceBuiltInRoleAssignment(),
54+
"grafana_contact_point": ResourceContactPoint(),
55+
"grafana_dashboard": ResourceDashboard(),
56+
"grafana_dashboard_permission": ResourceDashboardPermission(),
57+
"grafana_data_source": ResourceDataSource(),
58+
"grafana_data_source_permission": ResourceDatasourcePermission(),
59+
"grafana_folder": ResourceFolder(),
60+
"grafana_folder_permission": ResourceFolderPermission(),
61+
"grafana_library_panel": ResourceLibraryPanel(),
62+
"grafana_message_template": ResourceMessageTemplate(),
63+
"grafana_mute_timing": ResourceMuteTiming(),
64+
"grafana_notification_policy": ResourceNotificationPolicy(),
65+
"grafana_organization": ResourceOrganization(),
66+
"grafana_organization_preferences": ResourceOrganizationPreferences(),
67+
"grafana_playlist": ResourcePlaylist(),
68+
"grafana_report": ResourceReport(),
69+
"grafana_role": ResourceRole(),
70+
"grafana_role_assignment": ResourceRoleAssignment(),
71+
"grafana_rule_group": ResourceRuleGroup(),
72+
"grafana_team": ResourceTeam(),
73+
"grafana_team_preferences": ResourceTeamPreferences(),
74+
"grafana_team_external_group": ResourceTeamExternalGroup(),
75+
"grafana_service_account_token": ResourceServiceAccountToken(),
76+
"grafana_service_account": ResourceServiceAccount(),
77+
"grafana_user": ResourceUser(),
7778

7879
// Machine Learning
7980
"grafana_machine_learning_job": ResourceMachineLearningJob(),
@@ -105,14 +106,15 @@ func Provider(version string) func() *schema.Provider {
105106

106107
// Datasources that require the Grafana client to exist.
107108
grafanaClientDatasources = addResourcesMetadataValidation(grafanaClientPresent, map[string]*schema.Resource{
108-
"grafana_dashboard": DatasourceDashboard(),
109-
"grafana_dashboards": DatasourceDashboards(),
110-
"grafana_folder": DatasourceFolder(),
111-
"grafana_folders": DatasourceFolders(),
112-
"grafana_library_panel": DatasourceLibraryPanel(),
113-
"grafana_user": DatasourceUser(),
114-
"grafana_team": DatasourceTeam(),
115-
"grafana_organization": DatasourceOrganization(),
109+
"grafana_dashboard": DatasourceDashboard(),
110+
"grafana_dashboards": DatasourceDashboards(),
111+
"grafana_folder": DatasourceFolder(),
112+
"grafana_folders": DatasourceFolders(),
113+
"grafana_library_panel": DatasourceLibraryPanel(),
114+
"grafana_user": DatasourceUser(),
115+
"grafana_team": DatasourceTeam(),
116+
"grafana_organization": DatasourceOrganization(),
117+
"grafana_organization_preferences": DatasourceOrganizationPreferences(),
116118
})
117119

118120
// Datasources that require the Synthetic Monitoring client to exist.
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package grafana
2+
3+
import (
4+
"context"
5+
6+
gapi "github.com/grafana/grafana-api-golang-client"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
10+
)
11+
12+
func ResourceOrganizationPreferences() *schema.Resource {
13+
return &schema.Resource{
14+
15+
Description: `
16+
* [Official documentation](https://grafana.com/docs/grafana/latest/administration/manage-organizations/)
17+
* [HTTP API](https://grafana.com/docs/grafana/latest/developers/http_api/preferences/#get-current-org-prefs)
18+
`,
19+
20+
CreateContext: CreateOrganizationPreferences,
21+
ReadContext: ReadOrganizationPreferences,
22+
UpdateContext: UpdateOrganizationPreferences,
23+
DeleteContext: DeleteOrganizationPreferences,
24+
Importer: &schema.ResourceImporter{
25+
StateContext: schema.ImportStatePassthroughContext,
26+
},
27+
28+
Schema: map[string]*schema.Schema{
29+
"theme": {
30+
Type: schema.TypeString,
31+
Optional: true,
32+
Description: "The Organization theme. Available values are `light`, `dark`, or an empty string for the default.",
33+
ValidateFunc: validation.StringInSlice([]string{"light", "dark", ""}, false),
34+
},
35+
"home_dashboard_id": {
36+
Type: schema.TypeInt,
37+
Optional: true,
38+
Description: "The Organization home dashboard ID.",
39+
},
40+
"home_dashboard_uid": {
41+
Type: schema.TypeString,
42+
Optional: true,
43+
Description: "The Organization home dashboard UID.",
44+
},
45+
"timezone": {
46+
Type: schema.TypeString,
47+
Optional: true,
48+
Description: "The Organization timezone. Available values are `utc`, `browser`, or an empty string for the default.",
49+
ValidateFunc: validation.StringInSlice([]string{"utc", "browser", ""}, false),
50+
},
51+
// TODO: add validation?
52+
"week_start": {
53+
Type: schema.TypeString,
54+
Optional: true,
55+
Description: "The Organization week start.",
56+
},
57+
},
58+
}
59+
}
60+
61+
func CreateOrganizationPreferences(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
62+
client := meta.(*client).gapi
63+
_, err := client.UpdateAllOrgPreferences(gapi.Preferences{
64+
Theme: d.Get("theme").(string),
65+
HomeDashboardID: int64(d.Get("home_dashboard_id").(int)),
66+
HomeDashboardUID: d.Get("home_dashboard_uid").(string),
67+
Timezone: d.Get("timezone").(string),
68+
WeekStart: d.Get("week_start").(string),
69+
})
70+
if err != nil {
71+
return diag.FromErr(err)
72+
}
73+
74+
d.SetId("organization_preferences")
75+
76+
return ReadOrganizationPreferences(ctx, d, meta)
77+
}
78+
79+
func ReadOrganizationPreferences(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
80+
client := meta.(*client).gapi
81+
prefs, err := client.OrgPreferences()
82+
83+
if err != nil {
84+
return diag.FromErr(err)
85+
}
86+
87+
d.Set("theme", prefs.Theme)
88+
d.Set("home_dashboard_id", prefs.HomeDashboardID)
89+
d.Set("home_dashboard_uid", prefs.HomeDashboardUID)
90+
d.Set("timezone", prefs.Timezone)
91+
d.Set("week_start", prefs.WeekStart)
92+
93+
d.SetId("organization_preferences")
94+
95+
return nil
96+
}
97+
98+
func UpdateOrganizationPreferences(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
99+
return CreateOrganizationPreferences(ctx, d, meta)
100+
}
101+
102+
func DeleteOrganizationPreferences(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
103+
client := meta.(*client).gapi
104+
if _, err := client.UpdateAllOrgPreferences(gapi.Preferences{}); err != nil {
105+
return diag.FromErr(err)
106+
}
107+
108+
return nil
109+
}

0 commit comments

Comments
 (0)