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

Adds new resource for azurerm_security_center_auto_provisioning #8595

Merged
merged 9 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package securitycenter

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/v1.0/security"
benc-uk marked this conversation as resolved.
Show resolved Hide resolved
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

// NOTE: 'default' is the only valid name currently supported by the API
// No other names can be created and the 'default' resource can not be destroyed
const securityCenterAutoProvisioningName = "default"

func resourceArmSecurityCenterAutoProvisioning() *schema.Resource {
return &schema.Resource{
Create: resourceArmSecurityCenterAutoProvisioningUpdate,
Read: resourceArmSecurityCenterAutoProvisioningRead,
Update: resourceArmSecurityCenterAutoProvisioningUpdate,
Delete: resourceArmSecurityCenterAutoProvisioningDelete,

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{
"auto_provision": {
Type: schema.TypeString,
Required: true,
// NOTE: the API seems case insensitive to this string value, 'ON', 'On', 'on' all work
ValidateFunc: validation.StringInSlice([]string{
string(security.AutoProvisionOn),
string(security.AutoProvisionOff),
}, false),
},
},
}
}

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

name := securityCenterAutoProvisioningName

// No need for import check as there's always single resource called 'default'
// - it cannot be deleted, all this does is set a string property to: "on" or "off"

// Build settings struct with auto_provision value
settings := security.AutoProvisioningSetting{
AutoProvisioningSettingProperties: &security.AutoProvisioningSettingProperties{
AutoProvision: security.AutoProvision(d.Get("auto_provision").(string)),
},
}

// There is no update function or operation in the API, only create
if _, err := client.Create(ctx, name, settings); err != nil {
return fmt.Errorf("Error creating/updating Security Center auto provisioning: %+v", err)
}

resp, err := client.Get(ctx, name)
if err != nil {
return fmt.Errorf("Error reading Security Center auto provisioning: %+v", err)
}
if resp.ID == nil {
return fmt.Errorf("Security Center auto provisioning ID is nil")
}
benc-uk marked this conversation as resolved.
Show resolved Hide resolved

d.SetId(*resp.ID)

return resourceArmSecurityCenterAutoProvisioningRead(d, meta)
}

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

resp, err := client.Get(ctx, securityCenterAutoProvisioningName)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[DEBUG] Security Center subscription was not found: %v", err)
d.SetId("")
return nil
}

return fmt.Errorf("Error reading Security Center auto provisioning: %+v", err)
}

if properties := resp.AutoProvisioningSettingProperties; properties != nil {
d.Set("auto_provision", properties.AutoProvision)
}

return nil
}

func resourceArmSecurityCenterAutoProvisioningDelete(_ *schema.ResourceData, _ interface{}) error {
benc-uk marked this conversation as resolved.
Show resolved Hide resolved
log.Printf("[DEBUG] Security Center auto provisioning deletion invocation")
return nil // cannot be deleted.
}
4 changes: 4 additions & 0 deletions azurerm/internal/services/securitycenter/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type Client struct {
PricingClient *security.PricingsClient
WorkspaceClient *security.WorkspaceSettingsClient
AdvancedThreatProtectionClient *security.AdvancedThreatProtectionClient
AutoProvisioningClient *security.AutoProvisioningSettingsClient
SettingClient *security.SettingsClient
}

Expand All @@ -28,6 +29,8 @@ func NewClient(o *common.ClientOptions) *Client {
AdvancedThreatProtectionClient := security.NewAdvancedThreatProtectionClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, ascLocation)
o.ConfigureClient(&AdvancedThreatProtectionClient.Client, o.ResourceManagerAuthorizer)

AutoProvisioningClient := security.NewAutoProvisioningSettingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, ascLocation)
o.ConfigureClient(&AutoProvisioningClient.Client, o.ResourceManagerAuthorizer)
benc-uk marked this conversation as resolved.
Show resolved Hide resolved
SettingClient := security.NewSettingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, ascLocation)
o.ConfigureClient(&SettingClient.Client, o.ResourceManagerAuthorizer)

Expand All @@ -36,6 +39,7 @@ func NewClient(o *common.ClientOptions) *Client {
PricingClient: &PricingClient,
WorkspaceClient: &WorkspaceClient,
AdvancedThreatProtectionClient: &AdvancedThreatProtectionClient,
AutoProvisioningClient: &AutoProvisioningClient,
SettingClient: &SettingClient,
}
}
1 change: 1 addition & 0 deletions azurerm/internal/services/securitycenter/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ func (r Registration) SupportedResources() map[string]*schema.Resource {
"azurerm_security_center_setting": resourceArmSecurityCenterSetting(),
"azurerm_security_center_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(),
"azurerm_security_center_workspace": resourceArmSecurityCenterWorkspace(),
"azurerm_security_center_auto_provisioning": resourceArmSecurityCenterAutoProvisioning(),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package tests

import (
"fmt"
"strings"
"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/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func TestAccAzureRMSecurityCenterAutoProvision_update(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_security_center_auto_provisioning", "test")

// lintignore:AT001
resource.Test(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
Steps: []resource.TestStep{
{
Config: testAccAzureRMSecurityCenterAutoProvisioning_setting("On"),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMSecurityCenterAutoProvisioningExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "auto_provision", "On"),
),
},
data.ImportStep(),
{
Config: testAccAzureRMSecurityCenterAutoProvisioning_setting("Off"),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMSecurityCenterAutoProvisioningExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "auto_provision", "Off"),
),
},
data.ImportStep(),
},
})
}

func testCheckAzureRMSecurityCenterAutoProvisioningExists(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
client := acceptance.AzureProvider.Meta().(*clients.Client).SecurityCenter.AutoProvisioningClient
ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext

rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("Not found: %s", resourceName)
}

idSplit := strings.Split(rs.Primary.Attributes["id"], "/")
autoProvisionResourceName := idSplit[len(idSplit)-1]

resp, err := client.Get(ctx, autoProvisionResourceName)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Security Center auto provision %q was not found: %+v", autoProvisionResourceName, err)
}

return fmt.Errorf("Bad: GetAutoProvisioning: %+v", err)
}

return nil
}
}

func testAccAzureRMSecurityCenterAutoProvisioning_setting(setting string) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_security_center_auto_provisioning" "test" {
auto_provision = "%s"
}
`, setting)
}