Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Resource: azurerm_kusto_attached_database_configuration #7377

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 11 additions & 6 deletions azurerm/internal/services/kusto/client/client.go
Expand Up @@ -6,9 +6,10 @@ import (
)

type Client struct {
ClustersClient *kusto.ClustersClient
DatabasesClient *kusto.DatabasesClient
DataConnectionsClient *kusto.DataConnectionsClient
ClustersClient *kusto.ClustersClient
DatabasesClient *kusto.DatabasesClient
DataConnectionsClient *kusto.DataConnectionsClient
AttachedDatabaseConfigurationsClient *kusto.AttachedDatabaseConfigurationsClient
}

func NewClient(o *common.ClientOptions) *Client {
Expand All @@ -21,9 +22,13 @@ func NewClient(o *common.ClientOptions) *Client {
DataConnectionsClient := kusto.NewDataConnectionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&DataConnectionsClient.Client, o.ResourceManagerAuthorizer)

AttachedDatabaseConfigurationsClient := kusto.NewAttachedDatabaseConfigurationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&AttachedDatabaseConfigurationsClient.Client, o.ResourceManagerAuthorizer)

return &Client{
ClustersClient: &ClustersClient,
DatabasesClient: &DatabasesClient,
DataConnectionsClient: &DataConnectionsClient,
ClustersClient: &ClustersClient,
DatabasesClient: &DatabasesClient,
DataConnectionsClient: &DataConnectionsClient,
AttachedDatabaseConfigurationsClient: &AttachedDatabaseConfigurationsClient,
}
}
@@ -0,0 +1,220 @@
package kusto

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/kusto/mgmt/2020-02-15/kusto"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/kusto/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmKustoAttachedDatabaseConfiguration() *schema.Resource {
return &schema.Resource{
Create: resourceArmKustoAttachedDatabaseConfigurationCreateUpdate,
Read: resourceArmKustoAttachedDatabaseConfigurationRead,
Update: resourceArmKustoAttachedDatabaseConfigurationCreateUpdate,
Delete: resourceArmKustoAttachedDatabaseConfigurationDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(60 * time.Minute),
Read: schema.DefaultTimeout(5 * time.Minute),
Update: schema.DefaultTimeout(60 * time.Minute),
Delete: schema.DefaultTimeout(60 * time.Minute),
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateAzureRMKustoDataConnectionName,
},

"resource_group_name": azure.SchemaResourceGroupName(),

"location": azure.SchemaLocation(),

"cluster_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateAzureRMKustoClusterName,
},

"database_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.Any(validateAzureRMKustoDatabaseName, validation.StringInSlice([]string{"*"}, false)),
},

"cluster_resource_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: azure.ValidateResourceID,
},

"attached_database_names": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},

"default_principal_modification_kind": {
Type: schema.TypeString,
Optional: true,
Default: kusto.DefaultPrincipalsModificationKindNone,
ValidateFunc: validation.StringInSlice([]string{
string(kusto.DefaultPrincipalsModificationKindNone),
string(kusto.DefaultPrincipalsModificationKindReplace),
string(kusto.DefaultPrincipalsModificationKindUnion),
}, false),
},
},
}
}

func resourceArmKustoAttachedDatabaseConfigurationCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Kusto.AttachedDatabaseConfigurationsClient
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

log.Printf("[INFO] preparing arguments for Azure Kusto Attached Database Configuration creation.")

name := d.Get("name").(string)
resourceGroup := d.Get("resource_group_name").(string)
clusterName := d.Get("cluster_name").(string)

if d.IsNewResource() {
resp, err := client.Get(ctx, resourceGroup, clusterName, name)
if err != nil {
if !utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Error checking for presence of existing Kusto Attached Database Configuration %q (Resource Group %q, Cluster %q): %s", name, resourceGroup, clusterName, err)
}
}

if resp.ID != nil && *resp.ID != "" {
return tf.ImportAsExistsError("azurerm_kusto_attached_database_configuration", *resp.ID)
}
}

location := azure.NormalizeLocation(d.Get("location").(string))

configurationProperties := expandKustoAttachedDatabaseConfigurationProperties(d)

configurationRequest := kusto.AttachedDatabaseConfiguration{
Location: &location,
AttachedDatabaseConfigurationProperties: configurationProperties,
}

future, err := client.CreateOrUpdate(ctx, resourceGroup, clusterName, name, configurationRequest)
if err != nil {
return fmt.Errorf("Error creating or updating Kusto Attached Database Configuration %q (Resource Group %q, Cluster %q): %+v", name, resourceGroup, clusterName, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("Error waiting for completion of Kusto Attached Database Configuration %q (Resource Group %q, Cluster %q): %+v", name, resourceGroup, clusterName, err)
}

configuration, err := client.Get(ctx, resourceGroup, clusterName, name)
if err != nil {
return fmt.Errorf("Error retrieving Kusto Attached Database Configuration %q (Resource Group %q, Cluster %q): %+v", name, resourceGroup, clusterName, err)
}

d.SetId(*configuration.ID)

return resourceArmKustoAttachedDatabaseConfigurationRead(d, meta)
}

func resourceArmKustoAttachedDatabaseConfigurationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Kusto.AttachedDatabaseConfigurationsClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.KustoAttachedDatabaseConfigurationID(d.Id())
if err != nil {
return err
}

configuration, err := client.Get(ctx, id.ResourceGroup, id.Cluster, id.Name)

