-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add security center setting resource
So that we can disable and/or enabled the access of Microsoft App Security (MCAS) and Windows Defender ATP (WDATP) to the subscription data.
- Loading branch information
Showing
10 changed files
with
402 additions
and
0 deletions.
There are no files selected for viewing
36 changes: 36 additions & 0 deletions
36
azurerm/internal/services/securitycenter/azuresdkhacks/security_center_setting.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package azuresdkhacks | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/v3.0/security" | ||
"github.com/Azure/go-autorest/autorest" | ||
"github.com/Azure/go-autorest/autorest/azure" | ||
) | ||
|
||
func GetSecurityCenterSetting(client *security.SettingsClient, ctx context.Context, settingName string) (setting security.DataExportSettings, err error) { | ||
// NOTE: client.Get() returns security.Setting, which doesn't contain the "Enabled" property | ||
req, err := client.GetPreparer(ctx, settingName) | ||
if err != nil { | ||
err = autorest.NewErrorWithError(err, "security.SettingsClient", "Get", nil, "Failure preparing request") | ||
return setting, fmt.Errorf("Error reading Security Center setting: %+v", err) | ||
} | ||
resp, err := client.GetSender(req) | ||
if err != nil { | ||
err = autorest.NewErrorWithError(err, "security.SettingsClient", "Get", resp, "Failure sending request") | ||
return setting, fmt.Errorf("Error reading Security Center setting: %+v", err) | ||
} | ||
|
||
err = autorest.Respond( | ||
resp, | ||
azure.WithErrorUnlessStatusCode(http.StatusOK), | ||
autorest.ByUnmarshallingJSON(&setting), | ||
autorest.ByClosing()) | ||
if err != nil { | ||
return setting, fmt.Errorf("Error reading Security Center setting: %+v", err) | ||
} | ||
|
||
return setting, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
azurerm/internal/services/securitycenter/parse/security_center_setting.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package parse | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" | ||
) | ||
|
||
type SecurityCenterSettingId struct { | ||
SettingName string | ||
} | ||
|
||
func SecurityCenterSettingID(input string) (*SecurityCenterSettingId, error) { | ||
id, err := azure.ParseAzureResourceID(input) | ||
if err != nil { | ||
return nil, fmt.Errorf("Unable to parse Security Center Setting ID %q: %+v", input, err) | ||
} | ||
|
||
setting := SecurityCenterSettingId{} | ||
|
||
if setting.SettingName, err = id.PopSegment("settings"); err != nil { | ||
return nil, err | ||
} | ||
|
||
if err := id.ValidateNoEmptySegments(input); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &setting, nil | ||
} |
54 changes: 54 additions & 0 deletions
54
azurerm/internal/services/securitycenter/parse/security_center_setting_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package parse | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestSecurityCenterSettingID(t *testing.T) { | ||
testData := []struct { | ||
Name string | ||
Input string | ||
Error bool | ||
Expect *SecurityCenterSettingId | ||
}{ | ||
{ | ||
Name: "Empty", | ||
Input: "", | ||
Error: true, | ||
}, | ||
{ | ||
Name: "No Settings Segment", | ||
Input: "/subscriptions/00000000-0000-0000-0000-000000000000", | ||
Error: true, | ||
}, | ||
{ | ||
Name: "No Settings Value", | ||
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/settings/", | ||
Error: true, | ||
}, | ||
{ | ||
Name: "Security Center Setting ID", | ||
Input: "/subscriptions/00000000-0000-0000-0000-000000000000/settings/MCAS", | ||
Expect: &SecurityCenterSettingId{ | ||
SettingName: "MCAS", | ||
}, | ||
}, | ||
} | ||
|
||
for _, v := range testData { | ||
t.Logf("[DEBUG] Testing %q", v.Name) | ||
|
||
actual, err := SecurityCenterSettingID(v.Input) | ||
if err != nil { | ||
if v.Error { | ||
continue | ||
} | ||
|
||
t.Fatalf("Expected a value but got an error: %s", err) | ||
} | ||
|
||
if actual.SettingName != v.Expect.SettingName { | ||
t.Fatalf("Expected %q but got %q for Name", v.Expect.SettingName, actual.SettingName) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
azurerm/internal/services/securitycenter/resource_arm_security_center_setting.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package securitycenter | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/v3.0/security" | ||
"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/services/securitycenter/azuresdkhacks" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/securitycenter/parse" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" | ||
) | ||
|
||
func resourceArmSecurityCenterSetting() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceArmSecurityCenterSettingUpdate, | ||
Read: resourceArmSecurityCenterSettingRead, | ||
Update: resourceArmSecurityCenterSettingUpdate, | ||
Delete: resourceArmSecurityCenterSettingDelete, | ||
|
||
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{ | ||
"setting_name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: validation.StringInSlice([]string{ | ||
"MCAS", | ||
"WDATP", | ||
}, false), | ||
}, | ||
"enabled": { | ||
Type: schema.TypeBool, | ||
Required: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceArmSecurityCenterSettingUpdate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*clients.Client).SecurityCenter.SettingClient | ||
ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) | ||
defer cancel() | ||
|
||
settingName := d.Get("setting_name").(string) | ||
enabled := d.Get("enabled").(bool) | ||
setting := security.DataExportSettings{ | ||
DataExportSettingProperties: &security.DataExportSettingProperties{ | ||
Enabled: &enabled, | ||
}, | ||
Kind: security.KindDataExportSettings, | ||
} | ||
|
||
if _, err := client.Update(ctx, settingName, setting); err != nil { | ||
return fmt.Errorf("Error creating/updating Security Center pricing: %+v", err) | ||
} | ||
// TODO: switch to back when Swagger/API bug has been fixed: | ||
// https://github.com/Azure/azure-sdk-for-go/issues/12687 | ||
resp, err := azuresdkhacks.GetSecurityCenterSetting(client, ctx, settingName) | ||
if err != nil { | ||
return fmt.Errorf("Error reading Security Center setting: %+v", err) | ||
} | ||
|
||
d.SetId(*resp.ID) | ||
|
||
return resourceArmSecurityCenterSettingRead(d, meta) | ||
} | ||
|
||
func resourceArmSecurityCenterSettingRead(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*clients.Client).SecurityCenter.SettingClient | ||
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) | ||
defer cancel() | ||
|
||
id, err := parse.SecurityCenterSettingID(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
// TODO: switch to back when Swagger/API bug has been fixed: | ||
// https://github.com/Azure/azure-sdk-for-go/issues/12687 (`Enabled` field missing) | ||
resp, err := azuresdkhacks.GetSecurityCenterSetting(client, ctx, id.SettingName) | ||
if err != nil { | ||
return fmt.Errorf("Error reading Security Center setting: %+v", err) | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error reading Security Center setting: %+v", err) | ||
} | ||
|
||
if properties := resp.DataExportSettingProperties; properties != nil { | ||
d.Set("enabled", properties.Enabled) | ||
} | ||
d.Set("setting_name", id.SettingName) | ||
|
||
return nil | ||
} | ||
|
||
func resourceArmSecurityCenterSettingDelete(_ *schema.ResourceData, _ interface{}) error { | ||
log.Printf("[DEBUG] Security Center deletion invocation") | ||
return nil // cannot be deleted. | ||
} |
98 changes: 98 additions & 0 deletions
98
azurerm/internal/services/securitycenter/tests/resource_arm_security_center_setting_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package tests | ||
|
||
import ( | ||
"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/clients" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" | ||
) | ||
|
||
func TestAccAzureRMSecurityCenterSetting_update(t *testing.T) { | ||
data := acceptance.BuildTestData(t, "azurerm_security_center_setting", "test") | ||
|
||
// lintignore:AT001 | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { acceptance.PreCheck(t) }, | ||
Providers: acceptance.SupportedProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAzureRMSecurityCenterSetting_cfg("MCAS", true), | ||
Check: resource.ComposeTestCheckFunc( | ||
testCheckAzureRMSecurityCenterSettingExists(data.ResourceName), | ||
resource.TestCheckResourceAttr(data.ResourceName, "setting_name", "MCAS"), | ||
resource.TestCheckResourceAttr(data.ResourceName, "enabled", "true"), | ||
), | ||
}, | ||
data.ImportStep(), | ||
{ | ||
Config: testAccAzureRMSecurityCenterSetting_cfg("MCAS", false), | ||
Check: resource.ComposeTestCheckFunc( | ||
testCheckAzureRMSecurityCenterSettingExists(data.ResourceName), | ||
resource.TestCheckResourceAttr(data.ResourceName, "setting_name", "MCAS"), | ||
resource.TestCheckResourceAttr(data.ResourceName, "enabled", "false"), | ||
), | ||
}, | ||
data.ImportStep(), | ||
{ | ||
Config: testAccAzureRMSecurityCenterSetting_cfg("WDATP", true), | ||
Check: resource.ComposeTestCheckFunc( | ||
testCheckAzureRMSecurityCenterSettingExists(data.ResourceName), | ||
resource.TestCheckResourceAttr(data.ResourceName, "setting_name", "WDATP"), | ||
resource.TestCheckResourceAttr(data.ResourceName, "enabled", "true"), | ||
), | ||
}, | ||
data.ImportStep(), | ||
{ | ||
Config: testAccAzureRMSecurityCenterSetting_cfg("WDATP", false), | ||
Check: resource.ComposeTestCheckFunc( | ||
testCheckAzureRMSecurityCenterSettingExists(data.ResourceName), | ||
resource.TestCheckResourceAttr(data.ResourceName, "setting_name", "WDATP"), | ||
resource.TestCheckResourceAttr(data.ResourceName, "enabled", "false"), | ||
), | ||
}, | ||
data.ImportStep(), | ||
}, | ||
}) | ||
} | ||
|
||
func testCheckAzureRMSecurityCenterSettingExists(resourceName string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
client := acceptance.AzureProvider.Meta().(*clients.Client).SecurityCenter.SettingClient | ||
ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext | ||
|
||
rs, ok := s.RootModule().Resources[resourceName] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", resourceName) | ||
} | ||
|
||
settingName := rs.Primary.Attributes["setting_name"] | ||
|
||
resp, err := client.Get(ctx, settingName) | ||
if err != nil { | ||
if utils.ResponseWasNotFound(resp.Response) { | ||
return fmt.Errorf("Security Center Setting %q was not found: %+v", settingName, err) | ||
} | ||
|
||
return fmt.Errorf("Bad: Get: %+v", err) | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccAzureRMSecurityCenterSetting_cfg(settingName string, enabled bool) string { | ||
return fmt.Sprintf(` | ||
provider "azurerm" { | ||
features {} | ||
} | ||
resource "azurerm_security_center_setting" "example" { | ||
setting_name = "%s" | ||
enabled = "%t" | ||
} | ||
`, settingName, enabled) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
provider "azurerm" { | ||
features {} | ||
} | ||
|
||
resource "azurerm_security_center_setting" "example" { | ||
setting_name = "MCAS" | ||
enabled = true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.