diff --git a/.github/labeler-pull-request-triage.yml b/.github/labeler-pull-request-triage.yml index 6fb7ff96aea3..246e625bd0c9 100644 --- a/.github/labeler-pull-request-triage.yml +++ b/.github/labeler-pull-request-triage.yml @@ -74,6 +74,9 @@ service/cost-management: service/custom-resource-provider: - internal/services/customproviders/**/* +service/dashboard: + - internal/services/dashboard/**/* + service/data-factory: - internal/services/datafactory/**/* diff --git a/.teamcity/components/generated/services.kt b/.teamcity/components/generated/services.kt index 86855202ee2b..ad59ec150a6e 100644 --- a/.teamcity/components/generated/services.kt +++ b/.teamcity/components/generated/services.kt @@ -28,6 +28,7 @@ var services = mapOf( "costmanagement" to "Cost Management", "customproviders" to "Custom Providers", "dns" to "DNS", + "dashboard" to "Dashboard", "datafactory" to "Data Factory", "datashare" to "Data Share", "databricks" to "DataBricks", diff --git a/go.mod b/go.mod index 1e43f3b443a4..a79362227669 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/google/go-cmp v0.5.8 github.com/google/uuid v1.1.2 github.com/hashicorp/go-azure-helpers v0.37.0 - github.com/hashicorp/go-azure-sdk v0.20220725.1163004 + github.com/hashicorp/go-azure-sdk v0.20220728.1092823 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.6.0 diff --git a/go.sum b/go.sum index a5c62bc03583..2ef09d7e7af2 100644 --- a/go.sum +++ b/go.sum @@ -216,8 +216,8 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv github.com/hashicorp/go-azure-helpers v0.12.0/go.mod h1:Zc3v4DNeX6PDdy7NljlYpnrdac1++qNW0I4U+ofGwpg= github.com/hashicorp/go-azure-helpers v0.37.0 h1:6UOoQ9esE4MJ4wHJr21qU81IJQ9zsXQ9FbANYUbeE4U= github.com/hashicorp/go-azure-helpers v0.37.0/go.mod h1:gcutZ/Hf/O7YN9M3UIvyZ9l0Rxv7Yrc9x5sSfM9cuSw= -github.com/hashicorp/go-azure-sdk v0.20220725.1163004 h1:F6fxwMrEBiroVssWLY3/fIEJ4E6qJQfL1jvsnTYkHpU= -github.com/hashicorp/go-azure-sdk v0.20220725.1163004/go.mod h1:yjQPw8DCOtQR8E8+FNaTxF6yz+tyQGkDNiVAGCNoLOo= +github.com/hashicorp/go-azure-sdk v0.20220728.1092823 h1:+X1Lxb2oBQjRdV7KbhLsS/CS7LS5m/upl5rg4lzGeGI= +github.com/hashicorp/go-azure-sdk v0.20220728.1092823/go.mod h1:yjQPw8DCOtQR8E8+FNaTxF6yz+tyQGkDNiVAGCNoLOo= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= diff --git a/internal/clients/client.go b/internal/clients/client.go index cb8d507e5a90..57a99ec0e663 100644 --- a/internal/clients/client.go +++ b/internal/clients/client.go @@ -32,6 +32,7 @@ import ( cosmosdb "github.com/hashicorp/terraform-provider-azurerm/internal/services/cosmos/client" costmanagement "github.com/hashicorp/terraform-provider-azurerm/internal/services/costmanagement/client" customproviders "github.com/hashicorp/terraform-provider-azurerm/internal/services/customproviders/client" + dashboard "github.com/hashicorp/terraform-provider-azurerm/internal/services/dashboard/client" datamigration "github.com/hashicorp/terraform-provider-azurerm/internal/services/databasemigration/client" databoxedge "github.com/hashicorp/terraform-provider-azurerm/internal/services/databoxedge/client" databricks "github.com/hashicorp/terraform-provider-azurerm/internal/services/databricks/client" @@ -145,6 +146,7 @@ type Client struct { Cosmos *cosmosdb.Client CostManagement *costmanagement.Client CustomProviders *customproviders.Client + Dashboard *dashboard.Client DatabaseMigration *datamigration.Client DataBricks *databricks.Client DataboxEdge *databoxedge.Client @@ -260,6 +262,7 @@ func (client *Client) Build(ctx context.Context, o *common.ClientOptions) error client.Cosmos = cosmosdb.NewClient(o) client.CostManagement = costmanagement.NewClient(o) client.CustomProviders = customproviders.NewClient(o) + client.Dashboard = dashboard.NewClient(o) client.DatabaseMigration = datamigration.NewClient(o) client.DataBricks = databricks.NewClient(o) client.DataboxEdge = databoxedge.NewClient(o) diff --git a/internal/provider/services.go b/internal/provider/services.go index 84c85dc8d6e6..0ec8b1d41132 100644 --- a/internal/provider/services.go +++ b/internal/provider/services.go @@ -28,6 +28,7 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/services/cosmos" "github.com/hashicorp/terraform-provider-azurerm/internal/services/costmanagement" "github.com/hashicorp/terraform-provider-azurerm/internal/services/customproviders" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/dashboard" "github.com/hashicorp/terraform-provider-azurerm/internal/services/databasemigration" "github.com/hashicorp/terraform-provider-azurerm/internal/services/databoxedge" "github.com/hashicorp/terraform-provider-azurerm/internal/services/databricks" @@ -123,6 +124,7 @@ func SupportedTypedServices() []sdk.TypedServiceRegistration { consumption.Registration{}, containers.Registration{}, costmanagement.Registration{}, + dashboard.Registration{}, disks.Registration{}, domainservices.Registration{}, eventhub.Registration{}, @@ -169,6 +171,7 @@ func SupportedUntypedServices() []sdk.UntypedServiceRegistration { consumption.Registration{}, cosmos.Registration{}, customproviders.Registration{}, + dashboard.Registration{}, databricks.Registration{}, datadog.Registration{}, datafactory.Registration{}, diff --git a/internal/services/dashboard/client/client.go b/internal/services/dashboard/client/client.go new file mode 100644 index 000000000000..e6ade515621c --- /dev/null +++ b/internal/services/dashboard/client/client.go @@ -0,0 +1,20 @@ +package client + +import ( + "github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource" + "github.com/hashicorp/terraform-provider-azurerm/internal/common" +) + +type Client struct { + GrafanaResourceClient *grafanaresource.GrafanaResourceClient +} + +func NewClient(o *common.ClientOptions) *Client { + + grafanaResourceClient := grafanaresource.NewGrafanaResourceClientWithBaseURI(o.ResourceManagerEndpoint) + o.ConfigureClient(&grafanaResourceClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + GrafanaResourceClient: &grafanaResourceClient, + } +} diff --git a/internal/services/dashboard/dashboard_grafana_resource.go b/internal/services/dashboard/dashboard_grafana_resource.go new file mode 100644 index 000000000000..3ae860e973da --- /dev/null +++ b/internal/services/dashboard/dashboard_grafana_resource.go @@ -0,0 +1,433 @@ +package dashboard + +import ( + "context" + "fmt" + "regexp" + "time" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/identity" + + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" + "github.com/hashicorp/go-azure-helpers/resourcemanager/location" + + "github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type DashboardGrafanaModel struct { + Name string `tfschema:"name"` + ResourceGroupName string `tfschema:"resource_group_name"` + ApiKeyEnabled bool `tfschema:"api_key_enabled"` + AutoGeneratedDomainNameLabelScope grafanaresource.AutoGeneratedDomainNameLabelScope `tfschema:"auto_generated_domain_name_label_scope"` + DeterministicOutboundIPEnabled bool `tfschema:"deterministic_outbound_ip_enabled"` + Location string `tfschema:"location"` + PublicNetworkAccessEnabled bool `tfschema:"public_network_access_enabled"` + Sku string `tfschema:"sku"` + Tags map[string]string `tfschema:"tags"` + ZoneRedundancyEnabled bool `tfschema:"zone_redundancy_enabled"` + Endpoint string `tfschema:"endpoint"` + GrafanaVersion string `tfschema:"grafana_version"` + OutboundIPs []string `tfschema:"outbound_ip"` +} + +type DashboardGrafanaResource struct{} + +var _ sdk.ResourceWithUpdate = DashboardGrafanaResource{} + +func (r DashboardGrafanaResource) ResourceType() string { + return "azurerm_dashboard_grafana" +} + +func (r DashboardGrafanaResource) ModelObject() interface{} { + return &DashboardGrafanaModel{} +} + +func (r DashboardGrafanaResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return grafanaresource.ValidateGrafanaID +} + +func (r DashboardGrafanaResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: 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.ResourceGroupName(), + + "location": commonschema.Location(), + + "api_key_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "auto_generated_domain_name_label_scope": { + Type: pluginsdk.TypeString, + Optional: true, + Default: string(grafanaresource.AutoGeneratedDomainNameLabelScopeTenantReuse), + ValidateFunc: validation.StringInSlice([]string{ + string(grafanaresource.AutoGeneratedDomainNameLabelScopeTenantReuse), + }, false), + }, + + "deterministic_outbound_ip_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "identity": commonschema.SystemAssignedIdentityOptionalForceNew(), + + "public_network_access_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "sku": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + Default: "Standard", + ValidateFunc: validation.StringInSlice([]string{ + "Standard", + }, false), + }, + + "tags": commonschema.Tags(), + + "zone_redundancy_enabled": { + Type: pluginsdk.TypeBool, + ForceNew: true, + Optional: true, + Default: false, + }, + } +} + +func (r DashboardGrafanaResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "endpoint": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "grafana_version": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "outbound_ip": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + } +} + +func (r DashboardGrafanaResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + var model DashboardGrafanaModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + client := metadata.Client.Dashboard.GrafanaResourceClient + subscriptionId := metadata.Client.Account.SubscriptionId + id := grafanaresource.NewGrafanaID(subscriptionId, model.ResourceGroupName, model.Name) + existing, err := client.GrafanaGet(ctx, id) + if err != nil && !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for existing %s: %+v", id, err) + } + + if !response.WasNotFound(existing.HttpResponse) { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + + identityValue, err := expandLegacySystemAndUserAssignedMap(metadata.ResourceData.Get("identity").([]interface{})) + if err != nil { + return fmt.Errorf("expanding `identity`: %+v", err) + } + + apiKey := grafanaresource.ApiKeyDisabled + if model.ApiKeyEnabled { + apiKey = grafanaresource.ApiKeyEnabled + } + + deterministicOutboundIP := grafanaresource.DeterministicOutboundIPDisabled + if model.DeterministicOutboundIPEnabled { + deterministicOutboundIP = grafanaresource.DeterministicOutboundIPEnabled + } + + publicNetworkAccess := grafanaresource.PublicNetworkAccessDisabled + if model.PublicNetworkAccessEnabled { + publicNetworkAccess = grafanaresource.PublicNetworkAccessEnabled + } + + zoneRedundancy := grafanaresource.ZoneRedundancyDisabled + if model.ZoneRedundancyEnabled { + zoneRedundancy = grafanaresource.ZoneRedundancyEnabled + } + + properties := &grafanaresource.ManagedGrafana{ + Identity: identityValue, + Location: utils.String(location.Normalize(model.Location)), + Properties: &grafanaresource.ManagedGrafanaProperties{ + ApiKey: &apiKey, + AutoGeneratedDomainNameLabelScope: &model.AutoGeneratedDomainNameLabelScope, + DeterministicOutboundIP: &deterministicOutboundIP, + PublicNetworkAccess: &publicNetworkAccess, + ZoneRedundancy: &zoneRedundancy, + }, + Sku: &grafanaresource.ResourceSku{ + Name: model.Sku, + }, + Tags: &model.Tags, + } + + if err := client.GrafanaCreateThenPoll(ctx, id, *properties); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r DashboardGrafanaResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Dashboard.GrafanaResourceClient + + id, err := grafanaresource.ParseGrafanaID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model DashboardGrafanaModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + resp, err := client.GrafanaGet(ctx, *id) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", *id, err) + } + + properties := resp.Model + if properties == nil { + return fmt.Errorf("retrieving %s: properties was nil", id) + } + + if metadata.ResourceData.HasChange("api_key_enabled") { + apiKey := grafanaresource.ApiKeyDisabled + if model.ApiKeyEnabled { + apiKey = grafanaresource.ApiKeyEnabled + } + + properties.Properties.ApiKey = &apiKey + } + + if metadata.ResourceData.HasChange("auto_generated_domain_name_label_scope") { + properties.Properties.AutoGeneratedDomainNameLabelScope = &model.AutoGeneratedDomainNameLabelScope + } + + if metadata.ResourceData.HasChange("deterministic_outbound_ip_enabled") { + deterministicOutboundIP := grafanaresource.DeterministicOutboundIPDisabled + if model.DeterministicOutboundIPEnabled { + deterministicOutboundIP = grafanaresource.DeterministicOutboundIPEnabled + } + + properties.Properties.DeterministicOutboundIP = &deterministicOutboundIP + } + + if metadata.ResourceData.HasChange("public_network_access_enabled") { + publicNetworkAccess := grafanaresource.PublicNetworkAccessDisabled + if model.PublicNetworkAccessEnabled { + publicNetworkAccess = grafanaresource.PublicNetworkAccessEnabled + } + + properties.Properties.PublicNetworkAccess = &publicNetworkAccess + } + + properties.SystemData = nil + + if metadata.ResourceData.HasChange("tags") { + properties.Tags = &model.Tags + } + + if err := client.GrafanaCreateThenPoll(ctx, *id, *properties); err != nil { + return fmt.Errorf("updating %s: %+v", *id, err) + } + + return nil + }, + } +} + +func (r DashboardGrafanaResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Dashboard.GrafanaResourceClient + + id, err := grafanaresource.ParseGrafanaID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + resp, err := client.GrafanaGet(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return metadata.MarkAsGone(id) + } + + return fmt.Errorf("retrieving %s: %+v", *id, err) + } + + model := resp.Model + if model == nil { + return fmt.Errorf("retrieving %s: model was nil", id) + } + + state := DashboardGrafanaModel{ + Name: id.WorkspaceName, + ResourceGroupName: id.ResourceGroupName, + Location: location.NormalizeNilable(model.Location), + } + + identityValue, err := flattenLegacySystemAndUserAssignedMap(model.Identity) + if err != nil { + return fmt.Errorf("flattening `identity`: %+v", err) + } + + if err := metadata.ResourceData.Set("identity", identityValue); err != nil { + return fmt.Errorf("setting `identity`: %+v", err) + } + + if properties := model.Properties; properties != nil { + if properties.ApiKey != nil { + if *properties.ApiKey == grafanaresource.ApiKeyEnabled { + state.ApiKeyEnabled = true + } else { + state.ApiKeyEnabled = false + } + } + + if properties.AutoGeneratedDomainNameLabelScope != nil { + state.AutoGeneratedDomainNameLabelScope = *properties.AutoGeneratedDomainNameLabelScope + } + + if properties.DeterministicOutboundIP != nil { + if *properties.DeterministicOutboundIP == grafanaresource.DeterministicOutboundIPEnabled { + state.DeterministicOutboundIPEnabled = true + } else { + state.DeterministicOutboundIPEnabled = false + } + } + + if properties.Endpoint != nil { + state.Endpoint = *properties.Endpoint + } + + if properties.GrafanaVersion != nil { + state.GrafanaVersion = *properties.GrafanaVersion + } + + if properties.OutboundIPs != nil { + state.OutboundIPs = *properties.OutboundIPs + } + + if properties.PublicNetworkAccess != nil { + if *properties.PublicNetworkAccess == grafanaresource.PublicNetworkAccessEnabled { + state.PublicNetworkAccessEnabled = true + } else { + state.PublicNetworkAccessEnabled = false + } + } + + if properties.ZoneRedundancy != nil { + if *properties.ZoneRedundancy == grafanaresource.ZoneRedundancyEnabled { + state.ZoneRedundancyEnabled = true + } else { + state.ZoneRedundancyEnabled = false + } + } + } + + if model.Sku != nil { + state.Sku = model.Sku.Name + } + + if model.Tags != nil { + state.Tags = *model.Tags + } + + return metadata.Encode(&state) + }, + } +} + +func (r DashboardGrafanaResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Dashboard.GrafanaResourceClient + + id, err := grafanaresource.ParseGrafanaID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + if err := client.GrafanaDeleteThenPoll(ctx, *id); err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + return nil + }, + } +} + +func expandLegacySystemAndUserAssignedMap(input []interface{}) (*identity.LegacySystemAndUserAssignedMap, error) { + identityValue, err := identity.ExpandSystemAssigned(input) + if err != nil { + return nil, err + } + + return &identity.LegacySystemAndUserAssignedMap{ + Type: identityValue.Type, + }, nil +} + +func flattenLegacySystemAndUserAssignedMap(input *identity.LegacySystemAndUserAssignedMap) (*[]interface{}, error) { + if input == nil { + return &[]interface{}{}, nil + } + + identityValue := &identity.SystemAssigned{ + Type: input.Type, + PrincipalId: input.PrincipalId, + TenantId: input.TenantId, + } + + output := identity.FlattenSystemAssigned(identityValue) + return &output, nil +} diff --git a/internal/services/dashboard/dashboard_grafana_resource_test.go b/internal/services/dashboard/dashboard_grafana_resource_test.go new file mode 100644 index 000000000000..775f0fa9466e --- /dev/null +++ b/internal/services/dashboard/dashboard_grafana_resource_test.go @@ -0,0 +1,182 @@ +package dashboard_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource" + + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type DashboardGrafanaResource struct{} + +func TestAccDashboardGrafana_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_dashboard_grafana", "test") + r := DashboardGrafanaResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccDashboardGrafana_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_dashboard_grafana", "test") + r := DashboardGrafanaResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.RequiresImportErrorStep(r.requiresImport), + }) +} + +func TestAccDashboardGrafana_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_dashboard_grafana", "test") + r := DashboardGrafanaResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccDashboardGrafana_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_dashboard_grafana", "test") + r := DashboardGrafanaResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.update(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func (r DashboardGrafanaResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := grafanaresource.ParseGrafanaID(state.ID) + if err != nil { + return nil, err + } + + client := clients.Dashboard.GrafanaResourceClient + resp, err := client.GrafanaGet(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + return utils.Bool(resp.Model != nil), nil +} + +func (r DashboardGrafanaResource) template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctest-rg-%d" + location = "%s" +} +`, data.RandomInteger, data.Locations.Primary) +} + +func (r DashboardGrafanaResource) basic(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` + %s + +resource "azurerm_dashboard_grafana" "test" { + name = "a-dg-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location +} +`, template, data.RandomInteger) +} + +func (r DashboardGrafanaResource) requiresImport(data acceptance.TestData) string { + config := r.basic(data) + return fmt.Sprintf(` + %s + +resource "azurerm_dashboard_grafana" "import" { + name = azurerm_dashboard_grafana.test.name + resource_group_name = azurerm_dashboard_grafana.test.resource_group_name + location = azurerm_dashboard_grafana.test.location +} +`, config) +} + +func (r DashboardGrafanaResource) complete(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` + %s + +resource "azurerm_dashboard_grafana" "test" { + name = "a-dg-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + api_key_enabled = true + deterministic_outbound_ip_enabled = true + public_network_access_enabled = false + + identity { + type = "SystemAssigned" + } + + tags = { + key = "value" + } +} +`, template, data.RandomInteger) +} + +func (r DashboardGrafanaResource) update(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` + %s + +resource "azurerm_dashboard_grafana" "test" { + name = "a-dg-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + + identity { + type = "SystemAssigned" + } + + tags = { + key2 = "value2" + } +} +`, template, data.RandomInteger) +} diff --git a/internal/services/dashboard/registration.go b/internal/services/dashboard/registration.go new file mode 100644 index 000000000000..8ee47c4e3879 --- /dev/null +++ b/internal/services/dashboard/registration.go @@ -0,0 +1,51 @@ +package dashboard + +import ( + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" +) + +type Registration struct{} + +var ( + _ sdk.TypedServiceRegistrationWithAGitHubLabel = Registration{} + _ sdk.UntypedServiceRegistrationWithAGitHubLabel = Registration{} +) + +func (r Registration) AssociatedGitHubLabel() string { + return "service/dashboard" +} + +// Name is the name of this Service +func (r Registration) Name() string { + return "Dashboard" +} + +// WebsiteCategories returns a list of categories which can be used for the sidebar +func (r Registration) WebsiteCategories() []string { + return []string{ + "Dashboard", + } +} + +// SupportedDataSources returns the supported Data Sources supported by this Service +func (r Registration) SupportedDataSources() map[string]*pluginsdk.Resource { + return map[string]*pluginsdk.Resource{} +} + +// SupportedResources returns the supported Resources supported by this Service +func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { + return map[string]*pluginsdk.Resource{} +} + +// DataSources returns a list of Data Sources supported by this Service +func (r Registration) DataSources() []sdk.DataSource { + return []sdk.DataSource{} +} + +// Resources returns a list of Resources supported by this Service +func (r Registration) Resources() []sdk.Resource { + return []sdk.Resource{ + DashboardGrafanaResource{}, + } +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/automation/2021-06-22/automationaccount/README.md b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/automation/2021-06-22/automationaccount/README.md new file mode 100644 index 000000000000..f0e30e273d51 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/automation/2021-06-22/automationaccount/README.md @@ -0,0 +1,128 @@ + +## `github.com/hashicorp/go-azure-sdk/resource-manager/automation/2021-06-22/automationaccount` Documentation + +The `automationaccount` SDK allows for interaction with the Azure Resource Manager Service `automation` (API Version `2021-06-22`). + +This readme covers example usages, but further information on [using this SDK can be found in the project root](https://github.com/hashicorp/go-azure-sdk/tree/main/docs). + +### Import Path + +```go +import "github.com/hashicorp/go-azure-sdk/resource-manager/automation/2021-06-22/automationaccount" +``` + + +### Client Initialization + +```go +client := automationaccount.NewAutomationAccountClientWithBaseURI("https://management.azure.com") +client.Client.Authorizer = authorizer +``` + + +### Example Usage: `AutomationAccountClient.CreateOrUpdate` + +```go +ctx := context.TODO() +id := automationaccount.NewAutomationAccountID("12345678-1234-9876-4563-123456789012", "example-resource-group", "automationAccountValue") + +payload := automationaccount.AutomationAccountCreateOrUpdateParameters{ + // ... +} + + +read, err := client.CreateOrUpdate(ctx, id, payload) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` + + +### Example Usage: `AutomationAccountClient.Delete` + +```go +ctx := context.TODO() +id := automationaccount.NewAutomationAccountID("12345678-1234-9876-4563-123456789012", "example-resource-group", "automationAccountValue") + +read, err := client.Delete(ctx, id) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` + + +### Example Usage: `AutomationAccountClient.Get` + +```go +ctx := context.TODO() +id := automationaccount.NewAutomationAccountID("12345678-1234-9876-4563-123456789012", "example-resource-group", "automationAccountValue") + +read, err := client.Get(ctx, id) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` + + +### Example Usage: `AutomationAccountClient.List` + +```go +ctx := context.TODO() +id := automationaccount.NewSubscriptionID("12345678-1234-9876-4563-123456789012") + +// alternatively `client.List(ctx, id)` can be used to do batched pagination +items, err := client.ListComplete(ctx, id) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` + + +### Example Usage: `AutomationAccountClient.ListByResourceGroup` + +```go +ctx := context.TODO() +id := automationaccount.NewResourceGroupID("12345678-1234-9876-4563-123456789012", "example-resource-group") + +// alternatively `client.ListByResourceGroup(ctx, id)` can be used to do batched pagination +items, err := client.ListByResourceGroupComplete(ctx, id) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` + + +### Example Usage: `AutomationAccountClient.Update` + +```go +ctx := context.TODO() +id := automationaccount.NewAutomationAccountID("12345678-1234-9876-4563-123456789012", "example-resource-group", "automationAccountValue") + +payload := automationaccount.AutomationAccountUpdateParameters{ + // ... +} + + +read, err := client.Update(ctx, id, payload) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/README.md b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/README.md new file mode 100644 index 000000000000..6f2ef458cee5 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/README.md @@ -0,0 +1,120 @@ + +## `github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource` Documentation + +The `grafanaresource` SDK allows for interaction with the Azure Resource Manager Service `dashboard` (API Version `2022-08-01`). + +This readme covers example usages, but further information on [using this SDK can be found in the project root](https://github.com/hashicorp/go-azure-sdk/tree/main/docs). + +### Import Path + +```go +import "github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource" +``` + + +### Client Initialization + +```go +client := grafanaresource.NewGrafanaResourceClientWithBaseURI("https://management.azure.com") +client.Client.Authorizer = authorizer +``` + + +### Example Usage: `GrafanaResourceClient.GrafanaCreate` + +```go +ctx := context.TODO() +id := grafanaresource.NewGrafanaID("12345678-1234-9876-4563-123456789012", "example-resource-group", "workspaceValue") + +payload := grafanaresource.ManagedGrafana{ + // ... +} + + +if err := client.GrafanaCreateThenPoll(ctx, id, payload); err != nil { + // handle the error +} +``` + + +### Example Usage: `GrafanaResourceClient.GrafanaDelete` + +```go +ctx := context.TODO() +id := grafanaresource.NewGrafanaID("12345678-1234-9876-4563-123456789012", "example-resource-group", "workspaceValue") + +if err := client.GrafanaDeleteThenPoll(ctx, id); err != nil { + // handle the error +} +``` + + +### Example Usage: `GrafanaResourceClient.GrafanaGet` + +```go +ctx := context.TODO() +id := grafanaresource.NewGrafanaID("12345678-1234-9876-4563-123456789012", "example-resource-group", "workspaceValue") + +read, err := client.GrafanaGet(ctx, id) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` + + +### Example Usage: `GrafanaResourceClient.GrafanaList` + +```go +ctx := context.TODO() +id := grafanaresource.NewSubscriptionID("12345678-1234-9876-4563-123456789012") + +// alternatively `client.GrafanaList(ctx, id)` can be used to do batched pagination +items, err := client.GrafanaListComplete(ctx, id) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` + + +### Example Usage: `GrafanaResourceClient.GrafanaListByResourceGroup` + +```go +ctx := context.TODO() +id := grafanaresource.NewResourceGroupID("12345678-1234-9876-4563-123456789012", "example-resource-group") + +// alternatively `client.GrafanaListByResourceGroup(ctx, id)` can be used to do batched pagination +items, err := client.GrafanaListByResourceGroupComplete(ctx, id) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` + + +### Example Usage: `GrafanaResourceClient.GrafanaUpdate` + +```go +ctx := context.TODO() +id := grafanaresource.NewGrafanaID("12345678-1234-9876-4563-123456789012", "example-resource-group", "workspaceValue") + +payload := grafanaresource.ManagedGrafanaUpdateParameters{ + // ... +} + + +read, err := client.GrafanaUpdate(ctx, id, payload) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/client.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/client.go new file mode 100644 index 000000000000..94d7f05bb8b7 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/client.go @@ -0,0 +1,18 @@ +package grafanaresource + +import "github.com/Azure/go-autorest/autorest" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GrafanaResourceClient struct { + Client autorest.Client + baseUri string +} + +func NewGrafanaResourceClientWithBaseURI(endpoint string) GrafanaResourceClient { + return GrafanaResourceClient{ + Client: autorest.NewClientWithUserAgent(userAgent()), + baseUri: endpoint, + } +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/constants.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/constants.go new file mode 100644 index 000000000000..7cb4869eaf04 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/constants.go @@ -0,0 +1,257 @@ +package grafanaresource + +import "strings" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ApiKey string + +const ( + ApiKeyDisabled ApiKey = "Disabled" + ApiKeyEnabled ApiKey = "Enabled" +) + +func PossibleValuesForApiKey() []string { + return []string{ + string(ApiKeyDisabled), + string(ApiKeyEnabled), + } +} + +func parseApiKey(input string) (*ApiKey, error) { + vals := map[string]ApiKey{ + "disabled": ApiKeyDisabled, + "enabled": ApiKeyEnabled, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := ApiKey(input) + return &out, nil +} + +type AutoGeneratedDomainNameLabelScope string + +const ( + AutoGeneratedDomainNameLabelScopeTenantReuse AutoGeneratedDomainNameLabelScope = "TenantReuse" +) + +func PossibleValuesForAutoGeneratedDomainNameLabelScope() []string { + return []string{ + string(AutoGeneratedDomainNameLabelScopeTenantReuse), + } +} + +func parseAutoGeneratedDomainNameLabelScope(input string) (*AutoGeneratedDomainNameLabelScope, error) { + vals := map[string]AutoGeneratedDomainNameLabelScope{ + "tenantreuse": AutoGeneratedDomainNameLabelScopeTenantReuse, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := AutoGeneratedDomainNameLabelScope(input) + return &out, nil +} + +type DeterministicOutboundIP string + +const ( + DeterministicOutboundIPDisabled DeterministicOutboundIP = "Disabled" + DeterministicOutboundIPEnabled DeterministicOutboundIP = "Enabled" +) + +func PossibleValuesForDeterministicOutboundIP() []string { + return []string{ + string(DeterministicOutboundIPDisabled), + string(DeterministicOutboundIPEnabled), + } +} + +func parseDeterministicOutboundIP(input string) (*DeterministicOutboundIP, error) { + vals := map[string]DeterministicOutboundIP{ + "disabled": DeterministicOutboundIPDisabled, + "enabled": DeterministicOutboundIPEnabled, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := DeterministicOutboundIP(input) + return &out, nil +} + +type PrivateEndpointConnectionProvisioningState string + +const ( + PrivateEndpointConnectionProvisioningStateCreating PrivateEndpointConnectionProvisioningState = "Creating" + PrivateEndpointConnectionProvisioningStateDeleting PrivateEndpointConnectionProvisioningState = "Deleting" + PrivateEndpointConnectionProvisioningStateFailed PrivateEndpointConnectionProvisioningState = "Failed" + PrivateEndpointConnectionProvisioningStateSucceeded PrivateEndpointConnectionProvisioningState = "Succeeded" +) + +func PossibleValuesForPrivateEndpointConnectionProvisioningState() []string { + return []string{ + string(PrivateEndpointConnectionProvisioningStateCreating), + string(PrivateEndpointConnectionProvisioningStateDeleting), + string(PrivateEndpointConnectionProvisioningStateFailed), + string(PrivateEndpointConnectionProvisioningStateSucceeded), + } +} + +func parsePrivateEndpointConnectionProvisioningState(input string) (*PrivateEndpointConnectionProvisioningState, error) { + vals := map[string]PrivateEndpointConnectionProvisioningState{ + "creating": PrivateEndpointConnectionProvisioningStateCreating, + "deleting": PrivateEndpointConnectionProvisioningStateDeleting, + "failed": PrivateEndpointConnectionProvisioningStateFailed, + "succeeded": PrivateEndpointConnectionProvisioningStateSucceeded, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := PrivateEndpointConnectionProvisioningState(input) + return &out, nil +} + +type PrivateEndpointServiceConnectionStatus string + +const ( + PrivateEndpointServiceConnectionStatusApproved PrivateEndpointServiceConnectionStatus = "Approved" + PrivateEndpointServiceConnectionStatusPending PrivateEndpointServiceConnectionStatus = "Pending" + PrivateEndpointServiceConnectionStatusRejected PrivateEndpointServiceConnectionStatus = "Rejected" +) + +func PossibleValuesForPrivateEndpointServiceConnectionStatus() []string { + return []string{ + string(PrivateEndpointServiceConnectionStatusApproved), + string(PrivateEndpointServiceConnectionStatusPending), + string(PrivateEndpointServiceConnectionStatusRejected), + } +} + +func parsePrivateEndpointServiceConnectionStatus(input string) (*PrivateEndpointServiceConnectionStatus, error) { + vals := map[string]PrivateEndpointServiceConnectionStatus{ + "approved": PrivateEndpointServiceConnectionStatusApproved, + "pending": PrivateEndpointServiceConnectionStatusPending, + "rejected": PrivateEndpointServiceConnectionStatusRejected, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := PrivateEndpointServiceConnectionStatus(input) + return &out, nil +} + +type ProvisioningState string + +const ( + ProvisioningStateAccepted ProvisioningState = "Accepted" + ProvisioningStateCanceled ProvisioningState = "Canceled" + ProvisioningStateCreating ProvisioningState = "Creating" + ProvisioningStateDeleted ProvisioningState = "Deleted" + ProvisioningStateDeleting ProvisioningState = "Deleting" + ProvisioningStateFailed ProvisioningState = "Failed" + ProvisioningStateNotSpecified ProvisioningState = "NotSpecified" + ProvisioningStateSucceeded ProvisioningState = "Succeeded" + ProvisioningStateUpdating ProvisioningState = "Updating" +) + +func PossibleValuesForProvisioningState() []string { + return []string{ + string(ProvisioningStateAccepted), + string(ProvisioningStateCanceled), + string(ProvisioningStateCreating), + string(ProvisioningStateDeleted), + string(ProvisioningStateDeleting), + string(ProvisioningStateFailed), + string(ProvisioningStateNotSpecified), + string(ProvisioningStateSucceeded), + string(ProvisioningStateUpdating), + } +} + +func parseProvisioningState(input string) (*ProvisioningState, error) { + vals := map[string]ProvisioningState{ + "accepted": ProvisioningStateAccepted, + "canceled": ProvisioningStateCanceled, + "creating": ProvisioningStateCreating, + "deleted": ProvisioningStateDeleted, + "deleting": ProvisioningStateDeleting, + "failed": ProvisioningStateFailed, + "notspecified": ProvisioningStateNotSpecified, + "succeeded": ProvisioningStateSucceeded, + "updating": ProvisioningStateUpdating, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := ProvisioningState(input) + return &out, nil +} + +type PublicNetworkAccess string + +const ( + PublicNetworkAccessDisabled PublicNetworkAccess = "Disabled" + PublicNetworkAccessEnabled PublicNetworkAccess = "Enabled" +) + +func PossibleValuesForPublicNetworkAccess() []string { + return []string{ + string(PublicNetworkAccessDisabled), + string(PublicNetworkAccessEnabled), + } +} + +func parsePublicNetworkAccess(input string) (*PublicNetworkAccess, error) { + vals := map[string]PublicNetworkAccess{ + "disabled": PublicNetworkAccessDisabled, + "enabled": PublicNetworkAccessEnabled, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := PublicNetworkAccess(input) + return &out, nil +} + +type ZoneRedundancy string + +const ( + ZoneRedundancyDisabled ZoneRedundancy = "Disabled" + ZoneRedundancyEnabled ZoneRedundancy = "Enabled" +) + +func PossibleValuesForZoneRedundancy() []string { + return []string{ + string(ZoneRedundancyDisabled), + string(ZoneRedundancyEnabled), + } +} + +func parseZoneRedundancy(input string) (*ZoneRedundancy, error) { + vals := map[string]ZoneRedundancy{ + "disabled": ZoneRedundancyDisabled, + "enabled": ZoneRedundancyEnabled, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := ZoneRedundancy(input) + return &out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/id_grafana.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/id_grafana.go new file mode 100644 index 000000000000..c23f68127beb --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/id_grafana.go @@ -0,0 +1,124 @@ +package grafanaresource + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.ResourceId = GrafanaId{} + +// GrafanaId is a struct representing the Resource ID for a Grafana +type GrafanaId struct { + SubscriptionId string + ResourceGroupName string + WorkspaceName string +} + +// NewGrafanaID returns a new GrafanaId struct +func NewGrafanaID(subscriptionId string, resourceGroupName string, workspaceName string) GrafanaId { + return GrafanaId{ + SubscriptionId: subscriptionId, + ResourceGroupName: resourceGroupName, + WorkspaceName: workspaceName, + } +} + +// ParseGrafanaID parses 'input' into a GrafanaId +func ParseGrafanaID(input string) (*GrafanaId, error) { + parser := resourceids.NewParserFromResourceIdType(GrafanaId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := GrafanaId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, fmt.Errorf("the segment 'subscriptionId' was not found in the resource id %q", input) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, fmt.Errorf("the segment 'resourceGroupName' was not found in the resource id %q", input) + } + + if id.WorkspaceName, ok = parsed.Parsed["workspaceName"]; !ok { + return nil, fmt.Errorf("the segment 'workspaceName' was not found in the resource id %q", input) + } + + return &id, nil +} + +// ParseGrafanaIDInsensitively parses 'input' case-insensitively into a GrafanaId +// note: this method should only be used for API response data and not user input +func ParseGrafanaIDInsensitively(input string) (*GrafanaId, error) { + parser := resourceids.NewParserFromResourceIdType(GrafanaId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := GrafanaId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, fmt.Errorf("the segment 'subscriptionId' was not found in the resource id %q", input) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, fmt.Errorf("the segment 'resourceGroupName' was not found in the resource id %q", input) + } + + if id.WorkspaceName, ok = parsed.Parsed["workspaceName"]; !ok { + return nil, fmt.Errorf("the segment 'workspaceName' was not found in the resource id %q", input) + } + + return &id, nil +} + +// ValidateGrafanaID checks that 'input' can be parsed as a Grafana ID +func ValidateGrafanaID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := ParseGrafanaID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Grafana ID +func (id GrafanaId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Dashboard/grafana/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroupName, id.WorkspaceName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Grafana ID +func (id GrafanaId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("staticSubscriptions", "subscriptions", "subscriptions"), + resourceids.SubscriptionIdSegment("subscriptionId", "12345678-1234-9876-4563-123456789012"), + resourceids.StaticSegment("staticResourceGroups", "resourceGroups", "resourceGroups"), + resourceids.ResourceGroupSegment("resourceGroupName", "example-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftDashboard", "Microsoft.Dashboard", "Microsoft.Dashboard"), + resourceids.StaticSegment("staticGrafana", "grafana", "grafana"), + resourceids.UserSpecifiedSegment("workspaceName", "workspaceValue"), + } +} + +// String returns a human-readable description of this Grafana ID +func (id GrafanaId) String() string { + components := []string{ + fmt.Sprintf("Subscription: %q", id.SubscriptionId), + fmt.Sprintf("Resource Group Name: %q", id.ResourceGroupName), + fmt.Sprintf("Workspace Name: %q", id.WorkspaceName), + } + return fmt.Sprintf("Grafana (%s)", strings.Join(components, "\n")) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanacreate_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanacreate_autorest.go new file mode 100644 index 000000000000..1457c8391957 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanacreate_autorest.go @@ -0,0 +1,79 @@ +package grafanaresource + +import ( + "context" + "fmt" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/polling" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GrafanaCreateOperationResponse struct { + Poller polling.LongRunningPoller + HttpResponse *http.Response +} + +// GrafanaCreate ... +func (c GrafanaResourceClient) GrafanaCreate(ctx context.Context, id GrafanaId, input ManagedGrafana) (result GrafanaCreateOperationResponse, err error) { + req, err := c.preparerForGrafanaCreate(ctx, id, input) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaCreate", nil, "Failure preparing request") + return + } + + result, err = c.senderForGrafanaCreate(ctx, req) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaCreate", result.HttpResponse, "Failure sending request") + return + } + + return +} + +// GrafanaCreateThenPoll performs GrafanaCreate then polls until it's completed +func (c GrafanaResourceClient) GrafanaCreateThenPoll(ctx context.Context, id GrafanaId, input ManagedGrafana) error { + result, err := c.GrafanaCreate(ctx, id, input) + if err != nil { + return fmt.Errorf("performing GrafanaCreate: %+v", err) + } + + if err := result.Poller.PollUntilDone(); err != nil { + return fmt.Errorf("polling after GrafanaCreate: %+v", err) + } + + return nil +} + +// preparerForGrafanaCreate prepares the GrafanaCreate request. +func (c GrafanaResourceClient) preparerForGrafanaCreate(ctx context.Context, id GrafanaId, input ManagedGrafana) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithJSON(input), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// senderForGrafanaCreate sends the GrafanaCreate request. The method will close the +// http.Response Body if it receives an error. +func (c GrafanaResourceClient) senderForGrafanaCreate(ctx context.Context, req *http.Request) (future GrafanaCreateOperationResponse, err error) { + var resp *http.Response + resp, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + return + } + + future.Poller, err = polling.NewPollerFromResponse(ctx, resp, c.Client, req.Method) + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanadelete_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanadelete_autorest.go new file mode 100644 index 000000000000..745efacd8898 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanadelete_autorest.go @@ -0,0 +1,78 @@ +package grafanaresource + +import ( + "context" + "fmt" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/polling" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GrafanaDeleteOperationResponse struct { + Poller polling.LongRunningPoller + HttpResponse *http.Response +} + +// GrafanaDelete ... +func (c GrafanaResourceClient) GrafanaDelete(ctx context.Context, id GrafanaId) (result GrafanaDeleteOperationResponse, err error) { + req, err := c.preparerForGrafanaDelete(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaDelete", nil, "Failure preparing request") + return + } + + result, err = c.senderForGrafanaDelete(ctx, req) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaDelete", result.HttpResponse, "Failure sending request") + return + } + + return +} + +// GrafanaDeleteThenPoll performs GrafanaDelete then polls until it's completed +func (c GrafanaResourceClient) GrafanaDeleteThenPoll(ctx context.Context, id GrafanaId) error { + result, err := c.GrafanaDelete(ctx, id) + if err != nil { + return fmt.Errorf("performing GrafanaDelete: %+v", err) + } + + if err := result.Poller.PollUntilDone(); err != nil { + return fmt.Errorf("polling after GrafanaDelete: %+v", err) + } + + return nil +} + +// preparerForGrafanaDelete prepares the GrafanaDelete request. +func (c GrafanaResourceClient) preparerForGrafanaDelete(ctx context.Context, id GrafanaId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsDelete(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// senderForGrafanaDelete sends the GrafanaDelete request. The method will close the +// http.Response Body if it receives an error. +func (c GrafanaResourceClient) senderForGrafanaDelete(ctx context.Context, req *http.Request) (future GrafanaDeleteOperationResponse, err error) { + var resp *http.Response + resp, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + return + } + + future.Poller, err = polling.NewPollerFromResponse(ctx, resp, c.Client, req.Method) + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanaget_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanaget_autorest.go new file mode 100644 index 000000000000..892abefed3be --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanaget_autorest.go @@ -0,0 +1,67 @@ +package grafanaresource + +import ( + "context" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GrafanaGetOperationResponse struct { + HttpResponse *http.Response + Model *ManagedGrafana +} + +// GrafanaGet ... +func (c GrafanaResourceClient) GrafanaGet(ctx context.Context, id GrafanaId) (result GrafanaGetOperationResponse, err error) { + req, err := c.preparerForGrafanaGet(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaGet", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaGet", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForGrafanaGet(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaGet", result.HttpResponse, "Failure responding to request") + return + } + + return +} + +// preparerForGrafanaGet prepares the GrafanaGet request. +func (c GrafanaResourceClient) preparerForGrafanaGet(ctx context.Context, id GrafanaId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForGrafanaGet handles the response to the GrafanaGet request. The method always +// closes the http.Response Body. +func (c GrafanaResourceClient) responderForGrafanaGet(resp *http.Response) (result GrafanaGetOperationResponse, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Model), + autorest.ByClosing()) + result.HttpResponse = resp + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanalist_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanalist_autorest.go new file mode 100644 index 000000000000..5f525cdc7e22 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanalist_autorest.go @@ -0,0 +1,187 @@ +package grafanaresource + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GrafanaListOperationResponse struct { + HttpResponse *http.Response + Model *[]ManagedGrafana + + nextLink *string + nextPageFunc func(ctx context.Context, nextLink string) (GrafanaListOperationResponse, error) +} + +type GrafanaListCompleteResult struct { + Items []ManagedGrafana +} + +func (r GrafanaListOperationResponse) HasMore() bool { + return r.nextLink != nil +} + +func (r GrafanaListOperationResponse) LoadMore(ctx context.Context) (resp GrafanaListOperationResponse, err error) { + if !r.HasMore() { + err = fmt.Errorf("no more pages returned") + return + } + return r.nextPageFunc(ctx, *r.nextLink) +} + +// GrafanaList ... +func (c GrafanaResourceClient) GrafanaList(ctx context.Context, id commonids.SubscriptionId) (resp GrafanaListOperationResponse, err error) { + req, err := c.preparerForGrafanaList(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaList", nil, "Failure preparing request") + return + } + + resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaList", resp.HttpResponse, "Failure sending request") + return + } + + resp, err = c.responderForGrafanaList(resp.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaList", resp.HttpResponse, "Failure responding to request") + return + } + return +} + +// GrafanaListComplete retrieves all of the results into a single object +func (c GrafanaResourceClient) GrafanaListComplete(ctx context.Context, id commonids.SubscriptionId) (GrafanaListCompleteResult, error) { + return c.GrafanaListCompleteMatchingPredicate(ctx, id, ManagedGrafanaOperationPredicate{}) +} + +// GrafanaListCompleteMatchingPredicate retrieves all of the results and then applied the predicate +func (c GrafanaResourceClient) GrafanaListCompleteMatchingPredicate(ctx context.Context, id commonids.SubscriptionId, predicate ManagedGrafanaOperationPredicate) (resp GrafanaListCompleteResult, err error) { + items := make([]ManagedGrafana, 0) + + page, err := c.GrafanaList(ctx, id) + if err != nil { + err = fmt.Errorf("loading the initial page: %+v", err) + return + } + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + for page.HasMore() { + page, err = page.LoadMore(ctx) + if err != nil { + err = fmt.Errorf("loading the next page: %+v", err) + return + } + + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + } + + out := GrafanaListCompleteResult{ + Items: items, + } + return out, nil +} + +// preparerForGrafanaList prepares the GrafanaList request. +func (c GrafanaResourceClient) preparerForGrafanaList(ctx context.Context, id commonids.SubscriptionId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(fmt.Sprintf("%s/providers/Microsoft.Dashboard/grafana", id.ID())), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// preparerForGrafanaListWithNextLink prepares the GrafanaList request with the given nextLink token. +func (c GrafanaResourceClient) preparerForGrafanaListWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { + uri, err := url.Parse(nextLink) + if err != nil { + return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) + } + queryParameters := map[string]interface{}{} + for k, v := range uri.Query() { + if len(v) == 0 { + continue + } + val := v[0] + val = autorest.Encode("query", val) + queryParameters[k] = val + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(uri.Path), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForGrafanaList handles the response to the GrafanaList request. The method always +// closes the http.Response Body. +func (c GrafanaResourceClient) responderForGrafanaList(resp *http.Response) (result GrafanaListOperationResponse, err error) { + type page struct { + Values []ManagedGrafana `json:"value"` + NextLink *string `json:"nextLink"` + } + var respObj page + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&respObj), + autorest.ByClosing()) + result.HttpResponse = resp + result.Model = &respObj.Values + result.nextLink = respObj.NextLink + if respObj.NextLink != nil { + result.nextPageFunc = func(ctx context.Context, nextLink string) (result GrafanaListOperationResponse, err error) { + req, err := c.preparerForGrafanaListWithNextLink(ctx, nextLink) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaList", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaList", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForGrafanaList(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaList", result.HttpResponse, "Failure responding to request") + return + } + + return + } + } + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanalistbyresourcegroup_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanalistbyresourcegroup_autorest.go new file mode 100644 index 000000000000..f16364e69abe --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanalistbyresourcegroup_autorest.go @@ -0,0 +1,187 @@ +package grafanaresource + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GrafanaListByResourceGroupOperationResponse struct { + HttpResponse *http.Response + Model *[]ManagedGrafana + + nextLink *string + nextPageFunc func(ctx context.Context, nextLink string) (GrafanaListByResourceGroupOperationResponse, error) +} + +type GrafanaListByResourceGroupCompleteResult struct { + Items []ManagedGrafana +} + +func (r GrafanaListByResourceGroupOperationResponse) HasMore() bool { + return r.nextLink != nil +} + +func (r GrafanaListByResourceGroupOperationResponse) LoadMore(ctx context.Context) (resp GrafanaListByResourceGroupOperationResponse, err error) { + if !r.HasMore() { + err = fmt.Errorf("no more pages returned") + return + } + return r.nextPageFunc(ctx, *r.nextLink) +} + +// GrafanaListByResourceGroup ... +func (c GrafanaResourceClient) GrafanaListByResourceGroup(ctx context.Context, id commonids.ResourceGroupId) (resp GrafanaListByResourceGroupOperationResponse, err error) { + req, err := c.preparerForGrafanaListByResourceGroup(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaListByResourceGroup", nil, "Failure preparing request") + return + } + + resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaListByResourceGroup", resp.HttpResponse, "Failure sending request") + return + } + + resp, err = c.responderForGrafanaListByResourceGroup(resp.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaListByResourceGroup", resp.HttpResponse, "Failure responding to request") + return + } + return +} + +// GrafanaListByResourceGroupComplete retrieves all of the results into a single object +func (c GrafanaResourceClient) GrafanaListByResourceGroupComplete(ctx context.Context, id commonids.ResourceGroupId) (GrafanaListByResourceGroupCompleteResult, error) { + return c.GrafanaListByResourceGroupCompleteMatchingPredicate(ctx, id, ManagedGrafanaOperationPredicate{}) +} + +// GrafanaListByResourceGroupCompleteMatchingPredicate retrieves all of the results and then applied the predicate +func (c GrafanaResourceClient) GrafanaListByResourceGroupCompleteMatchingPredicate(ctx context.Context, id commonids.ResourceGroupId, predicate ManagedGrafanaOperationPredicate) (resp GrafanaListByResourceGroupCompleteResult, err error) { + items := make([]ManagedGrafana, 0) + + page, err := c.GrafanaListByResourceGroup(ctx, id) + if err != nil { + err = fmt.Errorf("loading the initial page: %+v", err) + return + } + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + for page.HasMore() { + page, err = page.LoadMore(ctx) + if err != nil { + err = fmt.Errorf("loading the next page: %+v", err) + return + } + + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + } + + out := GrafanaListByResourceGroupCompleteResult{ + Items: items, + } + return out, nil +} + +// preparerForGrafanaListByResourceGroup prepares the GrafanaListByResourceGroup request. +func (c GrafanaResourceClient) preparerForGrafanaListByResourceGroup(ctx context.Context, id commonids.ResourceGroupId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(fmt.Sprintf("%s/providers/Microsoft.Dashboard/grafana", id.ID())), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// preparerForGrafanaListByResourceGroupWithNextLink prepares the GrafanaListByResourceGroup request with the given nextLink token. +func (c GrafanaResourceClient) preparerForGrafanaListByResourceGroupWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { + uri, err := url.Parse(nextLink) + if err != nil { + return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) + } + queryParameters := map[string]interface{}{} + for k, v := range uri.Query() { + if len(v) == 0 { + continue + } + val := v[0] + val = autorest.Encode("query", val) + queryParameters[k] = val + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(uri.Path), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForGrafanaListByResourceGroup handles the response to the GrafanaListByResourceGroup request. The method always +// closes the http.Response Body. +func (c GrafanaResourceClient) responderForGrafanaListByResourceGroup(resp *http.Response) (result GrafanaListByResourceGroupOperationResponse, err error) { + type page struct { + Values []ManagedGrafana `json:"value"` + NextLink *string `json:"nextLink"` + } + var respObj page + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&respObj), + autorest.ByClosing()) + result.HttpResponse = resp + result.Model = &respObj.Values + result.nextLink = respObj.NextLink + if respObj.NextLink != nil { + result.nextPageFunc = func(ctx context.Context, nextLink string) (result GrafanaListByResourceGroupOperationResponse, err error) { + req, err := c.preparerForGrafanaListByResourceGroupWithNextLink(ctx, nextLink) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaListByResourceGroup", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaListByResourceGroup", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForGrafanaListByResourceGroup(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaListByResourceGroup", result.HttpResponse, "Failure responding to request") + return + } + + return + } + } + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanaupdate_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanaupdate_autorest.go new file mode 100644 index 000000000000..0f5e1b737ac1 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/method_grafanaupdate_autorest.go @@ -0,0 +1,68 @@ +package grafanaresource + +import ( + "context" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GrafanaUpdateOperationResponse struct { + HttpResponse *http.Response + Model *ManagedGrafana +} + +// GrafanaUpdate ... +func (c GrafanaResourceClient) GrafanaUpdate(ctx context.Context, id GrafanaId, input ManagedGrafanaUpdateParameters) (result GrafanaUpdateOperationResponse, err error) { + req, err := c.preparerForGrafanaUpdate(ctx, id, input) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaUpdate", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaUpdate", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForGrafanaUpdate(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "grafanaresource.GrafanaResourceClient", "GrafanaUpdate", result.HttpResponse, "Failure responding to request") + return + } + + return +} + +// preparerForGrafanaUpdate prepares the GrafanaUpdate request. +func (c GrafanaResourceClient) preparerForGrafanaUpdate(ctx context.Context, id GrafanaId, input ManagedGrafanaUpdateParameters) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPatch(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithJSON(input), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForGrafanaUpdate handles the response to the GrafanaUpdate request. The method always +// closes the http.Response Body. +func (c GrafanaResourceClient) responderForGrafanaUpdate(resp *http.Response) (result GrafanaUpdateOperationResponse, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Model), + autorest.ByClosing()) + result.HttpResponse = resp + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafana.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafana.go new file mode 100644 index 000000000000..a4866e11e9da --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafana.go @@ -0,0 +1,21 @@ +package grafanaresource + +import ( + "github.com/hashicorp/go-azure-helpers/resourcemanager/identity" + "github.com/hashicorp/go-azure-helpers/resourcemanager/systemdata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ManagedGrafana struct { + Id *string `json:"id,omitempty"` + Identity *identity.LegacySystemAndUserAssignedMap `json:"identity,omitempty"` + Location *string `json:"location,omitempty"` + Name *string `json:"name,omitempty"` + Properties *ManagedGrafanaProperties `json:"properties,omitempty"` + Sku *ResourceSku `json:"sku,omitempty"` + SystemData *systemdata.SystemData `json:"systemData,omitempty"` + Tags *map[string]string `json:"tags,omitempty"` + Type *string `json:"type,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafanaproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafanaproperties.go new file mode 100644 index 000000000000..64785964604f --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafanaproperties.go @@ -0,0 +1,17 @@ +package grafanaresource + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ManagedGrafanaProperties struct { + ApiKey *ApiKey `json:"apiKey,omitempty"` + AutoGeneratedDomainNameLabelScope *AutoGeneratedDomainNameLabelScope `json:"autoGeneratedDomainNameLabelScope,omitempty"` + DeterministicOutboundIP *DeterministicOutboundIP `json:"deterministicOutboundIP,omitempty"` + Endpoint *string `json:"endpoint,omitempty"` + GrafanaVersion *string `json:"grafanaVersion,omitempty"` + OutboundIPs *[]string `json:"outboundIPs,omitempty"` + PrivateEndpointConnections *[]PrivateEndpointConnection `json:"privateEndpointConnections,omitempty"` + ProvisioningState *ProvisioningState `json:"provisioningState,omitempty"` + PublicNetworkAccess *PublicNetworkAccess `json:"publicNetworkAccess,omitempty"` + ZoneRedundancy *ZoneRedundancy `json:"zoneRedundancy,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafanapropertiesupdateparameters.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafanapropertiesupdateparameters.go new file mode 100644 index 000000000000..d5ca9077501d --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafanapropertiesupdateparameters.go @@ -0,0 +1,11 @@ +package grafanaresource + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ManagedGrafanaPropertiesUpdateParameters struct { + ApiKey *ApiKey `json:"apiKey,omitempty"` + DeterministicOutboundIP *DeterministicOutboundIP `json:"deterministicOutboundIP,omitempty"` + PublicNetworkAccess *PublicNetworkAccess `json:"publicNetworkAccess,omitempty"` + ZoneRedundancy *ZoneRedundancy `json:"zoneRedundancy,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafanaupdateparameters.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafanaupdateparameters.go new file mode 100644 index 000000000000..14141c5da2b2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_managedgrafanaupdateparameters.go @@ -0,0 +1,14 @@ +package grafanaresource + +import ( + "github.com/hashicorp/go-azure-helpers/resourcemanager/identity" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ManagedGrafanaUpdateParameters struct { + Identity *identity.LegacySystemAndUserAssignedMap `json:"identity,omitempty"` + Properties *ManagedGrafanaPropertiesUpdateParameters `json:"properties,omitempty"` + Tags *map[string]string `json:"tags,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privateendpoint.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privateendpoint.go new file mode 100644 index 000000000000..10e98b0bb2f0 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privateendpoint.go @@ -0,0 +1,8 @@ +package grafanaresource + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type PrivateEndpoint struct { + Id *string `json:"id,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privateendpointconnection.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privateendpointconnection.go new file mode 100644 index 000000000000..fd33336690f8 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privateendpointconnection.go @@ -0,0 +1,16 @@ +package grafanaresource + +import ( + "github.com/hashicorp/go-azure-helpers/resourcemanager/systemdata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type PrivateEndpointConnection struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Properties *PrivateEndpointConnectionProperties `json:"properties,omitempty"` + SystemData *systemdata.SystemData `json:"systemData,omitempty"` + Type *string `json:"type,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privateendpointconnectionproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privateendpointconnectionproperties.go new file mode 100644 index 000000000000..68afbda6939a --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privateendpointconnectionproperties.go @@ -0,0 +1,11 @@ +package grafanaresource + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type PrivateEndpointConnectionProperties struct { + GroupIds *[]string `json:"groupIds,omitempty"` + PrivateEndpoint *PrivateEndpoint `json:"privateEndpoint,omitempty"` + PrivateLinkServiceConnectionState PrivateLinkServiceConnectionState `json:"privateLinkServiceConnectionState"` + ProvisioningState *PrivateEndpointConnectionProvisioningState `json:"provisioningState,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privatelinkserviceconnectionstate.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privatelinkserviceconnectionstate.go new file mode 100644 index 000000000000..d61484a01663 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_privatelinkserviceconnectionstate.go @@ -0,0 +1,10 @@ +package grafanaresource + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type PrivateLinkServiceConnectionState struct { + ActionsRequired *string `json:"actionsRequired,omitempty"` + Description *string `json:"description,omitempty"` + Status *PrivateEndpointServiceConnectionStatus `json:"status,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_resourcesku.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_resourcesku.go new file mode 100644 index 000000000000..96839106d856 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/model_resourcesku.go @@ -0,0 +1,8 @@ +package grafanaresource + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ResourceSku struct { + Name string `json:"name"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/predicates.go new file mode 100644 index 000000000000..9666e9093d39 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/predicates.go @@ -0,0 +1,29 @@ +package grafanaresource + +type ManagedGrafanaOperationPredicate struct { + Id *string + Location *string + Name *string + Type *string +} + +func (p ManagedGrafanaOperationPredicate) Matches(input ManagedGrafana) bool { + + if p.Id != nil && (input.Id == nil && *p.Id != *input.Id) { + return false + } + + if p.Location != nil && (input.Location == nil && *p.Location != *input.Location) { + return false + } + + if p.Name != nil && (input.Name == nil && *p.Name != *input.Name) { + return false + } + + if p.Type != nil && (input.Type == nil && *p.Type != *input.Type) { + return false + } + + return true +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/version.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/version.go new file mode 100644 index 000000000000..f452602c04d2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource/version.go @@ -0,0 +1,12 @@ +package grafanaresource + +import "fmt" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +const defaultApiVersion = "2022-08-01" + +func userAgent() string { + return fmt.Sprintf("hashicorp/go-azure-sdk/grafanaresource/%s", defaultApiVersion) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 258d5d221c3a..14c8ddc9d596 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -191,7 +191,7 @@ github.com/hashicorp/go-azure-helpers/resourcemanager/zones github.com/hashicorp/go-azure-helpers/resourceproviders github.com/hashicorp/go-azure-helpers/sender github.com/hashicorp/go-azure-helpers/storage -# github.com/hashicorp/go-azure-sdk v0.20220725.1163004 +# github.com/hashicorp/go-azure-sdk v0.20220728.1092823 ## explicit; go 1.18 github.com/hashicorp/go-azure-sdk/resource-manager/aad/2020-01-01/domainservices github.com/hashicorp/go-azure-sdk/resource-manager/aadb2c/2021-04-01-preview/tenants @@ -208,6 +208,7 @@ github.com/hashicorp/go-azure-sdk/resource-manager/compute/2021-11-01/availabili github.com/hashicorp/go-azure-sdk/resource-manager/compute/2021-11-01/sshpublickeys github.com/hashicorp/go-azure-sdk/resource-manager/confidentialledger/2022-05-13/confidentialledger github.com/hashicorp/go-azure-sdk/resource-manager/containerinstance/2021-03-01/containerinstance +github.com/hashicorp/go-azure-sdk/resource-manager/dashboard/2022-08-01/grafanaresource github.com/hashicorp/go-azure-sdk/resource-manager/databricks/2021-04-01-preview/workspaces github.com/hashicorp/go-azure-sdk/resource-manager/dataprotection/2022-04-01/resourceguards github.com/hashicorp/go-azure-sdk/resource-manager/desktopvirtualization/2021-09-03-preview/application diff --git a/website/allowed-subcategories b/website/allowed-subcategories index 15fce44777d5..df60f78c3333 100644 --- a/website/allowed-subcategories +++ b/website/allowed-subcategories @@ -27,6 +27,7 @@ CosmosDB (DocumentDB) Cost Management Custom Providers DNS +Dashboard Data Explorer Data Factory Data Share diff --git a/website/docs/r/dashboard_grafana.html.markdown b/website/docs/r/dashboard_grafana.html.markdown new file mode 100644 index 000000000000..39121edf62fd --- /dev/null +++ b/website/docs/r/dashboard_grafana.html.markdown @@ -0,0 +1,108 @@ +--- +subcategory: "Dashboard" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_dashboard_grafana" +description: |- + Manages a Dashboard Grafana. +--- + +# azurerm_dashboard_grafana + +Manages a Dashboard Grafana. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_dashboard_grafana" "example" { + name = "example-dg" + resource_group_name = azurerm_resource_group.example.name + location = "West Europe" + api_key_enabled = true + deterministic_outbound_ip_enabled = true + public_network_access_enabled = false + + identity { + type = "SystemAssigned" + } + + tags = { + key = "value" + } +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name which should be used for this Dashboard Grafana. Changing this forces a new Dashboard Grafana to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group where the Dashboard Grafana should exist. Changing this forces a new Dashboard Grafana to be created. + +* `location` - (Required) Specifies the Azure Region where the Dashboard Grafana should exist. Changing this forces a new Dashboard Grafana to be created. + +* `api_key_enabled` - (Optional) Whether to enable the api key setting of the Grafana instance. Defaults to `false`. + +* `auto_generated_domain_name_label_scope` - (Optional) Scope for dns deterministic name hash calculation. The only possible value is `TenantReuse`. Defaults to `TenantReuse`. + +* `deterministic_outbound_ip_enabled` - (Optional) Whether to enable the Grafana instance to use deterministic outbound IPs. Defaults to `false`. + +* `identity` - (Optional) An `identity` block as defined below. Changing this forces a new Dashboard Grafana to be created. + +* `public_network_access_enabled` - (Optional) Whether to enable traffic over the public interface. Defaults to `true`. + +* `sku` - (Optional) The name of the SKU used for the Grafana instance. The only possible value is `Standard`. Defaults to `Standard`. Changing this forces a new Dashboard Grafana to be created. + +* `tags` - (Optional) A mapping of tags which should be assigned to the Dashboard Grafana. + +* `zone_redundancy_enabled` - (Optional) Whether to enable the zone redundancy setting of the Grafana instance. Defaults to `false`. Changing this forces a new Dashboard Grafana to be created. + +--- + +An `identity` block supports the following: + +* `type` - (Required) Specifies the type of Managed Service Identity. The only possible values is `SystemAssigned`. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Dashboard Grafana. + +* `endpoint` - The endpoint of the Grafana instance. + +* `grafana_version` - The Grafana software version. + +* `identity` - An `identity` block as defined below. + +* `outbound_ip` - List of outbound IPs if deterministicOutboundIP is enabled. + +--- + +An `identity` block exports the following: + +* `principal_id` - The Principal ID associated with this Managed Service Identity. + +* `tenant_id` - The Tenant ID associated with this Managed Service Identity. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Dashboard Grafana. +* `read` - (Defaults to 5 minutes) Used when retrieving the Dashboard Grafana. +* `update` - (Defaults to 30 minutes) Used when updating the Dashboard Grafana. +* `delete` - (Defaults to 30 minutes) Used when deleting the Dashboard Grafana. + +## Import + +Dashboard Grafana can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_dashboard_grafana.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1/providers/Microsoft.Dashboard/grafana/workspace1 +```