Skip to content

Commit

Permalink
Add new resource `azurerm_security_center_server_vulnerability_assess…
Browse files Browse the repository at this point in the history
…ments_setting` (#24299)
  • Loading branch information
alexwilcox9 authored Jan 8, 2024
1 parent 0d54027 commit c0b3999
Show file tree
Hide file tree
Showing 23 changed files with 1,282 additions and 26 deletions.
58 changes: 32 additions & 26 deletions internal/services/securitycenter/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,25 @@ import (
"github.com/hashicorp/go-azure-sdk/resource-manager/security/2022-05-01/settings"
"github.com/hashicorp/go-azure-sdk/resource-manager/security/2022-12-01-preview/defenderforstorage"
pricings_v2023_01_01 "github.com/hashicorp/go-azure-sdk/resource-manager/security/2023-01-01/pricings"
"github.com/hashicorp/go-azure-sdk/resource-manager/security/2023-05-01/servervulnerabilityassessmentssettings"
"github.com/hashicorp/terraform-provider-azurerm/internal/common"
)

type Client struct {
AssessmentsClient *security.AssessmentsClient
AssessmentsMetadataClient *assessmentsmetadata.AssessmentsMetadataClient
ContactsClient *security.ContactsClient
DeviceSecurityGroupsClient *security.DeviceSecurityGroupsClient
IotSecuritySolutionClient *security.IotSecuritySolutionClient
PricingClient *pricings_v2023_01_01.PricingsClient
WorkspaceClient *security.WorkspaceSettingsClient
AdvancedThreatProtectionClient *security.AdvancedThreatProtectionClient
AutoProvisioningClient *security.AutoProvisioningSettingsClient
SettingClient *settings.SettingsClient
AutomationsClient *automations.AutomationsClient
ServerVulnerabilityAssessmentClient *security.ServerVulnerabilityAssessmentClient
DefenderForStorageClient *defenderforstorage.DefenderForStorageClient
AssessmentsClient *security.AssessmentsClient
AssessmentsMetadataClient *assessmentsmetadata.AssessmentsMetadataClient
ContactsClient *security.ContactsClient
DeviceSecurityGroupsClient *security.DeviceSecurityGroupsClient
IotSecuritySolutionClient *security.IotSecuritySolutionClient
PricingClient *pricings_v2023_01_01.PricingsClient
WorkspaceClient *security.WorkspaceSettingsClient
AdvancedThreatProtectionClient *security.AdvancedThreatProtectionClient
AutoProvisioningClient *security.AutoProvisioningSettingsClient
SettingClient *settings.SettingsClient
AutomationsClient *automations.AutomationsClient
ServerVulnerabilityAssessmentClient *security.ServerVulnerabilityAssessmentClient
ServerVulnerabilityAssessmentSettingClient *servervulnerabilityassessmentssettings.ServerVulnerabilityAssessmentsSettingsClient
DefenderForStorageClient *defenderforstorage.DefenderForStorageClient
}

func NewClient(o *common.ClientOptions) *Client {
Expand Down Expand Up @@ -68,22 +70,26 @@ func NewClient(o *common.ClientOptions) *Client {
ServerVulnerabilityAssessmentClient := security.NewServerVulnerabilityAssessmentClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId, ascLocation)
o.ConfigureClient(&ServerVulnerabilityAssessmentClient.Client, o.ResourceManagerAuthorizer)

ServerVulnerabilityAssessmentSettingClient := servervulnerabilityassessmentssettings.NewServerVulnerabilityAssessmentsSettingsClientWithBaseURI(o.ResourceManagerEndpoint)
o.ConfigureClient(&ServerVulnerabilityAssessmentSettingClient.Client, o.ResourceManagerAuthorizer)

DefenderForStorageClient := defenderforstorage.NewDefenderForStorageClientWithBaseURI(o.ResourceManagerEndpoint)
o.ConfigureClient(&DefenderForStorageClient.Client, o.ResourceManagerAuthorizer)

return &Client{
AssessmentsClient: &AssessmentsClient,
AssessmentsMetadataClient: &AssessmentsMetadataClient,
ContactsClient: &ContactsClient,
DeviceSecurityGroupsClient: &DeviceSecurityGroupsClient,
IotSecuritySolutionClient: &IotSecuritySolutionClient,
PricingClient: &PricingClient,
WorkspaceClient: &WorkspaceClient,
AdvancedThreatProtectionClient: &AdvancedThreatProtectionClient,
AutoProvisioningClient: &AutoProvisioningClient,
SettingClient: &SettingClient,
AutomationsClient: &AutomationsClient,
ServerVulnerabilityAssessmentClient: &ServerVulnerabilityAssessmentClient,
DefenderForStorageClient: &DefenderForStorageClient,
AssessmentsClient: &AssessmentsClient,
AssessmentsMetadataClient: &AssessmentsMetadataClient,
ContactsClient: &ContactsClient,
DeviceSecurityGroupsClient: &DeviceSecurityGroupsClient,
IotSecuritySolutionClient: &IotSecuritySolutionClient,
PricingClient: &PricingClient,
WorkspaceClient: &WorkspaceClient,
AdvancedThreatProtectionClient: &AdvancedThreatProtectionClient,
AutoProvisioningClient: &AutoProvisioningClient,
SettingClient: &SettingClient,
AutomationsClient: &AutomationsClient,
ServerVulnerabilityAssessmentClient: &ServerVulnerabilityAssessmentClient,
ServerVulnerabilityAssessmentSettingClient: &ServerVulnerabilityAssessmentSettingClient,
DefenderForStorageClient: &DefenderForStorageClient,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"
"strings"

"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids"
)

type VulnerabilityAssessmentsSettingId struct {
SubscriptionId string
ServerVulnerabilityAssessmentsSettingName string
}

func NewVulnerabilityAssessmentsSettingID(subscriptionId, serverVulnerabilityAssessmentsSettingName string) VulnerabilityAssessmentsSettingId {
return VulnerabilityAssessmentsSettingId{
SubscriptionId: subscriptionId,
ServerVulnerabilityAssessmentsSettingName: serverVulnerabilityAssessmentsSettingName,
}
}

func (id VulnerabilityAssessmentsSettingId) String() string {
segments := []string{
fmt.Sprintf("Server Vulnerability Assessments Setting Name %q", id.ServerVulnerabilityAssessmentsSettingName),
}
segmentsStr := strings.Join(segments, " / ")
return fmt.Sprintf("%s: (%s)", "Vulnerability Assessments Setting", segmentsStr)
}

func (id VulnerabilityAssessmentsSettingId) ID() string {
fmtString := "/subscriptions/%s/providers/Microsoft.Security/serverVulnerabilityAssessmentsSettings/%s"
return fmt.Sprintf(fmtString, id.SubscriptionId, id.ServerVulnerabilityAssessmentsSettingName)
}

// VulnerabilityAssessmentsSettingID parses a VulnerabilityAssessmentsSetting ID into an VulnerabilityAssessmentsSettingId struct
func VulnerabilityAssessmentsSettingID(input string) (*VulnerabilityAssessmentsSettingId, error) {
id, err := resourceids.ParseAzureResourceID(input)
if err != nil {
return nil, fmt.Errorf("parsing %q as an VulnerabilityAssessmentsSetting ID: %+v", input, err)
}

resourceId := VulnerabilityAssessmentsSettingId{
SubscriptionId: id.SubscriptionID,
}

if resourceId.SubscriptionId == "" {
return nil, fmt.Errorf("ID was missing the 'subscriptions' element")
}

if resourceId.ServerVulnerabilityAssessmentsSettingName, err = id.PopSegment("serverVulnerabilityAssessmentsSettings"); err != nil {
return nil, err
}

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

return &resourceId, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"testing"

"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids"
)

var _ resourceids.Id = VulnerabilityAssessmentsSettingId{}

func TestVulnerabilityAssessmentsSettingIDFormatter(t *testing.T) {
actual := NewVulnerabilityAssessmentsSettingID("12345678-1234-9876-4563-123456789012", "AzureServersSetting").ID()
expected := "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Security/serverVulnerabilityAssessmentsSettings/AzureServersSetting"
if actual != expected {
t.Fatalf("Expected %q but got %q", expected, actual)
}
}

func TestVulnerabilityAssessmentsSettingID(t *testing.T) {
testData := []struct {
Input string
Error bool
Expected *VulnerabilityAssessmentsSettingId
}{

{
// empty
Input: "",
Error: true,
},

{
// missing SubscriptionId
Input: "/",
Error: true,
},

{
// missing value for SubscriptionId
Input: "/subscriptions/",
Error: true,
},

{
// missing ServerVulnerabilityAssessmentsSettingName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Security/",
Error: true,
},

{
// missing value for ServerVulnerabilityAssessmentsSettingName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Security/serverVulnerabilityAssessmentsSettings/",
Error: true,
},

{
// valid
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Security/serverVulnerabilityAssessmentsSettings/AzureServersSetting",
Expected: &VulnerabilityAssessmentsSettingId{
SubscriptionId: "12345678-1234-9876-4563-123456789012",
ServerVulnerabilityAssessmentsSettingName: "AzureServersSetting",
},
},

{
// upper-cased
Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/PROVIDERS/MICROSOFT.SECURITY/SERVERVULNERABILITYASSESSMENTSSETTINGS/AZURESERVERSSETTING",
Error: true,
},
}

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

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

t.Fatalf("Expect a value but got an error: %s", err)
}
if v.Error {
t.Fatal("Expect an error but didn't get one")
}

if actual.SubscriptionId != v.Expected.SubscriptionId {
t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId)
}
if actual.ServerVulnerabilityAssessmentsSettingName != v.Expected.ServerVulnerabilityAssessmentsSettingName {
t.Fatalf("Expected %q but got %q for ServerVulnerabilityAssessmentsSettingName", v.Expected.ServerVulnerabilityAssessmentsSettingName, actual.ServerVulnerabilityAssessmentsSettingName)
}
}
}
1 change: 1 addition & 0 deletions internal/services/securitycenter/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource {
"azurerm_security_center_automation": resourceSecurityCenterAutomation(),
"azurerm_security_center_auto_provisioning": resourceSecurityCenterAutoProvisioning(),
"azurerm_security_center_server_vulnerability_assessment": resourceServerVulnerabilityAssessment(),
"azurerm_security_center_server_vulnerability_assessments_setting": resourceSecurityCenterServerVulnerabilityAssessmentsSetting(),
"azurerm_security_center_server_vulnerability_assessment_virtual_machine": resourceServerVulnerabilityAssessmentVirtualMachine(),
}
}
Expand Down
1 change: 1 addition & 0 deletions internal/services/securitycenter/resourceids.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ package securitycenter
//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=IotSecuritySolution -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Security/iotSecuritySolutions/solution1 -rewrite=true

