Skip to content

Commit

Permalink
#24225: New datasource azurerm_dashboard_grafana (#24243)
Browse files Browse the repository at this point in the history
* #24225: New datasource azurerm_dashboard_grafana

* #24225: Support for azure_monitor_workspace_integrations attribute
  • Loading branch information
harshavmb authored Jan 4, 2024
1 parent 4a0ccb5 commit 0f1b22f
Show file tree
Hide file tree
Showing 4 changed files with 345 additions and 1 deletion.
229 changes: 229 additions & 0 deletions internal/services/dashboard/dashboard_grafana_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
package dashboard

import (
"fmt"
"regexp"
"time"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/identity"
"github.com/hashicorp/go-azure-helpers/resourcemanager/location"
"github.com/hashicorp/go-azure-helpers/resourcemanager/tags"
"github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2023-09-01/grafanaresource"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
)

func dataSourceDashboardGrafana() *pluginsdk.Resource {
return &pluginsdk.Resource{
Read: dataSourceDashboardGrafanaRead,

Timeouts: &pluginsdk.ResourceTimeout{
Read: pluginsdk.DefaultTimeout(5 * time.Minute),
},

Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringMatch(
regexp.MustCompile(`^[a-zA-Z][-a-zA-Z\d]{0,21}[a-zA-Z\d]$`),
`The name length must be from 2 to 23 characters. The name can only contain letters, numbers and dashes, and it must begin with a letter and end with a letter or digit.`,
),
},

"resource_group_name": commonschema.ResourceGroupNameForDataSource(),

"location": commonschema.LocationComputed(),

"api_key_enabled": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"auto_generated_domain_name_label_scope": {
Type: pluginsdk.TypeString,
Computed: true,
},

"deterministic_outbound_ip_enabled": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"azure_monitor_workspace_integrations": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"resource_id": {
Type: pluginsdk.TypeString,
Computed: true,
},
},
},
},

"identity": commonschema.SystemOrUserAssignedIdentityOptionalForceNew(),

"public_network_access_enabled": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"grafana_major_version": {
Type: pluginsdk.TypeString,
Computed: true,
},

"grafana_version": {
Type: pluginsdk.TypeString,
Computed: true,
},

"outbound_ips": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
},
},

"endpoint": {
Type: pluginsdk.TypeString,
Computed: true,
},

"sku": {
Type: pluginsdk.TypeString,
Computed: true,
},

"zone_redundancy_enabled": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"tags": commonschema.TagsDataSource(),
},
}
}

func dataSourceDashboardGrafanaRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Dashboard.GrafanaResourceClient
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id := grafanaresource.NewGrafanaID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string))
resp, err := client.GrafanaGet(ctx, id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
return fmt.Errorf("%s was not found", id)
}
return fmt.Errorf("retrieving %s: %+v", id, err)
}

d.SetId(id.ID())

d.Set("name", id.GrafanaName)
d.Set("resource_group_name", id.ResourceGroupName)

if model := resp.Model; model != nil {
d.Set("location", location.Normalize(*model.Location))
if properties := model.Properties; properties != nil {
if properties.ApiKey != nil {
if *properties.ApiKey == grafanaresource.ApiKeyEnabled {
d.Set("api_key_enabled", true)
} else {
d.Set("api_key_enabled", false)
}
}

if properties.AutoGeneratedDomainNameLabelScope != nil {
d.Set("auto_generated_domain_name_label_scope", string(*properties.AutoGeneratedDomainNameLabelScope))
}

if properties.DeterministicOutboundIP != nil {
if *properties.DeterministicOutboundIP == grafanaresource.DeterministicOutboundIPEnabled {
d.Set("deterministic_outbound_ip_enabled", true)
} else {
d.Set("deterministic_outbound_ip_enabled", false)
}
}

if properties.Endpoint != nil {
d.Set("endpoint", properties.Endpoint)
}

if properties.GrafanaIntegrations != nil && properties.GrafanaIntegrations.AzureMonitorWorkspaceIntegrations != nil {
d.Set("azure_monitor_workspace_integrations", flattenAzureMonitorWorkspaceIntegrations(*properties.GrafanaIntegrations.AzureMonitorWorkspaceIntegrations))
}

if properties.GrafanaVersion != nil {
d.Set("grafana_version", properties.GrafanaVersion)
}

if properties.GrafanaMajorVersion != nil {
d.Set("grafana_major_version", properties.GrafanaMajorVersion)
}

if properties.OutboundIPs != nil {
d.Set("outbound_ips", properties.OutboundIPs)
}

if properties.PublicNetworkAccess != nil {
if *properties.PublicNetworkAccess == grafanaresource.PublicNetworkAccessEnabled {
d.Set("public_network_access_enabled", true)
} else {
d.Set("public_network_access_enabled", false)
}
}

if properties.ZoneRedundancy != nil {
if *properties.ZoneRedundancy == grafanaresource.ZoneRedundancyEnabled {
d.Set("zone_redundancy_enabled", true)
} else {
d.Set("zone_redundancy_enabled", false)
}
}
}

if model.Sku != nil {
d.Set("sku", model.Sku.Name)
}

flattenedIdentity, err := identity.FlattenSystemAndUserAssignedMap((*identity.SystemAndUserAssignedMap)(model.Identity))
if err != nil {
return fmt.Errorf("flattening `identity`: %+v", err)
}

if err := d.Set("identity", flattenedIdentity); err != nil {
return fmt.Errorf("setting `identity`: %+v", err)
}

if err := tags.FlattenAndSet(d, model.Tags); err != nil {
return err
}
}

