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_security_center_workspace #2072

Merged
merged 7 commits into from
Oct 14, 2018
Merged
Show file tree
Hide file tree
Changes from 3 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
9 changes: 7 additions & 2 deletions azurerm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,9 @@ type ArmClient struct {
searchServicesClient search.ServicesClient

// Security Centre
securityCenterPricingClient security.PricingsClient
securityCenterContactsClient security.ContactsClient
securityCenterPricingClient security.PricingsClient
securityCenterContactsClient security.ContactsClient
securityCenterWorkspaceClient security.WorkspaceSettingsClient

// ServiceBus
serviceBusQueuesClient servicebus.QueuesClient
Expand Down Expand Up @@ -1030,6 +1031,10 @@ func (c *ArmClient) registerSecurityCenterClients(endpoint, subscriptionId, ascL
securityCenterContactsClient := security.NewContactsClientWithBaseURI(endpoint, subscriptionId, ascLocation)
c.configureClient(&securityCenterContactsClient.Client, auth)
c.securityCenterContactsClient = securityCenterContactsClient

securityCenterWorkspaceClient := security.NewWorkspaceSettingsClientWithBaseURI(endpoint, subscriptionId, ascLocation)
c.configureClient(&securityCenterWorkspaceClient.Client, auth)
c.securityCenterWorkspaceClient = securityCenterWorkspaceClient
}

func (c *ArmClient) registerServiceBusClients(endpoint, subscriptionId string, auth autorest.Authorizer) {
Expand Down
1 change: 1 addition & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_search_service": resourceArmSearchService(),
"azurerm_security_center_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(),
"azurerm_security_center_contact": resourceArmSecurityCenterContact(),
"azurerm_security_center_workspace": resourceArmSecurityCenterWorkspace(),
"azurerm_servicebus_namespace": resourceArmServiceBusNamespace(),
"azurerm_servicebus_namespace_authorization_rule": resourceArmServiceBusNamespaceAuthorizationRule(),
"azurerm_servicebus_queue": resourceArmServiceBusQueue(),
Expand Down
34 changes: 30 additions & 4 deletions azurerm/resource_arm_security_center_contact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ func TestAccAzureRMSecurityCenterContact_basic(t *testing.T) {
resourceName := "azurerm_security_center_contact.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMSecurityCenterContactDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMSecurityCenterContact_template("[email protected]", "+1-555-555-5555", true, true),
Expand All @@ -39,8 +40,9 @@ func TestAccAzureRMSecurityCenterContact_update(t *testing.T) {
resourceName := "azurerm_security_center_contact.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMSecurityCenterContactDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMSecurityCenterContact_template("[email protected]", "+1-555-555-5555", true, true),
Expand Down Expand Up @@ -96,6 +98,30 @@ func testCheckAzureRMSecurityCenterContactExists(name string) resource.TestCheck
}
}

func testCheckAzureRMSecurityCenterContactDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*ArmClient).securityCenterContactsClient
ctx := testAccProvider.Meta().(*ArmClient).StopContext

for _, res := range s.RootModule().Resources {
if res.Type != "azurerm_securitycenter_contact" {
continue
}

resp, err := client.Get(ctx, "default1")
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return nil
}

return err
}

return fmt.Errorf("security center worspace contact still exists")
}

return nil
}