//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=VulnerabilityAssessmentVm -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Compute/virtualMachines/vm-name1/providers/Microsoft.Security/serverVulnerabilityAssessments/default1
//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=VulnerabilityAssessmentsSetting -id=/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Security/serverVulnerabilityAssessmentsSettings/AzureServersSetting
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package securitycenter

import (
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-sdk/resource-manager/security/2023-05-01/servervulnerabilityassessmentssettings"
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/securitycenter/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

func resourceSecurityCenterServerVulnerabilityAssessmentsSetting() *pluginsdk.Resource {

return &pluginsdk.Resource{
Create: resourceSecurityCenterServerVulnerabilityAssessmentsSettingCreateOrUpdate,
Read: resourceSecurityCenterServerVulnerabilityAssessmentsSettingRead,
Update: resourceSecurityCenterServerVulnerabilityAssessmentsSettingCreateOrUpdate,
Delete: resourceSecurityCenterServerVulnerabilityAssessmentsSettingDelete,

Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error {
_, err := parse.VulnerabilityAssessmentsSettingID(id)
return err
}),

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

Schema: map[string]*pluginsdk.Schema{
"vulnerability_assessment_provider": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice(servervulnerabilityassessmentssettings.PossibleValuesForServerVulnerabilityAssessmentsAzureSettingSelectedProvider(), false),
},
},
}
}