if err != nil {
if utils.ResponseWasNotFound(configuration.Response) {
d.SetId("")
return nil
}
return fmt.Errorf("Error retrieving Kusto Attached Database Configuration %q (Resource Group %q, Cluster %q): %+v", id.Name, id.ResourceGroup, id.Cluster, err)
}

d.Set("name", id.Name)
d.Set("resource_group_name", id.ResourceGroup)
d.Set("cluster_name", id.Cluster)

if location := configuration.Location; location != nil {
d.Set("location", azure.NormalizeLocation(*location))
}

if props := configuration.AttachedDatabaseConfigurationProperties; props != nil {
d.Set("cluster_resource_id", props.ClusterResourceID)
d.Set("database_name", props.DatabaseName)
d.Set("default_principal_modification_kind", props.DefaultPrincipalsModificationKind)
d.Set("attached_database_names", props.AttachedDatabaseNames)
}

return nil
}

func resourceArmKustoAttachedDatabaseConfigurationDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Kusto.AttachedDatabaseConfigurationsClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.KustoAttachedDatabaseConfigurationID(d.Id())
if err != nil {
return err
}

future, err := client.Delete(ctx, id.ResourceGroup, id.Cluster, id.Name)
if err != nil {
return fmt.Errorf("Error deleting Kusto Attached Database Configuration %q (Resource Group %q, Cluster %q): %+v", id.Name, id.ResourceGroup, id.Cluster, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("Error waiting for deletion of Kusto Attached Database Configuration %q (Resource Group %q, Cluster %q): %+v", id.Name, id.ResourceGroup, id.Cluster, err)
}

return nil
}

func expandKustoAttachedDatabaseConfigurationProperties(d *schema.ResourceData) *kusto.AttachedDatabaseConfigurationProperties {
AttachedDatabaseConfigurationProperties := &kusto.AttachedDatabaseConfigurationProperties{}

if clusterResourceID, ok := d.GetOk("cluster_resource_id"); ok {
AttachedDatabaseConfigurationProperties.ClusterResourceID = utils.String(clusterResourceID.(string))
}

if databaseName, ok := d.GetOk("database_name"); ok {
AttachedDatabaseConfigurationProperties.DatabaseName = utils.String(databaseName.(string))
}

if defaultPrincipalModificationKind, ok := d.GetOk("default_principal_modification_kind"); ok {
AttachedDatabaseConfigurationProperties.DefaultPrincipalsModificationKind = kusto.DefaultPrincipalsModificationKind(defaultPrincipalModificationKind.(string))
}

return AttachedDatabaseConfigurationProperties
}
@@ -0,0 +1,38 @@
package parse

import (
"fmt"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
)

type KustoAttachedDatabaseConfigurationId struct {
ResourceGroup string
Cluster string
Name string
}

func KustoAttachedDatabaseConfigurationID(input string) (*KustoAttachedDatabaseConfigurationId, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, fmt.Errorf("[ERROR] Unable to parse Kusto Attached Database Configuration ID %q: %+v", input, err)
}

configuration := KustoAttachedDatabaseConfigurationId{
ResourceGroup: id.ResourceGroup,
}

if configuration.Cluster, err = id.PopSegment("Clusters"); err != nil {
return nil, err
}

if configuration.Name, err = id.PopSegment("AttachedDatabaseConfigurations"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &configuration, nil
}
@@ -0,0 +1,54 @@
package parse

import (
"testing"
)

func TestKustoAttachedDatabaseConfigurationId(t *testing.T) {
testData := []struct {
Name string
Input string
Expected *KustoAttachedDatabaseConfigurationId
}{
{
Name: "Empty",
Input: "",
Expected: nil,
},
{
Name: "No Cluster",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Kusto/AttachedDatabaseConfigurations/configuration1",
Expected: nil,
},
{
Name: "Kusto Attached Database Configuration ID",
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Kusto/Clusters/cluster1/AttachedDatabaseConfigurations/configuration1",
Expected: &KustoAttachedDatabaseConfigurationId{
Name: "configuration1",
Cluster: "cluster1",
ResourceGroup: "group1",
},
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q", v.Name)

actual, err := KustoAttachedDatabaseConfigurationID(v.Input)
if err != nil {
if v.Expected == nil {
continue
}

t.Fatalf("Expected a value but got an error: %s", err)
}

if actual.Name != v.Expected.Name {
t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name)
}

if actual.ResourceGroup != v.Expected.ResourceGroup {
t.Fatalf("Expected %q but got %q for Resource Group", v.Expected.ResourceGroup, actual.ResourceGroup)
}
}
}
9 changes: 5 additions & 4 deletions azurerm/internal/services/kusto/registration.go
Expand Up @@ -28,9 +28,10 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource {
// SupportedResources returns the supported Resources supported by this Service
func (r Registration) SupportedResources() map[string]*schema.Resource {
return map[string]*schema.Resource{
"azurerm_kusto_cluster": resourceArmKustoCluster(),
"azurerm_kusto_database": resourceArmKustoDatabase(),
"azurerm_kusto_database_principal": resourceArmKustoDatabasePrincipal(),
"azurerm_kusto_eventhub_data_connection": resourceArmKustoEventHubDataConnection(),
"azurerm_kusto_cluster": resourceArmKustoCluster(),
"azurerm_kusto_database": resourceArmKustoDatabase(),
"azurerm_kusto_database_principal": resourceArmKustoDatabasePrincipal(),
"azurerm_kusto_eventhub_data_connection": resourceArmKustoEventHubDataConnection(),
"azurerm_kusto_attached_database_configuration": resourceArmKustoAttachedDatabaseConfiguration(),
}
}