return nil
}

// AzureMonitorWorkspaceIntegration represents a struct for Azure Monitor Workspace Integration
type AzureMonitorWorkspaceIntegration struct {
AzureMonitorWorkspaceResourceId *string `json:"azureMonitorWorkspaceResourceId,omitempty"`
}

func flattenAzureMonitorWorkspaceIntegrations(integrations []grafanaresource.AzureMonitorWorkspaceIntegration) []interface{} {
result := make([]interface{}, len(integrations))
for i, integration := range integrations {
result[i] = map[string]interface{}{
"resource_id": integration.AzureMonitorWorkspaceResourceId,
}
}
return result
}
37 changes: 37 additions & 0 deletions internal/services/dashboard/dashboard_grafana_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package dashboard_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
)

type DashboardGrafanaDataSource struct{}

func TestAccDashboardGrafanaDataSource_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_dashboard_grafana", "test")
r := DashboardGrafanaDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("resource_group_name").Exists(),
check.That(data.ResourceName).Key("grafana_major_version").HasValue("9"),
),
},
})
}

func (DashboardGrafanaDataSource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
data "azurerm_dashboard_grafana" "test" {
name = azurerm_dashboard_grafana.test.name
resource_group_name = azurerm_dashboard_grafana.test.resource_group_name
}
`, DashboardGrafanaResource{}.basic(data))
}
4 changes: 3 additions & 1 deletion internal/services/dashboard/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ func (r Registration) WebsiteCategories() []string {

// SupportedDataSources returns the supported Data Sources supported by this Service
func (r Registration) SupportedDataSources() map[string]*pluginsdk.Resource {
return map[string]*pluginsdk.Resource{}
return map[string]*pluginsdk.Resource{
"azurerm_dashboard_grafana": dataSourceDashboardGrafana(),
}
}

// SupportedResources returns the supported Resources supported by this Service
Expand Down
76 changes: 76 additions & 0 deletions website/docs/d/dashboard_grafana.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
subcategory: "Dashboard"
layout: "azurerm"
page_title: "Azure Resource Manager: azurerm_dashboard_grafana"
description: |-
Gets information about an existing Grafana Dashboard.
---

# Data Source: azurerm_dashboard_grafana

Use this data source to access information about an existing Grafana Dashboard.

## Example Usage

```hcl
provider "azurerm" {
features {}
}
data "azurerm_dashboard_grafana" "example" {
name = "example-grafana-dashboard"
resource_group_name = "example-rg"
}
output "name" {
value = data.azurerm_dashboard_grafana.example.name
}
```

## Argument Reference

The following arguments are supported:

* `name` - (Required) Name of the grafana dashboard.

* `resource_group_name` - (Required) Name of the resource group where resource belongs to.

## Attributes Reference

The following attributes are exported:

* `id` - The ID of Grafana Dashboard.

* `location` - Azure location where the resource exists.

* `api_key_enabled` - Whether the api key setting of the Grafana instance is enabled.

* `auto_generated_domain_name_label_scope` - Scope for dns deterministic name hash calculation.

* `deterministic_outbound_ip_enabled` - Whether the Grafana instance uses deterministic outbound IPs.

* `grafana_major_version` - Major version of Grafana instance.

* `azure_monitor_workspace_integrations` - Integrations for Azure Monitor Workspace.

* `identity` - The managed identity of the grafana resource.

* `public_network_access_enabled` - Whether or not public endpoint access is allowed for this server.

* `endpoint` - The endpoint of the Grafana instance.

* `grafana_version` - The full Grafana software semantic version deployed.

* `outbound_ip` - List of outbound IPs if deterministicOutboundIP is enabled.

* `sku` - The name of the SKU used for the Grafana instance.

* `zone_redundancy_enabled` - The zone redundancy setting of the Grafana instance.

* `tags` - A mapping of tags to assigned to the resource.

## Timeouts

The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions:

* `read` - (Defaults to 5 minutes) Used when retrieving the API Management API.

0 comments on commit 0f1b22f

Please sign in to comment.