func resourceSecurityCenterServerVulnerabilityAssessmentsSettingCreateOrUpdate(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).SecurityCenter.ServerVulnerabilityAssessmentSettingClient
subscriptionId := commonids.NewSubscriptionID(meta.(*clients.Client).Account.SubscriptionId)
ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

id := parse.NewVulnerabilityAssessmentsSettingID(subscriptionId.SubscriptionId, "AzureServersSetting")

if d.IsNewResource() {
existing, err := client.Get(ctx, subscriptionId)
if err != nil {
if !response.WasNotFound(existing.HttpResponse) {
return fmt.Errorf("checking for presence of existing %s: %v", id, err)
}

if existing.Model != nil {
if azureServersSetting, ok := (*existing.Model).(servervulnerabilityassessmentssettings.AzureServersSetting); ok && azureServersSetting.Properties != nil && azureServersSetting.Properties.SelectedProvider != "" {
return tf.ImportAsExistsError("azurerm_security_center_server_vulnerability_assessments_setting", id.ID())
}
}
}
}

setting := servervulnerabilityassessmentssettings.AzureServersSetting{
Type: utils.String("AzureServersSetting"),
Name: utils.String("AzureServersSetting"),
Properties: &servervulnerabilityassessmentssettings.ServerVulnerabilityAssessmentsAzureSettingProperties{
SelectedProvider: servervulnerabilityassessmentssettings.ServerVulnerabilityAssessmentsAzureSettingSelectedProvider(d.Get("vulnerability_assessment_provider").(string)),
},
}

if _, err := client.CreateOrUpdate(ctx, subscriptionId, setting); err != nil {
return fmt.Errorf("creating %s: %+v", id, err)
}

d.SetId(id.ID())
return resourceSecurityCenterServerVulnerabilityAssessmentsSettingRead(d, meta)
}

func resourceSecurityCenterServerVulnerabilityAssessmentsSettingRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).SecurityCenter.ServerVulnerabilityAssessmentSettingClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

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

resp, err := client.Get(ctx, commonids.NewSubscriptionID(id.SubscriptionId))
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
d.SetId("")
return nil
}

return fmt.Errorf("retrieving %s: %+v", *id, err)
}

if resp.Model != nil {
if azureServersSetting, ok := (*resp.Model).(servervulnerabilityassessmentssettings.AzureServersSetting); ok && azureServersSetting.Properties != nil {
d.Set("vulnerability_assessment_provider", azureServersSetting.Properties.SelectedProvider)
}
}

return nil
}

func resourceSecurityCenterServerVulnerabilityAssessmentsSettingDelete(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).SecurityCenter.ServerVulnerabilityAssessmentSettingClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

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

if _, err := client.Delete(ctx, commonids.NewSubscriptionID(id.SubscriptionId)); err != nil {
return fmt.Errorf("disabling %s: %+v", id, err)
}

return nil
}
Loading

0 comments on commit c0b3999

Please sign in to comment.