func testAccAzureRMSecurityCenterContact_template(email, phone string, notifications, adminAlerts bool) string {
return fmt.Sprintf(`
resource "azurerm_security_center_contact" "test" {
Expand Down
143 changes: 143 additions & 0 deletions azurerm/resource_arm_security_center_workspace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package azurerm

import (
"fmt"
"github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
"log"
"time"
)

//only valid name is default
// Message="Invalid workspace settings name 'kttest' , only default is allowed "
const resourceArmSecurityCenterWorkspaceName = "default"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we ditch resourceArm from the start of this?


func resourceArmSecurityCenterWorkspace() *schema.Resource {
return &schema.Resource{
Create: resourceArmSecurityCenterWorkspaceCreateUpdate,
Read: resourceArmSecurityCenterWorkspaceRead,
Update: resourceArmSecurityCenterWorkspaceCreateUpdate,
Delete: resourceArmSecurityCenterWorkspaceDelete,

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

Schema: map[string]*schema.Schema{
"scope": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.NoZeroValues,
},

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

func resourceArmSecurityCenterWorkspaceCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).securityCenterWorkspaceClient
ctx := meta.(*ArmClient).StopContext

name := resourceArmSecurityCenterWorkspaceName

contact := security.WorkspaceSetting{
WorkspaceSettingProperties: &security.WorkspaceSettingProperties{
Scope: utils.String(d.Get("scope").(string)),
WorkspaceID: utils.String(d.Get("workspace_id").(string)),
},
}

if d.IsNewResource() {
_, err := client.Create(ctx, name, contact)
if err != nil {
return fmt.Errorf("Error creating Security Center Workspace: %+v", err)
}
} else {
_, err := client.Update(ctx, name, contact)
if err != nil {
return fmt.Errorf("Error updating Security Center Workspace: %+v", err)
}
}

stateConf := &resource.StateChangeConf{
Pending: []string{"Waiting"},
Target: []string{"Populated"},
Timeout: 60 * time.Minute,
MinTimeout: 30 * time.Second,
Refresh: func() (interface{}, string, error) {

resp, err := client.Get(ctx, name)
if err != nil {
return resp, "Error", fmt.Errorf("Error reading Security Center Workspace: %+v", err)
}

if properties := resp.WorkspaceSettingProperties; properties != nil {
if properties.WorkspaceID != nil && *properties.WorkspaceID != "" {
return resp, "Populated", nil
}
}

return resp, "Waiting", nil
},
}

resp, err := stateConf.WaitForState()
if err != nil {
return fmt.Errorf("Error waiting: %+v", err)
}

if d.IsNewResource() {
d.SetId(*resp.(security.WorkspaceSetting).ID)
}

return resourceArmSecurityCenterWorkspaceRead(d, meta)
}

func resourceArmSecurityCenterWorkspaceRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).securityCenterWorkspaceClient
ctx := meta.(*ArmClient).StopContext

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

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

if properties := resp.WorkspaceSettingProperties; properties != nil {
d.Set("scope", properties.Scope)
d.Set("workspace_id", properties.WorkspaceID)
}

return nil
}

func resourceArmSecurityCenterWorkspaceDelete(_ *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).securityCenterWorkspaceClient
ctx := meta.(*ArmClient).StopContext

resp, err := client.Delete(ctx, resourceArmSecurityCenterWorkspaceName)
if err != nil {
if utils.ResponseWasNotFound(resp) {
log.Printf("[DEBUG] Security Center Subscription Workspace was not found: %v", err)
return nil
}

return fmt.Errorf("Error deleting Security Center Workspace: %+v", err)
}

return nil
}
163 changes: 163 additions & 0 deletions azurerm/resource_arm_security_center_workspace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package azurerm

import (
"fmt"
"github.com/hashicorp/terraform/helper/acctest"
"os"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func TestAccAzureRMSecurityCenterWorkspace_basic(t *testing.T) {
resourceName := "azurerm_security_center_workspace.test"
ri := acctest.RandInt()

scope := fmt.Sprintf("/subscriptions/%s", os.Getenv("ARM_SUBSCRIPTION_ID"))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMSecurityCenterWorkspaceDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMSecurityCenterWorkspace_basic(ri, testLocation(), scope),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMSecurityCenterWorkspaceExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "scope", scope),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMSecurityCenterWorkspace_update(t *testing.T) {
resourceName := "azurerm_security_center_workspace.test"
ri := acctest.RandInt()

scope := fmt.Sprintf("/subscriptions/%s", os.Getenv("ARM_SUBSCRIPTION_ID"))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccAzureRMSecurityCenterWorkspace_basic(ri, testLocation(), scope),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMSecurityCenterWorkspaceExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "scope", scope),
),
},
{
Config: testAccAzureRMSecurityCenterWorkspace_differentWorkspace(ri, testLocation(), scope),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMSecurityCenterWorkspaceExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "scope", scope),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testCheckAzureRMSecurityCenterWorkspaceExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
client := testAccProvider.Meta().(*ArmClient).securityCenterWorkspaceClient
ctx := testAccProvider.Meta().(*ArmClient).StopContext

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

contactName := rs.Primary.Attributes["workspaceSettings"]

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

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

return nil
}
}

func testCheckAzureRMSecurityCenterWorkspaceDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*ArmClient).securityCenterWorkspaceClient
ctx := testAccProvider.Meta().(*ArmClient).StopContext

for _, res := range s.RootModule().Resources {
if res.Type != "azurerm_security_center_workspace" {
continue
}

resp, err := client.Get(ctx, resourceArmSecurityCenterWorkspaceName)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return nil
}

return err
}

return fmt.Errorf("security center worspace settings still exists")
}

return nil
}

func testAccAzureRMSecurityCenterWorkspace_basic(rInt int, location, scope string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%[1]d"
location = "%[2]s"
}

resource "azurerm_log_analytics_workspace" "test1" {
name = "acctest-%[1]d-1"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
sku = "PerGB2018"
}

resource "azurerm_security_center_workspace" "test" {
scope = "%[3]s"
workspace_id = "${azurerm_log_analytics_workspace.test1.id}"
}
`, rInt, location, scope)
}

func testAccAzureRMSecurityCenterWorkspace_differentWorkspace(rInt int, location, scope string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%[1]d"
location = "%[2]s"
}

resource "azurerm_log_analytics_workspace" "test2" {
name = "acctest-%[1]d-2"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
sku = "PerGB2018"
}

resource "azurerm_security_center_workspace" "test" {
scope = "%[3]s"
workspace_id = "${azurerm_log_analytics_workspace.test2.id}"
}
`, rInt, location, scope)
}
Loading