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_healthbot #11002

Merged
merged 11 commits into from Apr 23, 2021
198 changes: 198 additions & 0 deletions azurerm/internal/services/bot/bot_healthbot_resource.go
@@ -0,0 +1,198 @@
package bot

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/healthbot/mgmt/2020-12-08/healthbot"
"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/location"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/bot/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/bot/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceHealthbotService() *schema.Resource {
return &schema.Resource{
Create: resourceHealthbotServiceCreate,
Read: resourceHealthbotServiceRead,
Update: resourceHealthbotServiceUpdate,
Delete: resourceHealthbotServiceDelete,

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

Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error {
_, err := parse.BotHealthbotID(id)
return err
}),

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

"resource_group_name": azure.SchemaResourceGroupName(),

"location": azure.SchemaLocation(),

"sku_name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
string(healthbot.F0),
string(healthbot.S1),
}, false),
},

"bot_management_portal_link": {
haiyuazhang marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeString,
Computed: true,
},

"tags": tags.Schema(),
},
}
}

func resourceHealthbotServiceCreate(d *schema.ResourceData, meta interface{}) error {
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
client := meta.(*clients.Client).Bot.HealthbotClient
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
defer cancel()

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

id := parse.NewBotHealthbotID(subscriptionId, resourceGroup, name)

if d.IsNewResource() {
existing, err := client.Get(ctx, id.ResourceGroup, id.HealthBotName)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("checking for existing %s: %+v", id, err)
}
}
if !utils.ResponseWasNotFound(existing.Response) {
return tf.ImportAsExistsError("azurerm_healthbot", id.ID())
}
}

parameters := healthbot.HealthBot{
Location: utils.String(location.Normalize(d.Get("location").(string))),
Sku: &healthbot.Sku{
Name: healthbot.SkuName(d.Get("sku_name").(string)),
},
Tags: tags.Expand(d.Get("tags").(map[string]interface{})),
}

future, err := client.Create(ctx, resourceGroup, name, parameters)
if err != nil {
return fmt.Errorf("creating %s: %+v", id, err)
}

if err := future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("waiting for creation of %s: %+v", id, err)
}

d.SetId(id.ID())

return resourceHealthbotServiceRead(d, meta)
}

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

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

resp, err := client.Get(ctx, id.ResourceGroup, id.HealthBotName)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[INFO] healthbot %q does not exist - removing from state", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("retrieving %s: %+v", id, err)
}

d.Set("name", id.HealthBotName)
d.Set("resource_group_name", id.ResourceGroup)
d.Set("location", location.NormalizeNilable(resp.Location))

if sku := resp.Sku; sku != nil {
d.Set("sku_name", sku.Name)
}

if props := resp.Properties; props != nil {
d.Set("bot_management_portal_link", props.BotManagementPortalLink)
}
return tags.FlattenAndSet(d, resp.Tags)
}

func resourceHealthbotServiceUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Bot.HealthbotClient
ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

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

parameters := healthbot.UpdateParameters{}
if d.HasChange("sku_name") {
parameters.Sku = &healthbot.Sku{
Name: healthbot.SkuName(d.Get("sku_name").(string)),
}
}

if d.HasChange("tags") {
parameters.Tags = tags.Expand(d.Get("tags").(map[string]interface{}))
}

if _, err := client.Update(ctx, id.ResourceGroup, id.HealthBotName, parameters); err != nil {
return fmt.Errorf("updating %s: %+v", id, err)
}
return resourceHealthbotServiceRead(d, meta)
}

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

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

future, err := client.Delete(ctx, id.ResourceGroup, id.HealthBotName)
if err != nil {
return fmt.Errorf("deleting %s: %+v", id, err)
}

if err := future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("waiting for deletion of %s: %+v", id, err)
}
return nil
}
160 changes: 160 additions & 0 deletions azurerm/internal/services/bot/bot_healthbot_resource_test.go
@@ -0,0 +1,160 @@
package bot_test

import (
"context"
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance/check"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/bot/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

type HealthbotResource struct{}

func TestAccBotHealthbot_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_healthbot", "test")
r := HealthbotResource{}
data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basic(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccBotHealthbot_requiresImport(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_healthbot", "test")
r := HealthbotResource{}
data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basic(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.RequiresImportErrorStep(r.requiresImport),
})
}

func TestAccBotHealthbot_complete(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_healthbot", "test")
r := HealthbotResource{}
data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.complete(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccBotHealthbot_update(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_healthbot", "test")
r := HealthbotResource{}
data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basic(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.complete(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.basic(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func (r HealthbotResource) Exists(ctx context.Context, client *clients.Client, state *terraform.InstanceState) (*bool, error) {
id, err := parse.BotHealthbotID(state.ID)
if err != nil {
return nil, err
}

resp, err := client.Bot.HealthbotClient.Get(ctx, id.ResourceGroup, id.HealthBotName)
if err != nil {
return nil, fmt.Errorf("retrieving Healthbot service %q (resource group: %q): %+v", id.HealthBotName, id.ResourceGroup, err)
}

return utils.Bool(resp.Properties != nil), nil
}

func (r HealthbotResource) template(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctest-healthbot-%d"
location = "%s"
}
`, data.RandomInteger, data.Locations.Primary)
}

func (r HealthbotResource) basic(data acceptance.TestData) string {
template := r.template(data)
return fmt.Sprintf(`
%s

resource "azurerm_healthbot" "test" {
name = "acctest-hb-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
sku_name = "F0"
}
`, template, data.RandomInteger)
}

func (r HealthbotResource) requiresImport(data acceptance.TestData) string {
config := r.basic(data)
return fmt.Sprintf(`
%s

resource "azurerm_healthbot" "import" {
name = azurerm_healthbot.test.name
resource_group_name = azurerm_healthbot.test.resource_group_name
location = azurerm_healthbot.test.location
sku_name = azurerm_healthbot.test.sku_name
}
`, config)
}

func (r HealthbotResource) complete(data acceptance.TestData) string {
template := r.template(data)
return fmt.Sprintf(`
%s

resource "azurerm_healthbot" "test" {
name = "acctest-hb-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
sku_name = "S1"

tags = {
ENV = "Test"
}
}
`, template, data.RandomInteger)
}
6 changes: 6 additions & 0 deletions azurerm/internal/services/bot/client/client.go
@@ -1,6 +1,7 @@
package client

import (
"github.com/Azure/azure-sdk-for-go/services/healthbot/mgmt/2020-12-08/healthbot"
"github.com/Azure/azure-sdk-for-go/services/preview/botservice/mgmt/2018-07-12/botservice"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common"
)
Expand All @@ -9,6 +10,7 @@ type Client struct {
BotClient *botservice.BotsClient
ConnectionClient *botservice.BotConnectionClient
ChannelClient *botservice.ChannelsClient
HealthbotClient *healthbot.BotsClient
}

func NewClient(o *common.ClientOptions) *Client {
Expand All @@ -21,9 +23,13 @@ func NewClient(o *common.ClientOptions) *Client {
channelClient := botservice.NewChannelsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&channelClient.Client, o.ResourceManagerAuthorizer)

healthBotClient := healthbot.NewBotsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&healthBotClient.Client, o.ResourceManagerAuthorizer)

return &Client{
BotClient: &botClient,
ChannelClient: &channelClient,
ConnectionClient: &connectionClient,
HealthbotClient: &healthBotClient,
}
}