From f31eaa0931c536972bfd865b951825b87812b9ee Mon Sep 17 00:00:00 2001 From: kt Date: Tue, 9 Oct 2018 11:59:29 -0700 Subject: [PATCH 01/35] added new resource azurerm_securitycenter_subscription_pricing --- azurerm/config.go | 11 + azurerm/provider.go | 1 + azurerm/resource_arm_search_service_test.go | 2 - ...arm_securitycenter_subscription_pricing.go | 94 + ...ecuritycenter_subscription_pricing_test.go | 79 + .../security/advancedthreatprotection.go | 173 + .../2017-08-01-preview/security/alerts.go | 799 ++++ .../security/autoprovisioningsettings.go | 282 ++ .../2017-08-01-preview/security/client.go | 53 + .../security/compliances.go | 200 + .../2017-08-01-preview/security/contacts.go | 431 ++ .../security/discoveredsecuritysolutions.go | 313 ++ .../security/externalsecuritysolutions.go | 313 ++ .../security/jitnetworkaccesspolicies.go | 770 ++++ .../2017-08-01-preview/security/locations.go | 208 + .../2017-08-01-preview/security/models.go | 3863 +++++++++++++++++ .../2017-08-01-preview/security/operations.go | 126 + .../2017-08-01-preview/security/pricings.go | 546 +++ .../2017-08-01-preview/security/settings.go | 282 ++ .../mgmt/2017-08-01-preview/security/tasks.go | 659 +++ .../2017-08-01-preview/security/version.go | 30 + .../security/workspacesettings.go | 431 ++ vendor/vendor.json | 8 + 23 files changed, 9672 insertions(+), 2 deletions(-) create mode 100644 azurerm/resource_arm_securitycenter_subscription_pricing.go create mode 100644 azurerm/resource_arm_securitycenter_subscription_pricing_test.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/advancedthreatprotection.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/alerts.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/autoprovisioningsettings.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/compliances.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/contacts.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/discoveredsecuritysolutions.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/externalsecuritysolutions.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/jitnetworkaccesspolicies.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/locations.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/models.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/operations.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/pricings.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/settings.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/tasks.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/version.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/workspacesettings.go diff --git a/azurerm/config.go b/azurerm/config.go index 1cf30ebd1384..f9295dc68a0e 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -43,6 +43,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/preview/operationalinsights/mgmt/2015-11-01-preview/operationalinsights" "github.com/Azure/azure-sdk-for-go/services/preview/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement" "github.com/Azure/azure-sdk-for-go/services/preview/resources/mgmt/2018-03-01-preview/management" + "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security" "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" "github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/2016-06-01/recoveryservices" "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis" @@ -252,6 +253,9 @@ type ArmClient struct { // Search searchServicesClient search.ServicesClient + // Security Centre + securityCenterPricingClient security.PricingsClient + // ServiceBus serviceBusQueuesClient servicebus.QueuesClient serviceBusNamespacesClient servicebus.NamespacesClient @@ -492,6 +496,7 @@ func getArmClient(c *authentication.Config) (*ArmClient, error) { client.registerRelayClients(endpoint, c.SubscriptionID, auth, sender) client.registerResourcesClients(endpoint, c.SubscriptionID, auth) client.registerSearchClients(endpoint, c.SubscriptionID, auth) + client.registerSecurityCenterClients(endpoint, c.SubscriptionID, "Global", auth) client.registerServiceBusClients(endpoint, c.SubscriptionID, auth) client.registerServiceFabricClients(endpoint, c.SubscriptionID, auth) client.registerSchedulerClients(endpoint, c.SubscriptionID, auth) @@ -1016,6 +1021,12 @@ func (c *ArmClient) registerSearchClients(endpoint, subscriptionId string, auth c.searchServicesClient = searchClient } +func (c *ArmClient) registerSecurityCenterClients(endpoint, subscriptionId, ascLocation string, auth autorest.Authorizer) { + securityCenterPricingClient := security.NewPricingsClientWithBaseURI(endpoint, subscriptionId, ascLocation) + c.configureClient(&securityCenterPricingClient.Client, auth) + c.securityCenterPricingClient = securityCenterPricingClient +} + func (c *ArmClient) registerServiceBusClients(endpoint, subscriptionId string, auth autorest.Authorizer) { queuesClient := servicebus.NewQueuesClientWithBaseURI(endpoint, subscriptionId) c.configureClient(&queuesClient.Client, auth) diff --git a/azurerm/provider.go b/azurerm/provider.go index e82f7e28590c..e9488ae50e13 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -243,6 +243,7 @@ func Provider() terraform.ResourceProvider { "azurerm_route": resourceArmRoute(), "azurerm_route_table": resourceArmRouteTable(), "azurerm_search_service": resourceArmSearchService(), + "azurerm_securitycenter_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(), "azurerm_servicebus_namespace": resourceArmServiceBusNamespace(), "azurerm_servicebus_namespace_authorization_rule": resourceArmServiceBusNamespaceAuthorizationRule(), "azurerm_servicebus_queue": resourceArmServiceBusQueue(), diff --git a/azurerm/resource_arm_search_service_test.go b/azurerm/resource_arm_search_service_test.go index 7982a8e14ece..ae72f3811be6 100644 --- a/azurerm/resource_arm_search_service_test.go +++ b/azurerm/resource_arm_search_service_test.go @@ -68,7 +68,6 @@ func testCheckAzureRMSearchServiceExists(name string) resource.TestCheckFunc { ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, searchName, nil) - if err != nil { if utils.ResponseWasNotFound(resp.Response) { return fmt.Errorf("Search Service %q (resource group %q) was not found: %+v", searchName, resourceGroup, err) @@ -94,7 +93,6 @@ func testCheckAzureRMSearchServiceDestroy(s *terraform.State) error { ctx := testAccProvider.Meta().(*ArmClient).StopContext resp, err := client.Get(ctx, resourceGroup, searchName, nil) - if err != nil { if utils.ResponseWasNotFound(resp.Response) { return nil diff --git a/azurerm/resource_arm_securitycenter_subscription_pricing.go b/azurerm/resource_arm_securitycenter_subscription_pricing.go new file mode 100644 index 000000000000..d0a92f08e84d --- /dev/null +++ b/azurerm/resource_arm_securitycenter_subscription_pricing.go @@ -0,0 +1,94 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmSecurityCenterSubscriptionPricing() *schema.Resource { + return &schema.Resource{ + Create: resourceArmSecurityCenterSubscriptionPricingCreateUpdate, + Read: resourceArmSecurityCenterSubscriptionPricingRead, + Update: resourceArmSecurityCenterSubscriptionPricingCreateUpdate, + Delete: resourceArmSecurityCenterSubscriptionPricingDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "tier": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + string(security.Free), + string(security.Standard), + }, false), + }, + }, + } +} + +//NOTE: seems default is the only valid pricing name: +//Code="InvalidInputJson" Message="Pricing name '360k Sponsored' is not allowed. Expected 'default' for this scope." +func resourceArmSecurityCenterSubscriptionPricingCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).securityCenterPricingClient + ctx := meta.(*ArmClient).StopContext + + pricing := security.Pricing{ + PricingProperties: &security.PricingProperties{ + PricingTier: security.PricingTier(d.Get("tier").(string)), + }, + } + + _, err := client.UpdateSubscriptionPricing(ctx, "default", pricing) + if err != nil { + return fmt.Errorf("Error updating Security Center Subscription pricing: %+v", err) + } + + resp, err := client.GetSubscriptionPricing(ctx, "default") + if err != nil { + return fmt.Errorf("Error reading Security Center Subscription pricing: %+v", err) + } + if resp.ID == nil { + return fmt.Errorf("Security Center Subscription pricing ID is nil") + } + + d.SetId(*resp.ID) + + return resourceArmSecurityCenterSubscriptionPricingRead(d, meta) +} + +func resourceArmSecurityCenterSubscriptionPricingRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).securityCenterPricingClient + ctx := meta.(*ArmClient).StopContext + + resp, err := client.GetSubscriptionPricing(ctx, "default") + 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 Subscription pricing: %+v", err) + } + + if properties := resp.PricingProperties; properties != nil { + d.Set("tier", properties.PricingTier) + } + + return nil +} + +func resourceArmSecurityCenterSubscriptionPricingDelete(_ *schema.ResourceData, _ interface{}) error { + return nil +} diff --git a/azurerm/resource_arm_securitycenter_subscription_pricing_test.go b/azurerm/resource_arm_securitycenter_subscription_pricing_test.go new file mode 100644 index 000000000000..d06ae83b5ae2 --- /dev/null +++ b/azurerm/resource_arm_securitycenter_subscription_pricing_test.go @@ -0,0 +1,79 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMSecurityCenterSubscriptionPricing_update(t *testing.T) { + resourceName := "azurerm_securitycenter_subscription_pricing.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSecurityCenterSubscriptionPricing_tier("Standard"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSecurityCenterSubscriptionPricingExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tier", "Standard"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMSecurityCenterSubscriptionPricing_tier("Standard"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSecurityCenterSubscriptionPricingExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tier", "Standard"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMSecurityCenterSubscriptionPricingExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + pricingName := rs.Primary.Attributes["pricings"] + + client := testAccProvider.Meta().(*ArmClient).securityCenterPricingClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.GetSubscriptionPricing(ctx, pricingName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Security Center Subscription Pricing %q was not found: %+v", pricingName, err) + } + + return fmt.Errorf("Bad: GetSubscriptionPricing: %+v", err) + } + + return nil + } +} + +func testAccAzureRMSecurityCenterSubscriptionPricing_tier(tier string) string { + return fmt.Sprintf(` +resource "azurerm_securitycenter_subscription_pricing" "test" { + tier = "%s" +} +`, tier) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/advancedthreatprotection.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/advancedthreatprotection.go new file mode 100644 index 000000000000..92aaddbf2f52 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/advancedthreatprotection.go @@ -0,0 +1,173 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// AdvancedThreatProtectionClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type AdvancedThreatProtectionClient struct { + BaseClient +} + +// NewAdvancedThreatProtectionClient creates an instance of the AdvancedThreatProtectionClient client. +func NewAdvancedThreatProtectionClient(subscriptionID string, ascLocation string) AdvancedThreatProtectionClient { + return NewAdvancedThreatProtectionClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewAdvancedThreatProtectionClientWithBaseURI creates an instance of the AdvancedThreatProtectionClient client. +func NewAdvancedThreatProtectionClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) AdvancedThreatProtectionClient { + return AdvancedThreatProtectionClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// Create creates or updates the Advanced Threat Protection settings on a specified resource. +// Parameters: +// resourceID - the identifier of the resource. +// advancedThreatProtectionSetting - advanced Threat Protection Settings +func (client AdvancedThreatProtectionClient) Create(ctx context.Context, resourceID string, advancedThreatProtectionSetting AdvancedThreatProtectionSetting) (result AdvancedThreatProtectionSetting, err error) { + req, err := client.CreatePreparer(ctx, resourceID, advancedThreatProtectionSetting) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AdvancedThreatProtectionClient", "Create", nil, "Failure preparing request") + return + } + + resp, err := client.CreateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AdvancedThreatProtectionClient", "Create", resp, "Failure sending request") + return + } + + result, err = client.CreateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AdvancedThreatProtectionClient", "Create", resp, "Failure responding to request") + } + + return +} + +// CreatePreparer prepares the Create request. +func (client AdvancedThreatProtectionClient) CreatePreparer(ctx context.Context, resourceID string, advancedThreatProtectionSetting AdvancedThreatProtectionSetting) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceId": autorest.Encode("path", resourceID), + "settingName": autorest.Encode("path", "current"), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{resourceId}/providers/Microsoft.Security/advancedThreatProtectionSettings/{settingName}", pathParameters), + autorest.WithJSON(advancedThreatProtectionSetting), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateSender sends the Create request. The method will close the +// http.Response Body if it receives an error. +func (client AdvancedThreatProtectionClient) CreateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// CreateResponder handles the response to the Create request. The method always +// closes the http.Response Body. +func (client AdvancedThreatProtectionClient) CreateResponder(resp *http.Response) (result AdvancedThreatProtectionSetting, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Get gets the Advanced Threat Protection settings for the specified resource. +// Parameters: +// resourceID - the identifier of the resource. +func (client AdvancedThreatProtectionClient) Get(ctx context.Context, resourceID string) (result AdvancedThreatProtectionSetting, err error) { + req, err := client.GetPreparer(ctx, resourceID) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AdvancedThreatProtectionClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AdvancedThreatProtectionClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AdvancedThreatProtectionClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client AdvancedThreatProtectionClient) GetPreparer(ctx context.Context, resourceID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceId": autorest.Encode("path", resourceID), + "settingName": autorest.Encode("path", "current"), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{resourceId}/providers/Microsoft.Security/advancedThreatProtectionSettings/{settingName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client AdvancedThreatProtectionClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client AdvancedThreatProtectionClient) GetResponder(resp *http.Response) (result AdvancedThreatProtectionSetting, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/alerts.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/alerts.go new file mode 100644 index 000000000000..75b2552d9932 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/alerts.go @@ -0,0 +1,799 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// AlertsClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type AlertsClient struct { + BaseClient +} + +// NewAlertsClient creates an instance of the AlertsClient client. +func NewAlertsClient(subscriptionID string, ascLocation string) AlertsClient { + return NewAlertsClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewAlertsClientWithBaseURI creates an instance of the AlertsClient client. +func NewAlertsClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) AlertsClient { + return AlertsClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// GetResourceGroupLevelAlerts get an alert that is associated a resource group or a resource in a resource group +// Parameters: +// alertName - name of the alert object +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +func (client AlertsClient) GetResourceGroupLevelAlerts(ctx context.Context, alertName string, resourceGroupName string) (result Alert, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AlertsClient", "GetResourceGroupLevelAlerts", err.Error()) + } + + req, err := client.GetResourceGroupLevelAlertsPreparer(ctx, alertName, resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "GetResourceGroupLevelAlerts", nil, "Failure preparing request") + return + } + + resp, err := client.GetResourceGroupLevelAlertsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AlertsClient", "GetResourceGroupLevelAlerts", resp, "Failure sending request") + return + } + + result, err = client.GetResourceGroupLevelAlertsResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "GetResourceGroupLevelAlerts", resp, "Failure responding to request") + } + + return +} + +// GetResourceGroupLevelAlertsPreparer prepares the GetResourceGroupLevelAlerts request. +func (client AlertsClient) GetResourceGroupLevelAlertsPreparer(ctx context.Context, alertName string, resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "alertName": autorest.Encode("path", alertName), + "ascLocation": autorest.Encode("path", client.AscLocation), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/alerts/{alertName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetResourceGroupLevelAlertsSender sends the GetResourceGroupLevelAlerts request. The method will close the +// http.Response Body if it receives an error. +func (client AlertsClient) GetResourceGroupLevelAlertsSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResourceGroupLevelAlertsResponder handles the response to the GetResourceGroupLevelAlerts request. The method always +// closes the http.Response Body. +func (client AlertsClient) GetResourceGroupLevelAlertsResponder(resp *http.Response) (result Alert, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSubscriptionLevelAlert get an alert that is associated with a subscription +// Parameters: +// alertName - name of the alert object +func (client AlertsClient) GetSubscriptionLevelAlert(ctx context.Context, alertName string) (result Alert, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AlertsClient", "GetSubscriptionLevelAlert", err.Error()) + } + + req, err := client.GetSubscriptionLevelAlertPreparer(ctx, alertName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "GetSubscriptionLevelAlert", nil, "Failure preparing request") + return + } + + resp, err := client.GetSubscriptionLevelAlertSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AlertsClient", "GetSubscriptionLevelAlert", resp, "Failure sending request") + return + } + + result, err = client.GetSubscriptionLevelAlertResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "GetSubscriptionLevelAlert", resp, "Failure responding to request") + } + + return +} + +// GetSubscriptionLevelAlertPreparer prepares the GetSubscriptionLevelAlert request. +func (client AlertsClient) GetSubscriptionLevelAlertPreparer(ctx context.Context, alertName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "alertName": autorest.Encode("path", alertName), + "ascLocation": autorest.Encode("path", client.AscLocation), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations/{ascLocation}/alerts/{alertName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSubscriptionLevelAlertSender sends the GetSubscriptionLevelAlert request. The method will close the +// http.Response Body if it receives an error. +func (client AlertsClient) GetSubscriptionLevelAlertSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetSubscriptionLevelAlertResponder handles the response to the GetSubscriptionLevelAlert request. The method always +// closes the http.Response Body. +func (client AlertsClient) GetSubscriptionLevelAlertResponder(resp *http.Response) (result Alert, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List list all the alerts that are associated with the subscription +// Parameters: +// filter - oData filter. Optional. +// selectParameter - oData select. Optional. +// expand - oData expand. Optional. +func (client AlertsClient) List(ctx context.Context, filter string, selectParameter string, expand string) (result AlertListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AlertsClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx, filter, selectParameter, expand) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.al.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AlertsClient", "List", resp, "Failure sending request") + return + } + + result.al, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client AlertsClient) ListPreparer(ctx context.Context, filter string, selectParameter string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if len(selectParameter) > 0 { + queryParameters["$select"] = autorest.Encode("query", selectParameter) + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/alerts", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client AlertsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client AlertsClient) ListResponder(resp *http.Response) (result AlertList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client AlertsClient) listNextResults(lastResults AlertList) (result AlertList, err error) { + req, err := lastResults.alertListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.AlertsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.AlertsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client AlertsClient) ListComplete(ctx context.Context, filter string, selectParameter string, expand string) (result AlertListIterator, err error) { + result.page, err = client.List(ctx, filter, selectParameter, expand) + return +} + +// ListByResourceGroup list all the alerts alerts that are associated with the resource group +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// filter - oData filter. Optional. +// selectParameter - oData select. Optional. +// expand - oData expand. Optional. +func (client AlertsClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, filter string, selectParameter string, expand string) (result AlertListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AlertsClient", "ListByResourceGroup", err.Error()) + } + + result.fn = client.listByResourceGroupNextResults + req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName, filter, selectParameter, expand) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.al.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AlertsClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result.al, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client AlertsClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string, filter string, selectParameter string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if len(selectParameter) > 0 { + queryParameters["$select"] = autorest.Encode("query", selectParameter) + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/alerts", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client AlertsClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client AlertsClient) ListByResourceGroupResponder(resp *http.Response) (result AlertList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByResourceGroupNextResults retrieves the next set of results, if any. +func (client AlertsClient) listByResourceGroupNextResults(lastResults AlertList) (result AlertList, err error) { + req, err := lastResults.alertListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.AlertsClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.AlertsClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. +func (client AlertsClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, filter string, selectParameter string, expand string) (result AlertListIterator, err error) { + result.page, err = client.ListByResourceGroup(ctx, resourceGroupName, filter, selectParameter, expand) + return +} + +// ListResourceGroupLevelAlertsByRegion list all the alerts that are associated with the resource group that are stored +// in a specific location +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// filter - oData filter. Optional. +// selectParameter - oData select. Optional. +// expand - oData expand. Optional. +func (client AlertsClient) ListResourceGroupLevelAlertsByRegion(ctx context.Context, resourceGroupName string, filter string, selectParameter string, expand string) (result AlertListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AlertsClient", "ListResourceGroupLevelAlertsByRegion", err.Error()) + } + + result.fn = client.listResourceGroupLevelAlertsByRegionNextResults + req, err := client.ListResourceGroupLevelAlertsByRegionPreparer(ctx, resourceGroupName, filter, selectParameter, expand) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "ListResourceGroupLevelAlertsByRegion", nil, "Failure preparing request") + return + } + + resp, err := client.ListResourceGroupLevelAlertsByRegionSender(req) + if err != nil { + result.al.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AlertsClient", "ListResourceGroupLevelAlertsByRegion", resp, "Failure sending request") + return + } + + result.al, err = client.ListResourceGroupLevelAlertsByRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "ListResourceGroupLevelAlertsByRegion", resp, "Failure responding to request") + } + + return +} + +// ListResourceGroupLevelAlertsByRegionPreparer prepares the ListResourceGroupLevelAlertsByRegion request. +func (client AlertsClient) ListResourceGroupLevelAlertsByRegionPreparer(ctx context.Context, resourceGroupName string, filter string, selectParameter string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if len(selectParameter) > 0 { + queryParameters["$select"] = autorest.Encode("query", selectParameter) + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/alerts", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListResourceGroupLevelAlertsByRegionSender sends the ListResourceGroupLevelAlertsByRegion request. The method will close the +// http.Response Body if it receives an error. +func (client AlertsClient) ListResourceGroupLevelAlertsByRegionSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResourceGroupLevelAlertsByRegionResponder handles the response to the ListResourceGroupLevelAlertsByRegion request. The method always +// closes the http.Response Body. +func (client AlertsClient) ListResourceGroupLevelAlertsByRegionResponder(resp *http.Response) (result AlertList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listResourceGroupLevelAlertsByRegionNextResults retrieves the next set of results, if any. +func (client AlertsClient) listResourceGroupLevelAlertsByRegionNextResults(lastResults AlertList) (result AlertList, err error) { + req, err := lastResults.alertListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.AlertsClient", "listResourceGroupLevelAlertsByRegionNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListResourceGroupLevelAlertsByRegionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.AlertsClient", "listResourceGroupLevelAlertsByRegionNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResourceGroupLevelAlertsByRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "listResourceGroupLevelAlertsByRegionNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListResourceGroupLevelAlertsByRegionComplete enumerates all values, automatically crossing page boundaries as required. +func (client AlertsClient) ListResourceGroupLevelAlertsByRegionComplete(ctx context.Context, resourceGroupName string, filter string, selectParameter string, expand string) (result AlertListIterator, err error) { + result.page, err = client.ListResourceGroupLevelAlertsByRegion(ctx, resourceGroupName, filter, selectParameter, expand) + return +} + +// ListSubscriptionLevelAlertsByRegion list all the alerts that are associated with the subscription that are stored in +// a specific location +// Parameters: +// filter - oData filter. Optional. +// selectParameter - oData select. Optional. +// expand - oData expand. Optional. +func (client AlertsClient) ListSubscriptionLevelAlertsByRegion(ctx context.Context, filter string, selectParameter string, expand string) (result AlertListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AlertsClient", "ListSubscriptionLevelAlertsByRegion", err.Error()) + } + + result.fn = client.listSubscriptionLevelAlertsByRegionNextResults + req, err := client.ListSubscriptionLevelAlertsByRegionPreparer(ctx, filter, selectParameter, expand) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "ListSubscriptionLevelAlertsByRegion", nil, "Failure preparing request") + return + } + + resp, err := client.ListSubscriptionLevelAlertsByRegionSender(req) + if err != nil { + result.al.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AlertsClient", "ListSubscriptionLevelAlertsByRegion", resp, "Failure sending request") + return + } + + result.al, err = client.ListSubscriptionLevelAlertsByRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "ListSubscriptionLevelAlertsByRegion", resp, "Failure responding to request") + } + + return +} + +// ListSubscriptionLevelAlertsByRegionPreparer prepares the ListSubscriptionLevelAlertsByRegion request. +func (client AlertsClient) ListSubscriptionLevelAlertsByRegionPreparer(ctx context.Context, filter string, selectParameter string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + if len(selectParameter) > 0 { + queryParameters["$select"] = autorest.Encode("query", selectParameter) + } + if len(expand) > 0 { + queryParameters["$expand"] = autorest.Encode("query", expand) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations/{ascLocation}/alerts", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSubscriptionLevelAlertsByRegionSender sends the ListSubscriptionLevelAlertsByRegion request. The method will close the +// http.Response Body if it receives an error. +func (client AlertsClient) ListSubscriptionLevelAlertsByRegionSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListSubscriptionLevelAlertsByRegionResponder handles the response to the ListSubscriptionLevelAlertsByRegion request. The method always +// closes the http.Response Body. +func (client AlertsClient) ListSubscriptionLevelAlertsByRegionResponder(resp *http.Response) (result AlertList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listSubscriptionLevelAlertsByRegionNextResults retrieves the next set of results, if any. +func (client AlertsClient) listSubscriptionLevelAlertsByRegionNextResults(lastResults AlertList) (result AlertList, err error) { + req, err := lastResults.alertListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.AlertsClient", "listSubscriptionLevelAlertsByRegionNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSubscriptionLevelAlertsByRegionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.AlertsClient", "listSubscriptionLevelAlertsByRegionNextResults", resp, "Failure sending next results request") + } + result, err = client.ListSubscriptionLevelAlertsByRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "listSubscriptionLevelAlertsByRegionNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListSubscriptionLevelAlertsByRegionComplete enumerates all values, automatically crossing page boundaries as required. +func (client AlertsClient) ListSubscriptionLevelAlertsByRegionComplete(ctx context.Context, filter string, selectParameter string, expand string) (result AlertListIterator, err error) { + result.page, err = client.ListSubscriptionLevelAlertsByRegion(ctx, filter, selectParameter, expand) + return +} + +// UpdateResourceGroupLevelAlertState update the alert's state +// Parameters: +// alertName - name of the alert object +// alertUpdateActionType - type of the action to do on the alert +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +func (client AlertsClient) UpdateResourceGroupLevelAlertState(ctx context.Context, alertName string, alertUpdateActionType string, resourceGroupName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AlertsClient", "UpdateResourceGroupLevelAlertState", err.Error()) + } + + req, err := client.UpdateResourceGroupLevelAlertStatePreparer(ctx, alertName, alertUpdateActionType, resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "UpdateResourceGroupLevelAlertState", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateResourceGroupLevelAlertStateSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "security.AlertsClient", "UpdateResourceGroupLevelAlertState", resp, "Failure sending request") + return + } + + result, err = client.UpdateResourceGroupLevelAlertStateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "UpdateResourceGroupLevelAlertState", resp, "Failure responding to request") + } + + return +} + +// UpdateResourceGroupLevelAlertStatePreparer prepares the UpdateResourceGroupLevelAlertState request. +func (client AlertsClient) UpdateResourceGroupLevelAlertStatePreparer(ctx context.Context, alertName string, alertUpdateActionType string, resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "alertName": autorest.Encode("path", alertName), + "alertUpdateActionType": autorest.Encode("path", alertUpdateActionType), + "ascLocation": autorest.Encode("path", client.AscLocation), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/alerts/{alertName}/{alertUpdateActionType}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateResourceGroupLevelAlertStateSender sends the UpdateResourceGroupLevelAlertState request. The method will close the +// http.Response Body if it receives an error. +func (client AlertsClient) UpdateResourceGroupLevelAlertStateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// UpdateResourceGroupLevelAlertStateResponder handles the response to the UpdateResourceGroupLevelAlertState request. The method always +// closes the http.Response Body. +func (client AlertsClient) UpdateResourceGroupLevelAlertStateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// UpdateSubscriptionLevelAlertState update the alert's state +// Parameters: +// alertName - name of the alert object +// alertUpdateActionType - type of the action to do on the alert +func (client AlertsClient) UpdateSubscriptionLevelAlertState(ctx context.Context, alertName string, alertUpdateActionType string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AlertsClient", "UpdateSubscriptionLevelAlertState", err.Error()) + } + + req, err := client.UpdateSubscriptionLevelAlertStatePreparer(ctx, alertName, alertUpdateActionType) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "UpdateSubscriptionLevelAlertState", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSubscriptionLevelAlertStateSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "security.AlertsClient", "UpdateSubscriptionLevelAlertState", resp, "Failure sending request") + return + } + + result, err = client.UpdateSubscriptionLevelAlertStateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AlertsClient", "UpdateSubscriptionLevelAlertState", resp, "Failure responding to request") + } + + return +} + +// UpdateSubscriptionLevelAlertStatePreparer prepares the UpdateSubscriptionLevelAlertState request. +func (client AlertsClient) UpdateSubscriptionLevelAlertStatePreparer(ctx context.Context, alertName string, alertUpdateActionType string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "alertName": autorest.Encode("path", alertName), + "alertUpdateActionType": autorest.Encode("path", alertUpdateActionType), + "ascLocation": autorest.Encode("path", client.AscLocation), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations/{ascLocation}/alerts/{alertName}/{alertUpdateActionType}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateSubscriptionLevelAlertStateSender sends the UpdateSubscriptionLevelAlertState request. The method will close the +// http.Response Body if it receives an error. +func (client AlertsClient) UpdateSubscriptionLevelAlertStateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// UpdateSubscriptionLevelAlertStateResponder handles the response to the UpdateSubscriptionLevelAlertState request. The method always +// closes the http.Response Body. +func (client AlertsClient) UpdateSubscriptionLevelAlertStateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/autoprovisioningsettings.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/autoprovisioningsettings.go new file mode 100644 index 000000000000..eaa03e36e5b8 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/autoprovisioningsettings.go @@ -0,0 +1,282 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// AutoProvisioningSettingsClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type AutoProvisioningSettingsClient struct { + BaseClient +} + +// NewAutoProvisioningSettingsClient creates an instance of the AutoProvisioningSettingsClient client. +func NewAutoProvisioningSettingsClient(subscriptionID string, ascLocation string) AutoProvisioningSettingsClient { + return NewAutoProvisioningSettingsClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewAutoProvisioningSettingsClientWithBaseURI creates an instance of the AutoProvisioningSettingsClient client. +func NewAutoProvisioningSettingsClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) AutoProvisioningSettingsClient { + return AutoProvisioningSettingsClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// Create details of a specific setting +// Parameters: +// settingName - auto provisioning setting key +// setting - auto provisioning setting key +func (client AutoProvisioningSettingsClient) Create(ctx context.Context, settingName string, setting AutoProvisioningSetting) (result AutoProvisioningSetting, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AutoProvisioningSettingsClient", "Create", err.Error()) + } + + req, err := client.CreatePreparer(ctx, settingName, setting) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "Create", nil, "Failure preparing request") + return + } + + resp, err := client.CreateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "Create", resp, "Failure sending request") + return + } + + result, err = client.CreateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "Create", resp, "Failure responding to request") + } + + return +} + +// CreatePreparer prepares the Create request. +func (client AutoProvisioningSettingsClient) CreatePreparer(ctx context.Context, settingName string, setting AutoProvisioningSetting) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "settingName": autorest.Encode("path", settingName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/autoProvisioningSettings/{settingName}", pathParameters), + autorest.WithJSON(setting), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateSender sends the Create request. The method will close the +// http.Response Body if it receives an error. +func (client AutoProvisioningSettingsClient) CreateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// CreateResponder handles the response to the Create request. The method always +// closes the http.Response Body. +func (client AutoProvisioningSettingsClient) CreateResponder(resp *http.Response) (result AutoProvisioningSetting, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Get details of a specific setting +// Parameters: +// settingName - auto provisioning setting key +func (client AutoProvisioningSettingsClient) Get(ctx context.Context, settingName string) (result AutoProvisioningSetting, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AutoProvisioningSettingsClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx, settingName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client AutoProvisioningSettingsClient) GetPreparer(ctx context.Context, settingName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "settingName": autorest.Encode("path", settingName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/autoProvisioningSettings/{settingName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client AutoProvisioningSettingsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client AutoProvisioningSettingsClient) GetResponder(resp *http.Response) (result AutoProvisioningSetting, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List exposes the auto provisioning settings of the subscriptions +func (client AutoProvisioningSettingsClient) List(ctx context.Context) (result AutoProvisioningSettingListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.AutoProvisioningSettingsClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.apsl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "List", resp, "Failure sending request") + return + } + + result.apsl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client AutoProvisioningSettingsClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/autoProvisioningSettings", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client AutoProvisioningSettingsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client AutoProvisioningSettingsClient) ListResponder(resp *http.Response) (result AutoProvisioningSettingList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client AutoProvisioningSettingsClient) listNextResults(lastResults AutoProvisioningSettingList) (result AutoProvisioningSettingList, err error) { + req, err := lastResults.autoProvisioningSettingListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.AutoProvisioningSettingsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client AutoProvisioningSettingsClient) ListComplete(ctx context.Context) (result AutoProvisioningSettingListIterator, err error) { + result.page, err = client.List(ctx) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/client.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/client.go new file mode 100644 index 000000000000..c1db0ec1e825 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/client.go @@ -0,0 +1,53 @@ +// Package security implements the Azure ARM Security service API version . +// +// API spec for Microsoft.Security (Azure Security Center) resource provider +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // DefaultBaseURI is the default URI used for the service Security + DefaultBaseURI = "https://management.azure.com" +) + +// BaseClient is the base client for Security. +type BaseClient struct { + autorest.Client + BaseURI string + SubscriptionID string + AscLocation string +} + +// New creates an instance of the BaseClient client. +func New(subscriptionID string, ascLocation string) BaseClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewWithBaseURI creates an instance of the BaseClient client. +func NewWithBaseURI(baseURI string, subscriptionID string, ascLocation string) BaseClient { + return BaseClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + SubscriptionID: subscriptionID, + AscLocation: ascLocation, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/compliances.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/compliances.go new file mode 100644 index 000000000000..c8ebf1067465 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/compliances.go @@ -0,0 +1,200 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// CompliancesClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type CompliancesClient struct { + BaseClient +} + +// NewCompliancesClient creates an instance of the CompliancesClient client. +func NewCompliancesClient(subscriptionID string, ascLocation string) CompliancesClient { + return NewCompliancesClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewCompliancesClientWithBaseURI creates an instance of the CompliancesClient client. +func NewCompliancesClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) CompliancesClient { + return CompliancesClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// Get details of a specific Compliance. +// Parameters: +// scope - scope of the query, can be subscription (/subscriptions/0b06d9ea-afe6-4779-bd59-30e5c2d9d13f) or +// management group (/providers/Microsoft.Management/managementGroups/mgName). +// complianceName - name of the Compliance +func (client CompliancesClient) Get(ctx context.Context, scope string, complianceName string) (result Compliance, err error) { + req, err := client.GetPreparer(ctx, scope, complianceName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.CompliancesClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.CompliancesClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.CompliancesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client CompliancesClient) GetPreparer(ctx context.Context, scope string, complianceName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "complianceName": autorest.Encode("path", complianceName), + "scope": autorest.Encode("path", scope), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{scope}/providers/Microsoft.Security/compliances/{complianceName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client CompliancesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client CompliancesClient) GetResponder(resp *http.Response) (result Compliance, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the Compliance scores of the specific management group. +// Parameters: +// scope - scope of the query, can be subscription (/subscriptions/0b06d9ea-afe6-4779-bd59-30e5c2d9d13f) or +// management group (/providers/Microsoft.Management/managementGroups/mgName). +func (client CompliancesClient) List(ctx context.Context, scope string) (result ComplianceListPage, err error) { + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx, scope) + if err != nil { + err = autorest.NewErrorWithError(err, "security.CompliancesClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.cl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.CompliancesClient", "List", resp, "Failure sending request") + return + } + + result.cl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.CompliancesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client CompliancesClient) ListPreparer(ctx context.Context, scope string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "scope": autorest.Encode("path", scope), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{scope}/providers/Microsoft.Security/compliances", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client CompliancesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client CompliancesClient) ListResponder(resp *http.Response) (result ComplianceList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client CompliancesClient) listNextResults(lastResults ComplianceList) (result ComplianceList, err error) { + req, err := lastResults.complianceListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.CompliancesClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.CompliancesClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.CompliancesClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client CompliancesClient) ListComplete(ctx context.Context, scope string) (result ComplianceListIterator, err error) { + result.page, err = client.List(ctx, scope) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/contacts.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/contacts.go new file mode 100644 index 000000000000..13eaffbee663 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/contacts.go @@ -0,0 +1,431 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// ContactsClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type ContactsClient struct { + BaseClient +} + +// NewContactsClient creates an instance of the ContactsClient client. +func NewContactsClient(subscriptionID string, ascLocation string) ContactsClient { + return NewContactsClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewContactsClientWithBaseURI creates an instance of the ContactsClient client. +func NewContactsClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) ContactsClient { + return ContactsClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// Create security contact configurations for the subscription +// Parameters: +// securityContactName - name of the security contact object +// securityContact - security contact object +func (client ContactsClient) Create(ctx context.Context, securityContactName string, securityContact Contact) (result Contact, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: securityContact, + Constraints: []validation.Constraint{{Target: "securityContact.ContactProperties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "securityContact.ContactProperties.Email", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "securityContact.ContactProperties.Phone", Name: validation.Null, Rule: true, Chain: nil}, + }}}}}); err != nil { + return result, validation.NewError("security.ContactsClient", "Create", err.Error()) + } + + req, err := client.CreatePreparer(ctx, securityContactName, securityContact) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Create", nil, "Failure preparing request") + return + } + + resp, err := client.CreateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Create", resp, "Failure sending request") + return + } + + result, err = client.CreateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Create", resp, "Failure responding to request") + } + + return +} + +// CreatePreparer prepares the Create request. +func (client ContactsClient) CreatePreparer(ctx context.Context, securityContactName string, securityContact Contact) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "securityContactName": autorest.Encode("path", securityContactName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/securityContacts/{securityContactName}", pathParameters), + autorest.WithJSON(securityContact), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateSender sends the Create request. The method will close the +// http.Response Body if it receives an error. +func (client ContactsClient) CreateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// CreateResponder handles the response to the Create request. The method always +// closes the http.Response Body. +func (client ContactsClient) CreateResponder(resp *http.Response) (result Contact, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete security contact configurations for the subscription +// Parameters: +// securityContactName - name of the security contact object +func (client ContactsClient) Delete(ctx context.Context, securityContactName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.ContactsClient", "Delete", err.Error()) + } + + req, err := client.DeletePreparer(ctx, securityContactName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ContactsClient) DeletePreparer(ctx context.Context, securityContactName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "securityContactName": autorest.Encode("path", securityContactName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/securityContacts/{securityContactName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ContactsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ContactsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get security contact configurations for the subscription +// Parameters: +// securityContactName - name of the security contact object +func (client ContactsClient) Get(ctx context.Context, securityContactName string) (result Contact, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.ContactsClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx, securityContactName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ContactsClient) GetPreparer(ctx context.Context, securityContactName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "securityContactName": autorest.Encode("path", securityContactName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/securityContacts/{securityContactName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ContactsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ContactsClient) GetResponder(resp *http.Response) (result Contact, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List security contact configurations for the subscription +func (client ContactsClient) List(ctx context.Context) (result ContactListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.ContactsClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.cl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.ContactsClient", "List", resp, "Failure sending request") + return + } + + result.cl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ContactsClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/securityContacts", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ContactsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ContactsClient) ListResponder(resp *http.Response) (result ContactList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client ContactsClient) listNextResults(lastResults ContactList) (result ContactList, err error) { + req, err := lastResults.contactListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.ContactsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.ContactsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client ContactsClient) ListComplete(ctx context.Context) (result ContactListIterator, err error) { + result.page, err = client.List(ctx) + return +} + +// Update security contact configurations for the subscription +// Parameters: +// securityContactName - name of the security contact object +// securityContact - security contact object +func (client ContactsClient) Update(ctx context.Context, securityContactName string, securityContact Contact) (result Contact, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.ContactsClient", "Update", err.Error()) + } + + req, err := client.UpdatePreparer(ctx, securityContactName, securityContact) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Update", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Update", resp, "Failure sending request") + return + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ContactsClient", "Update", resp, "Failure responding to request") + } + + return +} + +// UpdatePreparer prepares the Update request. +func (client ContactsClient) UpdatePreparer(ctx context.Context, securityContactName string, securityContact Contact) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "securityContactName": autorest.Encode("path", securityContactName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/securityContacts/{securityContactName}", pathParameters), + autorest.WithJSON(securityContact), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client ContactsClient) UpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client ContactsClient) UpdateResponder(resp *http.Response) (result Contact, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/discoveredsecuritysolutions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/discoveredsecuritysolutions.go new file mode 100644 index 000000000000..cdc013d710ba --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/discoveredsecuritysolutions.go @@ -0,0 +1,313 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// DiscoveredSecuritySolutionsClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type DiscoveredSecuritySolutionsClient struct { + BaseClient +} + +// NewDiscoveredSecuritySolutionsClient creates an instance of the DiscoveredSecuritySolutionsClient client. +func NewDiscoveredSecuritySolutionsClient(subscriptionID string, ascLocation string) DiscoveredSecuritySolutionsClient { + return NewDiscoveredSecuritySolutionsClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewDiscoveredSecuritySolutionsClientWithBaseURI creates an instance of the DiscoveredSecuritySolutionsClient client. +func NewDiscoveredSecuritySolutionsClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) DiscoveredSecuritySolutionsClient { + return DiscoveredSecuritySolutionsClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// Get gets a specific discovered Security Solution. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// discoveredSecuritySolutionName - name of a discovered security solution. +func (client DiscoveredSecuritySolutionsClient) Get(ctx context.Context, resourceGroupName string, discoveredSecuritySolutionName string) (result DiscoveredSecuritySolution, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.DiscoveredSecuritySolutionsClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx, resourceGroupName, discoveredSecuritySolutionName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client DiscoveredSecuritySolutionsClient) GetPreparer(ctx context.Context, resourceGroupName string, discoveredSecuritySolutionName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "discoveredSecuritySolutionName": autorest.Encode("path", discoveredSecuritySolutionName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/discoveredSecuritySolutions/{discoveredSecuritySolutionName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client DiscoveredSecuritySolutionsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client DiscoveredSecuritySolutionsClient) GetResponder(resp *http.Response) (result DiscoveredSecuritySolution, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a list of discovered Security Solutions for the subscription. +func (client DiscoveredSecuritySolutionsClient) List(ctx context.Context) (result DiscoveredSecuritySolutionListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.DiscoveredSecuritySolutionsClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.dssl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "List", resp, "Failure sending request") + return + } + + result.dssl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client DiscoveredSecuritySolutionsClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/discoveredSecuritySolutions", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client DiscoveredSecuritySolutionsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client DiscoveredSecuritySolutionsClient) ListResponder(resp *http.Response) (result DiscoveredSecuritySolutionList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client DiscoveredSecuritySolutionsClient) listNextResults(lastResults DiscoveredSecuritySolutionList) (result DiscoveredSecuritySolutionList, err error) { + req, err := lastResults.discoveredSecuritySolutionListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client DiscoveredSecuritySolutionsClient) ListComplete(ctx context.Context) (result DiscoveredSecuritySolutionListIterator, err error) { + result.page, err = client.List(ctx) + return +} + +// ListByHomeRegion gets a list of discovered Security Solutions for the subscription and location. +func (client DiscoveredSecuritySolutionsClient) ListByHomeRegion(ctx context.Context) (result DiscoveredSecuritySolutionListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.DiscoveredSecuritySolutionsClient", "ListByHomeRegion", err.Error()) + } + + result.fn = client.listByHomeRegionNextResults + req, err := client.ListByHomeRegionPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "ListByHomeRegion", nil, "Failure preparing request") + return + } + + resp, err := client.ListByHomeRegionSender(req) + if err != nil { + result.dssl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "ListByHomeRegion", resp, "Failure sending request") + return + } + + result.dssl, err = client.ListByHomeRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "ListByHomeRegion", resp, "Failure responding to request") + } + + return +} + +// ListByHomeRegionPreparer prepares the ListByHomeRegion request. +func (client DiscoveredSecuritySolutionsClient) ListByHomeRegionPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations/{ascLocation}/discoveredSecuritySolutions", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByHomeRegionSender sends the ListByHomeRegion request. The method will close the +// http.Response Body if it receives an error. +func (client DiscoveredSecuritySolutionsClient) ListByHomeRegionSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByHomeRegionResponder handles the response to the ListByHomeRegion request. The method always +// closes the http.Response Body. +func (client DiscoveredSecuritySolutionsClient) ListByHomeRegionResponder(resp *http.Response) (result DiscoveredSecuritySolutionList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByHomeRegionNextResults retrieves the next set of results, if any. +func (client DiscoveredSecuritySolutionsClient) listByHomeRegionNextResults(lastResults DiscoveredSecuritySolutionList) (result DiscoveredSecuritySolutionList, err error) { + req, err := lastResults.discoveredSecuritySolutionListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "listByHomeRegionNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByHomeRegionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "listByHomeRegionNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByHomeRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.DiscoveredSecuritySolutionsClient", "listByHomeRegionNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByHomeRegionComplete enumerates all values, automatically crossing page boundaries as required. +func (client DiscoveredSecuritySolutionsClient) ListByHomeRegionComplete(ctx context.Context) (result DiscoveredSecuritySolutionListIterator, err error) { + result.page, err = client.ListByHomeRegion(ctx) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/externalsecuritysolutions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/externalsecuritysolutions.go new file mode 100644 index 000000000000..5f4247a52f1f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/externalsecuritysolutions.go @@ -0,0 +1,313 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// ExternalSecuritySolutionsClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type ExternalSecuritySolutionsClient struct { + BaseClient +} + +// NewExternalSecuritySolutionsClient creates an instance of the ExternalSecuritySolutionsClient client. +func NewExternalSecuritySolutionsClient(subscriptionID string, ascLocation string) ExternalSecuritySolutionsClient { + return NewExternalSecuritySolutionsClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewExternalSecuritySolutionsClientWithBaseURI creates an instance of the ExternalSecuritySolutionsClient client. +func NewExternalSecuritySolutionsClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) ExternalSecuritySolutionsClient { + return ExternalSecuritySolutionsClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// Get gets a specific external Security Solution. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// externalSecuritySolutionsName - name of an external security solution. +func (client ExternalSecuritySolutionsClient) Get(ctx context.Context, resourceGroupName string, externalSecuritySolutionsName string) (result ExternalSecuritySolutionModel, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.ExternalSecuritySolutionsClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx, resourceGroupName, externalSecuritySolutionsName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ExternalSecuritySolutionsClient) GetPreparer(ctx context.Context, resourceGroupName string, externalSecuritySolutionsName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "externalSecuritySolutionsName": autorest.Encode("path", externalSecuritySolutionsName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/ExternalSecuritySolutions/{externalSecuritySolutionsName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ExternalSecuritySolutionsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ExternalSecuritySolutionsClient) GetResponder(resp *http.Response) (result ExternalSecuritySolutionModel, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a list of external security solutions for the subscription. +func (client ExternalSecuritySolutionsClient) List(ctx context.Context) (result ExternalSecuritySolutionListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.ExternalSecuritySolutionsClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.essl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "List", resp, "Failure sending request") + return + } + + result.essl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ExternalSecuritySolutionsClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/externalSecuritySolutions", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ExternalSecuritySolutionsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ExternalSecuritySolutionsClient) ListResponder(resp *http.Response) (result ExternalSecuritySolutionList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client ExternalSecuritySolutionsClient) listNextResults(lastResults ExternalSecuritySolutionList) (result ExternalSecuritySolutionList, err error) { + req, err := lastResults.externalSecuritySolutionListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client ExternalSecuritySolutionsClient) ListComplete(ctx context.Context) (result ExternalSecuritySolutionListIterator, err error) { + result.page, err = client.List(ctx) + return +} + +// ListByHomeRegion gets a list of external Security Solutions for the subscription and location. +func (client ExternalSecuritySolutionsClient) ListByHomeRegion(ctx context.Context) (result ExternalSecuritySolutionListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.ExternalSecuritySolutionsClient", "ListByHomeRegion", err.Error()) + } + + result.fn = client.listByHomeRegionNextResults + req, err := client.ListByHomeRegionPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "ListByHomeRegion", nil, "Failure preparing request") + return + } + + resp, err := client.ListByHomeRegionSender(req) + if err != nil { + result.essl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "ListByHomeRegion", resp, "Failure sending request") + return + } + + result.essl, err = client.ListByHomeRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "ListByHomeRegion", resp, "Failure responding to request") + } + + return +} + +// ListByHomeRegionPreparer prepares the ListByHomeRegion request. +func (client ExternalSecuritySolutionsClient) ListByHomeRegionPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations/{ascLocation}/ExternalSecuritySolutions", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByHomeRegionSender sends the ListByHomeRegion request. The method will close the +// http.Response Body if it receives an error. +func (client ExternalSecuritySolutionsClient) ListByHomeRegionSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByHomeRegionResponder handles the response to the ListByHomeRegion request. The method always +// closes the http.Response Body. +func (client ExternalSecuritySolutionsClient) ListByHomeRegionResponder(resp *http.Response) (result ExternalSecuritySolutionList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByHomeRegionNextResults retrieves the next set of results, if any. +func (client ExternalSecuritySolutionsClient) listByHomeRegionNextResults(lastResults ExternalSecuritySolutionList) (result ExternalSecuritySolutionList, err error) { + req, err := lastResults.externalSecuritySolutionListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "listByHomeRegionNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByHomeRegionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "listByHomeRegionNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByHomeRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.ExternalSecuritySolutionsClient", "listByHomeRegionNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByHomeRegionComplete enumerates all values, automatically crossing page boundaries as required. +func (client ExternalSecuritySolutionsClient) ListByHomeRegionComplete(ctx context.Context) (result ExternalSecuritySolutionListIterator, err error) { + result.page, err = client.ListByHomeRegion(ctx) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/jitnetworkaccesspolicies.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/jitnetworkaccesspolicies.go new file mode 100644 index 000000000000..9377e0528767 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/jitnetworkaccesspolicies.go @@ -0,0 +1,770 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// JitNetworkAccessPoliciesClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type JitNetworkAccessPoliciesClient struct { + BaseClient +} + +// NewJitNetworkAccessPoliciesClient creates an instance of the JitNetworkAccessPoliciesClient client. +func NewJitNetworkAccessPoliciesClient(subscriptionID string, ascLocation string) JitNetworkAccessPoliciesClient { + return NewJitNetworkAccessPoliciesClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewJitNetworkAccessPoliciesClientWithBaseURI creates an instance of the JitNetworkAccessPoliciesClient client. +func NewJitNetworkAccessPoliciesClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) JitNetworkAccessPoliciesClient { + return JitNetworkAccessPoliciesClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// CreateOrUpdate create a policy for protecting resources using Just-in-Time access control +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// jitNetworkAccessPolicyName - name of a Just-in-Time access configuration policy. +func (client JitNetworkAccessPoliciesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, jitNetworkAccessPolicyName string, body JitNetworkAccessPolicy) (result JitNetworkAccessPolicy, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: body, + Constraints: []validation.Constraint{{Target: "body.JitNetworkAccessPolicyProperties", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "body.JitNetworkAccessPolicyProperties.VirtualMachines", Name: validation.Null, Rule: true, Chain: nil}}}}}}); err != nil { + return result, validation.NewError("security.JitNetworkAccessPoliciesClient", "CreateOrUpdate", err.Error()) + } + + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, jitNetworkAccessPolicyName, body) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client JitNetworkAccessPoliciesClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, jitNetworkAccessPolicyName string, body JitNetworkAccessPolicy) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "jitNetworkAccessPolicyName": autorest.Encode("path", jitNetworkAccessPolicyName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/jitNetworkAccessPolicies/{jitNetworkAccessPolicyName}", pathParameters), + autorest.WithJSON(body), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client JitNetworkAccessPoliciesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client JitNetworkAccessPoliciesClient) CreateOrUpdateResponder(resp *http.Response) (result JitNetworkAccessPolicy, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete delete a Just-in-Time access control policy. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// jitNetworkAccessPolicyName - name of a Just-in-Time access configuration policy. +func (client JitNetworkAccessPoliciesClient) Delete(ctx context.Context, resourceGroupName string, jitNetworkAccessPolicyName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.JitNetworkAccessPoliciesClient", "Delete", err.Error()) + } + + req, err := client.DeletePreparer(ctx, resourceGroupName, jitNetworkAccessPolicyName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client JitNetworkAccessPoliciesClient) DeletePreparer(ctx context.Context, resourceGroupName string, jitNetworkAccessPolicyName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "jitNetworkAccessPolicyName": autorest.Encode("path", jitNetworkAccessPolicyName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/jitNetworkAccessPolicies/{jitNetworkAccessPolicyName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client JitNetworkAccessPoliciesClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client JitNetworkAccessPoliciesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get policies for protecting resources using Just-in-Time access control for the subscription, location +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// jitNetworkAccessPolicyName - name of a Just-in-Time access configuration policy. +func (client JitNetworkAccessPoliciesClient) Get(ctx context.Context, resourceGroupName string, jitNetworkAccessPolicyName string) (result JitNetworkAccessPolicy, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.JitNetworkAccessPoliciesClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx, resourceGroupName, jitNetworkAccessPolicyName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client JitNetworkAccessPoliciesClient) GetPreparer(ctx context.Context, resourceGroupName string, jitNetworkAccessPolicyName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "jitNetworkAccessPolicyName": autorest.Encode("path", jitNetworkAccessPolicyName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/jitNetworkAccessPolicies/{jitNetworkAccessPolicyName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client JitNetworkAccessPoliciesClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client JitNetworkAccessPoliciesClient) GetResponder(resp *http.Response) (result JitNetworkAccessPolicy, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Initiate initiate a JIT access from a specific Just-in-Time policy configuration. +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// jitNetworkAccessPolicyName - name of a Just-in-Time access configuration policy. +func (client JitNetworkAccessPoliciesClient) Initiate(ctx context.Context, resourceGroupName string, jitNetworkAccessPolicyName string, body JitNetworkAccessPolicyInitiateRequest) (result JitNetworkAccessRequest, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: body, + Constraints: []validation.Constraint{{Target: "body.VirtualMachines", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.JitNetworkAccessPoliciesClient", "Initiate", err.Error()) + } + + req, err := client.InitiatePreparer(ctx, resourceGroupName, jitNetworkAccessPolicyName, body) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "Initiate", nil, "Failure preparing request") + return + } + + resp, err := client.InitiateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "Initiate", resp, "Failure sending request") + return + } + + result, err = client.InitiateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "Initiate", resp, "Failure responding to request") + } + + return +} + +// InitiatePreparer prepares the Initiate request. +func (client JitNetworkAccessPoliciesClient) InitiatePreparer(ctx context.Context, resourceGroupName string, jitNetworkAccessPolicyName string, body JitNetworkAccessPolicyInitiateRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "jitNetworkAccessPolicyInitiateType": autorest.Encode("path", "initiate"), + "jitNetworkAccessPolicyName": autorest.Encode("path", jitNetworkAccessPolicyName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/jitNetworkAccessPolicies/{jitNetworkAccessPolicyName}/{jitNetworkAccessPolicyInitiateType}", pathParameters), + autorest.WithJSON(body), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// InitiateSender sends the Initiate request. The method will close the +// http.Response Body if it receives an error. +func (client JitNetworkAccessPoliciesClient) InitiateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// InitiateResponder handles the response to the Initiate request. The method always +// closes the http.Response Body. +func (client JitNetworkAccessPoliciesClient) InitiateResponder(resp *http.Response) (result JitNetworkAccessRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List policies for protecting resources using Just-in-Time access control. +func (client JitNetworkAccessPoliciesClient) List(ctx context.Context) (result JitNetworkAccessPoliciesListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.JitNetworkAccessPoliciesClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.jnapl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "List", resp, "Failure sending request") + return + } + + result.jnapl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client JitNetworkAccessPoliciesClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/jitNetworkAccessPolicies", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client JitNetworkAccessPoliciesClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client JitNetworkAccessPoliciesClient) ListResponder(resp *http.Response) (result JitNetworkAccessPoliciesList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client JitNetworkAccessPoliciesClient) listNextResults(lastResults JitNetworkAccessPoliciesList) (result JitNetworkAccessPoliciesList, err error) { + req, err := lastResults.jitNetworkAccessPoliciesListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client JitNetworkAccessPoliciesClient) ListComplete(ctx context.Context) (result JitNetworkAccessPoliciesListIterator, err error) { + result.page, err = client.List(ctx) + return +} + +// ListByRegion policies for protecting resources using Just-in-Time access control for the subscription, location +func (client JitNetworkAccessPoliciesClient) ListByRegion(ctx context.Context) (result JitNetworkAccessPoliciesListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.JitNetworkAccessPoliciesClient", "ListByRegion", err.Error()) + } + + result.fn = client.listByRegionNextResults + req, err := client.ListByRegionPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "ListByRegion", nil, "Failure preparing request") + return + } + + resp, err := client.ListByRegionSender(req) + if err != nil { + result.jnapl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "ListByRegion", resp, "Failure sending request") + return + } + + result.jnapl, err = client.ListByRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "ListByRegion", resp, "Failure responding to request") + } + + return +} + +// ListByRegionPreparer prepares the ListByRegion request. +func (client JitNetworkAccessPoliciesClient) ListByRegionPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations/{ascLocation}/jitNetworkAccessPolicies", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByRegionSender sends the ListByRegion request. The method will close the +// http.Response Body if it receives an error. +func (client JitNetworkAccessPoliciesClient) ListByRegionSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByRegionResponder handles the response to the ListByRegion request. The method always +// closes the http.Response Body. +func (client JitNetworkAccessPoliciesClient) ListByRegionResponder(resp *http.Response) (result JitNetworkAccessPoliciesList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByRegionNextResults retrieves the next set of results, if any. +func (client JitNetworkAccessPoliciesClient) listByRegionNextResults(lastResults JitNetworkAccessPoliciesList) (result JitNetworkAccessPoliciesList, err error) { + req, err := lastResults.jitNetworkAccessPoliciesListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listByRegionNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByRegionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listByRegionNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listByRegionNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByRegionComplete enumerates all values, automatically crossing page boundaries as required. +func (client JitNetworkAccessPoliciesClient) ListByRegionComplete(ctx context.Context) (result JitNetworkAccessPoliciesListIterator, err error) { + result.page, err = client.ListByRegion(ctx) + return +} + +// ListByResourceGroup policies for protecting resources using Just-in-Time access control for the subscription, +// location +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +func (client JitNetworkAccessPoliciesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result JitNetworkAccessPoliciesListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.JitNetworkAccessPoliciesClient", "ListByResourceGroup", err.Error()) + } + + result.fn = client.listByResourceGroupNextResults + req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.jnapl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result.jnapl, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client JitNetworkAccessPoliciesClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/jitNetworkAccessPolicies", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client JitNetworkAccessPoliciesClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client JitNetworkAccessPoliciesClient) ListByResourceGroupResponder(resp *http.Response) (result JitNetworkAccessPoliciesList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByResourceGroupNextResults retrieves the next set of results, if any. +func (client JitNetworkAccessPoliciesClient) listByResourceGroupNextResults(lastResults JitNetworkAccessPoliciesList) (result JitNetworkAccessPoliciesList, err error) { + req, err := lastResults.jitNetworkAccessPoliciesListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. +func (client JitNetworkAccessPoliciesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string) (result JitNetworkAccessPoliciesListIterator, err error) { + result.page, err = client.ListByResourceGroup(ctx, resourceGroupName) + return +} + +// ListByResourceGroupAndRegion policies for protecting resources using Just-in-Time access control for the +// subscription, location +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +func (client JitNetworkAccessPoliciesClient) ListByResourceGroupAndRegion(ctx context.Context, resourceGroupName string) (result JitNetworkAccessPoliciesListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.JitNetworkAccessPoliciesClient", "ListByResourceGroupAndRegion", err.Error()) + } + + result.fn = client.listByResourceGroupAndRegionNextResults + req, err := client.ListByResourceGroupAndRegionPreparer(ctx, resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "ListByResourceGroupAndRegion", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupAndRegionSender(req) + if err != nil { + result.jnapl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "ListByResourceGroupAndRegion", resp, "Failure sending request") + return + } + + result.jnapl, err = client.ListByResourceGroupAndRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "ListByResourceGroupAndRegion", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupAndRegionPreparer prepares the ListByResourceGroupAndRegion request. +func (client JitNetworkAccessPoliciesClient) ListByResourceGroupAndRegionPreparer(ctx context.Context, resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/jitNetworkAccessPolicies", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByResourceGroupAndRegionSender sends the ListByResourceGroupAndRegion request. The method will close the +// http.Response Body if it receives an error. +func (client JitNetworkAccessPoliciesClient) ListByResourceGroupAndRegionSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByResourceGroupAndRegionResponder handles the response to the ListByResourceGroupAndRegion request. The method always +// closes the http.Response Body. +func (client JitNetworkAccessPoliciesClient) ListByResourceGroupAndRegionResponder(resp *http.Response) (result JitNetworkAccessPoliciesList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByResourceGroupAndRegionNextResults retrieves the next set of results, if any. +func (client JitNetworkAccessPoliciesClient) listByResourceGroupAndRegionNextResults(lastResults JitNetworkAccessPoliciesList) (result JitNetworkAccessPoliciesList, err error) { + req, err := lastResults.jitNetworkAccessPoliciesListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listByResourceGroupAndRegionNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByResourceGroupAndRegionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listByResourceGroupAndRegionNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByResourceGroupAndRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.JitNetworkAccessPoliciesClient", "listByResourceGroupAndRegionNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByResourceGroupAndRegionComplete enumerates all values, automatically crossing page boundaries as required. +func (client JitNetworkAccessPoliciesClient) ListByResourceGroupAndRegionComplete(ctx context.Context, resourceGroupName string) (result JitNetworkAccessPoliciesListIterator, err error) { + result.page, err = client.ListByResourceGroupAndRegion(ctx, resourceGroupName) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/locations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/locations.go new file mode 100644 index 000000000000..dcf9fe70c3df --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/locations.go @@ -0,0 +1,208 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// LocationsClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type LocationsClient struct { + BaseClient +} + +// NewLocationsClient creates an instance of the LocationsClient client. +func NewLocationsClient(subscriptionID string, ascLocation string) LocationsClient { + return NewLocationsClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewLocationsClientWithBaseURI creates an instance of the LocationsClient client. +func NewLocationsClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) LocationsClient { + return LocationsClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// Get details of a specific location +func (client LocationsClient) Get(ctx context.Context) (result AscLocation, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.LocationsClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.LocationsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.LocationsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.LocationsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client LocationsClient) GetPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations/{ascLocation}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client LocationsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client LocationsClient) GetResponder(resp *http.Response) (result AscLocation, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the location of the responsible ASC of the specific subscription (home region). For each subscription there is +// only one responsible location. The location in the response should be used to read or write other resources in ASC +// according to their ID. +func (client LocationsClient) List(ctx context.Context) (result AscLocationListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.LocationsClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.LocationsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.all.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.LocationsClient", "List", resp, "Failure sending request") + return + } + + result.all, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.LocationsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client LocationsClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client LocationsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client LocationsClient) ListResponder(resp *http.Response) (result AscLocationList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client LocationsClient) listNextResults(lastResults AscLocationList) (result AscLocationList, err error) { + req, err := lastResults.ascLocationListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.LocationsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.LocationsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.LocationsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client LocationsClient) ListComplete(ctx context.Context) (result AscLocationListIterator, err error) { + result.page, err = client.List(ctx) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/models.go new file mode 100644 index 000000000000..330f35ea62c0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/models.go @@ -0,0 +1,3863 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "encoding/json" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/date" + "github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// AadConnectivityState enumerates the values for aad connectivity state. +type AadConnectivityState string + +const ( + // Connected ... + Connected AadConnectivityState = "Connected" + // Discovered ... + Discovered AadConnectivityState = "Discovered" + // NotLicensed ... + NotLicensed AadConnectivityState = "NotLicensed" +) + +// PossibleAadConnectivityStateValues returns an array of possible values for the AadConnectivityState const type. +func PossibleAadConnectivityStateValues() []AadConnectivityState { + return []AadConnectivityState{Connected, Discovered, NotLicensed} +} + +// AlertNotifications enumerates the values for alert notifications. +type AlertNotifications string + +const ( + // Off Don't get notifications on new alerts + Off AlertNotifications = "Off" + // On Get notifications on new alerts + On AlertNotifications = "On" +) + +// PossibleAlertNotificationsValues returns an array of possible values for the AlertNotifications const type. +func PossibleAlertNotificationsValues() []AlertNotifications { + return []AlertNotifications{Off, On} +} + +// AlertsToAdmins enumerates the values for alerts to admins. +type AlertsToAdmins string + +const ( + // AlertsToAdminsOff Don't send notification on new alerts to the subscription's admins + AlertsToAdminsOff AlertsToAdmins = "Off" + // AlertsToAdminsOn Send notification on new alerts to the subscription's admins + AlertsToAdminsOn AlertsToAdmins = "On" +) + +// PossibleAlertsToAdminsValues returns an array of possible values for the AlertsToAdmins const type. +func PossibleAlertsToAdminsValues() []AlertsToAdmins { + return []AlertsToAdmins{AlertsToAdminsOff, AlertsToAdminsOn} +} + +// AutoProvision enumerates the values for auto provision. +type AutoProvision string + +const ( + // AutoProvisionOff Do not install security agent on the VMs automatically + AutoProvisionOff AutoProvision = "Off" + // AutoProvisionOn Install missing security agent on VMs automatically + AutoProvisionOn AutoProvision = "On" +) + +// PossibleAutoProvisionValues returns an array of possible values for the AutoProvision const type. +func PossibleAutoProvisionValues() []AutoProvision { + return []AutoProvision{AutoProvisionOff, AutoProvisionOn} +} + +// ExternalSecuritySolutionKind enumerates the values for external security solution kind. +type ExternalSecuritySolutionKind string + +const ( + // AAD ... + AAD ExternalSecuritySolutionKind = "AAD" + // ATA ... + ATA ExternalSecuritySolutionKind = "ATA" + // CEF ... + CEF ExternalSecuritySolutionKind = "CEF" +) + +// PossibleExternalSecuritySolutionKindValues returns an array of possible values for the ExternalSecuritySolutionKind const type. +func PossibleExternalSecuritySolutionKindValues() []ExternalSecuritySolutionKind { + return []ExternalSecuritySolutionKind{AAD, ATA, CEF} +} + +// Family enumerates the values for family. +type Family string + +const ( + // Ngfw ... + Ngfw Family = "Ngfw" + // SaasWaf ... + SaasWaf Family = "SaasWaf" + // Va ... + Va Family = "Va" + // Waf ... + Waf Family = "Waf" +) + +// PossibleFamilyValues returns an array of possible values for the Family const type. +func PossibleFamilyValues() []Family { + return []Family{Ngfw, SaasWaf, Va, Waf} +} + +// KindEnum enumerates the values for kind enum. +type KindEnum string + +const ( + // KindDataExportSetting ... + KindDataExportSetting KindEnum = "DataExportSetting" + // KindSetting ... + KindSetting KindEnum = "Setting" +) + +// PossibleKindEnumValues returns an array of possible values for the KindEnum const type. +func PossibleKindEnumValues() []KindEnum { + return []KindEnum{KindDataExportSetting, KindSetting} +} + +// KindEnum1 enumerates the values for kind enum 1. +type KindEnum1 string + +const ( + // KindAAD ... + KindAAD KindEnum1 = "AAD" + // KindATA ... + KindATA KindEnum1 = "ATA" + // KindCEF ... + KindCEF KindEnum1 = "CEF" + // KindExternalSecuritySolution ... + KindExternalSecuritySolution KindEnum1 = "ExternalSecuritySolution" +) + +// PossibleKindEnum1Values returns an array of possible values for the KindEnum1 const type. +func PossibleKindEnum1Values() []KindEnum1 { + return []KindEnum1{KindAAD, KindATA, KindCEF, KindExternalSecuritySolution} +} + +// PricingTier enumerates the values for pricing tier. +type PricingTier string + +const ( + // Free Get free Azure security center experience with basic security features + Free PricingTier = "Free" + // Standard Get the standard Azure security center experience with advanced security features + Standard PricingTier = "Standard" +) + +// PossiblePricingTierValues returns an array of possible values for the PricingTier const type. +func PossiblePricingTierValues() []PricingTier { + return []PricingTier{Free, Standard} +} + +// Protocol enumerates the values for protocol. +type Protocol string + +const ( + // All ... + All Protocol = "*" + // TCP ... + TCP Protocol = "TCP" + // UDP ... + UDP Protocol = "UDP" +) + +// PossibleProtocolValues returns an array of possible values for the Protocol const type. +func PossibleProtocolValues() []Protocol { + return []Protocol{All, TCP, UDP} +} + +// SettingKind enumerates the values for setting kind. +type SettingKind string + +const ( + // SettingKindDataExportSetting ... + SettingKindDataExportSetting SettingKind = "DataExportSetting" +) + +// PossibleSettingKindValues returns an array of possible values for the SettingKind const type. +func PossibleSettingKindValues() []SettingKind { + return []SettingKind{SettingKindDataExportSetting} +} + +// Status enumerates the values for status. +type Status string + +const ( + // Initiated ... + Initiated Status = "Initiated" + // Revoked ... + Revoked Status = "Revoked" +) + +// PossibleStatusValues returns an array of possible values for the Status const type. +func PossibleStatusValues() []Status { + return []Status{Initiated, Revoked} +} + +// StatusReason enumerates the values for status reason. +type StatusReason string + +const ( + // Expired ... + Expired StatusReason = "Expired" + // NewerRequestInitiated ... + NewerRequestInitiated StatusReason = "NewerRequestInitiated" + // UserRequested ... + UserRequested StatusReason = "UserRequested" +) + +// PossibleStatusReasonValues returns an array of possible values for the StatusReason const type. +func PossibleStatusReasonValues() []StatusReason { + return []StatusReason{Expired, NewerRequestInitiated, UserRequested} +} + +// AadConnectivityState1 describes an Azure resource with kind +type AadConnectivityState1 struct { + // ConnectivityState - Possible values include: 'Discovered', 'NotLicensed', 'Connected' + ConnectivityState AadConnectivityState `json:"connectivityState,omitempty"` +} + +// AadExternalSecuritySolution represents an AAD identity protection solution which sends logs to an OMS workspace. +type AadExternalSecuritySolution struct { + Properties *AadSolutionProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Location - Location where the resource is stored + Location *string `json:"location,omitempty"` + // Kind - Possible values include: 'KindExternalSecuritySolution', 'KindCEF', 'KindATA', 'KindAAD' + Kind KindEnum1 `json:"kind,omitempty"` +} + +// MarshalJSON is the custom marshaler for AadExternalSecuritySolution. +func (aess AadExternalSecuritySolution) MarshalJSON() ([]byte, error) { + aess.Kind = KindAAD + objectMap := make(map[string]interface{}) + if aess.Properties != nil { + objectMap["properties"] = aess.Properties + } + if aess.ID != nil { + objectMap["id"] = aess.ID + } + if aess.Name != nil { + objectMap["name"] = aess.Name + } + if aess.Type != nil { + objectMap["type"] = aess.Type + } + if aess.Location != nil { + objectMap["location"] = aess.Location + } + if aess.Kind != "" { + objectMap["kind"] = aess.Kind + } + return json.Marshal(objectMap) +} + +// AsCefExternalSecuritySolution is the BasicExternalSecuritySolution implementation for AadExternalSecuritySolution. +func (aess AadExternalSecuritySolution) AsCefExternalSecuritySolution() (*CefExternalSecuritySolution, bool) { + return nil, false +} + +// AsAtaExternalSecuritySolution is the BasicExternalSecuritySolution implementation for AadExternalSecuritySolution. +func (aess AadExternalSecuritySolution) AsAtaExternalSecuritySolution() (*AtaExternalSecuritySolution, bool) { + return nil, false +} + +// AsAadExternalSecuritySolution is the BasicExternalSecuritySolution implementation for AadExternalSecuritySolution. +func (aess AadExternalSecuritySolution) AsAadExternalSecuritySolution() (*AadExternalSecuritySolution, bool) { + return &aess, true +} + +// AsExternalSecuritySolution is the BasicExternalSecuritySolution implementation for AadExternalSecuritySolution. +func (aess AadExternalSecuritySolution) AsExternalSecuritySolution() (*ExternalSecuritySolution, bool) { + return nil, false +} + +// AsBasicExternalSecuritySolution is the BasicExternalSecuritySolution implementation for AadExternalSecuritySolution. +func (aess AadExternalSecuritySolution) AsBasicExternalSecuritySolution() (BasicExternalSecuritySolution, bool) { + return &aess, true +} + +// AadSolutionProperties ... +type AadSolutionProperties struct { + DeviceVendor *string `json:"deviceVendor,omitempty"` + DeviceType *string `json:"deviceType,omitempty"` + Workspace *ConnectedWorkspace `json:"workspace,omitempty"` + // ConnectivityState - Possible values include: 'Discovered', 'NotLicensed', 'Connected' + ConnectivityState AadConnectivityState `json:"connectivityState,omitempty"` +} + +// AdvancedThreatProtectionProperties the Advanced Threat Protection settings. +type AdvancedThreatProtectionProperties struct { + // IsEnabled - Indicates whether Advanced Threat Protection is enabled. + IsEnabled *bool `json:"isEnabled,omitempty"` +} + +// AdvancedThreatProtectionSetting the Advanced Threat Protection resource. +type AdvancedThreatProtectionSetting struct { + autorest.Response `json:"-"` + *AdvancedThreatProtectionProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for AdvancedThreatProtectionSetting. +func (atps AdvancedThreatProtectionSetting) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if atps.AdvancedThreatProtectionProperties != nil { + objectMap["properties"] = atps.AdvancedThreatProtectionProperties + } + if atps.ID != nil { + objectMap["id"] = atps.ID + } + if atps.Name != nil { + objectMap["name"] = atps.Name + } + if atps.Type != nil { + objectMap["type"] = atps.Type + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for AdvancedThreatProtectionSetting struct. +func (atps *AdvancedThreatProtectionSetting) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var advancedThreatProtectionProperties AdvancedThreatProtectionProperties + err = json.Unmarshal(*v, &advancedThreatProtectionProperties) + if err != nil { + return err + } + atps.AdvancedThreatProtectionProperties = &advancedThreatProtectionProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + atps.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + atps.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + atps.Type = &typeVar + } + } + } + + return nil +} + +// Alert security alert +type Alert struct { + autorest.Response `json:"-"` + *AlertProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for Alert. +func (a Alert) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if a.AlertProperties != nil { + objectMap["properties"] = a.AlertProperties + } + if a.ID != nil { + objectMap["id"] = a.ID + } + if a.Name != nil { + objectMap["name"] = a.Name + } + if a.Type != nil { + objectMap["type"] = a.Type + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for Alert struct. +func (a *Alert) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var alertProperties AlertProperties + err = json.Unmarshal(*v, &alertProperties) + if err != nil { + return err + } + a.AlertProperties = &alertProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + a.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + a.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + a.Type = &typeVar + } + } + } + + return nil +} + +// AlertConfidenceReason factors that increase our confidence that the alert is a true positive +type AlertConfidenceReason struct { + // Type - Type of confidence factor + Type *string `json:"type,omitempty"` + // Reason - description of the confidence reason + Reason *string `json:"reason,omitempty"` +} + +// AlertEntity changing set of properties depending on the entity type. +type AlertEntity struct { + // AdditionalProperties - Unmatched properties from the message are deserialized this collection + AdditionalProperties map[string]interface{} `json:""` + // Type - Type of entity + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for AlertEntity. +func (ae AlertEntity) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if ae.Type != nil { + objectMap["type"] = ae.Type + } + for k, v := range ae.AdditionalProperties { + objectMap[k] = v + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for AlertEntity struct. +func (ae *AlertEntity) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + default: + if v != nil { + var additionalProperties interface{} + err = json.Unmarshal(*v, &additionalProperties) + if err != nil { + return err + } + if ae.AdditionalProperties == nil { + ae.AdditionalProperties = make(map[string]interface{}) + } + ae.AdditionalProperties[k] = additionalProperties + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + ae.Type = &typeVar + } + } + } + + return nil +} + +// AlertList list of security alerts +type AlertList struct { + autorest.Response `json:"-"` + Value *[]Alert `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// AlertListIterator provides access to a complete listing of Alert values. +type AlertListIterator struct { + i int + page AlertListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *AlertListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter AlertListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter AlertListIterator) Response() AlertList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter AlertListIterator) Value() Alert { + if !iter.page.NotDone() { + return Alert{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (al AlertList) IsEmpty() bool { + return al.Value == nil || len(*al.Value) == 0 +} + +// alertListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (al AlertList) alertListPreparer() (*http.Request, error) { + if al.NextLink == nil || len(to.String(al.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(al.NextLink))) +} + +// AlertListPage contains a page of Alert values. +type AlertListPage struct { + fn func(AlertList) (AlertList, error) + al AlertList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *AlertListPage) Next() error { + next, err := page.fn(page.al) + if err != nil { + return err + } + page.al = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page AlertListPage) NotDone() bool { + return !page.al.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page AlertListPage) Response() AlertList { + return page.al +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page AlertListPage) Values() []Alert { + if page.al.IsEmpty() { + return nil + } + return *page.al.Value +} + +// AlertProperties describes security alert properties. +type AlertProperties struct { + // State - State of the alert (Active, Dismissed etc.) + State *string `json:"state,omitempty"` + // ReportedTimeUtc - The time the incident was reported to Microsoft.Security in UTC + ReportedTimeUtc *date.Time `json:"reportedTimeUtc,omitempty"` + // VendorName - Name of the vendor that discovered the incident + VendorName *string `json:"vendorName,omitempty"` + // AlertName - Name of the alert type + AlertName *string `json:"alertName,omitempty"` + // AlertDisplayName - Display name of the alert type + AlertDisplayName *string `json:"alertDisplayName,omitempty"` + // DetectedTimeUtc - The time the incident was detected by the vendor + DetectedTimeUtc *date.Time `json:"detectedTimeUtc,omitempty"` + // Description - Description of the incident and what it means + Description *string `json:"description,omitempty"` + // RemediationSteps - Recommended steps to reradiate the incident + RemediationSteps *string `json:"remediationSteps,omitempty"` + // ActionTaken - The action that was taken as a response to the alert (Active, Blocked etc.) + ActionTaken *string `json:"actionTaken,omitempty"` + // ReportedSeverity - Estimated severity of this alert + ReportedSeverity *string `json:"reportedSeverity,omitempty"` + // CompromisedEntity - The entity that the incident happened on + CompromisedEntity *string `json:"compromisedEntity,omitempty"` + // AssociatedResource - Azure resource ID of the associated resource + AssociatedResource *string `json:"associatedResource,omitempty"` + ExtendedProperties map[string]interface{} `json:"extendedProperties"` + // SystemSource - The type of the alerted resource (Azure, Non-Azure) + SystemSource *string `json:"systemSource,omitempty"` + // CanBeInvestigated - Whether this alert can be investigated with Azure Security Center + CanBeInvestigated *bool `json:"canBeInvestigated,omitempty"` + // Entities - objects that are related to this alerts + Entities *[]AlertEntity `json:"entities,omitempty"` + // ConfidenceScore - level of confidence we have on the alert + ConfidenceScore *float64 `json:"confidenceScore,omitempty"` + // ConfidenceReasons - reasons the alert got the confidenceScore value + ConfidenceReasons *[]AlertConfidenceReason `json:"confidenceReasons,omitempty"` + // SubscriptionID - Azure subscription ID of the resource that had the security alert or the subscription ID of the workspace that this resource reports to + SubscriptionID *string `json:"subscriptionId,omitempty"` + // InstanceID - Instance ID of the alert. + InstanceID *string `json:"instanceId,omitempty"` + // WorkspaceArmID - Azure resource ID of the workspace that the alert was reported to. + WorkspaceArmID *string `json:"workspaceArmId,omitempty"` +} + +// MarshalJSON is the custom marshaler for AlertProperties. +func (ap AlertProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if ap.State != nil { + objectMap["state"] = ap.State + } + if ap.ReportedTimeUtc != nil { + objectMap["reportedTimeUtc"] = ap.ReportedTimeUtc + } + if ap.VendorName != nil { + objectMap["vendorName"] = ap.VendorName + } + if ap.AlertName != nil { + objectMap["alertName"] = ap.AlertName + } + if ap.AlertDisplayName != nil { + objectMap["alertDisplayName"] = ap.AlertDisplayName + } + if ap.DetectedTimeUtc != nil { + objectMap["detectedTimeUtc"] = ap.DetectedTimeUtc + } + if ap.Description != nil { + objectMap["description"] = ap.Description + } + if ap.RemediationSteps != nil { + objectMap["remediationSteps"] = ap.RemediationSteps + } + if ap.ActionTaken != nil { + objectMap["actionTaken"] = ap.ActionTaken + } + if ap.ReportedSeverity != nil { + objectMap["reportedSeverity"] = ap.ReportedSeverity + } + if ap.CompromisedEntity != nil { + objectMap["compromisedEntity"] = ap.CompromisedEntity + } + if ap.AssociatedResource != nil { + objectMap["associatedResource"] = ap.AssociatedResource + } + if ap.ExtendedProperties != nil { + objectMap["extendedProperties"] = ap.ExtendedProperties + } + if ap.SystemSource != nil { + objectMap["systemSource"] = ap.SystemSource + } + if ap.CanBeInvestigated != nil { + objectMap["canBeInvestigated"] = ap.CanBeInvestigated + } + if ap.Entities != nil { + objectMap["entities"] = ap.Entities + } + if ap.ConfidenceScore != nil { + objectMap["confidenceScore"] = ap.ConfidenceScore + } + if ap.ConfidenceReasons != nil { + objectMap["confidenceReasons"] = ap.ConfidenceReasons + } + if ap.SubscriptionID != nil { + objectMap["subscriptionId"] = ap.SubscriptionID + } + if ap.InstanceID != nil { + objectMap["instanceId"] = ap.InstanceID + } + if ap.WorkspaceArmID != nil { + objectMap["workspaceArmId"] = ap.WorkspaceArmID + } + return json.Marshal(objectMap) +} + +// AscLocation the ASC location of the subscription is in the "name" field +type AscLocation struct { + autorest.Response `json:"-"` + Properties interface{} `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` +} + +// AscLocationList list of locations where ASC saves your data +type AscLocationList struct { + autorest.Response `json:"-"` + Value *[]AscLocation `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// AscLocationListIterator provides access to a complete listing of AscLocation values. +type AscLocationListIterator struct { + i int + page AscLocationListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *AscLocationListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter AscLocationListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter AscLocationListIterator) Response() AscLocationList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter AscLocationListIterator) Value() AscLocation { + if !iter.page.NotDone() { + return AscLocation{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (all AscLocationList) IsEmpty() bool { + return all.Value == nil || len(*all.Value) == 0 +} + +// ascLocationListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (all AscLocationList) ascLocationListPreparer() (*http.Request, error) { + if all.NextLink == nil || len(to.String(all.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(all.NextLink))) +} + +// AscLocationListPage contains a page of AscLocation values. +type AscLocationListPage struct { + fn func(AscLocationList) (AscLocationList, error) + all AscLocationList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *AscLocationListPage) Next() error { + next, err := page.fn(page.all) + if err != nil { + return err + } + page.all = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page AscLocationListPage) NotDone() bool { + return !page.all.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page AscLocationListPage) Response() AscLocationList { + return page.all +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page AscLocationListPage) Values() []AscLocation { + if page.all.IsEmpty() { + return nil + } + return *page.all.Value +} + +// AtaExternalSecuritySolution represents an ATA security solution which sends logs to an OMS workspace +type AtaExternalSecuritySolution struct { + Properties *AtaSolutionProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Location - Location where the resource is stored + Location *string `json:"location,omitempty"` + // Kind - Possible values include: 'KindExternalSecuritySolution', 'KindCEF', 'KindATA', 'KindAAD' + Kind KindEnum1 `json:"kind,omitempty"` +} + +// MarshalJSON is the custom marshaler for AtaExternalSecuritySolution. +func (aess AtaExternalSecuritySolution) MarshalJSON() ([]byte, error) { + aess.Kind = KindATA + objectMap := make(map[string]interface{}) + if aess.Properties != nil { + objectMap["properties"] = aess.Properties + } + if aess.ID != nil { + objectMap["id"] = aess.ID + } + if aess.Name != nil { + objectMap["name"] = aess.Name + } + if aess.Type != nil { + objectMap["type"] = aess.Type + } + if aess.Location != nil { + objectMap["location"] = aess.Location + } + if aess.Kind != "" { + objectMap["kind"] = aess.Kind + } + return json.Marshal(objectMap) +} + +// AsCefExternalSecuritySolution is the BasicExternalSecuritySolution implementation for AtaExternalSecuritySolution. +func (aess AtaExternalSecuritySolution) AsCefExternalSecuritySolution() (*CefExternalSecuritySolution, bool) { + return nil, false +} + +// AsAtaExternalSecuritySolution is the BasicExternalSecuritySolution implementation for AtaExternalSecuritySolution. +func (aess AtaExternalSecuritySolution) AsAtaExternalSecuritySolution() (*AtaExternalSecuritySolution, bool) { + return &aess, true +} + +// AsAadExternalSecuritySolution is the BasicExternalSecuritySolution implementation for AtaExternalSecuritySolution. +func (aess AtaExternalSecuritySolution) AsAadExternalSecuritySolution() (*AadExternalSecuritySolution, bool) { + return nil, false +} + +// AsExternalSecuritySolution is the BasicExternalSecuritySolution implementation for AtaExternalSecuritySolution. +func (aess AtaExternalSecuritySolution) AsExternalSecuritySolution() (*ExternalSecuritySolution, bool) { + return nil, false +} + +// AsBasicExternalSecuritySolution is the BasicExternalSecuritySolution implementation for AtaExternalSecuritySolution. +func (aess AtaExternalSecuritySolution) AsBasicExternalSecuritySolution() (BasicExternalSecuritySolution, bool) { + return &aess, true +} + +// AtaSolutionProperties ... +type AtaSolutionProperties struct { + LastEventReceived *string `json:"lastEventReceived,omitempty"` + // AdditionalProperties - Unmatched properties from the message are deserialized this collection + AdditionalProperties map[string]interface{} `json:""` + DeviceVendor *string `json:"deviceVendor,omitempty"` + DeviceType *string `json:"deviceType,omitempty"` + Workspace *ConnectedWorkspace `json:"workspace,omitempty"` +} + +// MarshalJSON is the custom marshaler for AtaSolutionProperties. +func (asp AtaSolutionProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if asp.LastEventReceived != nil { + objectMap["lastEventReceived"] = asp.LastEventReceived + } + if asp.DeviceVendor != nil { + objectMap["deviceVendor"] = asp.DeviceVendor + } + if asp.DeviceType != nil { + objectMap["deviceType"] = asp.DeviceType + } + if asp.Workspace != nil { + objectMap["workspace"] = asp.Workspace + } + for k, v := range asp.AdditionalProperties { + objectMap[k] = v + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for AtaSolutionProperties struct. +func (asp *AtaSolutionProperties) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "lastEventReceived": + if v != nil { + var lastEventReceived string + err = json.Unmarshal(*v, &lastEventReceived) + if err != nil { + return err + } + asp.LastEventReceived = &lastEventReceived + } + default: + if v != nil { + var additionalProperties interface{} + err = json.Unmarshal(*v, &additionalProperties) + if err != nil { + return err + } + if asp.AdditionalProperties == nil { + asp.AdditionalProperties = make(map[string]interface{}) + } + asp.AdditionalProperties[k] = additionalProperties + } + case "deviceVendor": + if v != nil { + var deviceVendor string + err = json.Unmarshal(*v, &deviceVendor) + if err != nil { + return err + } + asp.DeviceVendor = &deviceVendor + } + case "deviceType": + if v != nil { + var deviceType string + err = json.Unmarshal(*v, &deviceType) + if err != nil { + return err + } + asp.DeviceType = &deviceType + } + case "workspace": + if v != nil { + var workspace ConnectedWorkspace + err = json.Unmarshal(*v, &workspace) + if err != nil { + return err + } + asp.Workspace = &workspace + } + } + } + + return nil +} + +// AutoProvisioningSetting auto provisioning setting +type AutoProvisioningSetting struct { + autorest.Response `json:"-"` + // AutoProvisioningSettingProperties - Auto provisioning setting data + *AutoProvisioningSettingProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for AutoProvisioningSetting. +func (aps AutoProvisioningSetting) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if aps.AutoProvisioningSettingProperties != nil { + objectMap["properties"] = aps.AutoProvisioningSettingProperties + } + if aps.ID != nil { + objectMap["id"] = aps.ID + } + if aps.Name != nil { + objectMap["name"] = aps.Name + } + if aps.Type != nil { + objectMap["type"] = aps.Type + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for AutoProvisioningSetting struct. +func (aps *AutoProvisioningSetting) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var autoProvisioningSettingProperties AutoProvisioningSettingProperties + err = json.Unmarshal(*v, &autoProvisioningSettingProperties) + if err != nil { + return err + } + aps.AutoProvisioningSettingProperties = &autoProvisioningSettingProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + aps.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + aps.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + aps.Type = &typeVar + } + } + } + + return nil +} + +// AutoProvisioningSettingList list of all the auto provisioning settings response +type AutoProvisioningSettingList struct { + autorest.Response `json:"-"` + // Value - List of all the auto provisioning settings + Value *[]AutoProvisioningSetting `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// AutoProvisioningSettingListIterator provides access to a complete listing of AutoProvisioningSetting values. +type AutoProvisioningSettingListIterator struct { + i int + page AutoProvisioningSettingListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *AutoProvisioningSettingListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter AutoProvisioningSettingListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter AutoProvisioningSettingListIterator) Response() AutoProvisioningSettingList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter AutoProvisioningSettingListIterator) Value() AutoProvisioningSetting { + if !iter.page.NotDone() { + return AutoProvisioningSetting{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (apsl AutoProvisioningSettingList) IsEmpty() bool { + return apsl.Value == nil || len(*apsl.Value) == 0 +} + +// autoProvisioningSettingListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (apsl AutoProvisioningSettingList) autoProvisioningSettingListPreparer() (*http.Request, error) { + if apsl.NextLink == nil || len(to.String(apsl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(apsl.NextLink))) +} + +// AutoProvisioningSettingListPage contains a page of AutoProvisioningSetting values. +type AutoProvisioningSettingListPage struct { + fn func(AutoProvisioningSettingList) (AutoProvisioningSettingList, error) + apsl AutoProvisioningSettingList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *AutoProvisioningSettingListPage) Next() error { + next, err := page.fn(page.apsl) + if err != nil { + return err + } + page.apsl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page AutoProvisioningSettingListPage) NotDone() bool { + return !page.apsl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page AutoProvisioningSettingListPage) Response() AutoProvisioningSettingList { + return page.apsl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page AutoProvisioningSettingListPage) Values() []AutoProvisioningSetting { + if page.apsl.IsEmpty() { + return nil + } + return *page.apsl.Value +} + +// AutoProvisioningSettingProperties describes properties of an auto provisioning setting +type AutoProvisioningSettingProperties struct { + // AutoProvision - Describes what kind of security agent provisioning action to take. Possible values include: 'AutoProvisionOn', 'AutoProvisionOff' + AutoProvision AutoProvision `json:"autoProvision,omitempty"` +} + +// CefExternalSecuritySolution represents a security solution which sends CEF logs to an OMS workspace +type CefExternalSecuritySolution struct { + Properties *CefSolutionProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Location - Location where the resource is stored + Location *string `json:"location,omitempty"` + // Kind - Possible values include: 'KindExternalSecuritySolution', 'KindCEF', 'KindATA', 'KindAAD' + Kind KindEnum1 `json:"kind,omitempty"` +} + +// MarshalJSON is the custom marshaler for CefExternalSecuritySolution. +func (cess CefExternalSecuritySolution) MarshalJSON() ([]byte, error) { + cess.Kind = KindCEF + objectMap := make(map[string]interface{}) + if cess.Properties != nil { + objectMap["properties"] = cess.Properties + } + if cess.ID != nil { + objectMap["id"] = cess.ID + } + if cess.Name != nil { + objectMap["name"] = cess.Name + } + if cess.Type != nil { + objectMap["type"] = cess.Type + } + if cess.Location != nil { + objectMap["location"] = cess.Location + } + if cess.Kind != "" { + objectMap["kind"] = cess.Kind + } + return json.Marshal(objectMap) +} + +// AsCefExternalSecuritySolution is the BasicExternalSecuritySolution implementation for CefExternalSecuritySolution. +func (cess CefExternalSecuritySolution) AsCefExternalSecuritySolution() (*CefExternalSecuritySolution, bool) { + return &cess, true +} + +// AsAtaExternalSecuritySolution is the BasicExternalSecuritySolution implementation for CefExternalSecuritySolution. +func (cess CefExternalSecuritySolution) AsAtaExternalSecuritySolution() (*AtaExternalSecuritySolution, bool) { + return nil, false +} + +// AsAadExternalSecuritySolution is the BasicExternalSecuritySolution implementation for CefExternalSecuritySolution. +func (cess CefExternalSecuritySolution) AsAadExternalSecuritySolution() (*AadExternalSecuritySolution, bool) { + return nil, false +} + +// AsExternalSecuritySolution is the BasicExternalSecuritySolution implementation for CefExternalSecuritySolution. +func (cess CefExternalSecuritySolution) AsExternalSecuritySolution() (*ExternalSecuritySolution, bool) { + return nil, false +} + +// AsBasicExternalSecuritySolution is the BasicExternalSecuritySolution implementation for CefExternalSecuritySolution. +func (cess CefExternalSecuritySolution) AsBasicExternalSecuritySolution() (BasicExternalSecuritySolution, bool) { + return &cess, true +} + +// CefSolutionProperties ... +type CefSolutionProperties struct { + Hostname *string `json:"hostname,omitempty"` + Agent *string `json:"agent,omitempty"` + LastEventReceived *string `json:"lastEventReceived,omitempty"` + // AdditionalProperties - Unmatched properties from the message are deserialized this collection + AdditionalProperties map[string]interface{} `json:""` + DeviceVendor *string `json:"deviceVendor,omitempty"` + DeviceType *string `json:"deviceType,omitempty"` + Workspace *ConnectedWorkspace `json:"workspace,omitempty"` +} + +// MarshalJSON is the custom marshaler for CefSolutionProperties. +func (csp CefSolutionProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if csp.Hostname != nil { + objectMap["hostname"] = csp.Hostname + } + if csp.Agent != nil { + objectMap["agent"] = csp.Agent + } + if csp.LastEventReceived != nil { + objectMap["lastEventReceived"] = csp.LastEventReceived + } + if csp.DeviceVendor != nil { + objectMap["deviceVendor"] = csp.DeviceVendor + } + if csp.DeviceType != nil { + objectMap["deviceType"] = csp.DeviceType + } + if csp.Workspace != nil { + objectMap["workspace"] = csp.Workspace + } + for k, v := range csp.AdditionalProperties { + objectMap[k] = v + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for CefSolutionProperties struct. +func (csp *CefSolutionProperties) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "hostname": + if v != nil { + var hostname string + err = json.Unmarshal(*v, &hostname) + if err != nil { + return err + } + csp.Hostname = &hostname + } + case "agent": + if v != nil { + var agent string + err = json.Unmarshal(*v, &agent) + if err != nil { + return err + } + csp.Agent = &agent + } + case "lastEventReceived": + if v != nil { + var lastEventReceived string + err = json.Unmarshal(*v, &lastEventReceived) + if err != nil { + return err + } + csp.LastEventReceived = &lastEventReceived + } + default: + if v != nil { + var additionalProperties interface{} + err = json.Unmarshal(*v, &additionalProperties) + if err != nil { + return err + } + if csp.AdditionalProperties == nil { + csp.AdditionalProperties = make(map[string]interface{}) + } + csp.AdditionalProperties[k] = additionalProperties + } + case "deviceVendor": + if v != nil { + var deviceVendor string + err = json.Unmarshal(*v, &deviceVendor) + if err != nil { + return err + } + csp.DeviceVendor = &deviceVendor + } + case "deviceType": + if v != nil { + var deviceType string + err = json.Unmarshal(*v, &deviceType) + if err != nil { + return err + } + csp.DeviceType = &deviceType + } + case "workspace": + if v != nil { + var workspace ConnectedWorkspace + err = json.Unmarshal(*v, &workspace) + if err != nil { + return err + } + csp.Workspace = &workspace + } + } + } + + return nil +} + +// CloudError error response structure. +type CloudError struct { + // CloudErrorBody - Error data + *CloudErrorBody `json:"error,omitempty"` +} + +// MarshalJSON is the custom marshaler for CloudError. +func (ce CloudError) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if ce.CloudErrorBody != nil { + objectMap["error"] = ce.CloudErrorBody + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for CloudError struct. +func (ce *CloudError) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "error": + if v != nil { + var cloudErrorBody CloudErrorBody + err = json.Unmarshal(*v, &cloudErrorBody) + if err != nil { + return err + } + ce.CloudErrorBody = &cloudErrorBody + } + } + } + + return nil +} + +// CloudErrorBody error details. +type CloudErrorBody struct { + // Code - An identifier for the error. Codes are invariant and are intended to be consumed programmatically. + Code *string `json:"code,omitempty"` + // Message - A message describing the error, intended to be suitable for display in a user interface. + Message *string `json:"message,omitempty"` +} + +// Compliance compliance of a scope +type Compliance struct { + autorest.Response `json:"-"` + // ComplianceProperties - Compliance data + *ComplianceProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for Compliance. +func (c Compliance) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if c.ComplianceProperties != nil { + objectMap["properties"] = c.ComplianceProperties + } + if c.ID != nil { + objectMap["id"] = c.ID + } + if c.Name != nil { + objectMap["name"] = c.Name + } + if c.Type != nil { + objectMap["type"] = c.Type + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for Compliance struct. +func (c *Compliance) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var complianceProperties ComplianceProperties + err = json.Unmarshal(*v, &complianceProperties) + if err != nil { + return err + } + c.ComplianceProperties = &complianceProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + c.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + c.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + c.Type = &typeVar + } + } + } + + return nil +} + +// ComplianceList list of Compliance objects response +type ComplianceList struct { + autorest.Response `json:"-"` + // Value - List of Compliance objects + Value *[]Compliance `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// ComplianceListIterator provides access to a complete listing of Compliance values. +type ComplianceListIterator struct { + i int + page ComplianceListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *ComplianceListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter ComplianceListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter ComplianceListIterator) Response() ComplianceList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter ComplianceListIterator) Value() Compliance { + if !iter.page.NotDone() { + return Compliance{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (cl ComplianceList) IsEmpty() bool { + return cl.Value == nil || len(*cl.Value) == 0 +} + +// complianceListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (cl ComplianceList) complianceListPreparer() (*http.Request, error) { + if cl.NextLink == nil || len(to.String(cl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(cl.NextLink))) +} + +// ComplianceListPage contains a page of Compliance values. +type ComplianceListPage struct { + fn func(ComplianceList) (ComplianceList, error) + cl ComplianceList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *ComplianceListPage) Next() error { + next, err := page.fn(page.cl) + if err != nil { + return err + } + page.cl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page ComplianceListPage) NotDone() bool { + return !page.cl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page ComplianceListPage) Response() ComplianceList { + return page.cl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page ComplianceListPage) Values() []Compliance { + if page.cl.IsEmpty() { + return nil + } + return *page.cl.Value +} + +// ComplianceProperties the Compliance score (percentage) of a Subscription is a sum of all Resources' Compliances +// under the given Subscription. A Resource Compliance is defined as the compliant ('healthy') Policy Definitions +// out of all Policy Definitions applicable to a given resource. +type ComplianceProperties struct { + // AssessmentTimestampUtcDate - The timestamp when the Compliance calculation was conducted. + AssessmentTimestampUtcDate *date.Time `json:"assessmentTimestampUtcDate,omitempty"` + // ResourceCount - The resource count of the given subscription for which the Compliance calculation was conducted (needed for Management Group Compliance calculation). + ResourceCount *int32 `json:"resourceCount,omitempty"` + // AssessmentResult - An array of segment, which is the actually the compliance assessment. + AssessmentResult *[]ComplianceSegment `json:"assessmentResult,omitempty"` +} + +// ComplianceSegment a segment of a compliance assessment. +type ComplianceSegment struct { + // SegmentType - The segment type, e.g. compliant, non-compliance, insufficient coverage, N/A, etc. + SegmentType *string `json:"segmentType,omitempty"` + // Percentage - The size (%) of the segment. + Percentage *float64 `json:"percentage,omitempty"` +} + +// ConnectedWorkspace ... +type ConnectedWorkspace struct { + // ID - Azure resource ID of the connected OMS workspace + ID *string `json:"id,omitempty"` +} + +// Contact contact details for security issues +type Contact struct { + autorest.Response `json:"-"` + // ContactProperties - Security contact data + *ContactProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for Contact. +func (c Contact) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if c.ContactProperties != nil { + objectMap["properties"] = c.ContactProperties + } + if c.ID != nil { + objectMap["id"] = c.ID + } + if c.Name != nil { + objectMap["name"] = c.Name + } + if c.Type != nil { + objectMap["type"] = c.Type + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for Contact struct. +func (c *Contact) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var contactProperties ContactProperties + err = json.Unmarshal(*v, &contactProperties) + if err != nil { + return err + } + c.ContactProperties = &contactProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + c.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + c.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + c.Type = &typeVar + } + } + } + + return nil +} + +// ContactList list of security contacts response +type ContactList struct { + autorest.Response `json:"-"` + // Value - List of security contacts + Value *[]Contact `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// ContactListIterator provides access to a complete listing of Contact values. +type ContactListIterator struct { + i int + page ContactListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *ContactListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter ContactListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter ContactListIterator) Response() ContactList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter ContactListIterator) Value() Contact { + if !iter.page.NotDone() { + return Contact{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (cl ContactList) IsEmpty() bool { + return cl.Value == nil || len(*cl.Value) == 0 +} + +// contactListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (cl ContactList) contactListPreparer() (*http.Request, error) { + if cl.NextLink == nil || len(to.String(cl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(cl.NextLink))) +} + +// ContactListPage contains a page of Contact values. +type ContactListPage struct { + fn func(ContactList) (ContactList, error) + cl ContactList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *ContactListPage) Next() error { + next, err := page.fn(page.cl) + if err != nil { + return err + } + page.cl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page ContactListPage) NotDone() bool { + return !page.cl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page ContactListPage) Response() ContactList { + return page.cl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page ContactListPage) Values() []Contact { + if page.cl.IsEmpty() { + return nil + } + return *page.cl.Value +} + +// ContactProperties describes security contact properties +type ContactProperties struct { + // Email - The email of this security contact + Email *string `json:"email,omitempty"` + // Phone - The phone number of this security contact + Phone *string `json:"phone,omitempty"` + // AlertNotifications - Whether to send security alerts notifications to the security contact. Possible values include: 'On', 'Off' + AlertNotifications AlertNotifications `json:"alertNotifications,omitempty"` + // AlertsToAdmins - Whether to send security alerts notifications to subscription admins. Possible values include: 'AlertsToAdminsOn', 'AlertsToAdminsOff' + AlertsToAdmins AlertsToAdmins `json:"alertsToAdmins,omitempty"` +} + +// DataExportSetting represents a data export setting +type DataExportSetting struct { + // DataExportSettingProperties - Data export setting data + *DataExportSettingProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Kind - Possible values include: 'KindSetting', 'KindDataExportSetting' + Kind KindEnum `json:"kind,omitempty"` +} + +// MarshalJSON is the custom marshaler for DataExportSetting. +func (desVar DataExportSetting) MarshalJSON() ([]byte, error) { + desVar.Kind = KindDataExportSetting + objectMap := make(map[string]interface{}) + if desVar.DataExportSettingProperties != nil { + objectMap["properties"] = desVar.DataExportSettingProperties + } + if desVar.ID != nil { + objectMap["id"] = desVar.ID + } + if desVar.Name != nil { + objectMap["name"] = desVar.Name + } + if desVar.Type != nil { + objectMap["type"] = desVar.Type + } + if desVar.Kind != "" { + objectMap["kind"] = desVar.Kind + } + return json.Marshal(objectMap) +} + +// AsDataExportSetting is the BasicSetting implementation for DataExportSetting. +func (desVar DataExportSetting) AsDataExportSetting() (*DataExportSetting, bool) { + return &desVar, true +} + +// AsSetting is the BasicSetting implementation for DataExportSetting. +func (desVar DataExportSetting) AsSetting() (*Setting, bool) { + return nil, false +} + +// AsBasicSetting is the BasicSetting implementation for DataExportSetting. +func (desVar DataExportSetting) AsBasicSetting() (BasicSetting, bool) { + return &desVar, true +} + +// UnmarshalJSON is the custom unmarshaler for DataExportSetting struct. +func (desVar *DataExportSetting) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var dataExportSettingProperties DataExportSettingProperties + err = json.Unmarshal(*v, &dataExportSettingProperties) + if err != nil { + return err + } + desVar.DataExportSettingProperties = &dataExportSettingProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + desVar.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + desVar.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + desVar.Type = &typeVar + } + case "kind": + if v != nil { + var kind KindEnum + err = json.Unmarshal(*v, &kind) + if err != nil { + return err + } + desVar.Kind = kind + } + } + } + + return nil +} + +// DataExportSettingProperties the data export setting properties +type DataExportSettingProperties struct { + // Enabled - Is the data export setting is enabled + Enabled *bool `json:"enabled,omitempty"` +} + +// DiscoveredSecuritySolution ... +type DiscoveredSecuritySolution struct { + autorest.Response `json:"-"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Location - Location where the resource is stored + Location *string `json:"location,omitempty"` + *DiscoveredSecuritySolutionProperties `json:"properties,omitempty"` +} + +// MarshalJSON is the custom marshaler for DiscoveredSecuritySolution. +func (dss DiscoveredSecuritySolution) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if dss.ID != nil { + objectMap["id"] = dss.ID + } + if dss.Name != nil { + objectMap["name"] = dss.Name + } + if dss.Type != nil { + objectMap["type"] = dss.Type + } + if dss.Location != nil { + objectMap["location"] = dss.Location + } + if dss.DiscoveredSecuritySolutionProperties != nil { + objectMap["properties"] = dss.DiscoveredSecuritySolutionProperties + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for DiscoveredSecuritySolution struct. +func (dss *DiscoveredSecuritySolution) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + dss.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + dss.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + dss.Type = &typeVar + } + case "location": + if v != nil { + var location string + err = json.Unmarshal(*v, &location) + if err != nil { + return err + } + dss.Location = &location + } + case "properties": + if v != nil { + var discoveredSecuritySolutionProperties DiscoveredSecuritySolutionProperties + err = json.Unmarshal(*v, &discoveredSecuritySolutionProperties) + if err != nil { + return err + } + dss.DiscoveredSecuritySolutionProperties = &discoveredSecuritySolutionProperties + } + } + } + + return nil +} + +// DiscoveredSecuritySolutionList ... +type DiscoveredSecuritySolutionList struct { + autorest.Response `json:"-"` + Value *[]DiscoveredSecuritySolution `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// DiscoveredSecuritySolutionListIterator provides access to a complete listing of DiscoveredSecuritySolution +// values. +type DiscoveredSecuritySolutionListIterator struct { + i int + page DiscoveredSecuritySolutionListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *DiscoveredSecuritySolutionListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter DiscoveredSecuritySolutionListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter DiscoveredSecuritySolutionListIterator) Response() DiscoveredSecuritySolutionList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter DiscoveredSecuritySolutionListIterator) Value() DiscoveredSecuritySolution { + if !iter.page.NotDone() { + return DiscoveredSecuritySolution{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (dssl DiscoveredSecuritySolutionList) IsEmpty() bool { + return dssl.Value == nil || len(*dssl.Value) == 0 +} + +// discoveredSecuritySolutionListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (dssl DiscoveredSecuritySolutionList) discoveredSecuritySolutionListPreparer() (*http.Request, error) { + if dssl.NextLink == nil || len(to.String(dssl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(dssl.NextLink))) +} + +// DiscoveredSecuritySolutionListPage contains a page of DiscoveredSecuritySolution values. +type DiscoveredSecuritySolutionListPage struct { + fn func(DiscoveredSecuritySolutionList) (DiscoveredSecuritySolutionList, error) + dssl DiscoveredSecuritySolutionList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *DiscoveredSecuritySolutionListPage) Next() error { + next, err := page.fn(page.dssl) + if err != nil { + return err + } + page.dssl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page DiscoveredSecuritySolutionListPage) NotDone() bool { + return !page.dssl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page DiscoveredSecuritySolutionListPage) Response() DiscoveredSecuritySolutionList { + return page.dssl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page DiscoveredSecuritySolutionListPage) Values() []DiscoveredSecuritySolution { + if page.dssl.IsEmpty() { + return nil + } + return *page.dssl.Value +} + +// DiscoveredSecuritySolutionProperties ... +type DiscoveredSecuritySolutionProperties struct { + // SecurityFamily - The security family of the discovered solution. Possible values include: 'Waf', 'Ngfw', 'SaasWaf', 'Va' + SecurityFamily Family `json:"securityFamily,omitempty"` + // Offer - The security solutions' image offer + Offer *string `json:"offer,omitempty"` + // Publisher - The security solutions' image publisher + Publisher *string `json:"publisher,omitempty"` + // Sku - The security solutions' image sku + Sku *string `json:"sku,omitempty"` +} + +// BasicExternalSecuritySolution represents a security solution external to Azure Security Center which sends +// information to an OMS workspace and whos data is displayed by Azure Security Center. +type BasicExternalSecuritySolution interface { + AsCefExternalSecuritySolution() (*CefExternalSecuritySolution, bool) + AsAtaExternalSecuritySolution() (*AtaExternalSecuritySolution, bool) + AsAadExternalSecuritySolution() (*AadExternalSecuritySolution, bool) + AsExternalSecuritySolution() (*ExternalSecuritySolution, bool) +} + +// ExternalSecuritySolution represents a security solution external to Azure Security Center which sends +// information to an OMS workspace and whos data is displayed by Azure Security Center. +type ExternalSecuritySolution struct { + autorest.Response `json:"-"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Location - Location where the resource is stored + Location *string `json:"location,omitempty"` + // Kind - Possible values include: 'KindExternalSecuritySolution', 'KindCEF', 'KindATA', 'KindAAD' + Kind KindEnum1 `json:"kind,omitempty"` +} + +func unmarshalBasicExternalSecuritySolution(body []byte) (BasicExternalSecuritySolution, error) { + var m map[string]interface{} + err := json.Unmarshal(body, &m) + if err != nil { + return nil, err + } + + switch m["kind"] { + case string(KindCEF): + var cess CefExternalSecuritySolution + err := json.Unmarshal(body, &cess) + return cess, err + case string(KindATA): + var aess AtaExternalSecuritySolution + err := json.Unmarshal(body, &aess) + return aess, err + case string(KindAAD): + var aess AadExternalSecuritySolution + err := json.Unmarshal(body, &aess) + return aess, err + default: + var ess ExternalSecuritySolution + err := json.Unmarshal(body, &ess) + return ess, err + } +} +func unmarshalBasicExternalSecuritySolutionArray(body []byte) ([]BasicExternalSecuritySolution, error) { + var rawMessages []*json.RawMessage + err := json.Unmarshal(body, &rawMessages) + if err != nil { + return nil, err + } + + essArray := make([]BasicExternalSecuritySolution, len(rawMessages)) + + for index, rawMessage := range rawMessages { + ess, err := unmarshalBasicExternalSecuritySolution(*rawMessage) + if err != nil { + return nil, err + } + essArray[index] = ess + } + return essArray, nil +} + +// MarshalJSON is the custom marshaler for ExternalSecuritySolution. +func (ess ExternalSecuritySolution) MarshalJSON() ([]byte, error) { + ess.Kind = KindExternalSecuritySolution + objectMap := make(map[string]interface{}) + if ess.ID != nil { + objectMap["id"] = ess.ID + } + if ess.Name != nil { + objectMap["name"] = ess.Name + } + if ess.Type != nil { + objectMap["type"] = ess.Type + } + if ess.Location != nil { + objectMap["location"] = ess.Location + } + if ess.Kind != "" { + objectMap["kind"] = ess.Kind + } + return json.Marshal(objectMap) +} + +// AsCefExternalSecuritySolution is the BasicExternalSecuritySolution implementation for ExternalSecuritySolution. +func (ess ExternalSecuritySolution) AsCefExternalSecuritySolution() (*CefExternalSecuritySolution, bool) { + return nil, false +} + +// AsAtaExternalSecuritySolution is the BasicExternalSecuritySolution implementation for ExternalSecuritySolution. +func (ess ExternalSecuritySolution) AsAtaExternalSecuritySolution() (*AtaExternalSecuritySolution, bool) { + return nil, false +} + +// AsAadExternalSecuritySolution is the BasicExternalSecuritySolution implementation for ExternalSecuritySolution. +func (ess ExternalSecuritySolution) AsAadExternalSecuritySolution() (*AadExternalSecuritySolution, bool) { + return nil, false +} + +// AsExternalSecuritySolution is the BasicExternalSecuritySolution implementation for ExternalSecuritySolution. +func (ess ExternalSecuritySolution) AsExternalSecuritySolution() (*ExternalSecuritySolution, bool) { + return &ess, true +} + +// AsBasicExternalSecuritySolution is the BasicExternalSecuritySolution implementation for ExternalSecuritySolution. +func (ess ExternalSecuritySolution) AsBasicExternalSecuritySolution() (BasicExternalSecuritySolution, bool) { + return &ess, true +} + +// ExternalSecuritySolutionKind1 describes an Azure resource with kind +type ExternalSecuritySolutionKind1 struct { + // Kind - The kind of the external solution. Possible values include: 'CEF', 'ATA', 'AAD' + Kind ExternalSecuritySolutionKind `json:"kind,omitempty"` +} + +// ExternalSecuritySolutionList ... +type ExternalSecuritySolutionList struct { + autorest.Response `json:"-"` + Value *[]BasicExternalSecuritySolution `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// UnmarshalJSON is the custom unmarshaler for ExternalSecuritySolutionList struct. +func (essl *ExternalSecuritySolutionList) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "value": + if v != nil { + value, err := unmarshalBasicExternalSecuritySolutionArray(*v) + if err != nil { + return err + } + essl.Value = &value + } + case "nextLink": + if v != nil { + var nextLink string + err = json.Unmarshal(*v, &nextLink) + if err != nil { + return err + } + essl.NextLink = &nextLink + } + } + } + + return nil +} + +// ExternalSecuritySolutionListIterator provides access to a complete listing of ExternalSecuritySolution values. +type ExternalSecuritySolutionListIterator struct { + i int + page ExternalSecuritySolutionListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *ExternalSecuritySolutionListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter ExternalSecuritySolutionListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter ExternalSecuritySolutionListIterator) Response() ExternalSecuritySolutionList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter ExternalSecuritySolutionListIterator) Value() BasicExternalSecuritySolution { + if !iter.page.NotDone() { + return ExternalSecuritySolution{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (essl ExternalSecuritySolutionList) IsEmpty() bool { + return essl.Value == nil || len(*essl.Value) == 0 +} + +// externalSecuritySolutionListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (essl ExternalSecuritySolutionList) externalSecuritySolutionListPreparer() (*http.Request, error) { + if essl.NextLink == nil || len(to.String(essl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(essl.NextLink))) +} + +// ExternalSecuritySolutionListPage contains a page of BasicExternalSecuritySolution values. +type ExternalSecuritySolutionListPage struct { + fn func(ExternalSecuritySolutionList) (ExternalSecuritySolutionList, error) + essl ExternalSecuritySolutionList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *ExternalSecuritySolutionListPage) Next() error { + next, err := page.fn(page.essl) + if err != nil { + return err + } + page.essl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page ExternalSecuritySolutionListPage) NotDone() bool { + return !page.essl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page ExternalSecuritySolutionListPage) Response() ExternalSecuritySolutionList { + return page.essl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page ExternalSecuritySolutionListPage) Values() []BasicExternalSecuritySolution { + if page.essl.IsEmpty() { + return nil + } + return *page.essl.Value +} + +// ExternalSecuritySolutionModel ... +type ExternalSecuritySolutionModel struct { + autorest.Response `json:"-"` + Value BasicExternalSecuritySolution `json:"value,omitempty"` +} + +// UnmarshalJSON is the custom unmarshaler for ExternalSecuritySolutionModel struct. +func (essm *ExternalSecuritySolutionModel) UnmarshalJSON(body []byte) error { + ess, err := unmarshalBasicExternalSecuritySolution(body) + if err != nil { + return err + } + essm.Value = ess + + return nil +} + +// ExternalSecuritySolutionProperties the solution properties (correspond to the solution kind) +type ExternalSecuritySolutionProperties struct { + // AdditionalProperties - Unmatched properties from the message are deserialized this collection + AdditionalProperties map[string]interface{} `json:""` + DeviceVendor *string `json:"deviceVendor,omitempty"` + DeviceType *string `json:"deviceType,omitempty"` + Workspace *ConnectedWorkspace `json:"workspace,omitempty"` +} + +// MarshalJSON is the custom marshaler for ExternalSecuritySolutionProperties. +func (essp ExternalSecuritySolutionProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if essp.DeviceVendor != nil { + objectMap["deviceVendor"] = essp.DeviceVendor + } + if essp.DeviceType != nil { + objectMap["deviceType"] = essp.DeviceType + } + if essp.Workspace != nil { + objectMap["workspace"] = essp.Workspace + } + for k, v := range essp.AdditionalProperties { + objectMap[k] = v + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for ExternalSecuritySolutionProperties struct. +func (essp *ExternalSecuritySolutionProperties) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + default: + if v != nil { + var additionalProperties interface{} + err = json.Unmarshal(*v, &additionalProperties) + if err != nil { + return err + } + if essp.AdditionalProperties == nil { + essp.AdditionalProperties = make(map[string]interface{}) + } + essp.AdditionalProperties[k] = additionalProperties + } + case "deviceVendor": + if v != nil { + var deviceVendor string + err = json.Unmarshal(*v, &deviceVendor) + if err != nil { + return err + } + essp.DeviceVendor = &deviceVendor + } + case "deviceType": + if v != nil { + var deviceType string + err = json.Unmarshal(*v, &deviceType) + if err != nil { + return err + } + essp.DeviceType = &deviceType + } + case "workspace": + if v != nil { + var workspace ConnectedWorkspace + err = json.Unmarshal(*v, &workspace) + if err != nil { + return err + } + essp.Workspace = &workspace + } + } + } + + return nil +} + +// JitNetworkAccessPoliciesList ... +type JitNetworkAccessPoliciesList struct { + autorest.Response `json:"-"` + Value *[]JitNetworkAccessPolicy `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// JitNetworkAccessPoliciesListIterator provides access to a complete listing of JitNetworkAccessPolicy values. +type JitNetworkAccessPoliciesListIterator struct { + i int + page JitNetworkAccessPoliciesListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *JitNetworkAccessPoliciesListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter JitNetworkAccessPoliciesListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter JitNetworkAccessPoliciesListIterator) Response() JitNetworkAccessPoliciesList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter JitNetworkAccessPoliciesListIterator) Value() JitNetworkAccessPolicy { + if !iter.page.NotDone() { + return JitNetworkAccessPolicy{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (jnapl JitNetworkAccessPoliciesList) IsEmpty() bool { + return jnapl.Value == nil || len(*jnapl.Value) == 0 +} + +// jitNetworkAccessPoliciesListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (jnapl JitNetworkAccessPoliciesList) jitNetworkAccessPoliciesListPreparer() (*http.Request, error) { + if jnapl.NextLink == nil || len(to.String(jnapl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(jnapl.NextLink))) +} + +// JitNetworkAccessPoliciesListPage contains a page of JitNetworkAccessPolicy values. +type JitNetworkAccessPoliciesListPage struct { + fn func(JitNetworkAccessPoliciesList) (JitNetworkAccessPoliciesList, error) + jnapl JitNetworkAccessPoliciesList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *JitNetworkAccessPoliciesListPage) Next() error { + next, err := page.fn(page.jnapl) + if err != nil { + return err + } + page.jnapl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page JitNetworkAccessPoliciesListPage) NotDone() bool { + return !page.jnapl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page JitNetworkAccessPoliciesListPage) Response() JitNetworkAccessPoliciesList { + return page.jnapl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page JitNetworkAccessPoliciesListPage) Values() []JitNetworkAccessPolicy { + if page.jnapl.IsEmpty() { + return nil + } + return *page.jnapl.Value +} + +// JitNetworkAccessPolicy ... +type JitNetworkAccessPolicy struct { + autorest.Response `json:"-"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Kind - Kind of the resource + Kind *string `json:"kind,omitempty"` + // Location - Location where the resource is stored + Location *string `json:"location,omitempty"` + *JitNetworkAccessPolicyProperties `json:"properties,omitempty"` +} + +// MarshalJSON is the custom marshaler for JitNetworkAccessPolicy. +func (jnap JitNetworkAccessPolicy) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if jnap.ID != nil { + objectMap["id"] = jnap.ID + } + if jnap.Name != nil { + objectMap["name"] = jnap.Name + } + if jnap.Type != nil { + objectMap["type"] = jnap.Type + } + if jnap.Kind != nil { + objectMap["kind"] = jnap.Kind + } + if jnap.Location != nil { + objectMap["location"] = jnap.Location + } + if jnap.JitNetworkAccessPolicyProperties != nil { + objectMap["properties"] = jnap.JitNetworkAccessPolicyProperties + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for JitNetworkAccessPolicy struct. +func (jnap *JitNetworkAccessPolicy) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + jnap.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + jnap.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + jnap.Type = &typeVar + } + case "kind": + if v != nil { + var kind string + err = json.Unmarshal(*v, &kind) + if err != nil { + return err + } + jnap.Kind = &kind + } + case "location": + if v != nil { + var location string + err = json.Unmarshal(*v, &location) + if err != nil { + return err + } + jnap.Location = &location + } + case "properties": + if v != nil { + var jitNetworkAccessPolicyProperties JitNetworkAccessPolicyProperties + err = json.Unmarshal(*v, &jitNetworkAccessPolicyProperties) + if err != nil { + return err + } + jnap.JitNetworkAccessPolicyProperties = &jitNetworkAccessPolicyProperties + } + } + } + + return nil +} + +// JitNetworkAccessPolicyInitiatePort ... +type JitNetworkAccessPolicyInitiatePort struct { + Number *int32 `json:"number,omitempty"` + // AllowedSourceAddressPrefix - Source of the allowed traffic. If omitted, the request will be for the source IP address of the initiate request. + AllowedSourceAddressPrefix *string `json:"allowedSourceAddressPrefix,omitempty"` + // EndTimeUtc - The time to close the request in UTC + EndTimeUtc *date.Time `json:"endTimeUtc,omitempty"` +} + +// JitNetworkAccessPolicyInitiateRequest ... +type JitNetworkAccessPolicyInitiateRequest struct { + // VirtualMachines - A list of virtual machines & ports to open access for + VirtualMachines *[]JitNetworkAccessPolicyInitiateVirtualMachine `json:"virtualMachines,omitempty"` +} + +// JitNetworkAccessPolicyInitiateVirtualMachine ... +type JitNetworkAccessPolicyInitiateVirtualMachine struct { + // ID - Resource ID of the virtual machine that is linked to this policy + ID *string `json:"id,omitempty"` + // Ports - The ports to open for the resource with the `id` + Ports *[]JitNetworkAccessPolicyInitiatePort `json:"ports,omitempty"` +} + +// JitNetworkAccessPolicyProperties ... +type JitNetworkAccessPolicyProperties struct { + // VirtualMachines - Configurations for Microsoft.Compute/virtualMachines resource type. + VirtualMachines *[]JitNetworkAccessPolicyVirtualMachine `json:"virtualMachines,omitempty"` + Requests *[]JitNetworkAccessRequest `json:"requests,omitempty"` + // ProvisioningState - Gets the provisioning state of the Just-in-Time policy. + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// JitNetworkAccessPolicyVirtualMachine ... +type JitNetworkAccessPolicyVirtualMachine struct { + // ID - Resource ID of the virtual machine that is linked to this policy + ID *string `json:"id,omitempty"` + // Ports - Port configurations for the virtual machine + Ports *[]JitNetworkAccessPortRule `json:"ports,omitempty"` +} + +// JitNetworkAccessPortRule ... +type JitNetworkAccessPortRule struct { + Number *int32 `json:"number,omitempty"` + // Protocol - Possible values include: 'TCP', 'UDP', 'All' + Protocol Protocol `json:"protocol,omitempty"` + // AllowedSourceAddressPrefix - Mutually exclusive with the "allowedSourceAddressPrefixes" parameter. Should be an IP address or CIDR, for example "192.168.0.3" or "192.168.0.0/16". + AllowedSourceAddressPrefix *string `json:"allowedSourceAddressPrefix,omitempty"` + // AllowedSourceAddressPrefixes - Mutually exclusive with the "allowedSourceAddressPrefix" parameter. + AllowedSourceAddressPrefixes *[]string `json:"allowedSourceAddressPrefixes,omitempty"` + // MaxRequestAccessDuration - Maximum duration requests can be made for. In ISO 8601 duration format. Minimum 5 minutes, maximum 1 day + MaxRequestAccessDuration *string `json:"maxRequestAccessDuration,omitempty"` +} + +// JitNetworkAccessRequest ... +type JitNetworkAccessRequest struct { + autorest.Response `json:"-"` + VirtualMachines *[]JitNetworkAccessRequestVirtualMachine `json:"virtualMachines,omitempty"` + // StartTimeUtc - The start time of the request in UTC + StartTimeUtc *date.Time `json:"startTimeUtc,omitempty"` + // Requestor - The identity of the person who made the request + Requestor *string `json:"requestor,omitempty"` +} + +// JitNetworkAccessRequestPort ... +type JitNetworkAccessRequestPort struct { + Number *int32 `json:"number,omitempty"` + // AllowedSourceAddressPrefix - Mutually exclusive with the "allowedSourceAddressPrefixes" parameter. Should be an IP address or CIDR, for example "192.168.0.3" or "192.168.0.0/16". + AllowedSourceAddressPrefix *string `json:"allowedSourceAddressPrefix,omitempty"` + // AllowedSourceAddressPrefixes - Mutually exclusive with the "allowedSourceAddressPrefix" parameter. + AllowedSourceAddressPrefixes *[]string `json:"allowedSourceAddressPrefixes,omitempty"` + // EndTimeUtc - The date & time at which the request ends in UTC + EndTimeUtc *date.Time `json:"endTimeUtc,omitempty"` + // Status - The status of the port. Possible values include: 'Revoked', 'Initiated' + Status Status `json:"status,omitempty"` + // StatusReason - A description of why the `status` has its value. Possible values include: 'Expired', 'UserRequested', 'NewerRequestInitiated' + StatusReason StatusReason `json:"statusReason,omitempty"` +} + +// JitNetworkAccessRequestVirtualMachine ... +type JitNetworkAccessRequestVirtualMachine struct { + // ID - Resource ID of the virtual machine that is linked to this policy + ID *string `json:"id,omitempty"` + // Ports - The ports that were opened for the virtual machine + Ports *[]JitNetworkAccessRequestPort `json:"ports,omitempty"` +} + +// Kind describes an Azure resource with kind +type Kind struct { + // Kind - Kind of the resource + Kind *string `json:"kind,omitempty"` +} + +// Location describes an Azure resource with location +type Location struct { + // Location - Location where the resource is stored + Location *string `json:"location,omitempty"` +} + +// Operation possible operation in the REST API of Microsoft.Security +type Operation struct { + // Name - Name of the operation + Name *string `json:"name,omitempty"` + // Origin - Where the operation is originated + Origin *string `json:"origin,omitempty"` + Display *OperationDisplay `json:"display,omitempty"` +} + +// OperationDisplay security operation display +type OperationDisplay struct { + // Provider - The resource provider for the operation. + Provider *string `json:"provider,omitempty"` + // Resource - The display name of the resource the operation applies to. + Resource *string `json:"resource,omitempty"` + // Operation - The display name of the security operation. + Operation *string `json:"operation,omitempty"` + // Description - The description of the operation. + Description *string `json:"description,omitempty"` +} + +// OperationList list of possible operations for Microsoft.Security resource provider +type OperationList struct { + autorest.Response `json:"-"` + // Value - List of Security operations + Value *[]Operation `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// OperationListIterator provides access to a complete listing of Operation values. +type OperationListIterator struct { + i int + page OperationListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *OperationListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter OperationListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter OperationListIterator) Response() OperationList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter OperationListIterator) Value() Operation { + if !iter.page.NotDone() { + return Operation{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (ol OperationList) IsEmpty() bool { + return ol.Value == nil || len(*ol.Value) == 0 +} + +// operationListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (ol OperationList) operationListPreparer() (*http.Request, error) { + if ol.NextLink == nil || len(to.String(ol.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(ol.NextLink))) +} + +// OperationListPage contains a page of Operation values. +type OperationListPage struct { + fn func(OperationList) (OperationList, error) + ol OperationList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *OperationListPage) Next() error { + next, err := page.fn(page.ol) + if err != nil { + return err + } + page.ol = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page OperationListPage) NotDone() bool { + return !page.ol.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page OperationListPage) Response() OperationList { + return page.ol +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page OperationListPage) Values() []Operation { + if page.ol.IsEmpty() { + return nil + } + return *page.ol.Value +} + +// Pricing pricing tier will be applied for the scope based on the resource ID +type Pricing struct { + autorest.Response `json:"-"` + // PricingProperties - Pricing data + *PricingProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for Pricing. +func (p Pricing) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if p.PricingProperties != nil { + objectMap["properties"] = p.PricingProperties + } + if p.ID != nil { + objectMap["id"] = p.ID + } + if p.Name != nil { + objectMap["name"] = p.Name + } + if p.Type != nil { + objectMap["type"] = p.Type + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for Pricing struct. +func (p *Pricing) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var pricingProperties PricingProperties + err = json.Unmarshal(*v, &pricingProperties) + if err != nil { + return err + } + p.PricingProperties = &pricingProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + p.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + p.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + p.Type = &typeVar + } + } + } + + return nil +} + +// PricingList list of pricing configurations response +type PricingList struct { + autorest.Response `json:"-"` + // Value - List of pricing configurations + Value *[]Pricing `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// PricingListIterator provides access to a complete listing of Pricing values. +type PricingListIterator struct { + i int + page PricingListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *PricingListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter PricingListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter PricingListIterator) Response() PricingList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter PricingListIterator) Value() Pricing { + if !iter.page.NotDone() { + return Pricing{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (pl PricingList) IsEmpty() bool { + return pl.Value == nil || len(*pl.Value) == 0 +} + +// pricingListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (pl PricingList) pricingListPreparer() (*http.Request, error) { + if pl.NextLink == nil || len(to.String(pl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(pl.NextLink))) +} + +// PricingListPage contains a page of Pricing values. +type PricingListPage struct { + fn func(PricingList) (PricingList, error) + pl PricingList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *PricingListPage) Next() error { + next, err := page.fn(page.pl) + if err != nil { + return err + } + page.pl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page PricingListPage) NotDone() bool { + return !page.pl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page PricingListPage) Response() PricingList { + return page.pl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page PricingListPage) Values() []Pricing { + if page.pl.IsEmpty() { + return nil + } + return *page.pl.Value +} + +// PricingProperties pricing data +type PricingProperties struct { + // PricingTier - Pricing tier type. Possible values include: 'Free', 'Standard' + PricingTier PricingTier `json:"pricingTier,omitempty"` +} + +// Resource describes an Azure resource. +type Resource struct { + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` +} + +// BasicSetting represents a security setting in Azure Security Center. +type BasicSetting interface { + AsDataExportSetting() (*DataExportSetting, bool) + AsSetting() (*Setting, bool) +} + +// Setting represents a security setting in Azure Security Center. +type Setting struct { + autorest.Response `json:"-"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` + // Kind - Possible values include: 'KindSetting', 'KindDataExportSetting' + Kind KindEnum `json:"kind,omitempty"` +} + +func unmarshalBasicSetting(body []byte) (BasicSetting, error) { + var m map[string]interface{} + err := json.Unmarshal(body, &m) + if err != nil { + return nil, err + } + + switch m["kind"] { + case string(KindDataExportSetting): + var desVar DataExportSetting + err := json.Unmarshal(body, &desVar) + return desVar, err + default: + var s Setting + err := json.Unmarshal(body, &s) + return s, err + } +} +func unmarshalBasicSettingArray(body []byte) ([]BasicSetting, error) { + var rawMessages []*json.RawMessage + err := json.Unmarshal(body, &rawMessages) + if err != nil { + return nil, err + } + + sArray := make([]BasicSetting, len(rawMessages)) + + for index, rawMessage := range rawMessages { + s, err := unmarshalBasicSetting(*rawMessage) + if err != nil { + return nil, err + } + sArray[index] = s + } + return sArray, nil +} + +// MarshalJSON is the custom marshaler for Setting. +func (s Setting) MarshalJSON() ([]byte, error) { + s.Kind = KindSetting + objectMap := make(map[string]interface{}) + if s.ID != nil { + objectMap["id"] = s.ID + } + if s.Name != nil { + objectMap["name"] = s.Name + } + if s.Type != nil { + objectMap["type"] = s.Type + } + if s.Kind != "" { + objectMap["kind"] = s.Kind + } + return json.Marshal(objectMap) +} + +// AsDataExportSetting is the BasicSetting implementation for Setting. +func (s Setting) AsDataExportSetting() (*DataExportSetting, bool) { + return nil, false +} + +// AsSetting is the BasicSetting implementation for Setting. +func (s Setting) AsSetting() (*Setting, bool) { + return &s, true +} + +// AsBasicSetting is the BasicSetting implementation for Setting. +func (s Setting) AsBasicSetting() (BasicSetting, bool) { + return &s, true +} + +// SettingKind1 the kind of the security setting +type SettingKind1 struct { + // Kind - the kind of the settings string. Possible values include: 'SettingKindDataExportSetting' + Kind SettingKind `json:"kind,omitempty"` +} + +// SettingModel ... +type SettingModel struct { + autorest.Response `json:"-"` + Value BasicSetting `json:"value,omitempty"` +} + +// UnmarshalJSON is the custom unmarshaler for SettingModel struct. +func (sm *SettingModel) UnmarshalJSON(body []byte) error { + s, err := unmarshalBasicSetting(body) + if err != nil { + return err + } + sm.Value = s + + return nil +} + +// SettingsList subscription settings list. +type SettingsList struct { + autorest.Response `json:"-"` + // Value - The settings list. + Value *[]BasicSetting `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// UnmarshalJSON is the custom unmarshaler for SettingsList struct. +func (sl *SettingsList) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "value": + if v != nil { + value, err := unmarshalBasicSettingArray(*v) + if err != nil { + return err + } + sl.Value = &value + } + case "nextLink": + if v != nil { + var nextLink string + err = json.Unmarshal(*v, &nextLink) + if err != nil { + return err + } + sl.NextLink = &nextLink + } + } + } + + return nil +} + +// SettingsListIterator provides access to a complete listing of Setting values. +type SettingsListIterator struct { + i int + page SettingsListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *SettingsListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter SettingsListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter SettingsListIterator) Response() SettingsList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter SettingsListIterator) Value() BasicSetting { + if !iter.page.NotDone() { + return Setting{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (sl SettingsList) IsEmpty() bool { + return sl.Value == nil || len(*sl.Value) == 0 +} + +// settingsListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (sl SettingsList) settingsListPreparer() (*http.Request, error) { + if sl.NextLink == nil || len(to.String(sl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(sl.NextLink))) +} + +// SettingsListPage contains a page of BasicSetting values. +type SettingsListPage struct { + fn func(SettingsList) (SettingsList, error) + sl SettingsList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *SettingsListPage) Next() error { + next, err := page.fn(page.sl) + if err != nil { + return err + } + page.sl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page SettingsListPage) NotDone() bool { + return !page.sl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page SettingsListPage) Response() SettingsList { + return page.sl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page SettingsListPage) Values() []BasicSetting { + if page.sl.IsEmpty() { + return nil + } + return *page.sl.Value +} + +// Task security task that we recommend to do in order to strengthen security +type Task struct { + autorest.Response `json:"-"` + *TaskProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for Task. +func (t Task) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if t.TaskProperties != nil { + objectMap["properties"] = t.TaskProperties + } + if t.ID != nil { + objectMap["id"] = t.ID + } + if t.Name != nil { + objectMap["name"] = t.Name + } + if t.Type != nil { + objectMap["type"] = t.Type + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for Task struct. +func (t *Task) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var taskProperties TaskProperties + err = json.Unmarshal(*v, &taskProperties) + if err != nil { + return err + } + t.TaskProperties = &taskProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + t.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + t.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + t.Type = &typeVar + } + } + } + + return nil +} + +// TaskList list of security task recommendations +type TaskList struct { + autorest.Response `json:"-"` + Value *[]Task `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// TaskListIterator provides access to a complete listing of Task values. +type TaskListIterator struct { + i int + page TaskListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *TaskListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter TaskListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter TaskListIterator) Response() TaskList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter TaskListIterator) Value() Task { + if !iter.page.NotDone() { + return Task{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (tl TaskList) IsEmpty() bool { + return tl.Value == nil || len(*tl.Value) == 0 +} + +// taskListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (tl TaskList) taskListPreparer() (*http.Request, error) { + if tl.NextLink == nil || len(to.String(tl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(tl.NextLink))) +} + +// TaskListPage contains a page of Task values. +type TaskListPage struct { + fn func(TaskList) (TaskList, error) + tl TaskList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *TaskListPage) Next() error { + next, err := page.fn(page.tl) + if err != nil { + return err + } + page.tl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page TaskListPage) NotDone() bool { + return !page.tl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page TaskListPage) Response() TaskList { + return page.tl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page TaskListPage) Values() []Task { + if page.tl.IsEmpty() { + return nil + } + return *page.tl.Value +} + +// TaskParameters changing set of properties, depending on the task type that is derived from the name field +type TaskParameters struct { + // AdditionalProperties - Unmatched properties from the message are deserialized this collection + AdditionalProperties map[string]interface{} `json:""` + // Name - Name of the task type + Name *string `json:"name,omitempty"` +} + +// MarshalJSON is the custom marshaler for TaskParameters. +func (tp TaskParameters) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if tp.Name != nil { + objectMap["name"] = tp.Name + } + for k, v := range tp.AdditionalProperties { + objectMap[k] = v + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for TaskParameters struct. +func (tp *TaskParameters) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + default: + if v != nil { + var additionalProperties interface{} + err = json.Unmarshal(*v, &additionalProperties) + if err != nil { + return err + } + if tp.AdditionalProperties == nil { + tp.AdditionalProperties = make(map[string]interface{}) + } + tp.AdditionalProperties[k] = additionalProperties + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + tp.Name = &name + } + } + } + + return nil +} + +// TaskProperties describes properties of a task. +type TaskProperties struct { + // State - State of the task (Active, Resolved etc.) + State *string `json:"state,omitempty"` + // CreationTimeUtc - The time this task was discovered in UTC + CreationTimeUtc *date.Time `json:"creationTimeUtc,omitempty"` + SecurityTaskParameters *TaskParameters `json:"securityTaskParameters,omitempty"` + // LastStateChangeTimeUtc - The time this task's details were last changed in UTC + LastStateChangeTimeUtc *date.Time `json:"lastStateChangeTimeUtc,omitempty"` + // SubState - Additional data on the state of the task + SubState *string `json:"subState,omitempty"` +} + +// WorkspaceSetting configures where to store the OMS agent data for workspaces under a scope +type WorkspaceSetting struct { + autorest.Response `json:"-"` + // WorkspaceSettingProperties - Workspace setting data + *WorkspaceSettingProperties `json:"properties,omitempty"` + // ID - Resource Id + ID *string `json:"id,omitempty"` + // Name - Resource name + Name *string `json:"name,omitempty"` + // Type - Resource type + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for WorkspaceSetting. +func (ws WorkspaceSetting) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if ws.WorkspaceSettingProperties != nil { + objectMap["properties"] = ws.WorkspaceSettingProperties + } + if ws.ID != nil { + objectMap["id"] = ws.ID + } + if ws.Name != nil { + objectMap["name"] = ws.Name + } + if ws.Type != nil { + objectMap["type"] = ws.Type + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for WorkspaceSetting struct. +func (ws *WorkspaceSetting) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "properties": + if v != nil { + var workspaceSettingProperties WorkspaceSettingProperties + err = json.Unmarshal(*v, &workspaceSettingProperties) + if err != nil { + return err + } + ws.WorkspaceSettingProperties = &workspaceSettingProperties + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + ws.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + ws.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + ws.Type = &typeVar + } + } + } + + return nil +} + +// WorkspaceSettingList list of workspace settings response +type WorkspaceSettingList struct { + autorest.Response `json:"-"` + // Value - List of workspace settings + Value *[]WorkspaceSetting `json:"value,omitempty"` + // NextLink - The URI to fetch the next page. + NextLink *string `json:"nextLink,omitempty"` +} + +// WorkspaceSettingListIterator provides access to a complete listing of WorkspaceSetting values. +type WorkspaceSettingListIterator struct { + i int + page WorkspaceSettingListPage +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *WorkspaceSettingListIterator) Next() error { + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err := iter.page.Next() + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter WorkspaceSettingListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter WorkspaceSettingListIterator) Response() WorkspaceSettingList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter WorkspaceSettingListIterator) Value() WorkspaceSetting { + if !iter.page.NotDone() { + return WorkspaceSetting{} + } + return iter.page.Values()[iter.i] +} + +// IsEmpty returns true if the ListResult contains no values. +func (wsl WorkspaceSettingList) IsEmpty() bool { + return wsl.Value == nil || len(*wsl.Value) == 0 +} + +// workspaceSettingListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (wsl WorkspaceSettingList) workspaceSettingListPreparer() (*http.Request, error) { + if wsl.NextLink == nil || len(to.String(wsl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(wsl.NextLink))) +} + +// WorkspaceSettingListPage contains a page of WorkspaceSetting values. +type WorkspaceSettingListPage struct { + fn func(WorkspaceSettingList) (WorkspaceSettingList, error) + wsl WorkspaceSettingList +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *WorkspaceSettingListPage) Next() error { + next, err := page.fn(page.wsl) + if err != nil { + return err + } + page.wsl = next + return nil +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page WorkspaceSettingListPage) NotDone() bool { + return !page.wsl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page WorkspaceSettingListPage) Response() WorkspaceSettingList { + return page.wsl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page WorkspaceSettingListPage) Values() []WorkspaceSetting { + if page.wsl.IsEmpty() { + return nil + } + return *page.wsl.Value +} + +// WorkspaceSettingProperties workspace setting data +type WorkspaceSettingProperties struct { + // WorkspaceID - The full Azure ID of the workspace to save the data in + WorkspaceID *string `json:"workspaceId,omitempty"` + // Scope - All the VMs in this scope will send their security data to the mentioned workspace unless overridden by a setting with more specific scope + Scope *string `json:"scope,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/operations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/operations.go new file mode 100644 index 000000000000..806fc8906346 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/operations.go @@ -0,0 +1,126 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// OperationsClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type OperationsClient struct { + BaseClient +} + +// NewOperationsClient creates an instance of the OperationsClient client. +func NewOperationsClient(subscriptionID string, ascLocation string) OperationsClient { + return NewOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewOperationsClientWithBaseURI creates an instance of the OperationsClient client. +func NewOperationsClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) OperationsClient { + return OperationsClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// List exposes all available operations for discovery purposes. +func (client OperationsClient) List(ctx context.Context) (result OperationListPage, err error) { + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.OperationsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.ol.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.OperationsClient", "List", resp, "Failure sending request") + return + } + + result.ol, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.OperationsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client OperationsClient) ListPreparer(ctx context.Context) (*http.Request, error) { + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.Security/operations"), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client OperationsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client OperationsClient) ListResponder(resp *http.Response) (result OperationList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client OperationsClient) listNextResults(lastResults OperationList) (result OperationList, err error) { + req, err := lastResults.operationListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.OperationsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.OperationsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.OperationsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client OperationsClient) ListComplete(ctx context.Context) (result OperationListIterator, err error) { + result.page, err = client.List(ctx) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/pricings.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/pricings.go new file mode 100644 index 000000000000..cf813ee8c0a8 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/pricings.go @@ -0,0 +1,546 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// PricingsClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type PricingsClient struct { + BaseClient +} + +// NewPricingsClient creates an instance of the PricingsClient client. +func NewPricingsClient(subscriptionID string, ascLocation string) PricingsClient { + return NewPricingsClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewPricingsClientWithBaseURI creates an instance of the PricingsClient client. +func NewPricingsClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) PricingsClient { + return PricingsClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// CreateOrUpdateResourceGroupPricing security pricing configuration in the resource group +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// pricingName - name of the pricing configuration +// pricing - pricing object +func (client PricingsClient) CreateOrUpdateResourceGroupPricing(ctx context.Context, resourceGroupName string, pricingName string, pricing Pricing) (result Pricing, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.PricingsClient", "CreateOrUpdateResourceGroupPricing", err.Error()) + } + + req, err := client.CreateOrUpdateResourceGroupPricingPreparer(ctx, resourceGroupName, pricingName, pricing) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "CreateOrUpdateResourceGroupPricing", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateResourceGroupPricingSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.PricingsClient", "CreateOrUpdateResourceGroupPricing", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResourceGroupPricingResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "CreateOrUpdateResourceGroupPricing", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdateResourceGroupPricingPreparer prepares the CreateOrUpdateResourceGroupPricing request. +func (client PricingsClient) CreateOrUpdateResourceGroupPricingPreparer(ctx context.Context, resourceGroupName string, pricingName string, pricing Pricing) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "pricingName": autorest.Encode("path", pricingName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/pricings/{pricingName}", pathParameters), + autorest.WithJSON(pricing), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateOrUpdateResourceGroupPricingSender sends the CreateOrUpdateResourceGroupPricing request. The method will close the +// http.Response Body if it receives an error. +func (client PricingsClient) CreateOrUpdateResourceGroupPricingSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// CreateOrUpdateResourceGroupPricingResponder handles the response to the CreateOrUpdateResourceGroupPricing request. The method always +// closes the http.Response Body. +func (client PricingsClient) CreateOrUpdateResourceGroupPricingResponder(resp *http.Response) (result Pricing, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetResourceGroupPricing security pricing configuration in the resource group +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// pricingName - name of the pricing configuration +func (client PricingsClient) GetResourceGroupPricing(ctx context.Context, resourceGroupName string, pricingName string) (result Pricing, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.PricingsClient", "GetResourceGroupPricing", err.Error()) + } + + req, err := client.GetResourceGroupPricingPreparer(ctx, resourceGroupName, pricingName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "GetResourceGroupPricing", nil, "Failure preparing request") + return + } + + resp, err := client.GetResourceGroupPricingSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.PricingsClient", "GetResourceGroupPricing", resp, "Failure sending request") + return + } + + result, err = client.GetResourceGroupPricingResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "GetResourceGroupPricing", resp, "Failure responding to request") + } + + return +} + +// GetResourceGroupPricingPreparer prepares the GetResourceGroupPricing request. +func (client PricingsClient) GetResourceGroupPricingPreparer(ctx context.Context, resourceGroupName string, pricingName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "pricingName": autorest.Encode("path", pricingName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/pricings/{pricingName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetResourceGroupPricingSender sends the GetResourceGroupPricing request. The method will close the +// http.Response Body if it receives an error. +func (client PricingsClient) GetResourceGroupPricingSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResourceGroupPricingResponder handles the response to the GetResourceGroupPricing request. The method always +// closes the http.Response Body. +func (client PricingsClient) GetResourceGroupPricingResponder(resp *http.Response) (result Pricing, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSubscriptionPricing security pricing configuration in the subscriptionSecurity pricing configuration in the +// subscription +// Parameters: +// pricingName - name of the pricing configuration +func (client PricingsClient) GetSubscriptionPricing(ctx context.Context, pricingName string) (result Pricing, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.PricingsClient", "GetSubscriptionPricing", err.Error()) + } + + req, err := client.GetSubscriptionPricingPreparer(ctx, pricingName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "GetSubscriptionPricing", nil, "Failure preparing request") + return + } + + resp, err := client.GetSubscriptionPricingSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.PricingsClient", "GetSubscriptionPricing", resp, "Failure sending request") + return + } + + result, err = client.GetSubscriptionPricingResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "GetSubscriptionPricing", resp, "Failure responding to request") + } + + return +} + +// GetSubscriptionPricingPreparer prepares the GetSubscriptionPricing request. +func (client PricingsClient) GetSubscriptionPricingPreparer(ctx context.Context, pricingName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "pricingName": autorest.Encode("path", pricingName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/pricings/{pricingName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSubscriptionPricingSender sends the GetSubscriptionPricing request. The method will close the +// http.Response Body if it receives an error. +func (client PricingsClient) GetSubscriptionPricingSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetSubscriptionPricingResponder handles the response to the GetSubscriptionPricing request. The method always +// closes the http.Response Body. +func (client PricingsClient) GetSubscriptionPricingResponder(resp *http.Response) (result Pricing, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List security pricing configurations in the subscription +func (client PricingsClient) List(ctx context.Context) (result PricingListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.PricingsClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.pl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.PricingsClient", "List", resp, "Failure sending request") + return + } + + result.pl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client PricingsClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/pricings", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client PricingsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client PricingsClient) ListResponder(resp *http.Response) (result PricingList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client PricingsClient) listNextResults(lastResults PricingList) (result PricingList, err error) { + req, err := lastResults.pricingListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.PricingsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.PricingsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client PricingsClient) ListComplete(ctx context.Context) (result PricingListIterator, err error) { + result.page, err = client.List(ctx) + return +} + +// ListByResourceGroup security pricing configurations in the resource group +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +func (client PricingsClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result PricingListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.PricingsClient", "ListByResourceGroup", err.Error()) + } + + result.fn = client.listByResourceGroupNextResults + req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.pl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.PricingsClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result.pl, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client PricingsClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/pricings", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client PricingsClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client PricingsClient) ListByResourceGroupResponder(resp *http.Response) (result PricingList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByResourceGroupNextResults retrieves the next set of results, if any. +func (client PricingsClient) listByResourceGroupNextResults(lastResults PricingList) (result PricingList, err error) { + req, err := lastResults.pricingListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.PricingsClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.PricingsClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. +func (client PricingsClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string) (result PricingListIterator, err error) { + result.page, err = client.ListByResourceGroup(ctx, resourceGroupName) + return +} + +// UpdateSubscriptionPricing security pricing configuration in the subscription +// Parameters: +// pricingName - name of the pricing configuration +// pricing - pricing object +func (client PricingsClient) UpdateSubscriptionPricing(ctx context.Context, pricingName string, pricing Pricing) (result Pricing, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.PricingsClient", "UpdateSubscriptionPricing", err.Error()) + } + + req, err := client.UpdateSubscriptionPricingPreparer(ctx, pricingName, pricing) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "UpdateSubscriptionPricing", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSubscriptionPricingSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.PricingsClient", "UpdateSubscriptionPricing", resp, "Failure sending request") + return + } + + result, err = client.UpdateSubscriptionPricingResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.PricingsClient", "UpdateSubscriptionPricing", resp, "Failure responding to request") + } + + return +} + +// UpdateSubscriptionPricingPreparer prepares the UpdateSubscriptionPricing request. +func (client PricingsClient) UpdateSubscriptionPricingPreparer(ctx context.Context, pricingName string, pricing Pricing) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "pricingName": autorest.Encode("path", pricingName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/pricings/{pricingName}", pathParameters), + autorest.WithJSON(pricing), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateSubscriptionPricingSender sends the UpdateSubscriptionPricing request. The method will close the +// http.Response Body if it receives an error. +func (client PricingsClient) UpdateSubscriptionPricingSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// UpdateSubscriptionPricingResponder handles the response to the UpdateSubscriptionPricing request. The method always +// closes the http.Response Body. +func (client PricingsClient) UpdateSubscriptionPricingResponder(resp *http.Response) (result Pricing, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/settings.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/settings.go new file mode 100644 index 000000000000..6991ea8df8a2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/settings.go @@ -0,0 +1,282 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// SettingsClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type SettingsClient struct { + BaseClient +} + +// NewSettingsClient creates an instance of the SettingsClient client. +func NewSettingsClient(subscriptionID string, ascLocation string) SettingsClient { + return NewSettingsClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewSettingsClientWithBaseURI creates an instance of the SettingsClient client. +func NewSettingsClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) SettingsClient { + return SettingsClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// Get settings of different configurations in security center +// Parameters: +// settingName - name of setting +func (client SettingsClient) Get(ctx context.Context, settingName string) (result SettingModel, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.SettingsClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx, settingName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.SettingsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.SettingsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.SettingsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client SettingsClient) GetPreparer(ctx context.Context, settingName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "settingName": autorest.Encode("path", settingName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/settings/{settingName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client SettingsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client SettingsClient) GetResponder(resp *http.Response) (result SettingModel, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List settings about different configurations in security center +func (client SettingsClient) List(ctx context.Context) (result SettingsListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.SettingsClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.SettingsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.sl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.SettingsClient", "List", resp, "Failure sending request") + return + } + + result.sl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.SettingsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client SettingsClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/settings", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client SettingsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client SettingsClient) ListResponder(resp *http.Response) (result SettingsList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client SettingsClient) listNextResults(lastResults SettingsList) (result SettingsList, err error) { + req, err := lastResults.settingsListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.SettingsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.SettingsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.SettingsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client SettingsClient) ListComplete(ctx context.Context) (result SettingsListIterator, err error) { + result.page, err = client.List(ctx) + return +} + +// Update updating settings about different configurations in security center +// Parameters: +// settingName - name of setting +// setting - setting object +func (client SettingsClient) Update(ctx context.Context, settingName string, setting BasicSetting) (result SettingModel, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.SettingsClient", "Update", err.Error()) + } + + req, err := client.UpdatePreparer(ctx, settingName, setting) + if err != nil { + err = autorest.NewErrorWithError(err, "security.SettingsClient", "Update", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.SettingsClient", "Update", resp, "Failure sending request") + return + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.SettingsClient", "Update", resp, "Failure responding to request") + } + + return +} + +// UpdatePreparer prepares the Update request. +func (client SettingsClient) UpdatePreparer(ctx context.Context, settingName string, setting BasicSetting) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "settingName": autorest.Encode("path", settingName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/settings/{settingName}", pathParameters), + autorest.WithJSON(setting), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client SettingsClient) UpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client SettingsClient) UpdateResponder(resp *http.Response) (result SettingModel, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/tasks.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/tasks.go new file mode 100644 index 000000000000..b4c89c0f399d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/tasks.go @@ -0,0 +1,659 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// TasksClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type TasksClient struct { + BaseClient +} + +// NewTasksClient creates an instance of the TasksClient client. +func NewTasksClient(subscriptionID string, ascLocation string) TasksClient { + return NewTasksClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewTasksClientWithBaseURI creates an instance of the TasksClient client. +func NewTasksClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) TasksClient { + return TasksClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// GetResourceGroupLevelTask recommended tasks that will help improve the security of the subscription proactively +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// taskName - name of the task object, will be a GUID +func (client TasksClient) GetResourceGroupLevelTask(ctx context.Context, resourceGroupName string, taskName string) (result Task, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.TasksClient", "GetResourceGroupLevelTask", err.Error()) + } + + req, err := client.GetResourceGroupLevelTaskPreparer(ctx, resourceGroupName, taskName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "GetResourceGroupLevelTask", nil, "Failure preparing request") + return + } + + resp, err := client.GetResourceGroupLevelTaskSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.TasksClient", "GetResourceGroupLevelTask", resp, "Failure sending request") + return + } + + result, err = client.GetResourceGroupLevelTaskResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "GetResourceGroupLevelTask", resp, "Failure responding to request") + } + + return +} + +// GetResourceGroupLevelTaskPreparer prepares the GetResourceGroupLevelTask request. +func (client TasksClient) GetResourceGroupLevelTaskPreparer(ctx context.Context, resourceGroupName string, taskName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "taskName": autorest.Encode("path", taskName), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/tasks/{taskName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetResourceGroupLevelTaskSender sends the GetResourceGroupLevelTask request. The method will close the +// http.Response Body if it receives an error. +func (client TasksClient) GetResourceGroupLevelTaskSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResourceGroupLevelTaskResponder handles the response to the GetResourceGroupLevelTask request. The method always +// closes the http.Response Body. +func (client TasksClient) GetResourceGroupLevelTaskResponder(resp *http.Response) (result Task, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSubscriptionLevelTask recommended tasks that will help improve the security of the subscription proactively +// Parameters: +// taskName - name of the task object, will be a GUID +func (client TasksClient) GetSubscriptionLevelTask(ctx context.Context, taskName string) (result Task, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.TasksClient", "GetSubscriptionLevelTask", err.Error()) + } + + req, err := client.GetSubscriptionLevelTaskPreparer(ctx, taskName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "GetSubscriptionLevelTask", nil, "Failure preparing request") + return + } + + resp, err := client.GetSubscriptionLevelTaskSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.TasksClient", "GetSubscriptionLevelTask", resp, "Failure sending request") + return + } + + result, err = client.GetSubscriptionLevelTaskResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "GetSubscriptionLevelTask", resp, "Failure responding to request") + } + + return +} + +// GetSubscriptionLevelTaskPreparer prepares the GetSubscriptionLevelTask request. +func (client TasksClient) GetSubscriptionLevelTaskPreparer(ctx context.Context, taskName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "taskName": autorest.Encode("path", taskName), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations/{ascLocation}/tasks/{taskName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSubscriptionLevelTaskSender sends the GetSubscriptionLevelTask request. The method will close the +// http.Response Body if it receives an error. +func (client TasksClient) GetSubscriptionLevelTaskSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetSubscriptionLevelTaskResponder handles the response to the GetSubscriptionLevelTask request. The method always +// closes the http.Response Body. +func (client TasksClient) GetSubscriptionLevelTaskResponder(resp *http.Response) (result Task, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List recommended tasks that will help improve the security of the subscription proactively +// Parameters: +// filter - oData filter. Optional. +func (client TasksClient) List(ctx context.Context, filter string) (result TaskListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.TasksClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx, filter) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.tl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.TasksClient", "List", resp, "Failure sending request") + return + } + + result.tl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client TasksClient) ListPreparer(ctx context.Context, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/tasks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client TasksClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client TasksClient) ListResponder(resp *http.Response) (result TaskList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client TasksClient) listNextResults(lastResults TaskList) (result TaskList, err error) { + req, err := lastResults.taskListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.TasksClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.TasksClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client TasksClient) ListComplete(ctx context.Context, filter string) (result TaskListIterator, err error) { + result.page, err = client.List(ctx, filter) + return +} + +// ListByHomeRegion recommended tasks that will help improve the security of the subscription proactively +// Parameters: +// filter - oData filter. Optional. +func (client TasksClient) ListByHomeRegion(ctx context.Context, filter string) (result TaskListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.TasksClient", "ListByHomeRegion", err.Error()) + } + + result.fn = client.listByHomeRegionNextResults + req, err := client.ListByHomeRegionPreparer(ctx, filter) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "ListByHomeRegion", nil, "Failure preparing request") + return + } + + resp, err := client.ListByHomeRegionSender(req) + if err != nil { + result.tl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.TasksClient", "ListByHomeRegion", resp, "Failure sending request") + return + } + + result.tl, err = client.ListByHomeRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "ListByHomeRegion", resp, "Failure responding to request") + } + + return +} + +// ListByHomeRegionPreparer prepares the ListByHomeRegion request. +func (client TasksClient) ListByHomeRegionPreparer(ctx context.Context, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations/{ascLocation}/tasks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByHomeRegionSender sends the ListByHomeRegion request. The method will close the +// http.Response Body if it receives an error. +func (client TasksClient) ListByHomeRegionSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByHomeRegionResponder handles the response to the ListByHomeRegion request. The method always +// closes the http.Response Body. +func (client TasksClient) ListByHomeRegionResponder(resp *http.Response) (result TaskList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByHomeRegionNextResults retrieves the next set of results, if any. +func (client TasksClient) listByHomeRegionNextResults(lastResults TaskList) (result TaskList, err error) { + req, err := lastResults.taskListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.TasksClient", "listByHomeRegionNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByHomeRegionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.TasksClient", "listByHomeRegionNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByHomeRegionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "listByHomeRegionNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByHomeRegionComplete enumerates all values, automatically crossing page boundaries as required. +func (client TasksClient) ListByHomeRegionComplete(ctx context.Context, filter string) (result TaskListIterator, err error) { + result.page, err = client.ListByHomeRegion(ctx, filter) + return +} + +// ListByResourceGroup recommended tasks that will help improve the security of the subscription proactively +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// filter - oData filter. Optional. +func (client TasksClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, filter string) (result TaskListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.TasksClient", "ListByResourceGroup", err.Error()) + } + + result.fn = client.listByResourceGroupNextResults + req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName, filter) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.tl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.TasksClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result.tl, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client TasksClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = autorest.Encode("query", filter) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/tasks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client TasksClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client TasksClient) ListByResourceGroupResponder(resp *http.Response) (result TaskList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByResourceGroupNextResults retrieves the next set of results, if any. +func (client TasksClient) listByResourceGroupNextResults(lastResults TaskList) (result TaskList, err error) { + req, err := lastResults.taskListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.TasksClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.TasksClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. +func (client TasksClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, filter string) (result TaskListIterator, err error) { + result.page, err = client.ListByResourceGroup(ctx, resourceGroupName, filter) + return +} + +// UpdateResourceGroupLevelTaskState recommended tasks that will help improve the security of the subscription +// proactively +// Parameters: +// resourceGroupName - the name of the resource group within the user's subscription. The name is case +// insensitive. +// taskName - name of the task object, will be a GUID +// taskUpdateActionType - type of the action to do on the task +func (client TasksClient) UpdateResourceGroupLevelTaskState(ctx context.Context, resourceGroupName string, taskName string, taskUpdateActionType string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.TasksClient", "UpdateResourceGroupLevelTaskState", err.Error()) + } + + req, err := client.UpdateResourceGroupLevelTaskStatePreparer(ctx, resourceGroupName, taskName, taskUpdateActionType) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "UpdateResourceGroupLevelTaskState", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateResourceGroupLevelTaskStateSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "security.TasksClient", "UpdateResourceGroupLevelTaskState", resp, "Failure sending request") + return + } + + result, err = client.UpdateResourceGroupLevelTaskStateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "UpdateResourceGroupLevelTaskState", resp, "Failure responding to request") + } + + return +} + +// UpdateResourceGroupLevelTaskStatePreparer prepares the UpdateResourceGroupLevelTaskState request. +func (client TasksClient) UpdateResourceGroupLevelTaskStatePreparer(ctx context.Context, resourceGroupName string, taskName string, taskUpdateActionType string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "taskName": autorest.Encode("path", taskName), + "taskUpdateActionType": autorest.Encode("path", taskUpdateActionType), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Security/locations/{ascLocation}/tasks/{taskName}/{taskUpdateActionType}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateResourceGroupLevelTaskStateSender sends the UpdateResourceGroupLevelTaskState request. The method will close the +// http.Response Body if it receives an error. +func (client TasksClient) UpdateResourceGroupLevelTaskStateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// UpdateResourceGroupLevelTaskStateResponder handles the response to the UpdateResourceGroupLevelTaskState request. The method always +// closes the http.Response Body. +func (client TasksClient) UpdateResourceGroupLevelTaskStateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// UpdateSubscriptionLevelTaskState recommended tasks that will help improve the security of the subscription +// proactively +// Parameters: +// taskName - name of the task object, will be a GUID +// taskUpdateActionType - type of the action to do on the task +func (client TasksClient) UpdateSubscriptionLevelTaskState(ctx context.Context, taskName string, taskUpdateActionType string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.TasksClient", "UpdateSubscriptionLevelTaskState", err.Error()) + } + + req, err := client.UpdateSubscriptionLevelTaskStatePreparer(ctx, taskName, taskUpdateActionType) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "UpdateSubscriptionLevelTaskState", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSubscriptionLevelTaskStateSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "security.TasksClient", "UpdateSubscriptionLevelTaskState", resp, "Failure sending request") + return + } + + result, err = client.UpdateSubscriptionLevelTaskStateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.TasksClient", "UpdateSubscriptionLevelTaskState", resp, "Failure responding to request") + } + + return +} + +// UpdateSubscriptionLevelTaskStatePreparer prepares the UpdateSubscriptionLevelTaskState request. +func (client TasksClient) UpdateSubscriptionLevelTaskStatePreparer(ctx context.Context, taskName string, taskUpdateActionType string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "ascLocation": autorest.Encode("path", client.AscLocation), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "taskName": autorest.Encode("path", taskName), + "taskUpdateActionType": autorest.Encode("path", taskUpdateActionType), + } + + const APIVersion = "2015-06-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/locations/{ascLocation}/tasks/{taskName}/{taskUpdateActionType}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateSubscriptionLevelTaskStateSender sends the UpdateSubscriptionLevelTaskState request. The method will close the +// http.Response Body if it receives an error. +func (client TasksClient) UpdateSubscriptionLevelTaskStateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// UpdateSubscriptionLevelTaskStateResponder handles the response to the UpdateSubscriptionLevelTaskState request. The method always +// closes the http.Response Body. +func (client TasksClient) UpdateSubscriptionLevelTaskStateResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/version.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/version.go new file mode 100644 index 000000000000..3a47e09d03fe --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/version.go @@ -0,0 +1,30 @@ +package security + +import "github.com/Azure/azure-sdk-for-go/version" + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return "Azure-SDK-For-Go/" + version.Number + " security/2017-08-01-preview" +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return version.Number +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/workspacesettings.go b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/workspacesettings.go new file mode 100644 index 000000000000..59eb1d2610a2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security/workspacesettings.go @@ -0,0 +1,431 @@ +package security + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// WorkspaceSettingsClient is the API spec for Microsoft.Security (Azure Security Center) resource provider +type WorkspaceSettingsClient struct { + BaseClient +} + +// NewWorkspaceSettingsClient creates an instance of the WorkspaceSettingsClient client. +func NewWorkspaceSettingsClient(subscriptionID string, ascLocation string) WorkspaceSettingsClient { + return NewWorkspaceSettingsClientWithBaseURI(DefaultBaseURI, subscriptionID, ascLocation) +} + +// NewWorkspaceSettingsClientWithBaseURI creates an instance of the WorkspaceSettingsClient client. +func NewWorkspaceSettingsClientWithBaseURI(baseURI string, subscriptionID string, ascLocation string) WorkspaceSettingsClient { + return WorkspaceSettingsClient{NewWithBaseURI(baseURI, subscriptionID, ascLocation)} +} + +// Create creating settings about where we should store your security data and logs +// Parameters: +// workspaceSettingName - name of the security setting +// workspaceSetting - security data setting object +func (client WorkspaceSettingsClient) Create(ctx context.Context, workspaceSettingName string, workspaceSetting WorkspaceSetting) (result WorkspaceSetting, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}, + {TargetValue: workspaceSetting, + Constraints: []validation.Constraint{{Target: "workspaceSetting.WorkspaceSettingProperties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "workspaceSetting.WorkspaceSettingProperties.WorkspaceID", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "workspaceSetting.WorkspaceSettingProperties.Scope", Name: validation.Null, Rule: true, Chain: nil}, + }}}}}); err != nil { + return result, validation.NewError("security.WorkspaceSettingsClient", "Create", err.Error()) + } + + req, err := client.CreatePreparer(ctx, workspaceSettingName, workspaceSetting) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Create", nil, "Failure preparing request") + return + } + + resp, err := client.CreateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Create", resp, "Failure sending request") + return + } + + result, err = client.CreateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Create", resp, "Failure responding to request") + } + + return +} + +// CreatePreparer prepares the Create request. +func (client WorkspaceSettingsClient) CreatePreparer(ctx context.Context, workspaceSettingName string, workspaceSetting WorkspaceSetting) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "workspaceSettingName": autorest.Encode("path", workspaceSettingName), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/workspaceSettings/{workspaceSettingName}", pathParameters), + autorest.WithJSON(workspaceSetting), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateSender sends the Create request. The method will close the +// http.Response Body if it receives an error. +func (client WorkspaceSettingsClient) CreateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// CreateResponder handles the response to the Create request. The method always +// closes the http.Response Body. +func (client WorkspaceSettingsClient) CreateResponder(resp *http.Response) (result WorkspaceSetting, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes the custom workspace settings for this subscription. new VMs will report to the default workspace +// Parameters: +// workspaceSettingName - name of the security setting +func (client WorkspaceSettingsClient) Delete(ctx context.Context, workspaceSettingName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.WorkspaceSettingsClient", "Delete", err.Error()) + } + + req, err := client.DeletePreparer(ctx, workspaceSettingName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client WorkspaceSettingsClient) DeletePreparer(ctx context.Context, workspaceSettingName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "workspaceSettingName": autorest.Encode("path", workspaceSettingName), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/workspaceSettings/{workspaceSettingName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client WorkspaceSettingsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client WorkspaceSettingsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get settings about where we should store your security data and logs +// Parameters: +// workspaceSettingName - name of the security setting +func (client WorkspaceSettingsClient) Get(ctx context.Context, workspaceSettingName string) (result WorkspaceSetting, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.WorkspaceSettingsClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx, workspaceSettingName) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client WorkspaceSettingsClient) GetPreparer(ctx context.Context, workspaceSettingName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "workspaceSettingName": autorest.Encode("path", workspaceSettingName), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/workspaceSettings/{workspaceSettingName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client WorkspaceSettingsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client WorkspaceSettingsClient) GetResponder(resp *http.Response) (result WorkspaceSetting, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List settings about where we should store your security data and logs +func (client WorkspaceSettingsClient) List(ctx context.Context) (result WorkspaceSettingListPage, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.WorkspaceSettingsClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.wsl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "List", resp, "Failure sending request") + return + } + + result.wsl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client WorkspaceSettingsClient) ListPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/workspaceSettings", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client WorkspaceSettingsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client WorkspaceSettingsClient) ListResponder(resp *http.Response) (result WorkspaceSettingList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client WorkspaceSettingsClient) listNextResults(lastResults WorkspaceSettingList) (result WorkspaceSettingList, err error) { + req, err := lastResults.workspaceSettingListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client WorkspaceSettingsClient) ListComplete(ctx context.Context) (result WorkspaceSettingListIterator, err error) { + result.page, err = client.List(ctx) + return +} + +// Update settings about where we should store your security data and logs +// Parameters: +// workspaceSettingName - name of the security setting +// workspaceSetting - security data setting object +func (client WorkspaceSettingsClient) Update(ctx context.Context, workspaceSettingName string, workspaceSetting WorkspaceSetting) (result WorkspaceSetting, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.Pattern, Rule: `^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$`, Chain: nil}}}}); err != nil { + return result, validation.NewError("security.WorkspaceSettingsClient", "Update", err.Error()) + } + + req, err := client.UpdatePreparer(ctx, workspaceSettingName, workspaceSetting) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Update", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Update", resp, "Failure sending request") + return + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "security.WorkspaceSettingsClient", "Update", resp, "Failure responding to request") + } + + return +} + +// UpdatePreparer prepares the Update request. +func (client WorkspaceSettingsClient) UpdatePreparer(ctx context.Context, workspaceSettingName string, workspaceSetting WorkspaceSetting) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "workspaceSettingName": autorest.Encode("path", workspaceSettingName), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Security/workspaceSettings/{workspaceSettingName}", pathParameters), + autorest.WithJSON(workspaceSetting), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client WorkspaceSettingsClient) UpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client WorkspaceSettingsClient) UpdateResponder(resp *http.Response) (result WorkspaceSetting, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/vendor.json b/vendor/vendor.json index c0115a215875..089eece57aa9 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -266,6 +266,14 @@ "version": "v21.1.0", "versionExact": "v21.1.0" }, + { + "checksumSHA1": "JYviM5jpO03O52eg09sGqYk+f7I=", + "path": "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security", + "revision": "6d20bdbae88c06c36d72eb512295417693bfdf4e", + "revisionTime": "2018-09-27T22:44:43Z", + "version": "=v21.1.0", + "versionExact": "v21.1.0" + }, { "checksumSHA1": "/lxvjQjQNmBuS4tOwMdG3n4nWd0=", "path": "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql", From 05d7c54a97e151f7b9dbf42bb33d129f9f987075 Mon Sep 17 00:00:00 2001 From: kt Date: Tue, 9 Oct 2018 15:45:44 -0700 Subject: [PATCH 02/35] Added docs --- ...arm_securitycenter_subscription_pricing.go | 4 +- ...ecuritycenter_subscription_pricing_test.go | 9 ++-- website/azurerm.erb | 9 ++++ ...curitycenter_subscription_pricing.markdown | 42 +++++++++++++++++++ 4 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 website/docs/r/securitycenter_subscription_pricing.markdown diff --git a/azurerm/resource_arm_securitycenter_subscription_pricing.go b/azurerm/resource_arm_securitycenter_subscription_pricing.go index d0a92f08e84d..6899f3787dd6 100644 --- a/azurerm/resource_arm_securitycenter_subscription_pricing.go +++ b/azurerm/resource_arm_securitycenter_subscription_pricing.go @@ -51,7 +51,7 @@ func resourceArmSecurityCenterSubscriptionPricingCreateUpdate(d *schema.Resource _, err := client.UpdateSubscriptionPricing(ctx, "default", pricing) if err != nil { - return fmt.Errorf("Error updating Security Center Subscription pricing: %+v", err) + return fmt.Errorf("Error creating/updating Security Center Subscription pricing: %+v", err) } resp, err := client.GetSubscriptionPricing(ctx, "default") @@ -90,5 +90,5 @@ func resourceArmSecurityCenterSubscriptionPricingRead(d *schema.ResourceData, me } func resourceArmSecurityCenterSubscriptionPricingDelete(_ *schema.ResourceData, _ interface{}) error { - return nil + return nil //cannot be deleted } diff --git a/azurerm/resource_arm_securitycenter_subscription_pricing_test.go b/azurerm/resource_arm_securitycenter_subscription_pricing_test.go index d06ae83b5ae2..afd391519869 100644 --- a/azurerm/resource_arm_securitycenter_subscription_pricing_test.go +++ b/azurerm/resource_arm_securitycenter_subscription_pricing_test.go @@ -29,10 +29,10 @@ func TestAccAzureRMSecurityCenterSubscriptionPricing_update(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccAzureRMSecurityCenterSubscriptionPricing_tier("Standard"), + Config: testAccAzureRMSecurityCenterSubscriptionPricing_tier("Free"), Check: resource.ComposeTestCheckFunc( testCheckAzureRMSecurityCenterSubscriptionPricingExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "tier", "Standard"), + resource.TestCheckResourceAttr(resourceName, "tier", "Free"), ), }, { @@ -46,6 +46,8 @@ func TestAccAzureRMSecurityCenterSubscriptionPricing_update(t *testing.T) { func testCheckAzureRMSecurityCenterSubscriptionPricingExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).securityCenterPricingClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext rs, ok := s.RootModule().Resources[name] if !ok { @@ -54,9 +56,6 @@ func testCheckAzureRMSecurityCenterSubscriptionPricingExists(name string) resour pricingName := rs.Primary.Attributes["pricings"] - client := testAccProvider.Meta().(*ArmClient).securityCenterPricingClient - ctx := testAccProvider.Meta().(*ArmClient).StopContext - resp, err := client.GetSubscriptionPricing(ctx, pricingName) if err != nil { if utils.ResponseWasNotFound(resp.Response) { diff --git a/website/azurerm.erb b/website/azurerm.erb index 01bcc347ec48..1617539b25a7 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -973,6 +973,15 @@ + > + Security Center Resources + + + > Scheduler Resources + > diff --git a/website/docs/r/securitycenter_contact.markdown b/website/docs/r/securitycenter_contact.markdown new file mode 100644 index 000000000000..d1cc93abb596 --- /dev/null +++ b/website/docs/r/securitycenter_contact.markdown @@ -0,0 +1,46 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_securitycenter_contact" +sidebar_current: "docs-azurerm-securitycenter-contact" +description: |- + Manages the subscription's Security Center Contact. +--- + +# azurerm_securitycenter_contact + +Manages the subscription's Security Center Contact. + +## Example Usage + +```hcl +resource "azurerm_securitycenter_contact" "example" { + email = "contact@example.com" + phone = "+1-555-555-5555" + + alert_notifications = true + alerts_to_admins = true +} +``` + +## Argument Reference + +The following arguments are supported: + +* `email` - (Required) The email of the Security Center Contact. +* `phone` - (Required) The phone number of the Security Center Contact. +* `alert_notifications` - (Required) Whether to send security alerts notifications to the security contact. +* `alerts_to_admins` - (Required) Whether to send security alerts notifications to subscription admins. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Security Center Contact ID. + +## Import + +The contact can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_securitycenter_contact.example /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Security/securityContacts/default1 +``` From 64dfcadf18e7dd72b34e54cd5ba1dd83bf834612 Mon Sep 17 00:00:00 2001 From: kt Date: Tue, 9 Oct 2018 15:54:05 -0700 Subject: [PATCH 05/35] fix small typo in docs --- website/docs/r/securitycenter_subscription_pricing.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/securitycenter_subscription_pricing.markdown b/website/docs/r/securitycenter_subscription_pricing.markdown index 1aa464bc8108..f55627c03eb6 100644 --- a/website/docs/r/securitycenter_subscription_pricing.markdown +++ b/website/docs/r/securitycenter_subscription_pricing.markdown @@ -22,7 +22,7 @@ resource "azurerm_securitycenter_subscription_pricing" "example" { The following arguments are supported: -* `tier` - (Required) The pricing tier to use. Must be one of `Free` or `Standard` +* `tier` - (Required) The pricing tier to use. Must be one of `Free` or `Standard`. ~> **NOTE:** Changing the pricing tier to `Standard` affects all resources in the subscription and could be quite costly. @@ -35,7 +35,7 @@ The following attributes are exported: ## Import -Resource Groups can be imported using the `resource id`, e.g. +The pricing tier can be imported using the `resource id`, e.g. ```shell terraform import azurerm_securitycenter_subscription_pricing.example /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Security/pricings/default From 3be186012fc4eaad0bec8e9ed7194aea2d26cbdc Mon Sep 17 00:00:00 2001 From: kt Date: Wed, 10 Oct 2018 18:13:16 -0700 Subject: [PATCH 06/35] new resource secduriyt workspace --- azurerm/config.go | 9 +- azurerm/provider.go | 1 + .../resource_arm_securitycenter_contact.go | 17 +- ...esource_arm_securitycenter_contact_test.go | 34 +++- ...arm_securitycenter_subscription_pricing.go | 3 +- .../resource_arm_securitycenter_workspace.go | 168 ++++++++++++++++++ ...ource_arm_securitycenter_workspace_test.go | 163 +++++++++++++++++ 7 files changed, 374 insertions(+), 21 deletions(-) create mode 100644 azurerm/resource_arm_securitycenter_workspace.go create mode 100644 azurerm/resource_arm_securitycenter_workspace_test.go diff --git a/azurerm/config.go b/azurerm/config.go index 1f905f5ec002..a0e4e355838e 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -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 @@ -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) { diff --git a/azurerm/provider.go b/azurerm/provider.go index eb52799831b4..4a76e7e07691 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -245,6 +245,7 @@ func Provider() terraform.ResourceProvider { "azurerm_search_service": resourceArmSearchService(), "azurerm_securitycenter_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(), "azurerm_securitycenter_contact": resourceArmSecurityCenterContact(), + "azurerm_securitycenter_workspace": resourceArmSecurityCenterWorkspace(), "azurerm_servicebus_namespace": resourceArmServiceBusNamespace(), "azurerm_servicebus_namespace_authorization_rule": resourceArmServiceBusNamespaceAuthorizationRule(), "azurerm_servicebus_queue": resourceArmServiceBusQueue(), diff --git a/azurerm/resource_arm_securitycenter_contact.go b/azurerm/resource_arm_securitycenter_contact.go index 092f7cd13ca7..0a4492a75928 100644 --- a/azurerm/resource_arm_securitycenter_contact.go +++ b/azurerm/resource_arm_securitycenter_contact.go @@ -2,11 +2,9 @@ package azurerm import ( "fmt" - "log" - "strings" - "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "log" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" @@ -81,8 +79,7 @@ func resourceArmSecurityCenterContactCreateUpdate(d *schema.ResourceData, meta i } if d.IsNewResource() { - _, err := client.Create(ctx, "default1", contact) - if err != nil { + if _, err := client.Create(ctx, "default1", contact); err != nil { return fmt.Errorf("Error creating Security Center Contact: %+v", err) } @@ -96,8 +93,7 @@ func resourceArmSecurityCenterContactCreateUpdate(d *schema.ResourceData, meta i d.SetId(*resp.ID) } else { - _, err := client.Update(ctx, "default1", contact) - if err != nil { + if _, err := client.Update(ctx, "default1", contact); err != nil { return fmt.Errorf("Error updating Security Center Contact: %+v", err) } } @@ -109,12 +105,7 @@ func resourceArmSecurityCenterContactRead(d *schema.ResourceData, meta interface client := meta.(*ArmClient).securityCenterContactsClient ctx := meta.(*ArmClient).StopContext - //id is in format of `/subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23/providers/Microsoft.Security/securityContacts/john` - //parseAzureResourceID doesn't support id without a resource group - bits := strings.Split(d.Id(), "/") - name := bits[len(bits)-1] - - resp, err := client.Get(ctx, name) + resp, err := client.Get(ctx, "default1") if err != nil { if utils.ResponseWasNotFound(resp.Response) { log.Printf("[DEBUG] Security Center Subscription Contact was not found: %v", err) diff --git a/azurerm/resource_arm_securitycenter_contact_test.go b/azurerm/resource_arm_securitycenter_contact_test.go index cfba6f9eb705..1188dcdd0f65 100644 --- a/azurerm/resource_arm_securitycenter_contact_test.go +++ b/azurerm/resource_arm_securitycenter_contact_test.go @@ -13,8 +13,9 @@ func TestAccAzureRMSecurityCenterContact_basic(t *testing.T) { resourceName := "azurerm_securitycenter_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("email1@example.com", "+1-555-555-5555", true, true), @@ -39,8 +40,9 @@ func TestAccAzureRMSecurityCenterContact_update(t *testing.T) { resourceName := "azurerm_securitycenter_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("email1@example.com", "+1-555-555-5555", true, true), @@ -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_securitycenter_contact" "test" { diff --git a/azurerm/resource_arm_securitycenter_subscription_pricing.go b/azurerm/resource_arm_securitycenter_subscription_pricing.go index 6899f3787dd6..d200a4ab762a 100644 --- a/azurerm/resource_arm_securitycenter_subscription_pricing.go +++ b/azurerm/resource_arm_securitycenter_subscription_pricing.go @@ -49,8 +49,7 @@ func resourceArmSecurityCenterSubscriptionPricingCreateUpdate(d *schema.Resource }, } - _, err := client.UpdateSubscriptionPricing(ctx, "default", pricing) - if err != nil { + if _, err := client.UpdateSubscriptionPricing(ctx, "default", pricing); err != nil { return fmt.Errorf("Error creating/updating Security Center Subscription pricing: %+v", err) } diff --git a/azurerm/resource_arm_securitycenter_workspace.go b/azurerm/resource_arm_securitycenter_workspace.go new file mode 100644 index 000000000000..bb849d7ba725 --- /dev/null +++ b/azurerm/resource_arm_securitycenter_workspace.go @@ -0,0 +1,168 @@ +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/helpers/suppress" + "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 " +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, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.NoZeroValues, + }, + + "workspace_id": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: azure.ValidateResourceID, + }, + }, + } +} + +func resourceArmSecurityCenterWorkspaceCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).securityCenterWorkspaceClient + ctx := meta.(*ArmClient).StopContext + + 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, "default", contact) + if err != nil { + return fmt.Errorf("Error creating 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, "default") + 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) + } + + d.SetId(*resp.(security.WorkspaceSetting).ID) + + } else { + _, err := client.Update(ctx, "default", 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, "default") + 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 + }, + } + + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting: %+v", err) + } + } + + 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, "default") + 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, "default") + 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 +} diff --git a/azurerm/resource_arm_securitycenter_workspace_test.go b/azurerm/resource_arm_securitycenter_workspace_test.go new file mode 100644 index 000000000000..acb5d108f71c --- /dev/null +++ b/azurerm/resource_arm_securitycenter_workspace_test.go @@ -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_securitycenter_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_securitycenter_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_securitycenter_workspace" { + continue + } + + resp, err := client.Get(ctx, "default") + 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_securitycenter_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_securitycenter_workspace" "test" { + scope = "%[3]s" + workspace_id = "${azurerm_log_analytics_workspace.test2.id}" +} +`, rInt, location, scope) +} From 73c3e1e38f63672bb365d9d69669177062207653 Mon Sep 17 00:00:00 2001 From: Chang Li Date: Thu, 11 Oct 2018 21:54:58 +0800 Subject: [PATCH 07/35] Fix variable name in simple code --- website/docs/r/postgresql_virtual_network_rule.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/postgresql_virtual_network_rule.html.markdown b/website/docs/r/postgresql_virtual_network_rule.html.markdown index 026e4f7af8d2..cae70a8363af 100644 --- a/website/docs/r/postgresql_virtual_network_rule.html.markdown +++ b/website/docs/r/postgresql_virtual_network_rule.html.markdown @@ -29,8 +29,8 @@ resource "azurerm_virtual_network" "test" { resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.example.name}" - virtual_network_name = "${azurerm_virtual_network.vnet.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" address_prefix = "10.7.29.0/29" service_endpoints = ["Microsoft.Sql"] } From cdfcd89d4c29b00bf7364ce57703e8d63af91298 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Thu, 11 Oct 2018 11:25:37 -1000 Subject: [PATCH 08/35] r/dev_test_virtual_network: support for controlling the subnet (#2041) * r/dev_test_virtual_network: support for controlling the subnet * Removing the unnecessary expansion * r/dev_test_virtuql_network: defaulting to `allow` if not specified --- .../resource_arm_dev_test_virtual_network.go | 104 +++++++++++++++++- ...ource_arm_dev_test_virtual_network_test.go | 55 +++++++++ .../r/dev_test_virtual_network.html.markdown | 18 +++ 3 files changed, 176 insertions(+), 1 deletion(-) diff --git a/azurerm/resource_arm_dev_test_virtual_network.go b/azurerm/resource_arm_dev_test_virtual_network.go index f9d5924ade2c..fc685a07113e 100644 --- a/azurerm/resource_arm_dev_test_virtual_network.go +++ b/azurerm/resource_arm_dev_test_virtual_network.go @@ -46,6 +46,36 @@ func resourceArmDevTestVirtualNetwork() *schema.Resource { Optional: true, }, + "subnet": { + Type: schema.TypeList, + Optional: true, + Computed: true, + // whilst the API accepts multiple, in practice only one is usable + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + + "use_in_virtual_machine_creation": { + Type: schema.TypeString, + Optional: true, + Default: string(dtl.Allow), + ValidateFunc: validateDevTestVirtualNetworkUsagePermissionType(), + }, + + "use_public_ip_address": { + Type: schema.TypeString, + Optional: true, + Default: string(dtl.Allow), + ValidateFunc: validateDevTestVirtualNetworkUsagePermissionType(), + }, + }, + }, + }, + "tags": tagsSchema(), "unique_identifier": { @@ -68,10 +98,15 @@ func resourceArmDevTestVirtualNetworkCreateUpdate(d *schema.ResourceData, meta i description := d.Get("description").(string) tags := d.Get("tags").(map[string]interface{}) + subscriptionId := meta.(*ArmClient).subscriptionId + subnetsRaw := d.Get("subnet").([]interface{}) + subnets := expandDevTestVirtualNetworkSubnets(d, subnetsRaw, subscriptionId, resourceGroup, labName, name) + parameters := dtl.VirtualNetwork{ Tags: expandTags(tags), VirtualNetworkProperties: &dtl.VirtualNetworkProperties{ - Description: utils.String(description), + Description: utils.String(description), + SubnetOverrides: subnets, }, } @@ -129,6 +164,11 @@ func resourceArmDevTestVirtualNetworkRead(d *schema.ResourceData, meta interface if props := read.VirtualNetworkProperties; props != nil { d.Set("description", props.Description) + flattenedSubnets := flattenDevTestVirtualNetworkSubnets(props.SubnetOverrides) + if err := d.Set("subnet", flattenedSubnets); err != nil { + return fmt.Errorf("Error setting `subnet`: %+v", err) + } + // Computed fields d.Set("unique_identifier", props.UniqueIdentifier) } @@ -179,3 +219,65 @@ func validateDevTestVirtualNetworkName() schema.SchemaValidateFunc { regexp.MustCompile("^[A-Za-z0-9_-]+$"), "Virtual Network Name can only include alphanumeric characters, underscores, hyphens.") } + +func expandDevTestVirtualNetworkSubnets(d *schema.ResourceData, input []interface{}, subscriptionId, resourceGroupName, labName, virtualNetworkName string) *[]dtl.SubnetOverride { + results := make([]dtl.SubnetOverride, 0) + // default found from the Portal + name := fmt.Sprintf("%sSubnet", virtualNetworkName) + idFmt := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.DevTestLab/labs/%s/virtualnetworks/%s/subnets/%s" + subnetId := fmt.Sprintf(idFmt, subscriptionId, resourceGroupName, labName, virtualNetworkName, name) + if len(input) == 0 { + result := dtl.SubnetOverride{ + ResourceID: utils.String(subnetId), + LabSubnetName: utils.String(name), + UsePublicIPAddressPermission: dtl.Allow, + UseInVMCreationPermission: dtl.Allow, + } + results = append(results, result) + return &results + } + + for _, val := range input { + v := val.(map[string]interface{}) + usePublicIPAddress := v["use_public_ip_address"].(string) + useInVirtualMachineCreation := v["use_in_virtual_machine_creation"].(string) + + subnet := dtl.SubnetOverride{ + ResourceID: utils.String(subnetId), + LabSubnetName: utils.String(name), + UsePublicIPAddressPermission: dtl.UsagePermissionType(usePublicIPAddress), + UseInVMCreationPermission: dtl.UsagePermissionType(useInVirtualMachineCreation), + } + results = append(results, subnet) + } + + return &results +} + +func flattenDevTestVirtualNetworkSubnets(input *[]dtl.SubnetOverride) []interface{} { + outputs := make([]interface{}, 0) + if input == nil { + return outputs + } + + for _, v := range *input { + output := make(map[string]interface{}, 0) + if v.LabSubnetName != nil { + output["name"] = *v.LabSubnetName + } + output["use_public_ip_address"] = string(v.UsePublicIPAddressPermission) + output["use_in_virtual_machine_creation"] = string(v.UseInVMCreationPermission) + + outputs = append(outputs, output) + } + + return outputs +} + +func validateDevTestVirtualNetworkUsagePermissionType() schema.SchemaValidateFunc { + return validation.StringInSlice([]string{ + string(dtl.Allow), + string(dtl.Default), + string(dtl.Deny), + }, false) +} diff --git a/azurerm/resource_arm_dev_test_virtual_network_test.go b/azurerm/resource_arm_dev_test_virtual_network_test.go index f53009bdd476..0eb0dcef5a54 100644 --- a/azurerm/resource_arm_dev_test_virtual_network_test.go +++ b/azurerm/resource_arm_dev_test_virtual_network_test.go @@ -64,6 +64,35 @@ func TestAccAzureRMDevTestVirtualNetwork_basic(t *testing.T) { }) } +func TestAccAzureRMDevTestVirtualNetwork_subnet(t *testing.T) { + resourceName := "azurerm_dev_test_virtual_network.test" + rInt := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestVirtualNetworkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevTestVirtualNetwork_subnets(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestVirtualNetworkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "subnet.#", "1"), + resource.TestCheckResourceAttr(resourceName, "subnet.0.use_public_ip_address", "Allow"), + resource.TestCheckResourceAttr(resourceName, "subnet.0.use_in_virtual_machine_creation", "Allow"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMDevTestVirtualNetworkExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { // Ensure we have enough information in state to look up in API @@ -141,3 +170,29 @@ resource "azurerm_dev_test_virtual_network" "test" { } `, rInt, location, rInt, rInt) } + +func testAccAzureRMDevTestVirtualNetwork_subnets(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_dev_test_lab" "test" { + name = "acctestdtl%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_dev_test_virtual_network" "test" { + name = "acctestdtvn%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + use_public_ip_address = "Allow" + use_in_virtual_machine_creation = "Allow" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/website/docs/r/dev_test_virtual_network.html.markdown b/website/docs/r/dev_test_virtual_network.html.markdown index d12f1d5e1b01..632e6accf3b8 100644 --- a/website/docs/r/dev_test_virtual_network.html.markdown +++ b/website/docs/r/dev_test_virtual_network.html.markdown @@ -51,16 +51,34 @@ The following arguments are supported: * `description` - (Optional) A description for the Virtual Network. +* `subnet` - (Optional) A `subnet` block as defined below. + * `tags` - (Optional) A mapping of tags to assign to the resource. +--- + +A `subnet` block supports the following: + +* `use_public_ip_address` - (Required) Can Virtual Machines in this Subnet use Public IP Addresses? Possible values are `Allow`, `Default` and `Deny`. + +* `use_in_virtual_machine_creation` - (Required) Can this subnet be used for creating Virtual Machines? Possible values are `Allow`, `Default` and `Deny`. + ## Attributes Reference The following attributes are exported: * `id` - The ID of the Dev Test Virtual Network. +* `subnet` - A `subnet` block as defined below. + * `unique_identifier` - The unique immutable identifier of the Dev Test Virtual Network. +--- + +A `subnet` block exports the following: + +* `name` - The name of the Subnet for this Virtual Network. + ## Import Dev Test Virtual Networks can be imported using the `resource id`, e.g. From 710bac7932f63989ea5778adb9bd9bc541e49df2 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Thu, 11 Oct 2018 11:26:26 -1000 Subject: [PATCH 09/35] Updating to include #2041 --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index deb352d55516..fa77afa2e252 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,11 +19,11 @@ BUG FIXES: IMPROVEMENTS: -* `azurerm_application_gateway` - support for the `StandardV2` and `WAFV2` skus and tiers [GH-2015] +* `azurerm_application_gateway` - support for the `StandardV2` and `WAFV2` skus and tiers [GH-2015] +* `azurerm_dev_test_virtual_network` - support for managing the Subnet [GH-2041] * `azurerm_key_vault` - support for Virtual Network Rules [GH-2027] * `azurerm_kubernetes_cluster` - changing the `oms_agent` property no longer forces a new resource [GH-2021] - ## 1.16.0 (October 01, 2018) UPGRADE NOTES: From 080e0971d24dc7fa36a051b5769e399ac8ba93ef Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Thu, 11 Oct 2018 11:26:32 -1000 Subject: [PATCH 10/35] Updating to include #2041 From 3745f842b09d123a9c19e4d1100ff1cded93c94a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Arild=20T=C3=B8rresdal?= Date: Fri, 12 Oct 2018 15:13:30 +0200 Subject: [PATCH 11/35] Fixed regex validation of API Management Publisher Name --- azurerm/helpers/validate/api_management.go | 2 +- .../helpers/validate/api_management_test.go | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/azurerm/helpers/validate/api_management.go b/azurerm/helpers/validate/api_management.go index 97cdcb26d387..0c9466b2b298 100644 --- a/azurerm/helpers/validate/api_management.go +++ b/azurerm/helpers/validate/api_management.go @@ -18,7 +18,7 @@ func ApiManagementServiceName(v interface{}, k string) (ws []string, es []error) func ApiManagementServicePublisherName(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if matched := regexp.MustCompile(`^[\S*]{1,100}$`).Match([]byte(value)); !matched { + if matched := regexp.MustCompile(`^[\S ]{1,100}$`).Match([]byte(value)); !matched { es = append(es, fmt.Errorf("%q may only be up to 100 characters in length", k)) } diff --git a/azurerm/helpers/validate/api_management_test.go b/azurerm/helpers/validate/api_management_test.go index e3b684c97cec..3c7e3554b647 100644 --- a/azurerm/helpers/validate/api_management_test.go +++ b/azurerm/helpers/validate/api_management_test.go @@ -43,3 +43,55 @@ func TestAzureRMApiManagementServiceName_validation(t *testing.T) { } } } + +func TestAzureRMApiManagementPublisherName_validation(t *testing.T) { + cases := []struct { + Value string + ErrCount int + }{ + { + Value: "", + ErrCount: 1, + }, + { + Value: "a", + ErrCount: 0, + }, + { + Value: "abc", + ErrCount: 0, + }, + { + Value: "api1", + ErrCount: 0, + }, + { + Value: "company-api", + ErrCount: 0, + }, + { + Value: "hello_world", + ErrCount: 0, + }, + { + Value: "helloworld21!", + ErrCount: 0, + }, + { + Value: "company api", + ErrCount: 0, + }, + { + Value: "alsdkjflasjkdflajsdlfjkalsdfjkalskdjflajksdflkjasdlfkjasldkfjalksdjflakjsdfljkasdlkfjalskdjfalksdjfdd", + ErrCount: 1, + }, + } + + for _, tc := range cases { + _, errors := ApiManagementServicePublisherName(tc.Value, "azurerm_api_management") + + if len(errors) != tc.ErrCount { + t.Fatalf("Expected the Api Management Service Publisher Name to trigger a validation error for '%s'", tc.Value) + } + } +} From 438ac53e4e8d1b94c37febd1037021d1a19e5926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Arild=20T=C3=B8rresdal?= Date: Fri, 12 Oct 2018 15:19:03 +0200 Subject: [PATCH 12/35] Fixed regex validation of API Management Publisher Name to allow anything and just limit length --- azurerm/helpers/validate/api_management.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/helpers/validate/api_management.go b/azurerm/helpers/validate/api_management.go index 0c9466b2b298..1ef6b9512346 100644 --- a/azurerm/helpers/validate/api_management.go +++ b/azurerm/helpers/validate/api_management.go @@ -18,7 +18,7 @@ func ApiManagementServiceName(v interface{}, k string) (ws []string, es []error) func ApiManagementServicePublisherName(v interface{}, k string) (ws []string, es []error) { value := v.(string) - if matched := regexp.MustCompile(`^[\S ]{1,100}$`).Match([]byte(value)); !matched { + if matched := regexp.MustCompile(`^.{1,100}$`).Match([]byte(value)); !matched { es = append(es, fmt.Errorf("%q may only be up to 100 characters in length", k)) } From e39ecc1dc0cb97e5a34e9e7feb11016a51920af7 Mon Sep 17 00:00:00 2001 From: Jeffrey Cline Date: Fri, 12 Oct 2018 12:47:19 -0700 Subject: [PATCH 13/35] Exposed ignore_missing_vnet_service_endpoint attribute (#2056) * Exposed the ignore_missing_vnet_service_endpoint attribute * Updated documentation * Updated test cases * Moved optional attribute to bottom of schema definition * Add nil check and attribute validation in _IgnoreEndpointValid test case * fixed value check func * Removed nil check for VirtualNetworkRuleProperties * CnP Shenanigans * Updated language in documentation. * Removed is --- ...rm_postgresql_virtual_network_rule_test.go | 31 ------- ...rce_arm_postgresql_virtual_network_rule.go | 54 +++-------- ...rm_postgresql_virtual_network_rule_test.go | 93 ++++++++++++++++++- ...tgresql_virtual_network_rule.html.markdown | 17 ++-- 4 files changed, 113 insertions(+), 82 deletions(-) delete mode 100644 azurerm/import_arm_postgresql_virtual_network_rule_test.go diff --git a/azurerm/import_arm_postgresql_virtual_network_rule_test.go b/azurerm/import_arm_postgresql_virtual_network_rule_test.go deleted file mode 100644 index ed5232b296a6..000000000000 --- a/azurerm/import_arm_postgresql_virtual_network_rule_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package azurerm - -import ( - "testing" - - "github.com/hashicorp/terraform/helper/acctest" - "github.com/hashicorp/terraform/helper/resource" -) - -func TestAccAzureRMPostgreSQLVirtualNetworkRule_importBasic(t *testing.T) { - resourceName := "azurerm_postgresql_virtual_network_rule.test" - - ri := acctest.RandInt() - config := testAccAzureRMPostgreSQLVirtualNetworkRule_basic(ri, testLocation()) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testCheckAzureRMPostgreSQLVirtualNetworkRuleDestroy, - Steps: []resource.TestStep{ - { - Config: config, - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} diff --git a/azurerm/resource_arm_postgresql_virtual_network_rule.go b/azurerm/resource_arm_postgresql_virtual_network_rule.go index 72b882dc1ac9..ec5fbb6cd999 100644 --- a/azurerm/resource_arm_postgresql_virtual_network_rule.go +++ b/azurerm/resource_arm_postgresql_virtual_network_rule.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "log" - "strings" "time" "github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql" @@ -49,6 +48,11 @@ func resourceArmPostgreSQLVirtualNetworkRule() *schema.Resource { Required: true, ValidateFunc: azure.ValidateResourceID, }, + + "ignore_missing_vnet_service_endpoint": { + Type: schema.TypeBool, + Optional: true, + }, }, } } @@ -61,52 +65,21 @@ func resourceArmPostgreSQLVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, serverName := d.Get("server_name").(string) resourceGroup := d.Get("resource_group_name").(string) subnetId := d.Get("subnet_id").(string) - - // due to a bug in the API we have to ensure the Subnet's configured correctly or the API call will timeout - // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3719 - subnetsClient := meta.(*ArmClient).subnetClient - subnetParsedId, err := parseAzureResourceID(subnetId) - - subnetResourceGroup := subnetParsedId.ResourceGroup - virtualNetwork := subnetParsedId.Path["virtualNetworks"] - subnetName := subnetParsedId.Path["subnets"] - subnet, err := subnetsClient.Get(ctx, subnetResourceGroup, virtualNetwork, subnetName, "") - if err != nil { - if utils.ResponseWasNotFound(subnet.Response) { - return fmt.Errorf("Subnet with ID %q was not found: %+v", subnetId, err) - } - - return fmt.Errorf("Error obtaining Subnet %q (Virtual Network %q / Resource Group %q: %+v", subnetName, virtualNetwork, subnetResourceGroup, err) - } - - containsEndpoint := false - if props := subnet.SubnetPropertiesFormat; props != nil { - if endpoints := props.ServiceEndpoints; endpoints != nil { - for _, e := range *endpoints { - if e.Service == nil { - continue - } - - if strings.EqualFold(*e.Service, "Microsoft.Sql") { - containsEndpoint = true - break - } - } - } - } - - if !containsEndpoint { - return fmt.Errorf("Error creating PostgreSQL Virtual Network Rule: Subnet %q (Virtual Network %q / Resource Group %q) must contain a Service Endpoint for `Microsoft.Sql`", subnetName, virtualNetwork, subnetResourceGroup) - } + ignoreMissingVnetServiceEndpoint := d.Get("ignore_missing_vnet_service_endpoint").(bool) parameters := postgresql.VirtualNetworkRule{ VirtualNetworkRuleProperties: &postgresql.VirtualNetworkRuleProperties{ VirtualNetworkSubnetID: utils.String(subnetId), - IgnoreMissingVnetServiceEndpoint: utils.Bool(false), + IgnoreMissingVnetServiceEndpoint: utils.Bool(ignoreMissingVnetServiceEndpoint), }, } - _, err = client.CreateOrUpdate(ctx, resourceGroup, serverName, name, parameters) + future, err := client.CreateOrUpdate(ctx, resourceGroup, serverName, name, parameters) + if err != nil { + return fmt.Errorf("Error submitting PostgreSQL Virtual Network Rule %q (PostgreSQL Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + err = future.WaitForCompletionRef(ctx, client.Client) if err != nil { return fmt.Errorf("Error creating PostgreSQL Virtual Network Rule %q (PostgreSQL Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) } @@ -166,6 +139,7 @@ func resourceArmPostgreSQLVirtualNetworkRuleRead(d *schema.ResourceData, meta in if props := resp.VirtualNetworkRuleProperties; props != nil { d.Set("subnet_id", props.VirtualNetworkSubnetID) + d.Set("ignore_missing_vnet_service_endpoint", props.IgnoreMissingVnetServiceEndpoint) } return nil diff --git a/azurerm/resource_arm_postgresql_virtual_network_rule_test.go b/azurerm/resource_arm_postgresql_virtual_network_rule_test.go index d860cb74c1cf..ea36033dafd7 100644 --- a/azurerm/resource_arm_postgresql_virtual_network_rule_test.go +++ b/azurerm/resource_arm_postgresql_virtual_network_rule_test.go @@ -16,17 +16,24 @@ func TestAccAzureRMPostgreSQLVirtualNetworkRule_basic(t *testing.T) { resourceName := "azurerm_postgresql_virtual_network_rule.test" ri := acctest.RandInt() + config := testAccAzureRMPostgreSQLVirtualNetworkRule_basic(ri, testLocation()) + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testCheckAzureRMPostgreSQLVirtualNetworkRuleDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMPostgreSQLVirtualNetworkRule_basic(ri, testLocation()), + Config: config, Check: resource.ComposeTestCheckFunc( testCheckAzureRMPostgreSQLVirtualNetworkRuleExists(resourceName), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -111,6 +118,27 @@ func TestAccAzureRMPostgreSQLVirtualNetworkRule_multipleSubnets(t *testing.T) { }) } +func TestAccAzureRMPostgreSQLVirtualNetworkRule_IgnoreEndpointValid(t *testing.T) { + resourceName := "azurerm_postgresql_virtual_network_rule.test" + ri := acctest.RandInt() + config := testAccAzureRMPostgreSQLVirtualNetworkRule_ignoreEndpointValid(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPostgreSQLVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPostgreSQLVirtualNetworkRuleExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "ignore_missing_vnet_service_endpoint", "true"), + ), + }, + }, + }) +} + func testCheckAzureRMPostgreSQLVirtualNetworkRuleExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] @@ -128,7 +156,7 @@ func testCheckAzureRMPostgreSQLVirtualNetworkRuleExists(name string) resource.Te resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) if err != nil { if utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("Bad: PostgreSQL Firewall Rule %q (server %q / resource group %q) was not found", ruleName, serverName, resourceGroup) + return fmt.Errorf("Bad: PostgreSQL Virtual Network Rule %q (server %q / resource group %q) was not found", ruleName, serverName, resourceGroup) } return err @@ -160,7 +188,7 @@ func testCheckAzureRMPostgreSQLVirtualNetworkRuleDestroy(s *terraform.State) err return err } - return fmt.Errorf("Bad: PostgreSQL Firewall Rule %q (server %q / resource group %q) still exists: %+v", ruleName, serverName, resourceGroup, resp) + return fmt.Errorf("Bad: PostgreSQL Virtual Network Rule %q (server %q / resource group %q) still exists: %+v", ruleName, serverName, resourceGroup, resp) } return nil @@ -458,6 +486,7 @@ resource "azurerm_postgresql_virtual_network_rule" "rule1" { resource_group_name = "${azurerm_resource_group.test.name}" server_name = "${azurerm_postgresql_server.test.name}" subnet_id = "${azurerm_subnet.vnet1_subnet1.id}" + ignore_missing_vnet_service_endpoint = false } resource "azurerm_postgresql_virtual_network_rule" "rule2" { @@ -465,6 +494,7 @@ resource "azurerm_postgresql_virtual_network_rule" "rule2" { resource_group_name = "${azurerm_resource_group.test.name}" server_name = "${azurerm_postgresql_server.test.name}" subnet_id = "${azurerm_subnet.vnet1_subnet2.id}" + ignore_missing_vnet_service_endpoint = false } resource "azurerm_postgresql_virtual_network_rule" "rule3" { @@ -472,6 +502,63 @@ resource "azurerm_postgresql_virtual_network_rule" "rule3" { resource_group_name = "${azurerm_resource_group.test.name}" server_name = "${azurerm_postgresql_server.test.name}" subnet_id = "${azurerm_subnet.vnet2_subnet1.id}" + ignore_missing_vnet_service_endpoint = false } `, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt) } + +func testAccAzureRMPostgreSQLVirtualNetworkRule_ignoreEndpointValid(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvnet%d" + address_space = ["10.7.29.0/29"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.0/29" + service_endpoints = ["Microsoft.Storage"] +} + +resource "azurerm_postgresql_server" "test" { + name = "acctestpostgresqlsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } + + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "9.5" + ssl_enforcement = "Enabled" +} + +resource "azurerm_postgresql_virtual_network_rule" "test" { + name = "acctestpostgresqlvnetrule%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_postgresql_server.test.name}" + subnet_id = "${azurerm_subnet.test.id}" + ignore_missing_vnet_service_endpoint = true +} +`, rInt, location, rInt, rInt, rInt, rInt) +} diff --git a/website/docs/r/postgresql_virtual_network_rule.html.markdown b/website/docs/r/postgresql_virtual_network_rule.html.markdown index cae70a8363af..0cff617067c0 100644 --- a/website/docs/r/postgresql_virtual_network_rule.html.markdown +++ b/website/docs/r/postgresql_virtual_network_rule.html.markdown @@ -53,17 +53,18 @@ resource "azurerm_postgresql_server" "test" { geo_redundant_backup = "Disabled" } - administrator_login = "psqladminun" + administrator_login = "psqladminun" administrator_login_password = "H@Sh1CoR3!" - version = "9.5" - ssl_enforcement = "Enabled" + version = "9.5" + ssl_enforcement = "Enabled" } resource "azurerm_postgresql_virtual_network_rule" "test" { - name = "postgresql-vnet-rule" - resource_group_name = "${azurerm_resource_group.test.name}" - server_name = "${azurerm_postgresql_server.test.name}" - subnet_id = "${azurerm_subnet.internal.id}" + name = "postgresql-vnet-rule" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_postgresql_server.test.name}" + subnet_id = "${azurerm_subnet.internal.id}" + ignore_missing_vnet_service_endpoint = true } ``` @@ -84,7 +85,7 @@ The following arguments are supported: * `subnet_id` - (Required) The ID of the subnet that the PostgreSQL server will be connected to. -~> **NOTE:** Due to [a bug in the Azure API](https://github.com/Azure/azure-rest-api-specs/issues/3719) this resource currently doesn't expose the `ignore_missing_vnet_service_endpoint` field and defaults this to `false`. Terraform will check during the provisioning of the Virtual Network Rule that the Subnet contains the Service Rule to verify that the Virtual Network Rule can be created. +* `ignore_missing_vnet_service_endpoint` - (Optional) Should the Virtual Network Rule be created before the Subnet has the Virtual Network Service Endpoint enabled? Defaults to `false`. ## Attributes Reference From d4819b48609c443394705319a9ac3d1d46600f71 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 12 Oct 2018 09:48:21 -1000 Subject: [PATCH 14/35] Updating to include #2056 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa77afa2e252..85308644a6e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ IMPROVEMENTS: * `azurerm_dev_test_virtual_network` - support for managing the Subnet [GH-2041] * `azurerm_key_vault` - support for Virtual Network Rules [GH-2027] * `azurerm_kubernetes_cluster` - changing the `oms_agent` property no longer forces a new resource [GH-2021] +* `azurerm_postgresql_virtual_network_rule` - support for the `ignore_missing_vnet_service_endpoint` [GH-2056] ## 1.16.0 (October 01, 2018) From 39edd7a1141f571611209b2291462055c701e363 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 12 Oct 2018 12:22:05 -1000 Subject: [PATCH 15/35] New Resources: `azurerm_dev_test_(linux|windows)virtual_machine` (#2058) * r/dev_test_virtual_network: support for controlling the subnet * Removing the unnecessary expansion * r/dev_test_virtuql_network: defaulting to `allow` if not specified * Virtual Network: docs fixes * New Resource: `azurerm_dev_test_virtual_machine` * Refactoring dtl network * Fixing the tests * DTL VM: extra validation * Moving the DTL Validation into the validate package * Refactor: moving `inbound_nat_rule` out to it's own object * Refactoring: moving `gallery_image_reference` out to a shared function * Refactoring: splitting DTL VM into DTL Linux VM and DTL Windows VM * DevTest VM: adding validation for the machine name --- azurerm/config.go | 5 + azurerm/data_source_dev_test_lab.go | 4 +- azurerm/helpers/azure/devtest.go | 142 ++++++- azurerm/helpers/azure/devtest_test.go | 31 -- azurerm/helpers/validate/devtest.go | 58 +++ azurerm/helpers/validate/devtest_test.go | 68 ++++ azurerm/provider.go | 2 + azurerm/resource_arm_dev_test_lab.go | 4 +- ...urce_arm_dev_test_linux_virtual_machine.go | 306 +++++++++++++++ ...arm_dev_test_linux_virtual_machine_test.go | 351 ++++++++++++++++++ .../resource_arm_dev_test_virtual_network.go | 20 +- ...ce_arm_dev_test_windows_virtual_machine.go | 295 +++++++++++++++ ...m_dev_test_windows_virtual_machine_test.go | 291 +++++++++++++++ website/azurerm.erb | 8 + ...v_test_linux_virtual_machine.html.markdown | 156 ++++++++ .../r/dev_test_virtual_network.html.markdown | 7 +- ...test_windows_virtual_machine.html.markdown | 151 ++++++++ 17 files changed, 1843 insertions(+), 56 deletions(-) delete mode 100644 azurerm/helpers/azure/devtest_test.go create mode 100644 azurerm/helpers/validate/devtest.go create mode 100644 azurerm/helpers/validate/devtest_test.go create mode 100644 azurerm/resource_arm_dev_test_linux_virtual_machine.go create mode 100644 azurerm/resource_arm_dev_test_linux_virtual_machine_test.go create mode 100644 azurerm/resource_arm_dev_test_windows_virtual_machine.go create mode 100644 azurerm/resource_arm_dev_test_windows_virtual_machine_test.go create mode 100644 website/docs/r/dev_test_linux_virtual_machine.html.markdown create mode 100644 website/docs/r/dev_test_windows_virtual_machine.html.markdown diff --git a/azurerm/config.go b/azurerm/config.go index 5c50929f6055..84b14691ba7a 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -154,6 +154,7 @@ type ArmClient struct { // DevTestLabs devTestLabsClient dtl.LabsClient + devTestVirtualMachinesClient dtl.VirtualMachinesClient devTestVirtualNetworksClient dtl.VirtualNetworksClient // Databases @@ -773,6 +774,10 @@ func (c *ArmClient) registerDevTestClients(endpoint, subscriptionId string, auth c.configureClient(&labsClient.Client, auth) c.devTestLabsClient = labsClient + devTestVirtualMachinesClient := dtl.NewVirtualMachinesClientWithBaseURI(endpoint, subscriptionId) + c.configureClient(&devTestVirtualMachinesClient.Client, auth) + c.devTestVirtualMachinesClient = devTestVirtualMachinesClient + devTestVirtualNetworksClient := dtl.NewVirtualNetworksClientWithBaseURI(endpoint, subscriptionId) c.configureClient(&devTestVirtualNetworksClient.Client, auth) c.devTestVirtualNetworksClient = devTestVirtualNetworksClient diff --git a/azurerm/data_source_dev_test_lab.go b/azurerm/data_source_dev_test_lab.go index 8a1c6c78fa01..2e9b4f4551d0 100644 --- a/azurerm/data_source_dev_test_lab.go +++ b/azurerm/data_source_dev_test_lab.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/hashicorp/terraform/helper/schema" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -16,7 +16,7 @@ func dataSourceArmDevTestLab() *schema.Resource { "name": { Type: schema.TypeString, Required: true, - ValidateFunc: azure.ValidateDevTestLabName(), + ValidateFunc: validate.DevTestLabName(), }, "location": locationForDataSourceSchema(), diff --git a/azurerm/helpers/azure/devtest.go b/azurerm/helpers/azure/devtest.go index 3a18c96af15d..28b5f54076f2 100644 --- a/azurerm/helpers/azure/devtest.go +++ b/azurerm/helpers/azure/devtest.go @@ -1,14 +1,144 @@ package azure import ( - "regexp" - + "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func ValidateDevTestLabName() schema.SchemaValidateFunc { - return validation.StringMatch( - regexp.MustCompile("^[A-Za-z0-9_-]+$"), - "Lab Name can only include alphanumeric characters, underscores, hyphens.") +func SchemaDevTestVirtualMachineInboundNatRule() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + // since these aren't returned from the API + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "protocol": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(dtl.TCP), + string(dtl.UDP), + }, false), + }, + + "backend_port": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validate.PortNumber, + }, + + "frontend_port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + } +} + +func ExpandDevTestLabVirtualMachineNatRules(input *schema.Set) []dtl.InboundNatRule { + rules := make([]dtl.InboundNatRule, 0) + if input == nil { + return rules + } + + for _, val := range input.List() { + v := val.(map[string]interface{}) + backendPort := v["backend_port"].(int) + protocol := v["protocol"].(string) + + rule := dtl.InboundNatRule{ + TransportProtocol: dtl.TransportProtocol(protocol), + BackendPort: utils.Int32(int32(backendPort)), + } + + rules = append(rules, rule) + } + + return rules +} + +func ExpandDevTestLabVirtualMachineGalleryImageReference(input []interface{}, osType string) *dtl.GalleryImageReference { + if len(input) == 0 { + return nil + } + + v := input[0].(map[string]interface{}) + offer := v["offer"].(string) + publisher := v["publisher"].(string) + sku := v["sku"].(string) + version := v["version"].(string) + + return &dtl.GalleryImageReference{ + Offer: utils.String(offer), + OsType: utils.String(osType), + Publisher: utils.String(publisher), + Sku: utils.String(sku), + Version: utils.String(version), + } +} + +func SchemaDevTestVirtualMachineGalleryImageReference() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "offer": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "publisher": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "sku": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "version": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + }, + } +} + +func FlattenDevTestVirtualMachineGalleryImage(input *dtl.GalleryImageReference) []interface{} { + results := make([]interface{}, 0) + + if input != nil { + output := make(map[string]interface{}, 0) + + if input.Offer != nil { + output["offer"] = *input.Offer + } + + if input.Publisher != nil { + output["publisher"] = *input.Publisher + } + + if input.Sku != nil { + output["sku"] = *input.Sku + } + + if input.Version != nil { + output["version"] = *input.Version + } + + results = append(results, output) + } + + return results } diff --git a/azurerm/helpers/azure/devtest_test.go b/azurerm/helpers/azure/devtest_test.go deleted file mode 100644 index f5090b9d808c..000000000000 --- a/azurerm/helpers/azure/devtest_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package azure - -import "testing" - -func TestValidateDevTestLabName(t *testing.T) { - validNames := []string{ - "valid-name", - "valid02-name", - "validName1", - "-validname1", - "valid_name", - "double-hyphen--valid", - } - for _, v := range validNames { - _, errors := ValidateDevTestLabName()(v, "example") - if len(errors) != 0 { - t.Fatalf("%q should be a valid Dev Test Lab Name: %q", v, errors) - } - } - - invalidNames := []string{ - "invalid!", - "!@£", - } - for _, v := range invalidNames { - _, errors := ValidateDevTestLabName()(v, "name") - if len(errors) == 0 { - t.Fatalf("%q should be an invalid Dev Test Lab Name", v) - } - } -} diff --git a/azurerm/helpers/validate/devtest.go b/azurerm/helpers/validate/devtest.go new file mode 100644 index 000000000000..ea13e6c6f2f5 --- /dev/null +++ b/azurerm/helpers/validate/devtest.go @@ -0,0 +1,58 @@ +package validate + +import ( + "fmt" + "regexp" + + "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" +) + +func DevTestLabName() schema.SchemaValidateFunc { + return validation.StringMatch( + regexp.MustCompile("^[A-Za-z0-9_-]+$"), + "Lab Name can only include alphanumeric characters, underscores, hyphens.") +} + +func DevTestVirtualMachineName(maxLength int) schema.SchemaValidateFunc { + return func(i interface{}, k string) ([]string, []error) { + v, ok := i.(string) + if !ok { + return nil, []error{ + fmt.Errorf("expected type of %s to be string", k), + } + } + + errs := make([]error, 0) + if 1 <= len(v) && len(v) > maxLength { + errs = append(errs, fmt.Errorf("Expected %s to be between 1 and %d characters - got %d", k, maxLength, len(v))) + } + + matched, err := regexp.MatchString("^([a-zA-Z0-9]{1})([a-zA-Z0-9-]+)([a-zA-Z0-9]{1})$", v) + if err != nil { + errs = append(errs, fmt.Errorf("Error validating regex: %+v", err)) + } + if !matched { + errs = append(errs, fmt.Errorf("%s may contain letters, numbers, or '-', must begin and end with a letter or number, and cannot be all numbers.", k)) + } + + matched, err = regexp.MatchString("([a-zA-Z-]+)", v) + if err != nil { + errs = append(errs, fmt.Errorf("Error validating regex: %+v", err)) + } + if !matched { + errs = append(errs, fmt.Errorf("%s cannot be all numbers.", k)) + } + + return nil, errs + } +} + +func DevTestVirtualNetworkUsagePermissionType() schema.SchemaValidateFunc { + return validation.StringInSlice([]string{ + string(dtl.Allow), + string(dtl.Default), + string(dtl.Deny), + }, false) +} diff --git a/azurerm/helpers/validate/devtest_test.go b/azurerm/helpers/validate/devtest_test.go new file mode 100644 index 000000000000..07c58553478c --- /dev/null +++ b/azurerm/helpers/validate/devtest_test.go @@ -0,0 +1,68 @@ +package validate + +import "testing" + +func TestValidateDevTestLabName(t *testing.T) { + validNames := []string{ + "valid-name", + "valid02-name", + "validName1", + "-validname1", + "valid_name", + "double-hyphen--valid", + } + for _, v := range validNames { + _, errors := DevTestLabName()(v, "example") + if len(errors) != 0 { + t.Fatalf("%q should be a valid Dev Test Lab Name: %q", v, errors) + } + } + + invalidNames := []string{ + "invalid!", + "!@£", + } + for _, v := range invalidNames { + _, errors := DevTestLabName()(v, "name") + if len(errors) == 0 { + t.Fatalf("%q should be an invalid Dev Test Lab Name", v) + } + } +} + +func TestValidateDevTestVirtualMachineName(t *testing.T) { + validNames := []string{ + "valid-name", + "valid02-ne", + "validName1", + "1hello", + "hello1", + "1hello1", + "dbl--valid", + } + for _, v := range validNames { + _, errors := DevTestVirtualMachineName(10)(v, "example") + if len(errors) != 0 { + t.Fatalf("%q should be a valid Dev Test Virtual Machine Name: %q", v, errors) + } + } + + invalidNames := []string{ + "", + "-invalidname1", + "thisnameiswaytoolong", + "12345", + "in_valid", + "-hello", + "hello-", + "1hello-", + "invalid!", + "!@£", + } + for _, v := range invalidNames { + _, errors := DevTestVirtualMachineName(10)(v, "name") + if len(errors) == 0 { + t.Fatalf("%q should be an invalid Dev Test Virtual Machine Name", v) + } + } +} diff --git a/azurerm/provider.go b/azurerm/provider.go index e82f7e28590c..1444b21e3360 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -161,6 +161,8 @@ func Provider() terraform.ResourceProvider { "azurerm_data_lake_store_file": resourceArmDataLakeStoreFile(), "azurerm_data_lake_store_firewall_rule": resourceArmDataLakeStoreFirewallRule(), "azurerm_dev_test_lab": resourceArmDevTestLab(), + "azurerm_dev_test_linux_virtual_machine": resourceArmDevTestLinuxVirtualMachine(), + "azurerm_dev_test_windows_virtual_machine": resourceArmDevTestWindowsVirtualMachine(), "azurerm_dev_test_virtual_network": resourceArmDevTestVirtualNetwork(), "azurerm_dns_a_record": resourceArmDnsARecord(), "azurerm_dns_aaaa_record": resourceArmDnsAAAARecord(), diff --git a/azurerm/resource_arm_dev_test_lab.go b/azurerm/resource_arm_dev_test_lab.go index 2307727709a2..f08086c96453 100644 --- a/azurerm/resource_arm_dev_test_lab.go +++ b/azurerm/resource_arm_dev_test_lab.go @@ -7,7 +7,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" "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/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -26,7 +26,7 @@ func resourceArmDevTestLab() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: azure.ValidateDevTestLabName(), + ValidateFunc: validate.DevTestLabName(), }, "location": locationSchema(), diff --git a/azurerm/resource_arm_dev_test_linux_virtual_machine.go b/azurerm/resource_arm_dev_test_linux_virtual_machine.go new file mode 100644 index 000000000000..bb4a120de718 --- /dev/null +++ b/azurerm/resource_arm_dev_test_linux_virtual_machine.go @@ -0,0 +1,306 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" + "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/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDevTestLinuxVirtualMachine() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDevTestLinuxVirtualMachineCreateUpdate, + Read: resourceArmDevTestLinuxVirtualMachineRead, + Update: resourceArmDevTestLinuxVirtualMachineCreateUpdate, + Delete: resourceArmDevTestLinuxVirtualMachineDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.DevTestVirtualMachineName(62), + }, + + "lab_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.DevTestLabName(), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3964 + "resource_group_name": resourceGroupNameDiffSuppressSchema(), + + "location": locationSchema(), + + "size": { + Type: schema.TypeString, + Required: true, + // since this isn't returned from the API + ForceNew: true, + }, + + "username": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "storage_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "Standard", + "Premium", + }, false), + }, + + "lab_subnet_name": { + Type: schema.TypeString, + Required: true, + // since this isn't returned from the API + ForceNew: true, + }, + + "lab_virtual_network_id": { + Type: schema.TypeString, + Required: true, + // since this isn't returned from the API + ForceNew: true, + }, + + "allow_claim": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "disallow_public_ip_address": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + }, + + "password": { + Type: schema.TypeString, + Optional: true, + // since this isn't returned from the API + ForceNew: true, + Sensitive: true, + }, + + "ssh_key": { + Type: schema.TypeString, + Optional: true, + // since this isn't returned from the API + ForceNew: true, + }, + + "gallery_image_reference": azure.SchemaDevTestVirtualMachineGalleryImageReference(), + + "inbound_nat_rule": azure.SchemaDevTestVirtualMachineInboundNatRule(), + + "notes": { + Type: schema.TypeString, + Optional: true, + }, + + "tags": tagsSchema(), + + "fqdn": { + Type: schema.TypeString, + Computed: true, + }, + + "unique_identifier": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmDevTestLinuxVirtualMachineCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestVirtualMachinesClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for DevTest Linux Virtual Machine creation") + + name := d.Get("name").(string) + labName := d.Get("lab_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + tags := d.Get("tags").(map[string]interface{}) + + allowClaim := d.Get("allow_claim").(bool) + disallowPublicIPAddress := d.Get("disallow_public_ip_address").(bool) + labSubnetName := d.Get("lab_subnet_name").(string) + labVirtualNetworkId := d.Get("lab_virtual_network_id").(string) + location := azureRMNormalizeLocation(d.Get("location").(string)) + notes := d.Get("notes").(string) + password := d.Get("password").(string) + sshKey := d.Get("ssh_key").(string) + size := d.Get("size").(string) + storageType := d.Get("storage_type").(string) + username := d.Get("username").(string) + + galleryImageReferenceRaw := d.Get("gallery_image_reference").([]interface{}) + galleryImageReference := azure.ExpandDevTestLabVirtualMachineGalleryImageReference(galleryImageReferenceRaw, "Linux") + + natRulesRaw := d.Get("inbound_nat_rule").(*schema.Set) + natRules := azure.ExpandDevTestLabVirtualMachineNatRules(natRulesRaw) + + if len(natRules) > 0 && !disallowPublicIPAddress { + return fmt.Errorf("If `inbound_nat_rule` is specified then `disallow_public_ip_address` must be set to true.") + } + + nic := dtl.NetworkInterfaceProperties{} + if disallowPublicIPAddress { + nic.SharedPublicIPAddressConfiguration = &dtl.SharedPublicIPAddressConfiguration{ + InboundNatRules: &natRules, + } + } + + authenticateViaSsh := sshKey != "" + parameters := dtl.LabVirtualMachine{ + Location: utils.String(location), + LabVirtualMachineProperties: &dtl.LabVirtualMachineProperties{ + AllowClaim: utils.Bool(allowClaim), + IsAuthenticationWithSSHKey: utils.Bool(authenticateViaSsh), + DisallowPublicIPAddress: utils.Bool(disallowPublicIPAddress), + GalleryImageReference: galleryImageReference, + LabSubnetName: utils.String(labSubnetName), + LabVirtualNetworkID: utils.String(labVirtualNetworkId), + NetworkInterface: &nic, + OsType: utils.String("Linux"), + Notes: utils.String(notes), + Password: utils.String(password), + Size: utils.String(size), + SSHKey: utils.String(sshKey), + StorageType: utils.String(storageType), + UserName: utils.String(username), + }, + Tags: expandTags(tags), + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, labName, name, parameters) + if err != nil { + return fmt.Errorf("Error creating/updating DevTest Linux Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting for creation/update of DevTest Linux Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, labName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving DevTest Linux Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Cannot read DevTest Linux Virtual Machine %q (Lab %q / Resource Group %q) ID", name, labName, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmDevTestLinuxVirtualMachineRead(d, meta) +} + +func resourceArmDevTestLinuxVirtualMachineRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestVirtualMachinesClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + labName := id.Path["labs"] + name := id.Path["virtualmachines"] + + read, err := client.Get(ctx, resourceGroup, labName, name, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + log.Printf("[DEBUG] DevTest Linux Virtual Machine %q was not found in Lab %q / Resource Group %q - removing from state!", name, labName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on DevTest Linux Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + d.Set("name", read.Name) + d.Set("lab_name", labName) + d.Set("resource_group_name", resourceGroup) + if location := read.Location; location != nil { + d.Set("location", azureRMNormalizeLocation(*location)) + } + + if props := read.LabVirtualMachineProperties; props != nil { + d.Set("allow_claim", props.AllowClaim) + d.Set("disallow_public_ip_address", props.DisallowPublicIPAddress) + d.Set("notes", props.Notes) + d.Set("size", props.Size) + d.Set("storage_type", props.StorageType) + d.Set("username", props.UserName) + + flattenedImage := azure.FlattenDevTestVirtualMachineGalleryImage(props.GalleryImageReference) + if err := d.Set("gallery_image_reference", flattenedImage); err != nil { + return fmt.Errorf("Error flattening `gallery_image_reference`: %+v", err) + } + + // Computed fields + d.Set("fqdn", props.Fqdn) + d.Set("unique_identifier", props.UniqueIdentifier) + } + + flattenAndSetTags(d, read.Tags) + + return nil +} + +func resourceArmDevTestLinuxVirtualMachineDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestVirtualMachinesClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + labName := id.Path["labs"] + name := id.Path["virtualmachines"] + + read, err := client.Get(ctx, resourceGroup, labName, name, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + // deleted outside of TF + log.Printf("[DEBUG] DevTest Linux Virtual Machine %q was not found in Lab %q / Resource Group %q - assuming removed!", name, labName, resourceGroup) + return nil + } + + return fmt.Errorf("Error retrieving DevTest Linux Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + future, err := client.Delete(ctx, resourceGroup, labName, name) + if err != nil { + return fmt.Errorf("Error deleting DevTest Linux Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting for the deletion of DevTest Linux Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + return err +} diff --git a/azurerm/resource_arm_dev_test_linux_virtual_machine_test.go b/azurerm/resource_arm_dev_test_linux_virtual_machine_test.go new file mode 100644 index 000000000000..ad099532ec48 --- /dev/null +++ b/azurerm/resource_arm_dev_test_linux_virtual_machine_test.go @@ -0,0 +1,351 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMDevTestLinuxVirtualMachine_basic(t *testing.T) { + resourceName := "azurerm_dev_test_linux_virtual_machine.test" + rInt := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestLinuxVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevTestLinuxVirtualMachine_basic(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestLinuxVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "gallery_image_reference.0.publisher", "Canonical"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // not returned from the API + "lab_subnet_name", + "lab_virtual_network_id", + "password", + }, + }, + }, + }) +} + +func TestAccAzureRMDevTestLinuxVirtualMachine_basicSSH(t *testing.T) { + resourceName := "azurerm_dev_test_linux_virtual_machine.test" + rInt := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestLinuxVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevTestLinuxVirtualMachine_basicSSH(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestLinuxVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "gallery_image_reference.0.publisher", "Canonical"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // not returned from the API + "lab_subnet_name", + "lab_virtual_network_id", + "ssh_key", + }, + }, + }, + }) +} + +func TestAccAzureRMDevTestLinuxVirtualMachine_inboundNatRules(t *testing.T) { + resourceName := "azurerm_dev_test_linux_virtual_machine.test" + rInt := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestLinuxVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevTestLinuxVirtualMachine_inboundNatRules(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestLinuxVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "disallow_public_ip_address", "true"), + resource.TestCheckResourceAttr(resourceName, "gallery_image_reference.0.publisher", "Canonical"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Acceptance", "Test"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // not returned from the API + "inbound_nat_rule", + "lab_subnet_name", + "lab_virtual_network_id", + "password", + }, + }, + }, + }) +} + +func TestAccAzureRMDevTestLinuxVirtualMachine_updateStorage(t *testing.T) { + resourceName := "azurerm_dev_test_linux_virtual_machine.test" + rInt := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestLinuxVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevTestLinuxVirtualMachine_storage(rInt, location, "Standard"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestLinuxVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "gallery_image_reference.0.publisher", "Canonical"), + resource.TestCheckResourceAttr(resourceName, "storage_type", "Standard"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + Config: testAccAzureRMDevTestLinuxVirtualMachine_storage(rInt, location, "Premium"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestLinuxVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "gallery_image_reference.0.publisher", "Canonical"), + resource.TestCheckResourceAttr(resourceName, "storage_type", "Premium"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + }, + }) +} + +func testCheckAzureRMDevTestLinuxVirtualMachineExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + virtualMachineName := rs.Primary.Attributes["name"] + labName := rs.Primary.Attributes["lab_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + conn := testAccProvider.Meta().(*ArmClient).devTestVirtualMachinesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resourceGroup, labName, virtualMachineName, "") + if err != nil { + return fmt.Errorf("Bad: Get devTestVirtualMachinesClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: DevTest Linux Virtual Machine %q (Lab %q / Resource Group: %q) does not exist", virtualMachineName, labName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDevTestLinuxVirtualMachineDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).devTestVirtualMachinesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_dev_test_linux_virtual_machine" { + continue + } + + virtualMachineName := rs.Primary.Attributes["name"] + labName := rs.Primary.Attributes["lab_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, labName, virtualMachineName, "") + + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return nil + } + + return err + } + + return fmt.Errorf("DevTest Linux Virtual Machine still exists:\n%#v", resp) + } + + return nil +} + +func testAccAzureRMDevTestLinuxVirtualMachine_basic(rInt int, location string) string { + template := testAccAzureRMDevTestLinuxVirtualMachine_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_dev_test_linux_virtual_machine" "test" { + name = "acctestvm-vm%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + size = "Standard_F2" + username = "acct5stU5er" + password = "Pa$$w0rd1234!" + lab_virtual_network_id = "${azurerm_dev_test_virtual_network.test.id}" + lab_subnet_name = "${azurerm_dev_test_virtual_network.test.subnet.0.name}" + storage_type = "Standard" + + gallery_image_reference { + offer = "UbuntuServer" + publisher = "Canonical" + sku = "18.04-LTS" + version = "latest" + } +} +`, template, rInt) +} + +func testAccAzureRMDevTestLinuxVirtualMachine_basicSSH(rInt int, location string) string { + template := testAccAzureRMDevTestLinuxVirtualMachine_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_dev_test_linux_virtual_machine" "test" { + name = "acctestvm-vm%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + size = "Standard_F2" + username = "acct5stU5er" + ssh_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDCsTcryUl51Q2VSEHqDRNmceUFo55ZtcIwxl2QITbN1RREti5ml/VTytC0yeBOvnZA4x4CFpdw/lCDPk0yrH9Ei5vVkXmOrExdTlT3qI7YaAzj1tUVlBd4S6LX1F7y6VLActvdHuDDuXZXzCDd/97420jrDfWZqJMlUK/EmCE5ParCeHIRIvmBxcEnGfFIsw8xQZl0HphxWOtJil8qsUWSdMyCiJYYQpMoMliO99X40AUc4/AlsyPyT5ddbKk08YrZ+rKDVHF7o29rh4vi5MmHkVgVQHKiKybWlHq+b71gIAUQk9wrJxD+dqt4igrmDSpIjfjwnd+l5UIn5fJSO5DYV4YT/4hwK7OKmuo7OFHD0WyY5YnkYEMtFgzemnRBdE8ulcT60DQpVgRMXFWHvhyCWy0L6sgj1QWDZlLpvsIvNfHsyhKFMG1frLnMt/nP0+YCcfg+v1JYeCKjeoJxB8DWcRBsjzItY0CGmzP8UYZiYKl/2u+2TgFS5r7NWH11bxoUzjKdaa1NLw+ieA8GlBFfCbfWe6YVB9ggUte4VtYFMZGxOjS2bAiYtfgTKFJv+XqORAwExG6+G2eDxIDyo80/OA9IG7Xv/jwQr7D6KDjDuULFcN/iTxuttoKrHeYz1hf5ZQlBdllwJHYx6fK2g8kha6r2JIQKocvsAXiiONqSfw== hello@world.com" + lab_virtual_network_id = "${azurerm_dev_test_virtual_network.test.id}" + lab_subnet_name = "${azurerm_dev_test_virtual_network.test.subnet.0.name}" + storage_type = "Standard" + + gallery_image_reference { + offer = "UbuntuServer" + publisher = "Canonical" + sku = "18.04-LTS" + version = "latest" + } +} +`, template, rInt) +} + +func testAccAzureRMDevTestLinuxVirtualMachine_inboundNatRules(rInt int, location string) string { + template := testAccAzureRMDevTestLinuxVirtualMachine_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_dev_test_linux_virtual_machine" "test" { + name = "acctestvm-vm%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + size = "Standard_F2" + username = "acct5stU5er" + password = "Pa$$w0rd1234!" + disallow_public_ip_address = true + lab_virtual_network_id = "${azurerm_dev_test_virtual_network.test.id}" + lab_subnet_name = "${azurerm_dev_test_virtual_network.test.subnet.0.name}" + storage_type = "Standard" + + gallery_image_reference { + offer = "UbuntuServer" + publisher = "Canonical" + sku = "18.04-LTS" + version = "latest" + } + + inbound_nat_rule { + protocol = "Tcp" + backend_port = 22 + } + + inbound_nat_rule { + protocol = "Tcp" + backend_port = 3389 + } + + tags { + "Acceptance" = "Test" + } +} +`, template, rInt) +} + +func testAccAzureRMDevTestLinuxVirtualMachine_storage(rInt int, location, storageType string) string { + template := testAccAzureRMDevTestLinuxVirtualMachine_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_dev_test_linux_virtual_machine" "test" { + name = "acctestvm-vm%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + size = "Standard_B1ms" + username = "acct5stU5er" + password = "Pa$$w0rd1234!" + lab_virtual_network_id = "${azurerm_dev_test_virtual_network.test.id}" + lab_subnet_name = "${azurerm_dev_test_virtual_network.test.subnet.0.name}" + storage_type = "%s" + + gallery_image_reference { + offer = "UbuntuServer" + publisher = "Canonical" + sku = "18.04-LTS" + version = "latest" + } +} +`, template, rInt, storageType) +} + +func testAccAzureRMDevTestLinuxVirtualMachine_template(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_dev_test_lab" "test" { + name = "acctestdtl%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_dev_test_virtual_network" "test" { + name = "acctestdtvn%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + use_public_ip_address = "Allow" + use_in_virtual_machine_creation = "Allow" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/azurerm/resource_arm_dev_test_virtual_network.go b/azurerm/resource_arm_dev_test_virtual_network.go index fc685a07113e..3cdf56975a0f 100644 --- a/azurerm/resource_arm_dev_test_virtual_network.go +++ b/azurerm/resource_arm_dev_test_virtual_network.go @@ -8,7 +8,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" "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/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -34,7 +34,7 @@ func resourceArmDevTestVirtualNetwork() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: azure.ValidateDevTestLabName(), + ValidateFunc: validate.DevTestLabName(), }, // There's a bug in the Azure API where this is returned in lower-case @@ -63,14 +63,14 @@ func resourceArmDevTestVirtualNetwork() *schema.Resource { Type: schema.TypeString, Optional: true, Default: string(dtl.Allow), - ValidateFunc: validateDevTestVirtualNetworkUsagePermissionType(), + ValidateFunc: validate.DevTestVirtualNetworkUsagePermissionType(), }, "use_public_ip_address": { Type: schema.TypeString, Optional: true, Default: string(dtl.Allow), - ValidateFunc: validateDevTestVirtualNetworkUsagePermissionType(), + ValidateFunc: validate.DevTestVirtualNetworkUsagePermissionType(), }, }, }, @@ -100,7 +100,7 @@ func resourceArmDevTestVirtualNetworkCreateUpdate(d *schema.ResourceData, meta i subscriptionId := meta.(*ArmClient).subscriptionId subnetsRaw := d.Get("subnet").([]interface{}) - subnets := expandDevTestVirtualNetworkSubnets(d, subnetsRaw, subscriptionId, resourceGroup, labName, name) + subnets := expandDevTestVirtualNetworkSubnets(subnetsRaw, subscriptionId, resourceGroup, labName, name) parameters := dtl.VirtualNetwork{ Tags: expandTags(tags), @@ -220,7 +220,7 @@ func validateDevTestVirtualNetworkName() schema.SchemaValidateFunc { "Virtual Network Name can only include alphanumeric characters, underscores, hyphens.") } -func expandDevTestVirtualNetworkSubnets(d *schema.ResourceData, input []interface{}, subscriptionId, resourceGroupName, labName, virtualNetworkName string) *[]dtl.SubnetOverride { +func expandDevTestVirtualNetworkSubnets(input []interface{}, subscriptionId, resourceGroupName, labName, virtualNetworkName string) *[]dtl.SubnetOverride { results := make([]dtl.SubnetOverride, 0) // default found from the Portal name := fmt.Sprintf("%sSubnet", virtualNetworkName) @@ -273,11 +273,3 @@ func flattenDevTestVirtualNetworkSubnets(input *[]dtl.SubnetOverride) []interfac return outputs } - -func validateDevTestVirtualNetworkUsagePermissionType() schema.SchemaValidateFunc { - return validation.StringInSlice([]string{ - string(dtl.Allow), - string(dtl.Default), - string(dtl.Deny), - }, false) -} diff --git a/azurerm/resource_arm_dev_test_windows_virtual_machine.go b/azurerm/resource_arm_dev_test_windows_virtual_machine.go new file mode 100644 index 000000000000..9863cab7bc2a --- /dev/null +++ b/azurerm/resource_arm_dev_test_windows_virtual_machine.go @@ -0,0 +1,295 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" + "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/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDevTestWindowsVirtualMachine() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDevTestWindowsVirtualMachineCreateUpdate, + Read: resourceArmDevTestWindowsVirtualMachineRead, + Update: resourceArmDevTestWindowsVirtualMachineCreateUpdate, + Delete: resourceArmDevTestWindowsVirtualMachineDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.DevTestVirtualMachineName(15), + }, + + "lab_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.DevTestLabName(), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3964 + "resource_group_name": resourceGroupNameDiffSuppressSchema(), + + "location": locationSchema(), + + "size": { + Type: schema.TypeString, + Required: true, + // since this isn't returned from the API + ForceNew: true, + }, + + "username": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "password": { + Type: schema.TypeString, + Required: true, + // since this isn't returned from the API + ForceNew: true, + }, + + "storage_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "Standard", + "Premium", + }, false), + }, + + "lab_subnet_name": { + Type: schema.TypeString, + Required: true, + // since this isn't returned from the API + ForceNew: true, + }, + + "lab_virtual_network_id": { + Type: schema.TypeString, + Required: true, + // since this isn't returned from the API + ForceNew: true, + }, + + "allow_claim": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "disallow_public_ip_address": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + }, + + "gallery_image_reference": azure.SchemaDevTestVirtualMachineGalleryImageReference(), + + "inbound_nat_rule": azure.SchemaDevTestVirtualMachineInboundNatRule(), + + "notes": { + Type: schema.TypeString, + Optional: true, + }, + + "tags": tagsSchema(), + + "fqdn": { + Type: schema.TypeString, + Computed: true, + }, + + "unique_identifier": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceArmDevTestWindowsVirtualMachineCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestVirtualMachinesClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for DevTest Windows Virtual Machine creation") + + name := d.Get("name").(string) + labName := d.Get("lab_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + tags := d.Get("tags").(map[string]interface{}) + + allowClaim := d.Get("allow_claim").(bool) + disallowPublicIPAddress := d.Get("disallow_public_ip_address").(bool) + labSubnetName := d.Get("lab_subnet_name").(string) + labVirtualNetworkId := d.Get("lab_virtual_network_id").(string) + location := azureRMNormalizeLocation(d.Get("location").(string)) + notes := d.Get("notes").(string) + password := d.Get("password").(string) + size := d.Get("size").(string) + storageType := d.Get("storage_type").(string) + username := d.Get("username").(string) + + galleryImageReferenceRaw := d.Get("gallery_image_reference").([]interface{}) + galleryImageReference := azure.ExpandDevTestLabVirtualMachineGalleryImageReference(galleryImageReferenceRaw, "Windows") + + natRulesRaw := d.Get("inbound_nat_rule").(*schema.Set) + natRules := azure.ExpandDevTestLabVirtualMachineNatRules(natRulesRaw) + + if len(natRules) > 0 && !disallowPublicIPAddress { + return fmt.Errorf("If `inbound_nat_rule` is specified then `disallow_public_ip_address` must be set to true.") + } + + nic := dtl.NetworkInterfaceProperties{} + if disallowPublicIPAddress { + nic.SharedPublicIPAddressConfiguration = &dtl.SharedPublicIPAddressConfiguration{ + InboundNatRules: &natRules, + } + } + + parameters := dtl.LabVirtualMachine{ + Location: utils.String(location), + LabVirtualMachineProperties: &dtl.LabVirtualMachineProperties{ + AllowClaim: utils.Bool(allowClaim), + IsAuthenticationWithSSHKey: utils.Bool(false), + DisallowPublicIPAddress: utils.Bool(disallowPublicIPAddress), + GalleryImageReference: galleryImageReference, + LabSubnetName: utils.String(labSubnetName), + LabVirtualNetworkID: utils.String(labVirtualNetworkId), + NetworkInterface: &nic, + OsType: utils.String("Windows"), + Notes: utils.String(notes), + Password: utils.String(password), + Size: utils.String(size), + StorageType: utils.String(storageType), + UserName: utils.String(username), + }, + Tags: expandTags(tags), + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, labName, name, parameters) + if err != nil { + return fmt.Errorf("Error creating/updating DevTest Windows Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting for creation/update of DevTest Windows Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, labName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving DevTest Windows Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Cannot read DevTest Windows Virtual Machine %q (Lab %q / Resource Group %q) ID", name, labName, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmDevTestWindowsVirtualMachineRead(d, meta) +} + +func resourceArmDevTestWindowsVirtualMachineRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestVirtualMachinesClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + labName := id.Path["labs"] + name := id.Path["virtualmachines"] + + read, err := client.Get(ctx, resourceGroup, labName, name, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + log.Printf("[DEBUG] DevTest Windows Virtual Machine %q was not found in Lab %q / Resource Group %q - removing from state!", name, labName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on DevTest Windows Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + d.Set("name", read.Name) + d.Set("lab_name", labName) + d.Set("resource_group_name", resourceGroup) + if location := read.Location; location != nil { + d.Set("location", azureRMNormalizeLocation(*location)) + } + + if props := read.LabVirtualMachineProperties; props != nil { + d.Set("allow_claim", props.AllowClaim) + d.Set("disallow_public_ip_address", props.DisallowPublicIPAddress) + d.Set("notes", props.Notes) + d.Set("size", props.Size) + d.Set("storage_type", props.StorageType) + d.Set("username", props.UserName) + + flattenedImage := azure.FlattenDevTestVirtualMachineGalleryImage(props.GalleryImageReference) + if err := d.Set("gallery_image_reference", flattenedImage); err != nil { + return fmt.Errorf("Error flattening `gallery_image_reference`: %+v", err) + } + + // Computed fields + d.Set("fqdn", props.Fqdn) + d.Set("unique_identifier", props.UniqueIdentifier) + } + + flattenAndSetTags(d, read.Tags) + + return nil +} + +func resourceArmDevTestWindowsVirtualMachineDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestVirtualMachinesClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + labName := id.Path["labs"] + name := id.Path["virtualmachines"] + + read, err := client.Get(ctx, resourceGroup, labName, name, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + // deleted outside of TF + log.Printf("[DEBUG] DevTest Windows Virtual Machine %q was not found in Lab %q / Resource Group %q - assuming removed!", name, labName, resourceGroup) + return nil + } + + return fmt.Errorf("Error retrieving DevTest Windows Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + future, err := client.Delete(ctx, resourceGroup, labName, name) + if err != nil { + return fmt.Errorf("Error deleting DevTest Windows Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting for the deletion of DevTest Windows Virtual Machine %q (Lab %q / Resource Group %q): %+v", name, labName, resourceGroup, err) + } + + return err +} diff --git a/azurerm/resource_arm_dev_test_windows_virtual_machine_test.go b/azurerm/resource_arm_dev_test_windows_virtual_machine_test.go new file mode 100644 index 000000000000..0f3170f9bb80 --- /dev/null +++ b/azurerm/resource_arm_dev_test_windows_virtual_machine_test.go @@ -0,0 +1,291 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMDevTestVirtualMachine_basic(t *testing.T) { + resourceName := "azurerm_dev_test_windows_virtual_machine.test" + rInt := acctest.RandIntRange(11111, 99999) + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestWindowsVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevTestWindowsVirtualMachine_basic(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestWindowsVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "gallery_image_reference.0.publisher", "MicrosoftWindowsServer"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // not returned from the API + "lab_subnet_name", + "lab_virtual_network_id", + "password", + }, + }, + }, + }) +} + +func TestAccAzureRMDevTestWindowsVirtualMachine_inboundNatRules(t *testing.T) { + resourceName := "azurerm_dev_test_windows_virtual_machine.test" + rInt := acctest.RandIntRange(11111, 99999) + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestWindowsVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevTestWindowsVirtualMachine_inboundNatRules(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestWindowsVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "disallow_public_ip_address", "true"), + resource.TestCheckResourceAttr(resourceName, "gallery_image_reference.0.publisher", "MicrosoftWindowsServer"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Acceptance", "Test"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + // not returned from the API + "inbound_nat_rule", + "lab_subnet_name", + "lab_virtual_network_id", + "password", + }, + }, + }, + }) +} + +func TestAccAzureRMDevTestWindowsVirtualMachine_updateStorage(t *testing.T) { + resourceName := "azurerm_dev_test_windows_virtual_machine.test" + rInt := acctest.RandIntRange(11111, 99999) + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestWindowsVirtualMachineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevTestWindowsVirtualMachine_storage(rInt, location, "Standard"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestWindowsVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "gallery_image_reference.0.publisher", "MicrosoftWindowsServer"), + resource.TestCheckResourceAttr(resourceName, "storage_type", "Standard"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + Config: testAccAzureRMDevTestWindowsVirtualMachine_storage(rInt, location, "Premium"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestWindowsVirtualMachineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "gallery_image_reference.0.publisher", "MicrosoftWindowsServer"), + resource.TestCheckResourceAttr(resourceName, "storage_type", "Premium"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + }, + }) +} + +func testCheckAzureRMDevTestWindowsVirtualMachineExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + virtualMachineName := rs.Primary.Attributes["name"] + labName := rs.Primary.Attributes["lab_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + conn := testAccProvider.Meta().(*ArmClient).devTestVirtualMachinesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resourceGroup, labName, virtualMachineName, "") + if err != nil { + return fmt.Errorf("Bad: Get devTestVirtualMachinesClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: DevTest Windows Virtual Machine %q (Lab %q / Resource Group: %q) does not exist", virtualMachineName, labName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDevTestWindowsVirtualMachineDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).devTestVirtualMachinesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_dev_test_windows_virtual_machine" { + continue + } + + virtualMachineName := rs.Primary.Attributes["name"] + labName := rs.Primary.Attributes["lab_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, labName, virtualMachineName, "") + + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return nil + } + + return err + } + + return fmt.Errorf("DevTest Windows Virtual Machine still exists:\n%#v", resp) + } + + return nil +} + +func testAccAzureRMDevTestWindowsVirtualMachine_basic(rInt int, location string) string { + template := testAccAzureRMDevTestWindowsVirtualMachine_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_dev_test_windows_virtual_machine" "test" { + name = "acctestvm%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + size = "Standard_F2" + username = "acct5stU5er" + password = "Pa$$w0rd1234!" + lab_virtual_network_id = "${azurerm_dev_test_virtual_network.test.id}" + lab_subnet_name = "${azurerm_dev_test_virtual_network.test.subnet.0.name}" + storage_type = "Standard" + + gallery_image_reference { + offer = "WindowsServer" + publisher = "MicrosoftWindowsServer" + sku = "2012-Datacenter" + version = "latest" + } +} +`, template, rInt) +} + +func testAccAzureRMDevTestWindowsVirtualMachine_inboundNatRules(rInt int, location string) string { + template := testAccAzureRMDevTestWindowsVirtualMachine_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_dev_test_windows_virtual_machine" "test" { + name = "acctestvm%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + size = "Standard_F2" + username = "acct5stU5er" + password = "Pa$$w0rd1234!" + disallow_public_ip_address = true + lab_virtual_network_id = "${azurerm_dev_test_virtual_network.test.id}" + lab_subnet_name = "${azurerm_dev_test_virtual_network.test.subnet.0.name}" + storage_type = "Standard" + + gallery_image_reference { + offer = "WindowsServer" + publisher = "MicrosoftWindowsServer" + sku = "2012-Datacenter" + version = "latest" + } + + inbound_nat_rule { + protocol = "Tcp" + backend_port = 22 + } + + inbound_nat_rule { + protocol = "Tcp" + backend_port = 3389 + } + + tags { + "Acceptance" = "Test" + } +} +`, template, rInt) +} + +func testAccAzureRMDevTestWindowsVirtualMachine_storage(rInt int, location, storageType string) string { + template := testAccAzureRMDevTestWindowsVirtualMachine_template(rInt, location) + return fmt.Sprintf(` +%s + +resource "azurerm_dev_test_windows_virtual_machine" "test" { + name = "acctestvm%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + size = "Standard_B1ms" + username = "acct5stU5er" + password = "Pa$$w0rd1234!" + lab_virtual_network_id = "${azurerm_dev_test_virtual_network.test.id}" + lab_subnet_name = "${azurerm_dev_test_virtual_network.test.subnet.0.name}" + storage_type = "%s" + + gallery_image_reference { + offer = "WindowsServer" + publisher = "MicrosoftWindowsServer" + sku = "2012-Datacenter" + version = "latest" + } +} +`, template, rInt, storageType) +} + +func testAccAzureRMDevTestWindowsVirtualMachine_template(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_dev_test_lab" "test" { + name = "acctestdtl%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_dev_test_virtual_network" "test" { + name = "acctestdtvn%d" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + + subnet { + use_public_ip_address = "Allow" + use_in_virtual_machine_creation = "Allow" + } +} +`, rInt, location, rInt, rInt) +} diff --git a/website/azurerm.erb b/website/azurerm.erb index 01bcc347ec48..dc197c730ab7 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -553,10 +553,18 @@ azurerm_dev_test_lab + > + azurerm_dev_test_linux_virtual_machine + + > azurerm_dev_test_virtual_network + > + azurerm_dev_test_windows_virtual_machine + + diff --git a/website/docs/r/dev_test_linux_virtual_machine.html.markdown b/website/docs/r/dev_test_linux_virtual_machine.html.markdown new file mode 100644 index 000000000000..a0d05f773cc6 --- /dev/null +++ b/website/docs/r/dev_test_linux_virtual_machine.html.markdown @@ -0,0 +1,156 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_dev_test_linux_virtual_machine" +sidebar_current: "docs-azurerm-resource-dev-test-linux-virtual-machine" +description: |- + Manages a Linux Virtual Machine within a Dev Test Lab. +--- + +# azurerm_dev_test_linux_virtual_machine + +Manages a Linux Virtual Machine within a Dev Test Lab. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West US" +} + +resource "azurerm_dev_test_lab" "test" { + name = "example-devtestlab" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags { + "Sydney" = "Australia" + } +} + + +resource "azurerm_dev_test_virtual_network" "test" { + name = "example-network" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + subnet { + use_public_ip_address = "Allow" + use_in_virtual_machine_creation = "Allow" + } +} + +resource "azurerm_dev_test_linux_virtual_machine" "test" { + name = "example-vm03" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + size = "Standard_DS2" + username = "exampleuser99" + ssh_key = "${file("~/.ssh/id_rsa.pub")}" + lab_virtual_network_id = "${azurerm_dev_test_virtual_network.test.id}" + lab_subnet_name = "${azurerm_dev_test_virtual_network.test.subnet.0.name}" + storage_type = "Premium" + notes = "Some notes about this Virtual Machine." + + gallery_image_reference { + offer = "UbuntuServer" + publisher = "Canonical" + sku = "18.04-LTS" + version = "latest" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Dev Test Machine. Changing this forces a new resource to be created. + +-> **NOTE:** The validation requirements for the Name change based on the `os_type` used in this Virtual Machine. For a Linux VM the name must be between 1-62 characters, and for a Windows VM the name must be between 1-15 characters. It must begin and end with a letter or number, and cannot be all numbers. + +* `lab_name` - (Required) Specifies the name of the Dev Test Lab in which the Virtual Machine should be created. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the Dev Test Lab resource exists. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the Dev Test Lab exists. Changing this forces a new resource to be created. + +* `gallery_image_reference` - (Required) A `gallery_image_reference` block as defined below. + +* `lab_subnet_name` - (Required) The name of a Subnet within the Dev Test Virtual Network where this machine should exist. Changing this forces a new resource to be created. + +* `lab_virtual_network_id` - (Required) The ID of the Dev Test Virtual Network where this Virtual Machine should be created. Changing this forces a new resource to be created. + +* `size` - (Required) The Machine Size to use for this Virtual Machine, such as `Standard_F2`. Changing this forces a new resource to be created. + +* `storage_type` - (Required) The type of Storage to use on this Virtual Machine. Possible values are `Standard` and `Premium`. + +* `username` - (Required) The Username associated with the local administrator on this Virtual Machine. Changing this forces a new resource to be created. + +--- + +* `allow_claim` - (Optional) Can this Virtual Machine be claimed by users? Defaults to `true`. + +* `disallow_public_ip_address` - (Optional) Should the Virtual Machine be created without a Public IP Address? Changing this forces a new resource to be created. + +* `inbound_nat_rule` - (Optional) One or more `inbound_nat_rule` blocks as defined below. Changing this forces a new resource to be created. + +-> **NOTE:** If any `inbound_nat_rule` blocks are specified then `disallow_public_ip_address` must be set to `true`. + +* `notes` - (Optional) Any notes about the Virtual Machine. + +* `password` - (Optional) The Password associated with the `username` used to login to this Virtual Machine. Changing this forces a new resource to be created. + +* `ssh_key` - (Optional) The SSH Key associated with the `username` used to login to this Virtual Machine. Changing this forces a new resource to be created. + +-> **NOTE:** One or either `password` or `ssh_key` must be specified. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +--- + +A `gallery_image_reference` block supports the following: + +* `offer` - (Required) The Offer of the Gallery Image. Changing this forces a new resource to be created. + +* `publisher` - (Required) The Publisher of the Gallery Image. Changing this forces a new resource to be created. + +* `sku` - (Required) The SKU of the Gallery Image. Changing this forces a new resource to be created. + +* `version` - (Required) The Version of the Gallery Image. Changing this forces a new resource to be created. + +--- + +A `inbound_nat_rule` block supports the following: + +* `protocol` - (Required) The Protocol used for this NAT Rule. Possible values are `Tcp` and `Udp`. Changing this forces a new resource to be created. + +* `backend_port` - (Required) The Backend Port associated with this NAT Rule. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Virtual Machine. + +* `fqdn` - The FQDN of the Virtual Machine. + +* `inbound_nat_rule` - One or more `inbound_nat_rule` blocks as defined below. + +* `unique_identifier` - The unique immutable identifier of the Virtual Machine. + +--- + +A `inbound_nat_rule` block exports the following: + +* `frontend_port` - The frontend port associated with this Inbound NAT Rule. + +## Import + +Dev Test Linux Virtual Machines can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_dev_test_linux_virtual_machine.machine1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.DevTestLab/labs/lab1/virtualmachines/machine1 +``` diff --git a/website/docs/r/dev_test_virtual_network.html.markdown b/website/docs/r/dev_test_virtual_network.html.markdown index 632e6accf3b8..0c732df3ed7e 100644 --- a/website/docs/r/dev_test_virtual_network.html.markdown +++ b/website/docs/r/dev_test_virtual_network.html.markdown @@ -34,6 +34,11 @@ resource "azurerm_dev_test_virtual_network" "test" { lab_name = "${azurerm_dev_test_lab.test.name}" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" + + subnet { + use_public_ip_address = "Allow" + use_in_virtual_machine_creation = "Allow" + } } ``` @@ -41,7 +46,7 @@ resource "azurerm_dev_test_virtual_network" "test" { The following arguments are supported: -* `name` - (Required) Specifies the name of the Dev Test Lab. Changing this forces a new resource to be created. +* `name` - (Required) Specifies the name of the Dev Test Virtual Network. Changing this forces a new resource to be created. * `lab_name` - (Required) Specifies the name of the Dev Test Lab in which the Virtual Network should be created. Changing this forces a new resource to be created. diff --git a/website/docs/r/dev_test_windows_virtual_machine.html.markdown b/website/docs/r/dev_test_windows_virtual_machine.html.markdown new file mode 100644 index 000000000000..48fce2eaa75c --- /dev/null +++ b/website/docs/r/dev_test_windows_virtual_machine.html.markdown @@ -0,0 +1,151 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_dev_test_windows_virtual_machine" +sidebar_current: "docs-azurerm-resource-dev-test-windows-virtual-machine" +description: |- + Manages a Windows Virtual Machine within a Dev Test Lab. +--- + +# azurerm_dev_test_windows_virtual_machine + +Manages a Windows Virtual Machine within a Dev Test Lab. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West US" +} + +resource "azurerm_dev_test_lab" "test" { + name = "example-devtestlab" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags { + "Sydney" = "Australia" + } +} + +resource "azurerm_dev_test_virtual_network" "test" { + name = "example-network" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + subnet { + use_public_ip_address = "Allow" + use_in_virtual_machine_creation = "Allow" + } +} + +resource "azurerm_dev_test_windows_virtual_machine" "test" { + name = "example-vm03" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + size = "Standard_DS2" + username = "exampleuser99" + password = "Pa$$w0rd1234!" + lab_virtual_network_id = "${azurerm_dev_test_virtual_network.test.id}" + lab_subnet_name = "${azurerm_dev_test_virtual_network.test.subnet.0.name}" + storage_type = "Premium" + notes = "Some notes about this Virtual Machine." + + gallery_image_reference { + offer = "UbuntuServer" + publisher = "Canonical" + sku = "18.04-LTS" + version = "latest" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Dev Test Machine. Changing this forces a new resource to be created. + +-> **NOTE:** The validation requirements for the Name change based on the `os_type` used in this Virtual Machine. For a Linux VM the name must be between 1-62 characters, and for a Windows VM the name must be between 1-15 characters. It must begin and end with a letter or number, and cannot be all numbers. + +* `lab_name` - (Required) Specifies the name of the Dev Test Lab in which the Virtual Machine should be created. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the Dev Test Lab resource exists. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the Dev Test Lab exists. Changing this forces a new resource to be created. + +* `gallery_image_reference` - (Required) A `gallery_image_reference` block as defined below. + +* `lab_subnet_name` - (Required) The name of a Subnet within the Dev Test Virtual Network where this machine should exist. Changing this forces a new resource to be created. + +* `lab_virtual_network_id` - (Required) The ID of the Dev Test Virtual Network where this Virtual Machine should be created. Changing this forces a new resource to be created. + +* `password` - (Required) The Password associated with the `username` used to login to this Virtual Machine. Changing this forces a new resource to be created. + +* `size` - (Required) The Machine Size to use for this Virtual Machine, such as `Standard_F2`. Changing this forces a new resource to be created. + +* `storage_type` - (Required) The type of Storage to use on this Virtual Machine. Possible values are `Standard` and `Premium`. + +* `username` - (Required) The Username associated with the local administrator on this Virtual Machine. Changing this forces a new resource to be created. + +--- + +* `allow_claim` - (Optional) Can this Virtual Machine be claimed by users? Defaults to `true`. + +* `disallow_public_ip_address` - (Optional) Should the Virtual Machine be created without a Public IP Address? Changing this forces a new resource to be created. + +* `inbound_nat_rule` - (Optional) One or more `inbound_nat_rule` blocks as defined below. Changing this forces a new resource to be created. + +-> **NOTE:** If any `inbound_nat_rule` blocks are specified then `disallow_public_ip_address` must be set to `true`. + +* `notes` - (Optional) Any notes about the Virtual Machine. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +--- + +A `gallery_image_reference` block supports the following: + +* `offer` - (Required) The Offer of the Gallery Image. Changing this forces a new resource to be created. + +* `publisher` - (Required) The Publisher of the Gallery Image. Changing this forces a new resource to be created. + +* `sku` - (Required) The SKU of the Gallery Image. Changing this forces a new resource to be created. + +* `version` - (Required) The Version of the Gallery Image. Changing this forces a new resource to be created. + +--- + +A `inbound_nat_rule` block supports the following: + +* `protocol` - (Required) The Protocol used for this NAT Rule. Possible values are `Tcp` and `Udp`. Changing this forces a new resource to be created. + +* `backend_port` - (Required) The Backend Port associated with this NAT Rule. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Virtual Machine. + +* `fqdn` - The FQDN of the Virtual Machine. + +* `inbound_nat_rule` - One or more `inbound_nat_rule` blocks as defined below. + +* `unique_identifier` - The unique immutable identifier of the Virtual Machine. + +--- + +A `inbound_nat_rule` block exports the following: + +* `frontend_port` - The frontend port associated with this Inbound NAT Rule. + +## Import + +Dev Test Windows Virtual Machines can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_dev_test_windows_virtual_machine.machine1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.DevTestLab/labs/lab1/virtualmachines/machine1 +``` From 80d23ee139750c8d0315c49a14f27ef04e7293ac Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 12 Oct 2018 12:22:42 -1000 Subject: [PATCH 16/35] Updating to include #2058 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85308644a6e0..e6fd4e7cab0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ FEATURES: * **New Resource:** `azurerm_api_management` [GH-1516] * **New Resource:** `azurerm_cognitive_account` [GH-962] * **New Resource:** `azurerm_databricks_workspace` [GH-1134] +* **New Resource:** `azurerm_dev_test_linux_virtual_machine` [GH-2058] +* **New Resource:** `azurerm_dev_test_windows_virtual_machine` [GH-2058] BUG FIXES: From cb09837f6678ed72a7673452d36ca68eecbd38ca Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 12 Oct 2018 12:40:08 -1000 Subject: [PATCH 17/35] New Resource: `azurerm_dev_test_policy` (#2070) * New Resource: `azurerm_dev_test_policy` * Updating to match the changes in master / adding `description` to the test --- azurerm/config.go | 5 + azurerm/provider.go | 3 +- azurerm/resource_arm_dev_test_policy.go | 208 +++++++++++++++++++ azurerm/resource_arm_dev_test_policy_test.go | 176 ++++++++++++++++ website/azurerm.erb | 4 + website/docs/r/dev_test_policy.html.markdown | 83 ++++++++ 6 files changed, 478 insertions(+), 1 deletion(-) create mode 100644 azurerm/resource_arm_dev_test_policy.go create mode 100644 azurerm/resource_arm_dev_test_policy_test.go create mode 100644 website/docs/r/dev_test_policy.html.markdown diff --git a/azurerm/config.go b/azurerm/config.go index 84b14691ba7a..7a7fcc307bec 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -154,6 +154,7 @@ type ArmClient struct { // DevTestLabs devTestLabsClient dtl.LabsClient + devTestPoliciesClient dtl.PoliciesClient devTestVirtualMachinesClient dtl.VirtualMachinesClient devTestVirtualNetworksClient dtl.VirtualNetworksClient @@ -774,6 +775,10 @@ func (c *ArmClient) registerDevTestClients(endpoint, subscriptionId string, auth c.configureClient(&labsClient.Client, auth) c.devTestLabsClient = labsClient + devTestPoliciesClient := dtl.NewPoliciesClientWithBaseURI(endpoint, subscriptionId) + c.configureClient(&devTestPoliciesClient.Client, auth) + c.devTestPoliciesClient = devTestPoliciesClient + devTestVirtualMachinesClient := dtl.NewVirtualMachinesClientWithBaseURI(endpoint, subscriptionId) c.configureClient(&devTestVirtualMachinesClient.Client, auth) c.devTestVirtualMachinesClient = devTestVirtualMachinesClient diff --git a/azurerm/provider.go b/azurerm/provider.go index 1444b21e3360..52be61c14dd4 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -161,9 +161,10 @@ func Provider() terraform.ResourceProvider { "azurerm_data_lake_store_file": resourceArmDataLakeStoreFile(), "azurerm_data_lake_store_firewall_rule": resourceArmDataLakeStoreFirewallRule(), "azurerm_dev_test_lab": resourceArmDevTestLab(), + "azurerm_dev_test_policy": resourceArmDevTestPolicy(), "azurerm_dev_test_linux_virtual_machine": resourceArmDevTestLinuxVirtualMachine(), - "azurerm_dev_test_windows_virtual_machine": resourceArmDevTestWindowsVirtualMachine(), "azurerm_dev_test_virtual_network": resourceArmDevTestVirtualNetwork(), + "azurerm_dev_test_windows_virtual_machine": resourceArmDevTestWindowsVirtualMachine(), "azurerm_dns_a_record": resourceArmDnsARecord(), "azurerm_dns_aaaa_record": resourceArmDnsAAAARecord(), "azurerm_dns_caa_record": resourceArmDnsCaaRecord(), diff --git a/azurerm/resource_arm_dev_test_policy.go b/azurerm/resource_arm_dev_test_policy.go new file mode 100644 index 000000000000..4c21ae419e20 --- /dev/null +++ b/azurerm/resource_arm_dev_test_policy.go @@ -0,0 +1,208 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDevTestPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDevTestPolicyCreateUpdate, + Read: resourceArmDevTestPolicyRead, + Update: resourceArmDevTestPolicyCreateUpdate, + Delete: resourceArmDevTestPolicyDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(dtl.PolicyFactNameGalleryImage), + string(dtl.PolicyFactNameLabPremiumVMCount), + string(dtl.PolicyFactNameLabTargetCost), + string(dtl.PolicyFactNameLabVMCount), + string(dtl.PolicyFactNameLabVMSize), + string(dtl.PolicyFactNameUserOwnedLabPremiumVMCount), + string(dtl.PolicyFactNameUserOwnedLabVMCount), + string(dtl.PolicyFactNameUserOwnedLabVMCountInSubnet), + }, false), + }, + + "policy_set_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "lab_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.DevTestLabName(), + }, + + // There's a bug in the Azure API where this is returned in lower-case + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3964 + "resource_group_name": resourceGroupNameDiffSuppressSchema(), + + "threshold": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + + "evaluator_type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(dtl.AllowedValuesPolicy), + string(dtl.MaxValuePolicy), + }, false), + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "fact_data": { + Type: schema.TypeString, + Optional: true, + }, + + "tags": tagsSchema(), + }, + } +} + +func resourceArmDevTestPolicyCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestPoliciesClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for DevTest Policy creation") + + name := d.Get("name").(string) + policySetName := d.Get("policy_set_name").(string) + labName := d.Get("lab_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + factData := d.Get("fact_data").(string) + threshold := d.Get("threshold").(string) + evaluatorType := d.Get("evaluator_type").(string) + + description := d.Get("description").(string) + tags := d.Get("tags").(map[string]interface{}) + + parameters := dtl.Policy{ + Tags: expandTags(tags), + PolicyProperties: &dtl.PolicyProperties{ + FactName: dtl.PolicyFactName(name), + FactData: utils.String(factData), + Description: utils.String(description), + EvaluatorType: dtl.PolicyEvaluatorType(evaluatorType), + Threshold: utils.String(threshold), + }, + } + + _, err := client.CreateOrUpdate(ctx, resourceGroup, labName, policySetName, name, parameters) + if err != nil { + return fmt.Errorf("Error creating/updating DevTest Policy %q (Policy Set %q / Lab %q / Resource Group %q): %+v", name, policySetName, labName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, labName, policySetName, name, "") + if err != nil { + return fmt.Errorf("Error retrieving DevTest Policy %q (Policy Set %q / Lab %q / Resource Group %q): %+v", name, policySetName, labName, resourceGroup, err) + } + + if read.ID == nil { + return fmt.Errorf("Cannot read DevTest Policy %q (Policy Set %q / Lab %q / Resource Group %q) ID", name, policySetName, labName, resourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmDevTestPolicyRead(d, meta) +} + +func resourceArmDevTestPolicyRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestPoliciesClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + labName := id.Path["labs"] + policySetName := id.Path["policysets"] + name := id.Path["policies"] + + read, err := client.Get(ctx, resourceGroup, labName, policySetName, name, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + log.Printf("[DEBUG] DevTest Policy %q was not found in Policy Set %q / Lab %q / Resource Group %q - removing from state!", name, policySetName, labName, resourceGroup) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on DevTest Policy %q (Policy Set %q / Lab %q / Resource Group %q): %+v", name, policySetName, labName, resourceGroup, err) + } + + d.Set("name", read.Name) + d.Set("policy_set_name", policySetName) + d.Set("lab_name", labName) + d.Set("resource_group_name", resourceGroup) + + if props := read.PolicyProperties; props != nil { + d.Set("description", props.Description) + d.Set("fact_data", props.FactData) + d.Set("evaluator_type", string(props.EvaluatorType)) + d.Set("threshold", props.Threshold) + } + + flattenAndSetTags(d, read.Tags) + + return nil +} + +func resourceArmDevTestPolicyDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).devTestPoliciesClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + labName := id.Path["labs"] + policySetName := id.Path["policysets"] + name := id.Path["policies"] + + read, err := client.Get(ctx, resourceGroup, policySetName, labName, name, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + // deleted outside of TF + log.Printf("[DEBUG] DevTest Policy %q was not found in Policy Set %q / Lab %q / Resource Group %q - assuming removed!", name, policySetName, labName, resourceGroup) + return nil + } + + return fmt.Errorf("Error retrieving DevTest Policy %q (Policy Set %q / Lab %q / Resource Group %q): %+v", name, policySetName, labName, resourceGroup, err) + } + + _, err = client.Delete(ctx, resourceGroup, labName, policySetName, name) + if err != nil { + return fmt.Errorf("Error deleting DevTest Policy %q (Policy Set %q / Lab %q / Resource Group %q): %+v", name, policySetName, labName, resourceGroup, err) + } + + return err +} diff --git a/azurerm/resource_arm_dev_test_policy_test.go b/azurerm/resource_arm_dev_test_policy_test.go new file mode 100644 index 000000000000..269c71dd41d7 --- /dev/null +++ b/azurerm/resource_arm_dev_test_policy_test.go @@ -0,0 +1,176 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMDevTestPolicy_basic(t *testing.T) { + resourceName := "azurerm_dev_test_policy.test" + rInt := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevTestPolicy_basic(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestPolicyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMDevTestPolicy_complete(t *testing.T) { + resourceName := "azurerm_dev_test_policy.test" + rInt := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDevTestPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevTestPolicy_complete(rInt, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevTestPolicyExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Acceptance", "Test"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMDevTestPolicyExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + policyName := rs.Primary.Attributes["name"] + policySetName := rs.Primary.Attributes["policy_set_name"] + labName := rs.Primary.Attributes["lab_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + conn := testAccProvider.Meta().(*ArmClient).devTestPoliciesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resourceGroup, labName, policySetName, policyName, "") + if err != nil { + return fmt.Errorf("Bad: Get devTestPoliciesClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: DevTest Policy %q (Policy Set %q / Lab %q / Resource Group: %q) does not exist", policyName, policySetName, labName, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMDevTestPolicyDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).devTestPoliciesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_dev_test_policy" { + continue + } + + policyName := rs.Primary.Attributes["name"] + policySetName := rs.Primary.Attributes["policy_set_name"] + labName := rs.Primary.Attributes["lab_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, labName, policySetName, policyName, "") + + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return nil + } + + return err + } + + return fmt.Errorf("DevTest Policy still exists:\n%#v", resp) + } + + return nil +} + +func testAccAzureRMDevTestPolicy_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_dev_test_lab" "test" { + name = "acctestdtl%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_dev_test_policy" "test" { + name = "LabVmCount" + policy_set_name = "default" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + threshold = "999" + evaluator_type = "MaxValuePolicy" +} +`, rInt, location, rInt) +} + +func testAccAzureRMDevTestPolicy_complete(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_dev_test_lab" "test" { + name = "acctestdtl%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_dev_test_policy" "test" { + name = "LabVmCount" + policy_set_name = "default" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + threshold = "999" + evaluator_type = "MaxValuePolicy" + description = "Aloha this is the max number of VM's'" + + tags { + "Acceptance" = "Test" + } +} +`, rInt, location, rInt) +} diff --git a/website/azurerm.erb b/website/azurerm.erb index dc197c730ab7..b20146a23970 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -557,6 +557,10 @@ azurerm_dev_test_linux_virtual_machine + > + azurerm_dev_test_policy + + > azurerm_dev_test_virtual_network diff --git a/website/docs/r/dev_test_policy.html.markdown b/website/docs/r/dev_test_policy.html.markdown new file mode 100644 index 000000000000..71a540512d91 --- /dev/null +++ b/website/docs/r/dev_test_policy.html.markdown @@ -0,0 +1,83 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_dev_test_policy" +sidebar_current: "docs-azurerm-resource-dev-test-policy" +description: |- + Manages a Policy within a Dev Test Policy Set. +--- + +# azurerm_dev_test_policy + +Manages a Policy within a Dev Test Policy Set. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West US" +} + +resource "azurerm_dev_test_lab" "test" { + name = "example-devtestlab" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + tags { + "Sydney" = "Australia" + } +} + + +resource "azurerm_dev_test_policy" "test" { + name = "LabVmCount" + policy_set_name = "default" + lab_name = "${azurerm_dev_test_lab.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + fact_data = "" + threshold = "999" + evaluator_type = "MaxValuePolicy" + + tags { + "Acceptance" = "Test" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Dev Test Policy. Possible values are `GalleryImage`, `LabPremiumVmCount`, `LabTargetCost`, `LabVmCount`, `LabVmSize`, `UserOwnedLabPremiumVmCount`, `UserOwnedLabVmCount` and `UserOwnedLabVmCountInSubnet`. Changing this forces a new resource to be created. + +* `policy_set_name` - (Required) Specifies the name of the Policy Set within the Dev Test Lab where this policy should be created. Changing this forces a new resource to be created. + +* `lab_name` - (Required) Specifies the name of the Dev Test Lab in which the Policy should be created. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the Dev Test Lab resource exists. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the Dev Test Lab exists. Changing this forces a new resource to be created. + +* `description` - (Optional) A description for the Policy. + +* `evaluator_type` - (Required) The Evaluation Type used for this Policy. Possible values include: 'AllowedValuesPolicy', 'MaxValuePolicy'. Changing this forces a new resource to be created. + +* `threshold` - (Required) The Threshold for this Policy. + +* `fact_data` - (Optional) The Fact Data for this Policy. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Dev Test Policy. + +## Import + +Dev Test Policies can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_dev_test_policy.policy1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.DevTestLab/labs/lab1/policysets/default/policies/policy1 +``` From 44441c86820f1b58bdc654358dee7ae660bce7d1 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 12 Oct 2018 12:40:32 -1000 Subject: [PATCH 18/35] Updating to include #2070 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6fd4e7cab0b..ff2754739ee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ FEATURES: * **New Resource:** `azurerm_api_management` [GH-1516] * **New Resource:** `azurerm_cognitive_account` [GH-962] * **New Resource:** `azurerm_databricks_workspace` [GH-1134] +* **New Resource:** `azurerm_dev_test_policy` [GH-2070] * **New Resource:** `azurerm_dev_test_linux_virtual_machine` [GH-2058] * **New Resource:** `azurerm_dev_test_windows_virtual_machine` [GH-2058] From 1ee95b2ede8ee76d8e660b4bdb2a2021fa48fda3 Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 12 Oct 2018 19:03:17 -0700 Subject: [PATCH 19/35] Address PR #2043 comments --- azurerm/provider.go | 2 +- ...m_security_center_subscription_pricing.go} | 29 ++++++++++--------- ...urity_center_subscription_pricing_test.go} | 4 +-- website/azurerm.erb | 6 ++-- website/docs/r/search_service.html.markdown | 2 +- ...rity_center_subscription_pricing.markdown} | 14 +++++---- 6 files changed, 30 insertions(+), 27 deletions(-) rename azurerm/{resource_arm_securitycenter_subscription_pricing.go => resource_arm_security_center_subscription_pricing.go} (73%) rename azurerm/{resource_arm_securitycenter_subscription_pricing_test.go => resource_arm_security_center_subscription_pricing_test.go} (94%) rename website/docs/r/{securitycenter_subscription_pricing.markdown => security_center_subscription_pricing.markdown} (60%) diff --git a/azurerm/provider.go b/azurerm/provider.go index e9488ae50e13..f776509c5f88 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -243,7 +243,7 @@ func Provider() terraform.ResourceProvider { "azurerm_route": resourceArmRoute(), "azurerm_route_table": resourceArmRouteTable(), "azurerm_search_service": resourceArmSearchService(), - "azurerm_securitycenter_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(), + "azurerm_security_center_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(), "azurerm_servicebus_namespace": resourceArmServiceBusNamespace(), "azurerm_servicebus_namespace_authorization_rule": resourceArmServiceBusNamespaceAuthorizationRule(), "azurerm_servicebus_queue": resourceArmServiceBusQueue(), diff --git a/azurerm/resource_arm_securitycenter_subscription_pricing.go b/azurerm/resource_arm_security_center_subscription_pricing.go similarity index 73% rename from azurerm/resource_arm_securitycenter_subscription_pricing.go rename to azurerm/resource_arm_security_center_subscription_pricing.go index 6899f3787dd6..ebe94b86e4f6 100644 --- a/azurerm/resource_arm_securitycenter_subscription_pricing.go +++ b/azurerm/resource_arm_security_center_subscription_pricing.go @@ -5,18 +5,20 @@ import ( "log" "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" - "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) +//NOTE: seems default is the only valid pricing name: +//Code="InvalidInputJson" Message="Pricing name 'kt's price' is not allowed. Expected 'default' for this scope." +const securityCenterConfigurationSubscriptionPricingName = "default" + func resourceArmSecurityCenterSubscriptionPricing() *schema.Resource { return &schema.Resource{ - Create: resourceArmSecurityCenterSubscriptionPricingCreateUpdate, + Create: resourceArmSecurityCenterSubscriptionPricingUpdate, Read: resourceArmSecurityCenterSubscriptionPricingRead, - Update: resourceArmSecurityCenterSubscriptionPricingCreateUpdate, + Update: resourceArmSecurityCenterSubscriptionPricingUpdate, Delete: resourceArmSecurityCenterSubscriptionPricingDelete, Importer: &schema.ResourceImporter{ @@ -25,9 +27,8 @@ func resourceArmSecurityCenterSubscriptionPricing() *schema.Resource { Schema: map[string]*schema.Schema{ "tier": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: suppress.CaseDifference, + Type: schema.TypeString, + Required: true, ValidateFunc: validation.StringInSlice([]string{ string(security.Free), string(security.Standard), @@ -37,9 +38,8 @@ func resourceArmSecurityCenterSubscriptionPricing() *schema.Resource { } } -//NOTE: seems default is the only valid pricing name: -//Code="InvalidInputJson" Message="Pricing name '360k Sponsored' is not allowed. Expected 'default' for this scope." -func resourceArmSecurityCenterSubscriptionPricingCreateUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceArmSecurityCenterSubscriptionPricingUpdate(d *schema.ResourceData, meta interface{}) error { + name := securityCenterConfigurationSubscriptionPricingName client := meta.(*ArmClient).securityCenterPricingClient ctx := meta.(*ArmClient).StopContext @@ -49,12 +49,12 @@ func resourceArmSecurityCenterSubscriptionPricingCreateUpdate(d *schema.Resource }, } - _, err := client.UpdateSubscriptionPricing(ctx, "default", pricing) + _, err := client.UpdateSubscriptionPricing(ctx, name, pricing) if err != nil { return fmt.Errorf("Error creating/updating Security Center Subscription pricing: %+v", err) } - resp, err := client.GetSubscriptionPricing(ctx, "default") + resp, err := client.GetSubscriptionPricing(ctx, name) if err != nil { return fmt.Errorf("Error reading Security Center Subscription pricing: %+v", err) } @@ -68,10 +68,11 @@ func resourceArmSecurityCenterSubscriptionPricingCreateUpdate(d *schema.Resource } func resourceArmSecurityCenterSubscriptionPricingRead(d *schema.ResourceData, meta interface{}) error { + name := securityCenterConfigurationSubscriptionPricingName client := meta.(*ArmClient).securityCenterPricingClient ctx := meta.(*ArmClient).StopContext - resp, err := client.GetSubscriptionPricing(ctx, "default") + resp, err := client.GetSubscriptionPricing(ctx, name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { log.Printf("[DEBUG] Security Center Subscription was not found: %v", err) @@ -90,5 +91,5 @@ func resourceArmSecurityCenterSubscriptionPricingRead(d *schema.ResourceData, me } func resourceArmSecurityCenterSubscriptionPricingDelete(_ *schema.ResourceData, _ interface{}) error { - return nil //cannot be deleted + return nil //cannot be deleted. } diff --git a/azurerm/resource_arm_securitycenter_subscription_pricing_test.go b/azurerm/resource_arm_security_center_subscription_pricing_test.go similarity index 94% rename from azurerm/resource_arm_securitycenter_subscription_pricing_test.go rename to azurerm/resource_arm_security_center_subscription_pricing_test.go index afd391519869..cc3504667fd3 100644 --- a/azurerm/resource_arm_securitycenter_subscription_pricing_test.go +++ b/azurerm/resource_arm_security_center_subscription_pricing_test.go @@ -10,7 +10,7 @@ import ( ) func TestAccAzureRMSecurityCenterSubscriptionPricing_update(t *testing.T) { - resourceName := "azurerm_securitycenter_subscription_pricing.test" + resourceName := "azurerm_security_center_subscription_pricing.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -71,7 +71,7 @@ func testCheckAzureRMSecurityCenterSubscriptionPricingExists(name string) resour func testAccAzureRMSecurityCenterSubscriptionPricing_tier(tier string) string { return fmt.Sprintf(` -resource "azurerm_securitycenter_subscription_pricing" "test" { +resource "azurerm_security_center_subscription_pricing" "test" { tier = "%s" } `, tier) diff --git a/website/azurerm.erb b/website/azurerm.erb index 1617539b25a7..583388b08495 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -973,11 +973,11 @@ - > + > Security Center Resources diff --git a/website/docs/r/search_service.html.markdown b/website/docs/r/search_service.html.markdown index 0cc2418edcee..220e57b94cef 100644 --- a/website/docs/r/search_service.html.markdown +++ b/website/docs/r/search_service.html.markdown @@ -8,7 +8,7 @@ description: |- # azurerm_search_service -Allows you to manage an Azure Search Service +Allows you to manage an Azure Search Service. ## Example Usage diff --git a/website/docs/r/securitycenter_subscription_pricing.markdown b/website/docs/r/security_center_subscription_pricing.markdown similarity index 60% rename from website/docs/r/securitycenter_subscription_pricing.markdown rename to website/docs/r/security_center_subscription_pricing.markdown index f55627c03eb6..e5f87402266b 100644 --- a/website/docs/r/securitycenter_subscription_pricing.markdown +++ b/website/docs/r/security_center_subscription_pricing.markdown @@ -1,19 +1,21 @@ --- layout: "azurerm" -page_title: "Azure Resource Manager: azurerm_securitycenter_subscription_pricing" -sidebar_current: "docs-azurerm-securitycenter-subscription-pricing" +page_title: "Azure Resource Manager: azurerm_security_center_subscription_pricing" +sidebar_current: "docs-azurerm-security-center-subscription-pricing" description: |- - Manages the subscription's Security Center pricing tier. + Manages the Pricing Tier for Azure Security Center in the current subscription. --- -# azurerm_securitycenter_subscription_pricing +# azurerm_security_center_subscription_pricing -Manages the subscription's Security Center pricing tier. +Manages the Pricing Tier for Azure Security Center in the current subscription. + +~> **NOTE:** Owner access permission is required. ## Example Usage ```hcl -resource "azurerm_securitycenter_subscription_pricing" "example" { +resource "azurerm_security_center_subscription_pricing" "example" { tier = "Standard" } ``` From 30f52c57ab28af37269bccba3b28bbe10313dfbf Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 12 Oct 2018 19:22:07 -0700 Subject: [PATCH 20/35] Address PR #2045 comments --- azurerm/provider.go | 2 +- ...> resource_arm_security_center_contact.go} | 38 +++++++++---------- ...ource_arm_security_center_contact_test.go} | 6 +-- website/azurerm.erb | 4 +- ...kdown => security_center_contact.markdown} | 6 +-- 5 files changed, 26 insertions(+), 30 deletions(-) rename azurerm/{resource_arm_securitycenter_contact.go => resource_arm_security_center_contact.go} (81%) rename azurerm/{resource_arm_securitycenter_contact_test.go => resource_arm_security_center_contact_test.go} (95%) rename website/docs/r/{securitycenter_contact.markdown => security_center_contact.markdown} (85%) diff --git a/azurerm/provider.go b/azurerm/provider.go index 71f2282f5625..3762c3377521 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -244,7 +244,7 @@ func Provider() terraform.ResourceProvider { "azurerm_route_table": resourceArmRouteTable(), "azurerm_search_service": resourceArmSearchService(), "azurerm_security_center_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(), - "azurerm_securitycenter_contact": resourceArmSecurityCenterContact(), + "azurerm_security_center_contact": resourceArmSecurityCenterContact(), "azurerm_servicebus_namespace": resourceArmServiceBusNamespace(), "azurerm_servicebus_namespace_authorization_rule": resourceArmServiceBusNamespaceAuthorizationRule(), "azurerm_servicebus_queue": resourceArmServiceBusQueue(), diff --git a/azurerm/resource_arm_securitycenter_contact.go b/azurerm/resource_arm_security_center_contact.go similarity index 81% rename from azurerm/resource_arm_securitycenter_contact.go rename to azurerm/resource_arm_security_center_contact.go index 092f7cd13ca7..656bcad9486c 100644 --- a/azurerm/resource_arm_securitycenter_contact.go +++ b/azurerm/resource_arm_security_center_contact.go @@ -2,21 +2,18 @@ package azurerm import ( "fmt" - "log" - "strings" - "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" - "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" + "log" ) //seems you can only set one contact: // Invalid security contact name was provided - only 'defaultX' is allowed where X is an index // Invalid security contact name 'default0' was provided. Expected 'default1' // Message="Invalid security contact name 'default2' was provided. Expected 'default1'" +const resourceArmSecurityCenterContactName = "default1" func resourceArmSecurityCenterContact() *schema.Resource { return &schema.Resource{ @@ -31,17 +28,15 @@ func resourceArmSecurityCenterContact() *schema.Resource { Schema: map[string]*schema.Schema{ "email": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: suppress.CaseDifference, - //todo validation + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, }, "phone": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: suppress.CaseDifference, - ValidateFunc: validation.NoZeroValues, + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, }, "alert_notifications": { @@ -61,6 +56,8 @@ func resourceArmSecurityCenterContactCreateUpdate(d *schema.ResourceData, meta i client := meta.(*ArmClient).securityCenterContactsClient ctx := meta.(*ArmClient).StopContext + name := resourceArmSecurityCenterContactName + contact := security.Contact{ ContactProperties: &security.ContactProperties{ Email: utils.String(d.Get("email").(string)), @@ -81,12 +78,12 @@ func resourceArmSecurityCenterContactCreateUpdate(d *schema.ResourceData, meta i } if d.IsNewResource() { - _, err := client.Create(ctx, "default1", contact) + _, err := client.Create(ctx, name, contact) if err != nil { return fmt.Errorf("Error creating Security Center Contact: %+v", err) } - resp, err := client.Get(ctx, "default1") + resp, err := client.Get(ctx, name) if err != nil { return fmt.Errorf("Error reading Security Center Contact: %+v", err) } @@ -96,7 +93,7 @@ func resourceArmSecurityCenterContactCreateUpdate(d *schema.ResourceData, meta i d.SetId(*resp.ID) } else { - _, err := client.Update(ctx, "default1", contact) + _, err := client.Update(ctx, name, contact) if err != nil { return fmt.Errorf("Error updating Security Center Contact: %+v", err) } @@ -109,10 +106,7 @@ func resourceArmSecurityCenterContactRead(d *schema.ResourceData, meta interface client := meta.(*ArmClient).securityCenterContactsClient ctx := meta.(*ArmClient).StopContext - //id is in format of `/subscriptions/20ff7fc3-e762-44dd-bd96-b71116dcdc23/providers/Microsoft.Security/securityContacts/john` - //parseAzureResourceID doesn't support id without a resource group - bits := strings.Split(d.Id(), "/") - name := bits[len(bits)-1] + name := resourceArmSecurityCenterContactName resp, err := client.Get(ctx, name) if err != nil { @@ -139,7 +133,9 @@ func resourceArmSecurityCenterContactDelete(_ *schema.ResourceData, meta interfa client := meta.(*ArmClient).securityCenterContactsClient ctx := meta.(*ArmClient).StopContext - resp, err := client.Delete(ctx, "default1") + name := resourceArmSecurityCenterContactName + + resp, err := client.Delete(ctx, name) if err != nil { if utils.ResponseWasNotFound(resp) { log.Printf("[DEBUG] Security Center Subscription Contact was not found: %v", err) diff --git a/azurerm/resource_arm_securitycenter_contact_test.go b/azurerm/resource_arm_security_center_contact_test.go similarity index 95% rename from azurerm/resource_arm_securitycenter_contact_test.go rename to azurerm/resource_arm_security_center_contact_test.go index cfba6f9eb705..72cac5b59c46 100644 --- a/azurerm/resource_arm_securitycenter_contact_test.go +++ b/azurerm/resource_arm_security_center_contact_test.go @@ -10,7 +10,7 @@ import ( ) func TestAccAzureRMSecurityCenterContact_basic(t *testing.T) { - resourceName := "azurerm_securitycenter_contact.test" + resourceName := "azurerm_security_center_contact.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -36,7 +36,7 @@ func TestAccAzureRMSecurityCenterContact_basic(t *testing.T) { } func TestAccAzureRMSecurityCenterContact_update(t *testing.T) { - resourceName := "azurerm_securitycenter_contact.test" + resourceName := "azurerm_security_center_contact.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -98,7 +98,7 @@ func testCheckAzureRMSecurityCenterContactExists(name string) resource.TestCheck func testAccAzureRMSecurityCenterContact_template(email, phone string, notifications, adminAlerts bool) string { return fmt.Sprintf(` -resource "azurerm_securitycenter_contact" "test" { +resource "azurerm_security_center_contact" "test" { email = "%s" phone = "%s" diff --git a/website/azurerm.erb b/website/azurerm.erb index 71c180e6968e..174617fa581c 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -981,8 +981,8 @@ diff --git a/website/docs/r/securitycenter_contact.markdown b/website/docs/r/security_center_contact.markdown similarity index 85% rename from website/docs/r/securitycenter_contact.markdown rename to website/docs/r/security_center_contact.markdown index d1cc93abb596..a7a3c081831a 100644 --- a/website/docs/r/securitycenter_contact.markdown +++ b/website/docs/r/security_center_contact.markdown @@ -1,7 +1,7 @@ --- layout: "azurerm" -page_title: "Azure Resource Manager: azurerm_securitycenter_contact" -sidebar_current: "docs-azurerm-securitycenter-contact" +page_title: "Azure Resource Manager: azurerm_security_center_contact" +sidebar_current: "docs-azurerm-security-center-contact" description: |- Manages the subscription's Security Center Contact. --- @@ -13,7 +13,7 @@ Manages the subscription's Security Center Contact. ## Example Usage ```hcl -resource "azurerm_securitycenter_contact" "example" { +resource "azurerm_security_center_contact" "example" { email = "contact@example.com" phone = "+1-555-555-5555" From 0ccb7103a41f57c84da380fbad79513a4fbc5e3f Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 12 Oct 2018 19:41:34 -0700 Subject: [PATCH 21/35] Update resource and add docs --- azurerm/provider.go | 2 +- ...resource_arm_security_center_workspace.go} | 105 +++++++----------- ...rce_arm_security_center_workspace_test.go} | 12 +- website/azurerm.erb | 9 +- .../docs/r/security_center_workspace.markdown | 53 +++++++++ 5 files changed, 107 insertions(+), 74 deletions(-) rename azurerm/{resource_arm_securitycenter_workspace.go => resource_arm_security_center_workspace.go} (58%) rename azurerm/{resource_arm_securitycenter_workspace_test.go => resource_arm_security_center_workspace_test.go} (92%) create mode 100644 website/docs/r/security_center_workspace.markdown diff --git a/azurerm/provider.go b/azurerm/provider.go index c5ad9ffeae35..f90807849760 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -245,7 +245,7 @@ func Provider() terraform.ResourceProvider { "azurerm_search_service": resourceArmSearchService(), "azurerm_security_center_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(), "azurerm_security_center_contact": resourceArmSecurityCenterContact(), - "azurerm_securitycenter_workspace": resourceArmSecurityCenterWorkspace(), + "azurerm_security_center_workspace": resourceArmSecurityCenterWorkspace(), "azurerm_servicebus_namespace": resourceArmServiceBusNamespace(), "azurerm_servicebus_namespace_authorization_rule": resourceArmServiceBusNamespaceAuthorizationRule(), "azurerm_servicebus_queue": resourceArmServiceBusQueue(), diff --git a/azurerm/resource_arm_securitycenter_workspace.go b/azurerm/resource_arm_security_center_workspace.go similarity index 58% rename from azurerm/resource_arm_securitycenter_workspace.go rename to azurerm/resource_arm_security_center_workspace.go index bb849d7ba725..f9253ec80121 100644 --- a/azurerm/resource_arm_securitycenter_workspace.go +++ b/azurerm/resource_arm_security_center_workspace.go @@ -7,7 +7,6 @@ import ( "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/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" "log" "time" @@ -15,6 +14,8 @@ import ( //only valid name is default // Message="Invalid workspace settings name 'kttest' , only default is allowed " +const resourceArmSecurityCenterWorkspaceName = "default" + func resourceArmSecurityCenterWorkspace() *schema.Resource { return &schema.Resource{ Create: resourceArmSecurityCenterWorkspaceCreateUpdate, @@ -28,17 +29,15 @@ func resourceArmSecurityCenterWorkspace() *schema.Resource { Schema: map[string]*schema.Schema{ "scope": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: suppress.CaseDifference, - ValidateFunc: validation.NoZeroValues, + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, }, "workspace_id": { - Type: schema.TypeString, - Required: true, - DiffSuppressFunc: suppress.CaseDifference, - ValidateFunc: azure.ValidateResourceID, + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, }, }, } @@ -48,6 +47,8 @@ func resourceArmSecurityCenterWorkspaceCreateUpdate(d *schema.ResourceData, meta client := meta.(*ArmClient).securityCenterWorkspaceClient ctx := meta.(*ArmClient).StopContext + name := resourceArmSecurityCenterWorkspaceName + contact := security.WorkspaceSetting{ WorkspaceSettingProperties: &security.WorkspaceSettingProperties{ Scope: utils.String(d.Get("scope").(string)), @@ -56,72 +57,46 @@ func resourceArmSecurityCenterWorkspaceCreateUpdate(d *schema.ResourceData, meta } if d.IsNewResource() { - _, err := client.Create(ctx, "default", contact) + _, err := client.Create(ctx, name, contact) if err != nil { return fmt.Errorf("Error creating 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, "default") - 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) - } - - d.SetId(*resp.(security.WorkspaceSetting).ID) - } else { - _, err := client.Update(ctx, "default", contact) + _, 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, "default") - if err != nil { - return resp, "Error", fmt.Errorf("Error reading 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 } + } - if properties := resp.WorkspaceSettingProperties; properties != nil { - if properties.WorkspaceID != nil && *properties.WorkspaceID != "" { - return resp, "Populated", nil - } - } + return resp, "Waiting", nil + }, + } - return resp, "Waiting", nil - }, - } + resp, err := stateConf.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting: %+v", err) + } - _, 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) @@ -131,7 +106,7 @@ func resourceArmSecurityCenterWorkspaceRead(d *schema.ResourceData, meta interfa client := meta.(*ArmClient).securityCenterWorkspaceClient ctx := meta.(*ArmClient).StopContext - resp, err := client.Get(ctx, "default") + 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) @@ -154,7 +129,7 @@ func resourceArmSecurityCenterWorkspaceDelete(_ *schema.ResourceData, meta inter client := meta.(*ArmClient).securityCenterWorkspaceClient ctx := meta.(*ArmClient).StopContext - resp, err := client.Delete(ctx, "default") + 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) diff --git a/azurerm/resource_arm_securitycenter_workspace_test.go b/azurerm/resource_arm_security_center_workspace_test.go similarity index 92% rename from azurerm/resource_arm_securitycenter_workspace_test.go rename to azurerm/resource_arm_security_center_workspace_test.go index acb5d108f71c..c6eadaa56e27 100644 --- a/azurerm/resource_arm_securitycenter_workspace_test.go +++ b/azurerm/resource_arm_security_center_workspace_test.go @@ -12,7 +12,7 @@ import ( ) func TestAccAzureRMSecurityCenterWorkspace_basic(t *testing.T) { - resourceName := "azurerm_securitycenter_workspace.test" + resourceName := "azurerm_security_center_workspace.test" ri := acctest.RandInt() scope := fmt.Sprintf("/subscriptions/%s", os.Getenv("ARM_SUBSCRIPTION_ID")) @@ -39,7 +39,7 @@ func TestAccAzureRMSecurityCenterWorkspace_basic(t *testing.T) { } func TestAccAzureRMSecurityCenterWorkspace_update(t *testing.T) { - resourceName := "azurerm_securitycenter_workspace.test" + resourceName := "azurerm_security_center_workspace.test" ri := acctest.RandInt() scope := fmt.Sprintf("/subscriptions/%s", os.Getenv("ARM_SUBSCRIPTION_ID")) @@ -101,11 +101,11 @@ func testCheckAzureRMSecurityCenterWorkspaceDestroy(s *terraform.State) error { ctx := testAccProvider.Meta().(*ArmClient).StopContext for _, res := range s.RootModule().Resources { - if res.Type != "azurerm_securitycenter_workspace" { + if res.Type != "azurerm_security_center_workspace" { continue } - resp, err := client.Get(ctx, "default") + resp, err := client.Get(ctx, resourceArmSecurityCenterWorkspaceName) if err != nil { if utils.ResponseWasNotFound(resp.Response) { return nil @@ -134,7 +134,7 @@ resource "azurerm_log_analytics_workspace" "test1" { sku = "PerGB2018" } -resource "azurerm_securitycenter_workspace" "test" { +resource "azurerm_security_center_workspace" "test" { scope = "%[3]s" workspace_id = "${azurerm_log_analytics_workspace.test1.id}" } @@ -155,7 +155,7 @@ resource "azurerm_log_analytics_workspace" "test2" { sku = "PerGB2018" } -resource "azurerm_securitycenter_workspace" "test" { +resource "azurerm_security_center_workspace" "test" { scope = "%[3]s" workspace_id = "${azurerm_log_analytics_workspace.test2.id}" } diff --git a/website/azurerm.erb b/website/azurerm.erb index 174617fa581c..47837f55cf12 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -981,8 +981,13 @@ + diff --git a/website/docs/r/security_center_workspace.markdown b/website/docs/r/security_center_workspace.markdown new file mode 100644 index 000000000000..f5f4c04a6a4c --- /dev/null +++ b/website/docs/r/security_center_workspace.markdown @@ -0,0 +1,53 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_security_center_workspace" +sidebar_current: "docs-azurerm-security-center-workspace" +description: |- + Manages the subscription's Security Center Workspace. +--- + +# azurerm_security_center_workspace + +Manages the subscription's Security Center Workspace. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "tfex-security-workspace" + location = "westus" +} + +resource "azurerm_log_analytics_workspace" "example" { + name = "tfex-security-workspace" + location = "${azurerm_resource_group.example.location}" + resource_group_name = "${azurerm_resource_group.example.name}" + sku = "PerGB2018" +} + +resource "azurerm_security_center_contact" "example" { + scope = "/subscriptions/00000000-0000-0000-0000-000000000000" + workspace_id = "${azurerm_log_analytics_workspace.example.id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `scope` - (Required) The scope of VMs to send their security data to the desired workspace, unless overridden by a setting with more specific scope. +* `workspace_id` - (Required) The resource ID of the log analytics workspace to save the data in. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Security Center Contact ID. + +## Import + +The contact can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_securitycenter_workspace.example /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Security/securityWorkspaces/default +``` From 61d3be3c5a4c0c31fec647529cbc7ea5d125642f Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 12 Oct 2018 19:50:43 -0700 Subject: [PATCH 22/35] Added checkDestroy function --- ...source_arm_security_center_contact_test.go | 29 ++++++++++++++++--- .../docs/r/security_center_contact.markdown | 2 +- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/azurerm/resource_arm_security_center_contact_test.go b/azurerm/resource_arm_security_center_contact_test.go index 72cac5b59c46..af008b4c1655 100644 --- a/azurerm/resource_arm_security_center_contact_test.go +++ b/azurerm/resource_arm_security_center_contact_test.go @@ -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("email1@example.com", "+1-555-555-5555", true, true), @@ -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("email1@example.com", "+1-555-555-5555", true, true), @@ -96,6 +98,25 @@ 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_security_center_contact" { + continue + } + resp, err := client.Get(ctx, resourceArmSecurityCenterContactName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + return err + } + return fmt.Errorf("security center contact still exists") + } + return nil +} + func testAccAzureRMSecurityCenterContact_template(email, phone string, notifications, adminAlerts bool) string { return fmt.Sprintf(` resource "azurerm_security_center_contact" "test" { diff --git a/website/docs/r/security_center_contact.markdown b/website/docs/r/security_center_contact.markdown index a7a3c081831a..3b9d883a855a 100644 --- a/website/docs/r/security_center_contact.markdown +++ b/website/docs/r/security_center_contact.markdown @@ -6,7 +6,7 @@ description: |- Manages the subscription's Security Center Contact. --- -# azurerm_securitycenter_contact +# azurerm_security_center_contact Manages the subscription's Security Center Contact. From 9029ed9470eb6c1569298bfc67e86987ae16c058 Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 12 Oct 2018 19:53:01 -0700 Subject: [PATCH 23/35] Simplified code a little --- .../resource_arm_security_center_subscription_pricing.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/azurerm/resource_arm_security_center_subscription_pricing.go b/azurerm/resource_arm_security_center_subscription_pricing.go index ebe94b86e4f6..20371983d0fd 100644 --- a/azurerm/resource_arm_security_center_subscription_pricing.go +++ b/azurerm/resource_arm_security_center_subscription_pricing.go @@ -39,10 +39,11 @@ func resourceArmSecurityCenterSubscriptionPricing() *schema.Resource { } func resourceArmSecurityCenterSubscriptionPricingUpdate(d *schema.ResourceData, meta interface{}) error { - name := securityCenterConfigurationSubscriptionPricingName client := meta.(*ArmClient).securityCenterPricingClient ctx := meta.(*ArmClient).StopContext + name := securityCenterConfigurationSubscriptionPricingName + pricing := security.Pricing{ PricingProperties: &security.PricingProperties{ PricingTier: security.PricingTier(d.Get("tier").(string)), @@ -68,11 +69,10 @@ func resourceArmSecurityCenterSubscriptionPricingUpdate(d *schema.ResourceData, } func resourceArmSecurityCenterSubscriptionPricingRead(d *schema.ResourceData, meta interface{}) error { - name := securityCenterConfigurationSubscriptionPricingName client := meta.(*ArmClient).securityCenterPricingClient ctx := meta.(*ArmClient).StopContext - resp, err := client.GetSubscriptionPricing(ctx, name) + resp, err := client.GetSubscriptionPricing(ctx, securityCenterConfigurationSubscriptionPricingName) if err != nil { if utils.ResponseWasNotFound(resp.Response) { log.Printf("[DEBUG] Security Center Subscription was not found: %v", err) From 4a4268b114032d6674b6a7c725fe8a8a0f410185 Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 12 Oct 2018 20:44:20 -0700 Subject: [PATCH 24/35] Address more PR #2043 comments --- .../resource_arm_security_center_subscription_pricing.go | 7 ++++--- .../docs/r/security_center_subscription_pricing.markdown | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/azurerm/resource_arm_security_center_subscription_pricing.go b/azurerm/resource_arm_security_center_subscription_pricing.go index 20371983d0fd..b9f35ffa30bf 100644 --- a/azurerm/resource_arm_security_center_subscription_pricing.go +++ b/azurerm/resource_arm_security_center_subscription_pricing.go @@ -12,7 +12,7 @@ import ( //NOTE: seems default is the only valid pricing name: //Code="InvalidInputJson" Message="Pricing name 'kt's price' is not allowed. Expected 'default' for this scope." -const securityCenterConfigurationSubscriptionPricingName = "default" +const securityCenterSubscriptionPricingName = "default" func resourceArmSecurityCenterSubscriptionPricing() *schema.Resource { return &schema.Resource{ @@ -42,7 +42,7 @@ func resourceArmSecurityCenterSubscriptionPricingUpdate(d *schema.ResourceData, client := meta.(*ArmClient).securityCenterPricingClient ctx := meta.(*ArmClient).StopContext - name := securityCenterConfigurationSubscriptionPricingName + name := securityCenterSubscriptionPricingName pricing := security.Pricing{ PricingProperties: &security.PricingProperties{ @@ -72,7 +72,7 @@ func resourceArmSecurityCenterSubscriptionPricingRead(d *schema.ResourceData, me client := meta.(*ArmClient).securityCenterPricingClient ctx := meta.(*ArmClient).StopContext - resp, err := client.GetSubscriptionPricing(ctx, securityCenterConfigurationSubscriptionPricingName) + resp, err := client.GetSubscriptionPricing(ctx, securityCenterSubscriptionPricingName) if err != nil { if utils.ResponseWasNotFound(resp.Response) { log.Printf("[DEBUG] Security Center Subscription was not found: %v", err) @@ -91,5 +91,6 @@ func resourceArmSecurityCenterSubscriptionPricingRead(d *schema.ResourceData, me } func resourceArmSecurityCenterSubscriptionPricingDelete(_ *schema.ResourceData, _ interface{}) error { + log.Printf("[DEBUG] Security Center Subscription deletion invocation") return nil //cannot be deleted. } diff --git a/website/docs/r/security_center_subscription_pricing.markdown b/website/docs/r/security_center_subscription_pricing.markdown index e5f87402266b..957cc491ace3 100644 --- a/website/docs/r/security_center_subscription_pricing.markdown +++ b/website/docs/r/security_center_subscription_pricing.markdown @@ -10,7 +10,9 @@ description: |- Manages the Pricing Tier for Azure Security Center in the current subscription. -~> **NOTE:** Owner access permission is required. +~> **NOTE:** This resource requires the `Owner` permission on the Subscription. + +~> **NOTE:** Deletion of this resource does not change or reset the pricing tier to `Free` ## Example Usage @@ -24,7 +26,7 @@ resource "azurerm_security_center_subscription_pricing" "example" { The following arguments are supported: -* `tier` - (Required) The pricing tier to use. Must be one of `Free` or `Standard`. +* `tier` - (Required) The pricing tier to use. Possible values are `Free` and `Standard`. ~> **NOTE:** Changing the pricing tier to `Standard` affects all resources in the subscription and could be quite costly. @@ -40,5 +42,5 @@ The following attributes are exported: The pricing tier can be imported using the `resource id`, e.g. ```shell -terraform import azurerm_securitycenter_subscription_pricing.example /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Security/pricings/default +terraform import azurerm_security_center_subscription_pricing.example /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Security/pricings/default ``` From 53b08d233a512e0e7cdc8248c8098034a202cb42 Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 12 Oct 2018 20:49:09 -0700 Subject: [PATCH 25/35] Address more PR #2045 comments --- azurerm/resource_arm_security_center_contact.go | 8 ++++---- azurerm/resource_arm_security_center_contact_test.go | 2 +- website/azurerm.erb | 8 ++++---- website/docs/r/security_center_contact.markdown | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/azurerm/resource_arm_security_center_contact.go b/azurerm/resource_arm_security_center_contact.go index 656bcad9486c..6d1d24529d01 100644 --- a/azurerm/resource_arm_security_center_contact.go +++ b/azurerm/resource_arm_security_center_contact.go @@ -13,7 +13,7 @@ import ( // Invalid security contact name was provided - only 'defaultX' is allowed where X is an index // Invalid security contact name 'default0' was provided. Expected 'default1' // Message="Invalid security contact name 'default2' was provided. Expected 'default1'" -const resourceArmSecurityCenterContactName = "default1" +const securityCenterContactName = "default1" func resourceArmSecurityCenterContact() *schema.Resource { return &schema.Resource{ @@ -56,7 +56,7 @@ func resourceArmSecurityCenterContactCreateUpdate(d *schema.ResourceData, meta i client := meta.(*ArmClient).securityCenterContactsClient ctx := meta.(*ArmClient).StopContext - name := resourceArmSecurityCenterContactName + name := securityCenterContactName contact := security.Contact{ ContactProperties: &security.ContactProperties{ @@ -106,7 +106,7 @@ func resourceArmSecurityCenterContactRead(d *schema.ResourceData, meta interface client := meta.(*ArmClient).securityCenterContactsClient ctx := meta.(*ArmClient).StopContext - name := resourceArmSecurityCenterContactName + name := securityCenterContactName resp, err := client.Get(ctx, name) if err != nil { @@ -133,7 +133,7 @@ func resourceArmSecurityCenterContactDelete(_ *schema.ResourceData, meta interfa client := meta.(*ArmClient).securityCenterContactsClient ctx := meta.(*ArmClient).StopContext - name := resourceArmSecurityCenterContactName + name := securityCenterContactName resp, err := client.Delete(ctx, name) if err != nil { diff --git a/azurerm/resource_arm_security_center_contact_test.go b/azurerm/resource_arm_security_center_contact_test.go index af008b4c1655..3a8e2857203f 100644 --- a/azurerm/resource_arm_security_center_contact_test.go +++ b/azurerm/resource_arm_security_center_contact_test.go @@ -105,7 +105,7 @@ func testCheckAzureRMSecurityCenterContactDestroy(s *terraform.State) error { if res.Type != "azurerm_security_center_contact" { continue } - resp, err := client.Get(ctx, resourceArmSecurityCenterContactName) + resp, err := client.Get(ctx, securityCenterContactName) if err != nil { if utils.ResponseWasNotFound(resp.Response) { return nil diff --git a/website/azurerm.erb b/website/azurerm.erb index 174617fa581c..8443fe3dea2b 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -976,13 +976,13 @@ > Security Center Resources diff --git a/website/docs/r/security_center_contact.markdown b/website/docs/r/security_center_contact.markdown index 3b9d883a855a..b66bd61d7678 100644 --- a/website/docs/r/security_center_contact.markdown +++ b/website/docs/r/security_center_contact.markdown @@ -42,5 +42,5 @@ The following attributes are exported: The contact can be imported using the `resource id`, e.g. ```shell -terraform import azurerm_securitycenter_contact.example /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Security/securityContacts/default1 +terraform import azurerm_security_center_contact.example /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Security/securityContacts/default1 ``` From 4b598c9221c4bad51f487567bce402301c210f00 Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 12 Oct 2018 20:53:00 -0700 Subject: [PATCH 26/35] Update CHANGELOG.md to include #2043 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff2754739ee7..f80dcb455f12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ FEATURES: * **New Resource:** `azurerm_dev_test_policy` [GH-2070] * **New Resource:** `azurerm_dev_test_linux_virtual_machine` [GH-2058] * **New Resource:** `azurerm_dev_test_windows_virtual_machine` [GH-2058] +* **New Resource:** `azurerm_security_center_subscription_pricing` [GH-2043] BUG FIXES: From 43e9c50b4272fde255f552e29b979e47dc342e88 Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 12 Oct 2018 20:55:10 -0700 Subject: [PATCH 27/35] Update CHANGELOG.md to include #2045 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f80dcb455f12..3ca43c55ce28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ FEATURES: * **New Resource:** `azurerm_dev_test_policy` [GH-2070] * **New Resource:** `azurerm_dev_test_linux_virtual_machine` [GH-2058] * **New Resource:** `azurerm_dev_test_windows_virtual_machine` [GH-2058] +* **New Resource:** `azurerm_security_center_contact` [GH-2045] * **New Resource:** `azurerm_security_center_subscription_pricing` [GH-2043] BUG FIXES: From 5862ac585247f59f2ef847de9ce13409d84d1d22 Mon Sep 17 00:00:00 2001 From: Krueladin <29762882+Krueladin@users.noreply.github.com> Date: Fri, 12 Oct 2018 22:25:23 -0700 Subject: [PATCH 28/35] Feature: Add 'ip_version' to Public IP Address (#2019) * Feature: Add 'ip_version' to Public IP Address * Public IP Data Source Info for 'ip_version' * Public IP Documentation Update to include 'ip_version' for data and resource documentation. * Making the IP Version field case sensitive * Fixing the broken tests * Adding back in the Zones test ``` $ acctests azurerm TestAccAzureRMPublicIpStatic_zones === RUN TestAccAzureRMPublicIpStatic_zones --- PASS: TestAccAzureRMPublicIpStatic_zones (111.60s) PASS ok github.com/terraform-providers/terraform-provider-azurerm/azurerm 113.048s ``` --- azurerm/data_source_public_ip.go | 9 ++ azurerm/data_source_public_ip_test.go | 1 + azurerm/helpers/validate/network.go | 26 +++- azurerm/helpers/validate/network_test.go | 51 +++++++ azurerm/resource_arm_public_ip.go | 24 ++- azurerm/resource_arm_public_ip_test.go | 181 ++++++++++++++++++++++- website/docs/d/public_ip.html.markdown | 1 + website/docs/r/public_ip.html.markdown | 4 + 8 files changed, 294 insertions(+), 3 deletions(-) diff --git a/azurerm/data_source_public_ip.go b/azurerm/data_source_public_ip.go index 7164e6785d3f..fe469626c1a3 100644 --- a/azurerm/data_source_public_ip.go +++ b/azurerm/data_source_public_ip.go @@ -20,6 +20,11 @@ func dataSourceArmPublicIP() *schema.Resource { "resource_group_name": resourceGroupNameForDataSourceSchema(), + "ip_version": { + Type: schema.TypeString, + Computed: true, + }, + "domain_name_label": { Type: schema.TypeString, Computed: true, @@ -73,6 +78,10 @@ func dataSourceArmPublicIPRead(d *schema.ResourceData, meta interface{}) error { } } + if ipVersion := props.PublicIPAddressVersion; string(ipVersion) != "" { + d.Set("ip_version", string(ipVersion)) + } + if v := props.IPAddress; v != nil && *v != "" { d.Set("ip_address", v) } diff --git a/azurerm/data_source_public_ip_test.go b/azurerm/data_source_public_ip_test.go index 07899ea236b5..c5c2ca929524 100644 --- a/azurerm/data_source_public_ip_test.go +++ b/azurerm/data_source_public_ip_test.go @@ -31,6 +31,7 @@ func TestAccDataSourceAzureRMPublicIP_basic(t *testing.T) { resource.TestCheckResourceAttr(dataSourceName, "idle_timeout_in_minutes", "30"), resource.TestCheckResourceAttrSet(dataSourceName, "fqdn"), resource.TestCheckResourceAttrSet(dataSourceName, "ip_address"), + resource.TestCheckResourceAttr(dataSourceName, "ip_version", "IPv4"), resource.TestCheckResourceAttr(dataSourceName, "tags.%", "1"), resource.TestCheckResourceAttr(dataSourceName, "tags.environment", "test"), ), diff --git a/azurerm/helpers/validate/network.go b/azurerm/helpers/validate/network.go index 609a23a33ae3..3a38c2177e38 100644 --- a/azurerm/helpers/validate/network.go +++ b/azurerm/helpers/validate/network.go @@ -5,6 +5,30 @@ import ( "net" ) +func IPv6Address(i interface{}, k string) (_ []string, errors []error) { + return validateIpv6Address(i, k, false) +} + +func validateIpv6Address(i interface{}, k string, allowEmpty bool) (_ []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) + return + } + + if v == "" && allowEmpty { + return + } + + ip := net.ParseIP(v) + if six := ip.To16(); six == nil { + errors = append(errors, fmt.Errorf("%q is not a valid IPv6 address: %q", k, v)) + } + + return + +} + func IPv4Address(i interface{}, k string) (_ []string, errors []error) { return validateIpv4Address(i, k, false) } @@ -26,7 +50,7 @@ func validateIpv4Address(i interface{}, k string, allowEmpty bool) (_ []string, ip := net.ParseIP(v) if four := ip.To4(); four == nil { - errors = append(errors, fmt.Errorf("%q is not a valid IP4 address: %q", k, v)) + errors = append(errors, fmt.Errorf("%q is not a valid IPv4 address: %q", k, v)) } return diff --git a/azurerm/helpers/validate/network_test.go b/azurerm/helpers/validate/network_test.go index 3911319b0b77..0c59bb15c756 100644 --- a/azurerm/helpers/validate/network_test.go +++ b/azurerm/helpers/validate/network_test.go @@ -5,6 +5,57 @@ import ( "testing" ) +func TestIPv6Address(t *testing.T) { + cases := []struct { + IP string + Errors int + }{ + { + IP: "", + Errors: 1, + }, + { + IP: "0.0.0.0", + Errors: 0, + }, + { + IP: "not:a:real:address:1:2:3:4", + Errors: 1, + }, + { + IP: "text", + Errors: 1, + }, + { + IP: "::", + Errors: 0, + }, + { + IP: "0:0:0:0:0:0:0:0", + Errors: 0, + }, + { + IP: "2001:0db8:85a3:0:0:8a2e:0370:7334", + Errors: 0, + }, + { + IP: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + Errors: 0, + }, + } + + for _, tc := range cases { + t.Run(tc.IP, func(t *testing.T) { + _, errors := IPv6Address(tc.IP, "test") + + if len(errors) != tc.Errors { + t.Fatalf("Expected IPv6Address to return %d error(s) not %d", tc.Errors, len(errors)) + } + }) + } + +} + func TestIPv4Address(t *testing.T) { cases := []struct { IP string diff --git a/azurerm/resource_arm_public_ip.go b/azurerm/resource_arm_public_ip.go index 846338adaac9..84716ac742b3 100644 --- a/azurerm/resource_arm_public_ip.go +++ b/azurerm/resource_arm_public_ip.go @@ -2,11 +2,12 @@ package azurerm import ( "fmt" - "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "log" "regexp" "strings" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-04-01/network" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" @@ -60,6 +61,18 @@ func resourceArmPublicIp() *schema.Resource { }, true), }, + "ip_version": { + Type: schema.TypeString, + Optional: true, + Default: string(network.IPv4), + ForceNew: true, + DiffSuppressFunc: suppress.CaseDifference, + ValidateFunc: validation.StringInSlice([]string{ + string(network.IPv4), + string(network.IPv6), + }, true), + }, + "sku": { Type: schema.TypeString, Optional: true, @@ -122,6 +135,13 @@ func resourceArmPublicIpCreate(d *schema.ResourceData, meta interface{}) error { idleTimeout := d.Get("idle_timeout_in_minutes").(int) ipAllocationMethod := network.IPAllocationMethod(d.Get("public_ip_address_allocation").(string)) + ipVersion := network.IPVersion(d.Get("ip_version").(string)) + + if strings.EqualFold(string(ipVersion), string(network.IPv6)) { + if strings.EqualFold(string(ipAllocationMethod), "static") { + return fmt.Errorf("Cannot specify publicIpAllocationMethod as Static for IPv6 PublicIp") + } + } if strings.ToLower(string(sku.Name)) == "standard" { if strings.ToLower(string(ipAllocationMethod)) != "static" { @@ -135,6 +155,7 @@ func resourceArmPublicIpCreate(d *schema.ResourceData, meta interface{}) error { Sku: &sku, PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{ PublicIPAllocationMethod: ipAllocationMethod, + PublicIPAddressVersion: ipVersion, IdleTimeoutInMinutes: utils.Int32(int32(idleTimeout)), }, Tags: expandTags(tags), @@ -218,6 +239,7 @@ func resourceArmPublicIpRead(d *schema.ResourceData, meta interface{}) error { if props := resp.PublicIPAddressPropertiesFormat; props != nil { d.Set("public_ip_address_allocation", strings.ToLower(string(props.PublicIPAllocationMethod))) + d.Set("ip_version", strings.ToLower(string(props.PublicIPAddressVersion))) if settings := props.DNSSettings; settings != nil { d.Set("fqdn", settings.Fqdn) diff --git a/azurerm/resource_arm_public_ip_test.go b/azurerm/resource_arm_public_ip_test.go index 6fc922833be2..05902fdd4781 100644 --- a/azurerm/resource_arm_public_ip_test.go +++ b/azurerm/resource_arm_public_ip_test.go @@ -71,6 +71,34 @@ func TestAccAzureRMPublicIpStatic_basic(t *testing.T) { }) } +func TestAccAzureRMPublicIpStatic_zones(t *testing.T) { + resourceName := "azurerm_public_ip.test" + ri := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIpDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMPublicIPStatic_withZone(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIpExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "ip_address"), + resource.TestCheckResourceAttr(resourceName, "public_ip_address_allocation", "static"), + resource.TestCheckResourceAttr(resourceName, "zones.#", "1"), + resource.TestCheckResourceAttr(resourceName, "zones.0", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMPublicIpStatic_basic_withDNSLabel(t *testing.T) { resourceName := "azurerm_public_ip.test" ri := acctest.RandInt() @@ -100,6 +128,103 @@ func TestAccAzureRMPublicIpStatic_basic_withDNSLabel(t *testing.T) { }) } +func TestAccAzureRMPublicIpStatic_standard_withIPv6_fails(t *testing.T) { + ri := acctest.RandInt() + config := testAccAzureRMPublicIPStatic_standard_withIPVersion(ri, testLocation(), "IPv6") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIpDestroy, + Steps: []resource.TestStep{ + { + Config: config, + ExpectError: regexp.MustCompile("Cannot specify publicIpAllocationMethod as Static for IPv6 PublicIp"), + }, + }, + }) +} + +func TestAccAzureRMPublicIpDynamic_basic_withIPv6(t *testing.T) { + resourceName := "azurerm_public_ip.test" + ri := acctest.RandInt() + ipVersion := "Ipv6" + config := testAccAzureRMPublicIPDynamic_basic_withIPVersion(ri, testLocation(), ipVersion) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIpDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIpExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "ip_version", "IPv6"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) + +} + +func TestAccAzureRMPublicIpStatic_basic_defaultsToIPv4(t *testing.T) { + resourceName := "azurerm_public_ip.test" + ri := acctest.RandInt() + config := testAccAzureRMPublicIPStatic_basic(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIpDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIpExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "ip_version", "ipv4"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccAzureRMPublicIpStatic_basic_withIPv4(t *testing.T) { + resourceName := "azurerm_public_ip.test" + ri := acctest.RandInt() + ipVersion := "IPv4" + config := testAccAzureRMPublicIPStatic_basic_withIPVersion(ri, testLocation(), ipVersion) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMPublicIpDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMPublicIpExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "ip_version", "ipv4"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAzureRMPublicIpStatic_standard(t *testing.T) { resourceName := "azurerm_public_ip.test" ri := acctest.RandInt() @@ -392,7 +517,7 @@ resource "azurerm_public_ip" "test" { `, rInt, location, rInt) } -func testAccAzureRMPublicIPStatic_basic_withZone(rInt int, location string) string { +func testAccAzureRMPublicIPStatic_withZone(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "acctestRG-%d" @@ -428,6 +553,24 @@ resource "azurerm_public_ip" "test" { `, rInt, location, rInt, dnsNameLabel) } +func testAccAzureRMPublicIPStatic_basic_withIPVersion(rInt int, location string, ipVersion string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip" "test" { + name = "acctestpublicip-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + public_ip_address_allocation = "static" + + ip_version = "%s" +} +`, rInt, location, rInt, ipVersion) +} + func testAccAzureRMPublicIPStatic_standard(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -445,6 +588,24 @@ resource "azurerm_public_ip" "test" { `, rInt, location, rInt) } +func testAccAzureRMPublicIPStatic_standard_withIPVersion(rInt int, location string, ipVersion string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip" "test" { + name = "acctestpublicip-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + public_ip_address_allocation = "static" + ip_version = "%s" + sku = "standard" +} +`, rInt, location, rInt, ipVersion) +} + func testAccAzureRMPublicIPStatic_update(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -495,6 +656,24 @@ resource "azurerm_public_ip" "test" { `, rInt, location, rInt) } +func testAccAzureRMPublicIPDynamic_basic_withIPVersion(rInt int, location string, ipVersion string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_public_ip" "test" { + name = "acctestpublicip-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + public_ip_address_allocation = "dynamic" + + ip_version = "%s" +} +`, rInt, location, rInt, ipVersion) +} + func testAccAzureRMPublicIPStatic_withTags(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { diff --git a/website/docs/d/public_ip.html.markdown b/website/docs/d/public_ip.html.markdown index 27665fde2eca..f298f2ec6fc8 100644 --- a/website/docs/d/public_ip.html.markdown +++ b/website/docs/d/public_ip.html.markdown @@ -107,4 +107,5 @@ output "public_ip_address" { * `idle_timeout_in_minutes` - Specifies the timeout for the TCP idle connection. * `fqdn` - Fully qualified domain name of the A DNS record associated with the public IP. This is the concatenation of the domainNameLabel and the regionalized DNS zone. * `ip_address` - The IP address value that was allocated. +* `ip_version` - The IP version being used, for example `IPv4` or `IPv6`. * `tags` - A mapping of tags to assigned to the resource. diff --git a/website/docs/r/public_ip.html.markdown b/website/docs/r/public_ip.html.markdown index b832c8726bfc..8f5df3f4d488 100644 --- a/website/docs/r/public_ip.html.markdown +++ b/website/docs/r/public_ip.html.markdown @@ -52,6 +52,10 @@ The following arguments are supported: ~> **Note** `Dynamic` Public IP Addresses aren't allocated until they're assigned to a resource (such as a Virtual Machine or a Load Balancer) by design within Azure - [more information is available below](#ip_address). +* `ip_version` - (Optional) The IP Version to use, IPv6 or IPv4. + +-> **Note** Only `dynamic` IP address allocation is supported for IPv6. + * `idle_timeout_in_minutes` - (Optional) Specifies the timeout for the TCP idle connection. The value can be set between 4 and 30 minutes. * `domain_name_label` - (Optional) Label for the Domain Name. Will be used to make up the FQDN. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system. From c187201ff58647f724de1541217b0f30aec4dbc1 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 12 Oct 2018 19:25:50 -1000 Subject: [PATCH 29/35] Updating to include #2019 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ca43c55ce28..39175f120f10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ IMPROVEMENTS: * `azurerm_key_vault` - support for Virtual Network Rules [GH-2027] * `azurerm_kubernetes_cluster` - changing the `oms_agent` property no longer forces a new resource [GH-2021] * `azurerm_postgresql_virtual_network_rule` - support for the `ignore_missing_vnet_service_endpoint` [GH-2056] +* `azurerm_public_ip` - support for IPv6 addresses [GH-2019] ## 1.16.0 (October 01, 2018) From 4027cdd5713a450c9abfbe602b56a03427ac09a1 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 12 Oct 2018 23:25:55 -1000 Subject: [PATCH 30/35] New Resources: `azurerm_subnet_network_security_group_association` / `azurerm_subnet_route_table_association` (#1933) * New Resource: `azurerm_subnet_route_table_association` ``` $ acctests azurerm TestAccAzureRMSubnetRouteTableAssociation === RUN TestAccAzureRMSubnetRouteTableAssociation_basic --- PASS: TestAccAzureRMSubnetRouteTableAssociation_basic (145.86s) === RUN TestAccAzureRMSubnetRouteTableAssociation_deleted --- PASS: TestAccAzureRMSubnetRouteTableAssociation_deleted (103.94s) PASS ok github.com/terraform-providers/terraform-provider-azurerm/azurerm 250.163s ``` * New Resource: `azurerm_subnet_network_security_group_association` ``` $ acctests azurerm TestAccAzureRMSubnetNetworkSecurityGroupAssociation_ === RUN TestAccAzureRMSubnetNetworkSecurityGroupAssociation_basic --- PASS: TestAccAzureRMSubnetNetworkSecurityGroupAssociation_basic (129.21s) === RUN TestAccAzureRMSubnetNetworkSecurityGroupAssociation_deleted --- PASS: TestAccAzureRMSubnetNetworkSecurityGroupAssociation_deleted (99.74s) PASS ok github.com/terraform-providers/terraform-provider-azurerm/azurerm 229.367s ``` * WIP# Please enter the commit message for your changes. Lines starting * Subnet: documenting that both fields are required for the moment * Handling the config being required on both for the moment --- azurerm/provider.go | 320 +++++++++--------- azurerm/resource_arm_subnet.go | 20 +- ...bnet_network_security_group_association.go | 216 ++++++++++++ ...network_security_group_association_test.go | 234 +++++++++++++ ...urce_arm_subnet_route_table_association.go | 216 ++++++++++++ ...arm_subnet_route_table_association_test.go | 229 +++++++++++++ azurerm/resource_arm_subnet_test.go | 1 + website/azurerm.erb | 10 +- website/docs/r/route_table.html.markdown | 3 +- website/docs/r/subnet.html.markdown | 10 +- ...k_security_group_association.html.markdown | 83 +++++ ...bnet_route_table_association.html.markdown | 78 +++++ 12 files changed, 1249 insertions(+), 171 deletions(-) create mode 100644 azurerm/resource_arm_subnet_network_security_group_association.go create mode 100644 azurerm/resource_arm_subnet_network_security_group_association_test.go create mode 100644 azurerm/resource_arm_subnet_route_table_association.go create mode 100644 azurerm/resource_arm_subnet_route_table_association_test.go create mode 100644 website/docs/r/subnet_network_security_group_association.html.markdown create mode 100644 website/docs/r/subnet_route_table_association.html.markdown diff --git a/azurerm/provider.go b/azurerm/provider.go index ee79e9ec22ea..40c1dea5a6f8 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -129,165 +129,167 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ - "azurerm_azuread_application": resourceArmActiveDirectoryApplication(), - "azurerm_azuread_service_principal": resourceArmActiveDirectoryServicePrincipal(), - "azurerm_azuread_service_principal_password": resourceArmActiveDirectoryServicePrincipalPassword(), - "azurerm_api_management": resourceArmApiManagementService(), - "azurerm_application_gateway": resourceArmApplicationGateway(), - "azurerm_application_insights": resourceArmApplicationInsights(), - "azurerm_application_security_group": resourceArmApplicationSecurityGroup(), - "azurerm_app_service": resourceArmAppService(), - "azurerm_app_service_plan": resourceArmAppServicePlan(), - "azurerm_app_service_active_slot": resourceArmAppServiceActiveSlot(), - "azurerm_app_service_custom_hostname_binding": resourceArmAppServiceCustomHostnameBinding(), - "azurerm_app_service_slot": resourceArmAppServiceSlot(), - "azurerm_automation_account": resourceArmAutomationAccount(), - "azurerm_automation_credential": resourceArmAutomationCredential(), - "azurerm_automation_runbook": resourceArmAutomationRunbook(), - "azurerm_automation_schedule": resourceArmAutomationSchedule(), - "azurerm_autoscale_setting": resourceArmAutoScaleSetting(), - "azurerm_availability_set": resourceArmAvailabilitySet(), - "azurerm_cdn_endpoint": resourceArmCdnEndpoint(), - "azurerm_cdn_profile": resourceArmCdnProfile(), - "azurerm_cognitive_account": resourceArmCognitiveAccount(), - "azurerm_container_registry": resourceArmContainerRegistry(), - "azurerm_container_service": resourceArmContainerService(), - "azurerm_container_group": resourceArmContainerGroup(), - "azurerm_cosmosdb_account": resourceArmCosmosDBAccount(), - "azurerm_databricks_workspace": resourceArmDatabricksWorkspace(), - "azurerm_data_lake_analytics_account": resourceArmDataLakeAnalyticsAccount(), - "azurerm_data_lake_analytics_firewall_rule": resourceArmDataLakeAnalyticsFirewallRule(), - "azurerm_data_lake_store": resourceArmDataLakeStore(), - "azurerm_data_lake_store_file": resourceArmDataLakeStoreFile(), - "azurerm_data_lake_store_firewall_rule": resourceArmDataLakeStoreFirewallRule(), - "azurerm_dev_test_lab": resourceArmDevTestLab(), - "azurerm_dev_test_policy": resourceArmDevTestPolicy(), - "azurerm_dev_test_linux_virtual_machine": resourceArmDevTestLinuxVirtualMachine(), - "azurerm_dev_test_virtual_network": resourceArmDevTestVirtualNetwork(), - "azurerm_dev_test_windows_virtual_machine": resourceArmDevTestWindowsVirtualMachine(), - "azurerm_dns_a_record": resourceArmDnsARecord(), - "azurerm_dns_aaaa_record": resourceArmDnsAAAARecord(), - "azurerm_dns_caa_record": resourceArmDnsCaaRecord(), - "azurerm_dns_cname_record": resourceArmDnsCNameRecord(), - "azurerm_dns_mx_record": resourceArmDnsMxRecord(), - "azurerm_dns_ns_record": resourceArmDnsNsRecord(), - "azurerm_dns_ptr_record": resourceArmDnsPtrRecord(), - "azurerm_dns_srv_record": resourceArmDnsSrvRecord(), - "azurerm_dns_txt_record": resourceArmDnsTxtRecord(), - "azurerm_dns_zone": resourceArmDnsZone(), - "azurerm_eventgrid_topic": resourceArmEventGridTopic(), - "azurerm_eventhub": resourceArmEventHub(), - "azurerm_eventhub_authorization_rule": resourceArmEventHubAuthorizationRule(), - "azurerm_eventhub_consumer_group": resourceArmEventHubConsumerGroup(), - "azurerm_eventhub_namespace": resourceArmEventHubNamespace(), - "azurerm_eventhub_namespace_authorization_rule": resourceArmEventHubNamespaceAuthorizationRule(), - "azurerm_express_route_circuit": resourceArmExpressRouteCircuit(), - "azurerm_express_route_circuit_authorization": resourceArmExpressRouteCircuitAuthorization(), - "azurerm_express_route_circuit_peering": resourceArmExpressRouteCircuitPeering(), - "azurerm_firewall": resourceArmFirewall(), - "azurerm_firewall_network_rule_collection": resourceArmFirewallNetworkRuleCollection(), - "azurerm_function_app": resourceArmFunctionApp(), - "azurerm_image": resourceArmImage(), - "azurerm_iothub": resourceArmIotHub(), - "azurerm_key_vault": resourceArmKeyVault(), - "azurerm_key_vault_access_policy": resourceArmKeyVaultAccessPolicy(), - "azurerm_key_vault_certificate": resourceArmKeyVaultCertificate(), - "azurerm_key_vault_key": resourceArmKeyVaultKey(), - "azurerm_key_vault_secret": resourceArmKeyVaultSecret(), - "azurerm_kubernetes_cluster": resourceArmKubernetesCluster(), - "azurerm_lb": resourceArmLoadBalancer(), - "azurerm_lb_backend_address_pool": resourceArmLoadBalancerBackendAddressPool(), - "azurerm_lb_nat_rule": resourceArmLoadBalancerNatRule(), - "azurerm_lb_nat_pool": resourceArmLoadBalancerNatPool(), - "azurerm_lb_probe": resourceArmLoadBalancerProbe(), - "azurerm_lb_rule": resourceArmLoadBalancerRule(), - "azurerm_local_network_gateway": resourceArmLocalNetworkGateway(), - "azurerm_log_analytics_solution": resourceArmLogAnalyticsSolution(), - "azurerm_log_analytics_workspace": resourceArmLogAnalyticsWorkspace(), - "azurerm_logic_app_action_custom": resourceArmLogicAppActionCustom(), - "azurerm_logic_app_action_http": resourceArmLogicAppActionHTTP(), - "azurerm_logic_app_trigger_custom": resourceArmLogicAppTriggerCustom(), - "azurerm_logic_app_trigger_http_request": resourceArmLogicAppTriggerHttpRequest(), - "azurerm_logic_app_trigger_recurrence": resourceArmLogicAppTriggerRecurrence(), - "azurerm_logic_app_workflow": resourceArmLogicAppWorkflow(), - "azurerm_managed_disk": resourceArmManagedDisk(), - "azurerm_management_lock": resourceArmManagementLock(), - "azurerm_management_group": resourceArmManagementGroup(), - "azurerm_metric_alertrule": resourceArmMetricAlertRule(), - "azurerm_monitor_action_group": resourceArmMonitorActionGroup(), - "azurerm_mysql_configuration": resourceArmMySQLConfiguration(), - "azurerm_mysql_database": resourceArmMySqlDatabase(), - "azurerm_mysql_firewall_rule": resourceArmMySqlFirewallRule(), - "azurerm_mysql_server": resourceArmMySqlServer(), - "azurerm_mysql_virtual_network_rule": resourceArmMySqlVirtualNetworkRule(), - "azurerm_network_interface": resourceArmNetworkInterface(), - "azurerm_network_security_group": resourceArmNetworkSecurityGroup(), - "azurerm_network_security_rule": resourceArmNetworkSecurityRule(), - "azurerm_network_watcher": resourceArmNetworkWatcher(), - "azurerm_notification_hub": resourceArmNotificationHub(), - "azurerm_notification_hub_authorization_rule": resourceArmNotificationHubAuthorizationRule(), - "azurerm_notification_hub_namespace": resourceArmNotificationHubNamespace(), - "azurerm_packet_capture": resourceArmPacketCapture(), - "azurerm_policy_assignment": resourceArmPolicyAssignment(), - "azurerm_policy_definition": resourceArmPolicyDefinition(), - "azurerm_postgresql_configuration": resourceArmPostgreSQLConfiguration(), - "azurerm_postgresql_database": resourceArmPostgreSQLDatabase(), - "azurerm_postgresql_firewall_rule": resourceArmPostgreSQLFirewallRule(), - "azurerm_postgresql_server": resourceArmPostgreSQLServer(), - "azurerm_postgresql_virtual_network_rule": resourceArmPostgreSQLVirtualNetworkRule(), - "azurerm_public_ip": resourceArmPublicIp(), - "azurerm_relay_namespace": resourceArmRelayNamespace(), - "azurerm_recovery_services_vault": resourceArmRecoveryServicesVault(), - "azurerm_redis_cache": resourceArmRedisCache(), - "azurerm_redis_firewall_rule": resourceArmRedisFirewallRule(), - "azurerm_resource_group": resourceArmResourceGroup(), - "azurerm_role_assignment": resourceArmRoleAssignment(), - "azurerm_role_definition": resourceArmRoleDefinition(), - "azurerm_route": resourceArmRoute(), - "azurerm_route_table": resourceArmRouteTable(), - "azurerm_search_service": resourceArmSearchService(), - "azurerm_security_center_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(), - "azurerm_security_center_contact": resourceArmSecurityCenterContact(), - "azurerm_servicebus_namespace": resourceArmServiceBusNamespace(), - "azurerm_servicebus_namespace_authorization_rule": resourceArmServiceBusNamespaceAuthorizationRule(), - "azurerm_servicebus_queue": resourceArmServiceBusQueue(), - "azurerm_servicebus_queue_authorization_rule": resourceArmServiceBusQueueAuthorizationRule(), - "azurerm_servicebus_subscription": resourceArmServiceBusSubscription(), - "azurerm_servicebus_subscription_rule": resourceArmServiceBusSubscriptionRule(), - "azurerm_servicebus_topic": resourceArmServiceBusTopic(), - "azurerm_servicebus_topic_authorization_rule": resourceArmServiceBusTopicAuthorizationRule(), - "azurerm_service_fabric_cluster": resourceArmServiceFabricCluster(), - "azurerm_shared_image": resourceArmSharedImage(), - "azurerm_shared_image_gallery": resourceArmSharedImageGallery(), - "azurerm_shared_image_version": resourceArmSharedImageVersion(), - "azurerm_snapshot": resourceArmSnapshot(), - "azurerm_scheduler_job": resourceArmSchedulerJob(), - "azurerm_scheduler_job_collection": resourceArmSchedulerJobCollection(), - "azurerm_sql_database": resourceArmSqlDatabase(), - "azurerm_sql_elasticpool": resourceArmSqlElasticPool(), - "azurerm_sql_firewall_rule": resourceArmSqlFirewallRule(), - "azurerm_sql_active_directory_administrator": resourceArmSqlAdministrator(), - "azurerm_sql_server": resourceArmSqlServer(), - "azurerm_sql_virtual_network_rule": resourceArmSqlVirtualNetworkRule(), - "azurerm_storage_account": resourceArmStorageAccount(), - "azurerm_storage_blob": resourceArmStorageBlob(), - "azurerm_storage_container": resourceArmStorageContainer(), - "azurerm_storage_share": resourceArmStorageShare(), - "azurerm_storage_queue": resourceArmStorageQueue(), - "azurerm_storage_table": resourceArmStorageTable(), - "azurerm_subnet": resourceArmSubnet(), - "azurerm_template_deployment": resourceArmTemplateDeployment(), - "azurerm_traffic_manager_endpoint": resourceArmTrafficManagerEndpoint(), - "azurerm_traffic_manager_profile": resourceArmTrafficManagerProfile(), - "azurerm_user_assigned_identity": resourceArmUserAssignedIdentity(), - "azurerm_virtual_machine": resourceArmVirtualMachine(), - "azurerm_virtual_machine_data_disk_attachment": resourceArmVirtualMachineDataDiskAttachment(), - "azurerm_virtual_machine_extension": resourceArmVirtualMachineExtensions(), - "azurerm_virtual_machine_scale_set": resourceArmVirtualMachineScaleSet(), - "azurerm_virtual_network": resourceArmVirtualNetwork(), - "azurerm_virtual_network_gateway": resourceArmVirtualNetworkGateway(), - "azurerm_virtual_network_gateway_connection": resourceArmVirtualNetworkGatewayConnection(), - "azurerm_virtual_network_peering": resourceArmVirtualNetworkPeering(), + "azurerm_azuread_application": resourceArmActiveDirectoryApplication(), + "azurerm_azuread_service_principal": resourceArmActiveDirectoryServicePrincipal(), + "azurerm_azuread_service_principal_password": resourceArmActiveDirectoryServicePrincipalPassword(), + "azurerm_api_management": resourceArmApiManagementService(), + "azurerm_application_gateway": resourceArmApplicationGateway(), + "azurerm_application_insights": resourceArmApplicationInsights(), + "azurerm_application_security_group": resourceArmApplicationSecurityGroup(), + "azurerm_app_service": resourceArmAppService(), + "azurerm_app_service_plan": resourceArmAppServicePlan(), + "azurerm_app_service_active_slot": resourceArmAppServiceActiveSlot(), + "azurerm_app_service_custom_hostname_binding": resourceArmAppServiceCustomHostnameBinding(), + "azurerm_app_service_slot": resourceArmAppServiceSlot(), + "azurerm_automation_account": resourceArmAutomationAccount(), + "azurerm_automation_credential": resourceArmAutomationCredential(), + "azurerm_automation_runbook": resourceArmAutomationRunbook(), + "azurerm_automation_schedule": resourceArmAutomationSchedule(), + "azurerm_autoscale_setting": resourceArmAutoScaleSetting(), + "azurerm_availability_set": resourceArmAvailabilitySet(), + "azurerm_cdn_endpoint": resourceArmCdnEndpoint(), + "azurerm_cdn_profile": resourceArmCdnProfile(), + "azurerm_cognitive_account": resourceArmCognitiveAccount(), + "azurerm_container_registry": resourceArmContainerRegistry(), + "azurerm_container_service": resourceArmContainerService(), + "azurerm_container_group": resourceArmContainerGroup(), + "azurerm_cosmosdb_account": resourceArmCosmosDBAccount(), + "azurerm_databricks_workspace": resourceArmDatabricksWorkspace(), + "azurerm_data_lake_analytics_account": resourceArmDataLakeAnalyticsAccount(), + "azurerm_data_lake_analytics_firewall_rule": resourceArmDataLakeAnalyticsFirewallRule(), + "azurerm_data_lake_store": resourceArmDataLakeStore(), + "azurerm_data_lake_store_file": resourceArmDataLakeStoreFile(), + "azurerm_data_lake_store_firewall_rule": resourceArmDataLakeStoreFirewallRule(), + "azurerm_dev_test_lab": resourceArmDevTestLab(), + "azurerm_dev_test_policy": resourceArmDevTestPolicy(), + "azurerm_dev_test_linux_virtual_machine": resourceArmDevTestLinuxVirtualMachine(), + "azurerm_dev_test_virtual_network": resourceArmDevTestVirtualNetwork(), + "azurerm_dev_test_windows_virtual_machine": resourceArmDevTestWindowsVirtualMachine(), + "azurerm_dns_a_record": resourceArmDnsARecord(), + "azurerm_dns_aaaa_record": resourceArmDnsAAAARecord(), + "azurerm_dns_caa_record": resourceArmDnsCaaRecord(), + "azurerm_dns_cname_record": resourceArmDnsCNameRecord(), + "azurerm_dns_mx_record": resourceArmDnsMxRecord(), + "azurerm_dns_ns_record": resourceArmDnsNsRecord(), + "azurerm_dns_ptr_record": resourceArmDnsPtrRecord(), + "azurerm_dns_srv_record": resourceArmDnsSrvRecord(), + "azurerm_dns_txt_record": resourceArmDnsTxtRecord(), + "azurerm_dns_zone": resourceArmDnsZone(), + "azurerm_eventgrid_topic": resourceArmEventGridTopic(), + "azurerm_eventhub": resourceArmEventHub(), + "azurerm_eventhub_authorization_rule": resourceArmEventHubAuthorizationRule(), + "azurerm_eventhub_consumer_group": resourceArmEventHubConsumerGroup(), + "azurerm_eventhub_namespace": resourceArmEventHubNamespace(), + "azurerm_eventhub_namespace_authorization_rule": resourceArmEventHubNamespaceAuthorizationRule(), + "azurerm_express_route_circuit": resourceArmExpressRouteCircuit(), + "azurerm_express_route_circuit_authorization": resourceArmExpressRouteCircuitAuthorization(), + "azurerm_express_route_circuit_peering": resourceArmExpressRouteCircuitPeering(), + "azurerm_firewall": resourceArmFirewall(), + "azurerm_firewall_network_rule_collection": resourceArmFirewallNetworkRuleCollection(), + "azurerm_function_app": resourceArmFunctionApp(), + "azurerm_image": resourceArmImage(), + "azurerm_iothub": resourceArmIotHub(), + "azurerm_key_vault": resourceArmKeyVault(), + "azurerm_key_vault_access_policy": resourceArmKeyVaultAccessPolicy(), + "azurerm_key_vault_certificate": resourceArmKeyVaultCertificate(), + "azurerm_key_vault_key": resourceArmKeyVaultKey(), + "azurerm_key_vault_secret": resourceArmKeyVaultSecret(), + "azurerm_kubernetes_cluster": resourceArmKubernetesCluster(), + "azurerm_lb": resourceArmLoadBalancer(), + "azurerm_lb_backend_address_pool": resourceArmLoadBalancerBackendAddressPool(), + "azurerm_lb_nat_rule": resourceArmLoadBalancerNatRule(), + "azurerm_lb_nat_pool": resourceArmLoadBalancerNatPool(), + "azurerm_lb_probe": resourceArmLoadBalancerProbe(), + "azurerm_lb_rule": resourceArmLoadBalancerRule(), + "azurerm_local_network_gateway": resourceArmLocalNetworkGateway(), + "azurerm_log_analytics_solution": resourceArmLogAnalyticsSolution(), + "azurerm_log_analytics_workspace": resourceArmLogAnalyticsWorkspace(), + "azurerm_logic_app_action_custom": resourceArmLogicAppActionCustom(), + "azurerm_logic_app_action_http": resourceArmLogicAppActionHTTP(), + "azurerm_logic_app_trigger_custom": resourceArmLogicAppTriggerCustom(), + "azurerm_logic_app_trigger_http_request": resourceArmLogicAppTriggerHttpRequest(), + "azurerm_logic_app_trigger_recurrence": resourceArmLogicAppTriggerRecurrence(), + "azurerm_logic_app_workflow": resourceArmLogicAppWorkflow(), + "azurerm_managed_disk": resourceArmManagedDisk(), + "azurerm_management_lock": resourceArmManagementLock(), + "azurerm_management_group": resourceArmManagementGroup(), + "azurerm_metric_alertrule": resourceArmMetricAlertRule(), + "azurerm_monitor_action_group": resourceArmMonitorActionGroup(), + "azurerm_mysql_configuration": resourceArmMySQLConfiguration(), + "azurerm_mysql_database": resourceArmMySqlDatabase(), + "azurerm_mysql_firewall_rule": resourceArmMySqlFirewallRule(), + "azurerm_mysql_server": resourceArmMySqlServer(), + "azurerm_mysql_virtual_network_rule": resourceArmMySqlVirtualNetworkRule(), + "azurerm_network_interface": resourceArmNetworkInterface(), + "azurerm_network_security_group": resourceArmNetworkSecurityGroup(), + "azurerm_network_security_rule": resourceArmNetworkSecurityRule(), + "azurerm_network_watcher": resourceArmNetworkWatcher(), + "azurerm_notification_hub": resourceArmNotificationHub(), + "azurerm_notification_hub_authorization_rule": resourceArmNotificationHubAuthorizationRule(), + "azurerm_notification_hub_namespace": resourceArmNotificationHubNamespace(), + "azurerm_packet_capture": resourceArmPacketCapture(), + "azurerm_policy_assignment": resourceArmPolicyAssignment(), + "azurerm_policy_definition": resourceArmPolicyDefinition(), + "azurerm_postgresql_configuration": resourceArmPostgreSQLConfiguration(), + "azurerm_postgresql_database": resourceArmPostgreSQLDatabase(), + "azurerm_postgresql_firewall_rule": resourceArmPostgreSQLFirewallRule(), + "azurerm_postgresql_server": resourceArmPostgreSQLServer(), + "azurerm_postgresql_virtual_network_rule": resourceArmPostgreSQLVirtualNetworkRule(), + "azurerm_public_ip": resourceArmPublicIp(), + "azurerm_relay_namespace": resourceArmRelayNamespace(), + "azurerm_recovery_services_vault": resourceArmRecoveryServicesVault(), + "azurerm_redis_cache": resourceArmRedisCache(), + "azurerm_redis_firewall_rule": resourceArmRedisFirewallRule(), + "azurerm_resource_group": resourceArmResourceGroup(), + "azurerm_role_assignment": resourceArmRoleAssignment(), + "azurerm_role_definition": resourceArmRoleDefinition(), + "azurerm_route": resourceArmRoute(), + "azurerm_route_table": resourceArmRouteTable(), + "azurerm_search_service": resourceArmSearchService(), + "azurerm_security_center_subscription_pricing": resourceArmSecurityCenterSubscriptionPricing(), + "azurerm_security_center_contact": resourceArmSecurityCenterContact(), + "azurerm_servicebus_namespace": resourceArmServiceBusNamespace(), + "azurerm_servicebus_namespace_authorization_rule": resourceArmServiceBusNamespaceAuthorizationRule(), + "azurerm_servicebus_queue": resourceArmServiceBusQueue(), + "azurerm_servicebus_queue_authorization_rule": resourceArmServiceBusQueueAuthorizationRule(), + "azurerm_servicebus_subscription": resourceArmServiceBusSubscription(), + "azurerm_servicebus_subscription_rule": resourceArmServiceBusSubscriptionRule(), + "azurerm_servicebus_topic": resourceArmServiceBusTopic(), + "azurerm_servicebus_topic_authorization_rule": resourceArmServiceBusTopicAuthorizationRule(), + "azurerm_service_fabric_cluster": resourceArmServiceFabricCluster(), + "azurerm_shared_image": resourceArmSharedImage(), + "azurerm_shared_image_gallery": resourceArmSharedImageGallery(), + "azurerm_shared_image_version": resourceArmSharedImageVersion(), + "azurerm_snapshot": resourceArmSnapshot(), + "azurerm_scheduler_job": resourceArmSchedulerJob(), + "azurerm_scheduler_job_collection": resourceArmSchedulerJobCollection(), + "azurerm_sql_database": resourceArmSqlDatabase(), + "azurerm_sql_elasticpool": resourceArmSqlElasticPool(), + "azurerm_sql_firewall_rule": resourceArmSqlFirewallRule(), + "azurerm_sql_active_directory_administrator": resourceArmSqlAdministrator(), + "azurerm_sql_server": resourceArmSqlServer(), + "azurerm_sql_virtual_network_rule": resourceArmSqlVirtualNetworkRule(), + "azurerm_storage_account": resourceArmStorageAccount(), + "azurerm_storage_blob": resourceArmStorageBlob(), + "azurerm_storage_container": resourceArmStorageContainer(), + "azurerm_storage_share": resourceArmStorageShare(), + "azurerm_storage_queue": resourceArmStorageQueue(), + "azurerm_storage_table": resourceArmStorageTable(), + "azurerm_subnet": resourceArmSubnet(), + "azurerm_subnet_network_security_group_association": resourceArmSubnetNetworkSecurityGroupAssociation(), + "azurerm_subnet_route_table_association": resourceArmSubnetRouteTableAssociation(), + "azurerm_template_deployment": resourceArmTemplateDeployment(), + "azurerm_traffic_manager_endpoint": resourceArmTrafficManagerEndpoint(), + "azurerm_traffic_manager_profile": resourceArmTrafficManagerProfile(), + "azurerm_user_assigned_identity": resourceArmUserAssignedIdentity(), + "azurerm_virtual_machine": resourceArmVirtualMachine(), + "azurerm_virtual_machine_data_disk_attachment": resourceArmVirtualMachineDataDiskAttachment(), + "azurerm_virtual_machine_extension": resourceArmVirtualMachineExtensions(), + "azurerm_virtual_machine_scale_set": resourceArmVirtualMachineScaleSet(), + "azurerm_virtual_network": resourceArmVirtualNetwork(), + "azurerm_virtual_network_gateway": resourceArmVirtualNetworkGateway(), + "azurerm_virtual_network_gateway_connection": resourceArmVirtualNetworkGatewayConnection(), + "azurerm_virtual_network_peering": resourceArmVirtualNetworkPeering(), }, } diff --git a/azurerm/resource_arm_subnet.go b/azurerm/resource_arm_subnet.go index 82c993d53113..5ac7d928019a 100644 --- a/azurerm/resource_arm_subnet.go +++ b/azurerm/resource_arm_subnet.go @@ -42,13 +42,15 @@ func resourceArmSubnet() *schema.Resource { }, "network_security_group_id": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Deprecated: "Use the `azurerm_subnet_network_security_group_association` resource instead.", }, "route_table_id": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Deprecated: "Use the `azurerm_subnet_route_table_association` resource instead.", }, "ip_configurations": { @@ -99,6 +101,8 @@ func resourceArmSubnetCreate(d *schema.ResourceData, meta interface{}) error { azureRMLockByName(networkSecurityGroupName, networkSecurityGroupResourceName) defer azureRMUnlockByName(networkSecurityGroupName, networkSecurityGroupResourceName) + } else { + properties.NetworkSecurityGroup = nil } if v, ok := d.GetOk("route_table_id"); ok { @@ -114,6 +118,8 @@ func resourceArmSubnetCreate(d *schema.ResourceData, meta interface{}) error { azureRMLockByName(routeTableName, routeTableResourceName) defer azureRMUnlockByName(routeTableName, routeTableResourceName) + } else { + properties.RouteTable = nil } serviceEndpoints, serviceEndpointsErr := expandAzureRmServiceEndpoints(d) @@ -184,9 +190,11 @@ func resourceArmSubnetRead(d *schema.ResourceData, meta interface{}) error { d.Set("network_security_group_id", props.NetworkSecurityGroup.ID) } - if props.RouteTable != nil { - d.Set("route_table_id", props.RouteTable.ID) + var routeTableId string + if props.RouteTable != nil && props.RouteTable.ID != nil { + routeTableId = *props.RouteTable.ID } + d.Set("route_table_id", routeTableId) ips := flattenSubnetIPConfigurations(props.IPConfigurations) if err := d.Set("ip_configurations", ips); err != nil { diff --git a/azurerm/resource_arm_subnet_network_security_group_association.go b/azurerm/resource_arm_subnet_network_security_group_association.go new file mode 100644 index 000000000000..188b97b73391 --- /dev/null +++ b/azurerm/resource_arm_subnet_network_security_group_association.go @@ -0,0 +1,216 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-04-01/network" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmSubnetNetworkSecurityGroupAssociation() *schema.Resource { + return &schema.Resource{ + Create: resourceArmSubnetNetworkSecurityGroupAssociationCreate, + Read: resourceArmSubnetNetworkSecurityGroupAssociationRead, + Delete: resourceArmSubnetNetworkSecurityGroupAssociationDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "subnet_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "network_security_group_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + }, + } +} + +func resourceArmSubnetNetworkSecurityGroupAssociationCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).subnetClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Subnet <-> Network Security Group Association creation.") + + subnetId := d.Get("subnet_id").(string) + networkSecurityGroupId := d.Get("network_security_group_id").(string) + + parsedSubnetId, err := parseAzureResourceID(subnetId) + if err != nil { + return err + } + + networkSecurityGroupName, err := parseNetworkSecurityGroupName(networkSecurityGroupId) + if err != nil { + return err + } + + azureRMLockByName(networkSecurityGroupName, networkSecurityGroupResourceName) + defer azureRMUnlockByName(networkSecurityGroupName, networkSecurityGroupResourceName) + + subnetName := parsedSubnetId.Path["subnets"] + virtualNetworkName := parsedSubnetId.Path["virtualNetworks"] + resourceGroup := parsedSubnetId.ResourceGroup + + azureRMLockByName(virtualNetworkName, virtualNetworkResourceName) + defer azureRMUnlockByName(virtualNetworkName, virtualNetworkResourceName) + + subnet, err := client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(subnet.Response) { + return fmt.Errorf("Subnet %q (Virtual Network %q / Resource Group %q) was not found!", subnetName, virtualNetworkName, resourceGroup) + } + + return fmt.Errorf("Error retrieving Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + if props := subnet.SubnetPropertiesFormat; props != nil { + props.NetworkSecurityGroup = &network.SecurityGroup{ + ID: utils.String(networkSecurityGroupId), + } + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, virtualNetworkName, subnetName, subnet) + if err != nil { + return fmt.Errorf("Error updating Route Table Association for Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting for completion of Route Table Association for Subnet %q (VN %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + if err != nil { + return fmt.Errorf("Error retrieving Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + d.SetId(*read.ID) + + return resourceArmSubnetNetworkSecurityGroupAssociationRead(d, meta) +} + +func resourceArmSubnetNetworkSecurityGroupAssociationRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).subnetClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + virtualNetworkName := id.Path["virtualNetworks"] + subnetName := id.Path["subnets"] + + resp, err := client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Subnet %q (Virtual Network %q / Resource Group %q) could not be found - removing from state!", subnetName, virtualNetworkName, resourceGroup) + d.SetId("") + return nil + } + return fmt.Errorf("Error retrieving Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + props := resp.SubnetPropertiesFormat + if props == nil { + return fmt.Errorf("Error: `properties` was nil for Subnet %q (Virtual Network %q / Resource Group %q)", subnetName, virtualNetworkName, resourceGroup) + } + + securityGroup := props.NetworkSecurityGroup + if securityGroup == nil { + log.Printf("[DEBUG] Subnet %q (Virtual Network %q / Resource Group %q) doesn't have a Network Security Group - removing from state!", subnetName, virtualNetworkName, resourceGroup) + d.SetId("") + return nil + } + + d.Set("subnet_id", resp.ID) + d.Set("network_security_group_id", securityGroup.ID) + + return nil +} + +func resourceArmSubnetNetworkSecurityGroupAssociationDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).subnetClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + virtualNetworkName := id.Path["virtualNetworks"] + subnetName := id.Path["subnets"] + + // retrieve the subnet + read, err := client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + log.Printf("[DEBUG] Subnet %q (Virtual Network %q / Resource Group %q) could not be found - removing from state!", subnetName, virtualNetworkName, resourceGroup) + return nil + } + + return fmt.Errorf("Error retrieving Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + props := read.SubnetPropertiesFormat + if props == nil { + return fmt.Errorf("`Properties` was nil for Subnet %q (Virtual Network %q / Resource Group %q)", subnetName, virtualNetworkName, resourceGroup) + } + + if props.NetworkSecurityGroup == nil || props.NetworkSecurityGroup.ID == nil { + log.Printf("[DEBUG] Subnet %q (Virtual Network %q / Resource Group %q) has no Network Security Group - removing from state!", subnetName, virtualNetworkName, resourceGroup) + return nil + } + + // once we have the network security group id to lock on, lock on that + networkSecurityGroupName, err := parseNetworkSecurityGroupName(*props.NetworkSecurityGroup.ID) + if err != nil { + return err + } + + azureRMLockByName(networkSecurityGroupName, networkSecurityGroupResourceName) + defer azureRMUnlockByName(networkSecurityGroupName, networkSecurityGroupResourceName) + + azureRMLockByName(virtualNetworkName, virtualNetworkResourceName) + defer azureRMUnlockByName(virtualNetworkName, virtualNetworkResourceName) + + azureRMLockByName(subnetName, subnetResourceName) + defer azureRMUnlockByName(subnetName, subnetResourceName) + + // then re-retrieve it to ensure we've got the latest state + read, err = client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + log.Printf("[DEBUG] Subnet %q (Virtual Network %q / Resource Group %q) could not be found - removing from state!", subnetName, virtualNetworkName, resourceGroup) + return nil + } + + return fmt.Errorf("Error retrieving Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + read.SubnetPropertiesFormat.NetworkSecurityGroup = nil + + future, err := client.CreateOrUpdate(ctx, resourceGroup, virtualNetworkName, subnetName, read) + if err != nil { + return fmt.Errorf("Error removing Network Security Group Association from Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for removal of Network Security Group Association from Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + return nil +} diff --git a/azurerm/resource_arm_subnet_network_security_group_association_test.go b/azurerm/resource_arm_subnet_network_security_group_association_test.go new file mode 100644 index 000000000000..53fe6fc96857 --- /dev/null +++ b/azurerm/resource_arm_subnet_network_security_group_association_test.go @@ -0,0 +1,234 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMSubnetNetworkSecurityGroupAssociation_basic(t *testing.T) { + resourceName := "azurerm_subnet_network_security_group_association.test" + ri := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + // intentional as this is a Virtual Resource + CheckDestroy: testCheckAzureRMSubnetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSubnetNetworkSecurityGroupAssociation_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSubnetNetworkSecurityGroupAssociationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMSubnetNetworkSecurityGroupAssociation_deleted(t *testing.T) { + resourceName := "azurerm_subnet_network_security_group_association.test" + ri := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + // intentional as this is a Virtual Resource + CheckDestroy: testCheckAzureRMSubnetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSubnetNetworkSecurityGroupAssociation_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSubnetNetworkSecurityGroupAssociationExists(resourceName), + testCheckAzureRMSubnetNetworkSecurityGroupAssociationDisappears(resourceName), + testCheckAzureRMSubnetHasNoNetworkSecurityGroup(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testCheckAzureRMSubnetNetworkSecurityGroupAssociationExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + subnetId := rs.Primary.Attributes["subnet_id"] + parsedId, err := parseAzureResourceID(subnetId) + if err != nil { + return err + } + + resourceGroupName := parsedId.ResourceGroup + virtualNetworkName := parsedId.Path["virtualNetworks"] + subnetName := parsedId.Path["subnets"] + + client := testAccProvider.Meta().(*ArmClient).subnetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroupName, virtualNetworkName, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Subnet %q (Virtual Network %q / Resource Group: %q) does not exist", subnetName, virtualNetworkName, resourceGroupName) + } + + return fmt.Errorf("Bad: Get on subnetClient: %+v", err) + } + + props := resp.SubnetPropertiesFormat + if props == nil { + return fmt.Errorf("Properties was nil for Subnet %q (Virtual Network %q / Resource Group: %q)", subnetName, virtualNetworkName, resourceGroupName) + } + + if props.NetworkSecurityGroup == nil || props.NetworkSecurityGroup.ID == nil { + return fmt.Errorf("No Network Security Group association exists for Subnet %q (Virtual Network %q / Resource Group: %q)", subnetName, virtualNetworkName, resourceGroupName) + } + + return nil + } +} + +func testCheckAzureRMSubnetNetworkSecurityGroupAssociationDisappears(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + subnetId := rs.Primary.Attributes["subnet_id"] + parsedId, err := parseAzureResourceID(subnetId) + if err != nil { + return err + } + + resourceGroup := parsedId.ResourceGroup + virtualNetworkName := parsedId.Path["virtualNetworks"] + subnetName := parsedId.Path["subnets"] + + client := testAccProvider.Meta().(*ArmClient).subnetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + read, err := client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + if err != nil { + if !utils.ResponseWasNotFound(read.Response) { + return fmt.Errorf("Error retrieving Subnet %q (Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + } + + read.SubnetPropertiesFormat.NetworkSecurityGroup = nil + + future, err := client.CreateOrUpdate(ctx, resourceGroup, virtualNetworkName, subnetName, read) + if err != nil { + return fmt.Errorf("Error updating Subnet %q (Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting for completion of Subnet %q (Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + return nil + } +} + +func testCheckAzureRMSubnetHasNoNetworkSecurityGroup(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + subnetId := rs.Primary.Attributes["subnet_id"] + parsedId, err := parseAzureResourceID(subnetId) + if err != nil { + return err + } + + resourceGroupName := parsedId.ResourceGroup + virtualNetworkName := parsedId.Path["virtualNetworks"] + subnetName := parsedId.Path["subnets"] + + client := testAccProvider.Meta().(*ArmClient).subnetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroupName, virtualNetworkName, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Subnet %q (Virtual Network %q / Resource Group: %q) does not exist", subnetName, virtualNetworkName, resourceGroupName) + } + + return fmt.Errorf("Bad: Get on subnetClient: %+v", err) + } + + props := resp.SubnetPropertiesFormat + if props == nil { + return fmt.Errorf("Properties was nil for Subnet %q (Virtual Network %q / Resource Group: %q)", subnetName, virtualNetworkName, resourceGroupName) + } + + if props.NetworkSecurityGroup != nil && ((props.NetworkSecurityGroup.ID == nil) || (props.NetworkSecurityGroup.ID != nil && *props.NetworkSecurityGroup.ID == "")) { + return fmt.Errorf("No Network Security Group should exist for Subnet %q (Virtual Network %q / Resource Group: %q) but got %q", subnetName, virtualNetworkName, resourceGroupName, *props.NetworkSecurityGroup.ID) + } + + return nil + } +} + +func testAccAzureRMSubnetNetworkSecurityGroupAssociation_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" + network_security_group_id = "${azurerm_network_security_group.test.id}" +} + +resource "azurerm_network_security_group" "test" { + name = "acctestnsg%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + security_rule { + name = "test123" + priority = 100 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "*" + destination_address_prefix = "*" + } +} + +resource "azurerm_subnet_network_security_group_association" "test" { + subnet_id = "${azurerm_subnet.test.id}" + network_security_group_id = "${azurerm_network_security_group.test.id}" +} +`, rInt, location, rInt, rInt, rInt) +} diff --git a/azurerm/resource_arm_subnet_route_table_association.go b/azurerm/resource_arm_subnet_route_table_association.go new file mode 100644 index 000000000000..99f32d32f3cd --- /dev/null +++ b/azurerm/resource_arm_subnet_route_table_association.go @@ -0,0 +1,216 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-04-01/network" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmSubnetRouteTableAssociation() *schema.Resource { + return &schema.Resource{ + Create: resourceArmSubnetRouteTableAssociationCreate, + Read: resourceArmSubnetRouteTableAssociationRead, + Delete: resourceArmSubnetRouteTableAssociationDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "subnet_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + + "route_table_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: azure.ValidateResourceID, + }, + }, + } +} + +func resourceArmSubnetRouteTableAssociationCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).subnetClient + ctx := meta.(*ArmClient).StopContext + + log.Printf("[INFO] preparing arguments for Subnet <-> Route Table Association creation.") + + subnetId := d.Get("subnet_id").(string) + routeTableId := d.Get("route_table_id").(string) + + parsedSubnetId, err := parseAzureResourceID(subnetId) + if err != nil { + return err + } + + routeTableName, err := parseRouteTableName(routeTableId) + if err != nil { + return err + } + + azureRMLockByName(routeTableName, routeTableResourceName) + defer azureRMUnlockByName(routeTableName, routeTableResourceName) + + subnetName := parsedSubnetId.Path["subnets"] + virtualNetworkName := parsedSubnetId.Path["virtualNetworks"] + resourceGroup := parsedSubnetId.ResourceGroup + + azureRMLockByName(virtualNetworkName, virtualNetworkResourceName) + defer azureRMUnlockByName(virtualNetworkName, virtualNetworkResourceName) + + subnet, err := client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(subnet.Response) { + return fmt.Errorf("Subnet %q (Virtual Network %q / Resource Group %q) was not found!", subnetName, virtualNetworkName, resourceGroup) + } + + return fmt.Errorf("Error retrieving Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + if props := subnet.SubnetPropertiesFormat; props != nil { + props.RouteTable = &network.RouteTable{ + ID: utils.String(routeTableId), + } + } + + future, err := client.CreateOrUpdate(ctx, resourceGroup, virtualNetworkName, subnetName, subnet) + if err != nil { + return fmt.Errorf("Error updating Route Table Association for Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting for completion of Route Table Association for Subnet %q (VN %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + read, err := client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + if err != nil { + return fmt.Errorf("Error retrieving Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + d.SetId(*read.ID) + + return resourceArmSubnetRouteTableAssociationRead(d, meta) +} + +func resourceArmSubnetRouteTableAssociationRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).subnetClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + virtualNetworkName := id.Path["virtualNetworks"] + subnetName := id.Path["subnets"] + + resp, err := client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Subnet %q (Virtual Network %q / Resource Group %q) could not be found - removing from state!", subnetName, virtualNetworkName, resourceGroup) + d.SetId("") + return nil + } + return fmt.Errorf("Error retrieving Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + props := resp.SubnetPropertiesFormat + if props == nil { + return fmt.Errorf("Error: `properties` was nil for Subnet %q (Virtual Network %q / Resource Group %q)", subnetName, virtualNetworkName, resourceGroup) + } + + routeTable := props.RouteTable + if routeTable == nil { + log.Printf("[DEBUG] Subnet %q (Virtual Network %q / Resource Group %q) doesn't have a Route Table - removing from state!", subnetName, virtualNetworkName, resourceGroup) + d.SetId("") + return nil + } + + d.Set("subnet_id", resp.ID) + d.Set("route_table_id", routeTable.ID) + + return nil +} + +func resourceArmSubnetRouteTableAssociationDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).subnetClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resourceGroup := id.ResourceGroup + virtualNetworkName := id.Path["virtualNetworks"] + subnetName := id.Path["subnets"] + + // retrieve the subnet + read, err := client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + log.Printf("[DEBUG] Subnet %q (Virtual Network %q / Resource Group %q) could not be found - removing from state!", subnetName, virtualNetworkName, resourceGroup) + return nil + } + + return fmt.Errorf("Error retrieving Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + props := read.SubnetPropertiesFormat + if props == nil { + return fmt.Errorf("`Properties` was nil for Subnet %q (Virtual Network %q / Resource Group %q)", subnetName, virtualNetworkName, resourceGroup) + } + + if props.RouteTable == nil || props.RouteTable.ID == nil { + log.Printf("[DEBUG] Subnet %q (Virtual Network %q / Resource Group %q) has no Route Table - removing from state!", subnetName, virtualNetworkName, resourceGroup) + return nil + } + + // once we have the route table id to lock on, lock on that + routeTableName, err := parseRouteTableName(*props.RouteTable.ID) + if err != nil { + return err + } + + azureRMLockByName(routeTableName, routeTableResourceName) + defer azureRMUnlockByName(routeTableName, routeTableResourceName) + + azureRMLockByName(virtualNetworkName, virtualNetworkResourceName) + defer azureRMUnlockByName(virtualNetworkName, virtualNetworkResourceName) + + azureRMLockByName(subnetName, subnetResourceName) + defer azureRMUnlockByName(subnetName, subnetResourceName) + + // then re-retrieve it to ensure we've got the latest state + read, err = client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(read.Response) { + log.Printf("[DEBUG] Subnet %q (Virtual Network %q / Resource Group %q) could not be found - removing from state!", subnetName, virtualNetworkName, resourceGroup) + return nil + } + + return fmt.Errorf("Error retrieving Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + read.SubnetPropertiesFormat.RouteTable = nil + + future, err := client.CreateOrUpdate(ctx, resourceGroup, virtualNetworkName, subnetName, read) + if err != nil { + return fmt.Errorf("Error removing Route Table Association from Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting for removal of Route Table Association from Subnet %q (Virtual Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + return nil +} diff --git a/azurerm/resource_arm_subnet_route_table_association_test.go b/azurerm/resource_arm_subnet_route_table_association_test.go new file mode 100644 index 000000000000..ac2e669b3c21 --- /dev/null +++ b/azurerm/resource_arm_subnet_route_table_association_test.go @@ -0,0 +1,229 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMSubnetRouteTableAssociation_basic(t *testing.T) { + resourceName := "azurerm_subnet_route_table_association.test" + ri := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + // intentional since this is a Virtual Resource + CheckDestroy: testCheckAzureRMSubnetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSubnetRouteTableAssociation_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSubnetRouteTableAssociationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMSubnetRouteTableAssociation_deleted(t *testing.T) { + resourceName := "azurerm_subnet_route_table_association.test" + ri := acctest.RandInt() + location := testLocation() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + // intentional since this is a Virtual Resource + CheckDestroy: testCheckAzureRMSubnetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMSubnetRouteTableAssociation_basic(ri, location), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSubnetRouteTableAssociationExists(resourceName), + testCheckAzureRMSubnetRouteTableAssociationDisappears(resourceName), + testCheckAzureRMSubnetHasNoRouteTable(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testCheckAzureRMSubnetRouteTableAssociationExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + subnetId := rs.Primary.Attributes["subnet_id"] + parsedId, err := parseAzureResourceID(subnetId) + if err != nil { + return err + } + + resourceGroupName := parsedId.ResourceGroup + virtualNetworkName := parsedId.Path["virtualNetworks"] + subnetName := parsedId.Path["subnets"] + + client := testAccProvider.Meta().(*ArmClient).subnetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroupName, virtualNetworkName, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Subnet %q (Virtual Network %q / Resource Group: %q) does not exist", subnetName, virtualNetworkName, resourceGroupName) + } + + return fmt.Errorf("Bad: Get on subnetClient: %+v", err) + } + + props := resp.SubnetPropertiesFormat + if props == nil { + return fmt.Errorf("Properties was nil for Subnet %q (Virtual Network %q / Resource Group: %q)", subnetName, virtualNetworkName, resourceGroupName) + } + + if props.RouteTable == nil || props.RouteTable.ID == nil { + return fmt.Errorf("No Route Table association exists for Subnet %q (Virtual Network %q / Resource Group: %q)", subnetName, virtualNetworkName, resourceGroupName) + } + + return nil + } +} + +func testCheckAzureRMSubnetRouteTableAssociationDisappears(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + subnetId := rs.Primary.Attributes["subnet_id"] + parsedId, err := parseAzureResourceID(subnetId) + if err != nil { + return err + } + + resourceGroup := parsedId.ResourceGroup + virtualNetworkName := parsedId.Path["virtualNetworks"] + subnetName := parsedId.Path["subnets"] + + client := testAccProvider.Meta().(*ArmClient).subnetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + read, err := client.Get(ctx, resourceGroup, virtualNetworkName, subnetName, "") + if err != nil { + if !utils.ResponseWasNotFound(read.Response) { + return fmt.Errorf("Error retrieving Subnet %q (Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + } + + read.SubnetPropertiesFormat.RouteTable = nil + + future, err := client.CreateOrUpdate(ctx, resourceGroup, virtualNetworkName, subnetName, read) + if err != nil { + return fmt.Errorf("Error updating Subnet %q (Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting for completion of Subnet %q (Network %q / Resource Group %q): %+v", subnetName, virtualNetworkName, resourceGroup, err) + } + + return nil + } +} + +func testCheckAzureRMSubnetHasNoRouteTable(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + subnetId := rs.Primary.Attributes["subnet_id"] + parsedId, err := parseAzureResourceID(subnetId) + if err != nil { + return err + } + + resourceGroupName := parsedId.ResourceGroup + virtualNetworkName := parsedId.Path["virtualNetworks"] + subnetName := parsedId.Path["subnets"] + + client := testAccProvider.Meta().(*ArmClient).subnetClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroupName, virtualNetworkName, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Subnet %q (Virtual Network %q / Resource Group: %q) does not exist", subnetName, virtualNetworkName, resourceGroupName) + } + + return fmt.Errorf("Bad: Get on subnetClient: %+v", err) + } + + props := resp.SubnetPropertiesFormat + if props == nil { + return fmt.Errorf("Properties was nil for Subnet %q (Virtual Network %q / Resource Group: %q)", subnetName, virtualNetworkName, resourceGroupName) + } + + if props.RouteTable != nil && ((props.RouteTable.ID == nil) || (props.RouteTable.ID != nil && *props.RouteTable.ID == "")) { + return fmt.Errorf("No Route Table should exist for Subnet %q (Virtual Network %q / Resource Group: %q) but got %q", subnetName, virtualNetworkName, resourceGroupName, *props.RouteTable.ID) + } + + return nil + } +} + +func testAccAzureRMSubnetRouteTableAssociation_basic(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%d" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "acctestsubnet%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" + route_table_id = "${azurerm_route_table.test.id}" +} + +resource "azurerm_route_table" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + route { + name = "acctest-%d" + address_prefix = "10.100.0.0/14" + next_hop_type = "VirtualAppliance" + next_hop_in_ip_address = "10.10.1.1" + } +} + +resource "azurerm_subnet_route_table_association" "test" { + subnet_id = "${azurerm_subnet.test.id}" + route_table_id = "${azurerm_route_table.test.id}" +} +`, rInt, location, rInt, rInt, rInt, rInt) +} diff --git a/azurerm/resource_arm_subnet_test.go b/azurerm/resource_arm_subnet_test.go index af95e34a828f..28e8ec9c409c 100644 --- a/azurerm/resource_arm_subnet_test.go +++ b/azurerm/resource_arm_subnet_test.go @@ -424,6 +424,7 @@ resource "azurerm_subnet" "test" { resource_group_name = "${azurerm_resource_group.test.name}" virtual_network_name = "${azurerm_virtual_network.test.name}" address_prefix = "10.0.2.0/24" + route_table_id = "" } resource "azurerm_route_table" "test" { diff --git a/website/azurerm.erb b/website/azurerm.erb index 32afed36b18a..0831edc7afc7 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -891,10 +891,18 @@ azurerm_route_table - > + > azurerm_subnet + > + azurerm_subnet_network_security_group_association + + + > + azurerm_subnet_route_table_association + + > azurerm_traffic_manager_endpoint diff --git a/website/docs/r/route_table.html.markdown b/website/docs/r/route_table.html.markdown index fcf6384b2a05..5c818cad148c 100644 --- a/website/docs/r/route_table.html.markdown +++ b/website/docs/r/route_table.html.markdown @@ -23,8 +23,7 @@ resource "azurerm_route_table" "test" { name = "acceptanceTestSecurityGroup1" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - -disable_bgp_route_propagation = false + disable_bgp_route_propagation = false route { name = "route1" diff --git a/website/docs/r/subnet.html.markdown b/website/docs/r/subnet.html.markdown index e2e3c2bbb7c0..a703e5fab301 100644 --- a/website/docs/r/subnet.html.markdown +++ b/website/docs/r/subnet.html.markdown @@ -1,7 +1,7 @@ --- layout: "azurerm" page_title: "Azure Resource Manager: azurerm_subnet" -sidebar_current: "docs-azurerm-resource-network-subnet" +sidebar_current: "docs-azurerm-resource-network-subnet-x" description: |- Manages a subnet. Subnets represent network segments within the IP space defined by the virtual network. @@ -50,9 +50,13 @@ The following arguments are supported: * `address_prefix` - (Required) The address prefix to use for the subnet. -* `network_security_group_id` - (Optional) The ID of the Network Security Group to associate with the subnet. +* `network_security_group_id` - (Optional / **Deprecated**) The ID of the Network Security Group to associate with the subnet. -* `route_table_id` - (Optional) The ID of the Route Table to associate with the subnet. +-> **NOTE:** At this time Subnet <-> Network Security Group associations need to be configured both using this field (which is now Deprecated) and/or using the `azurerm_subnet_network_security_group_association` resource. This field field is deprecated and will be removed in favour of that resource in the next major version (2.0) of the AzureRM Provider. + +* `route_table_id` - (Optional / **Deprecated**) The ID of the Route Table to associate with the subnet. + +-> **NOTE:** At this time Subnet <-> Route Table associations need to be configured both using this field (which is now Deprecated) and/or using the `azurerm_subnet_route_table_association` resource. This field is deprecated and will be removed in favour of that resource in the next major version (2.0) of the AzureRM Provider. * `service_endpoints` - (Optional) The list of Service endpoints to associate with the subnet. Possible values include: `Microsoft.Storage`, `Microsoft.Sql`. diff --git a/website/docs/r/subnet_network_security_group_association.html.markdown b/website/docs/r/subnet_network_security_group_association.html.markdown new file mode 100644 index 000000000000..a0536989ba0a --- /dev/null +++ b/website/docs/r/subnet_network_security_group_association.html.markdown @@ -0,0 +1,83 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_subnet_network_security_group_association" +sidebar_current: "docs-azurerm-resource-network-subnet-network-security-group-association" +description: |- + Associates a [Network Security Group](network_security_group.html) with a [Subnet](subnet.html) within a [Virtual Network](virtual_network.html). + +--- + +# azurerm_subnet_network_security_group_association + +Associates a [Network Security Group](network_security_group.html) with a [Subnet](subnet.html) within a [Virtual Network](virtual_network.html). + +-> **NOTE:** Subnet <-> Network Security Group associations currently need to be configured on both this resource and using the `network_security_group_id` field on the `azurerm_subnet` resource. The next major version of the AzureRM Provider (2.0) will remove the `network_security_group_id` field from the `azurerm_subnet` resource such that this resource is used to link resources in future. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_virtual_network" "test" { + name = "example-network" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "frontend" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" + network_security_group_id = "${azurerm_network_security_group.test.id}" +} + +resource "azurerm_network_security_group" "test" { + name = "example-nsg" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + security_rule { + name = "test123" + priority = 100 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "*" + destination_address_prefix = "*" + } +} + +resource "azurerm_subnet_network_security_group_association" "test" { + subnet_id = "${azurerm_subnet.test.id}" + network_security_group_id = "${azurerm_network_security_group.test.id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `network_security_group_id` - (Optional) The ID of the Network Security Group which should be associated with the Subnet. Changing this forces a new resource to be created. + +* `subnet_id` - (Required) The ID of the Subnet. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Subnet. + +## Import + +Subnet <-> Network Security Group Associations can be imported using the `resource id` of the Subnet, e.g. + +```shell +terraform import azurerm_subnet_network_security_group_association.association1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Network/virtualNetworks/myvnet1/subnets/mysubnet1 +``` diff --git a/website/docs/r/subnet_route_table_association.html.markdown b/website/docs/r/subnet_route_table_association.html.markdown new file mode 100644 index 000000000000..f0a66d032655 --- /dev/null +++ b/website/docs/r/subnet_route_table_association.html.markdown @@ -0,0 +1,78 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_subnet_route_table_association" +sidebar_current: "docs-azurerm-resource-network-subnet-route-table-association" +description: |- + Associates a [Route Table](route_table.html) with a [Subnet](subnet.html) within a [Virtual Network](virtual_network.html). + +--- + +# azurerm_subnet_route_table_association + +Associates a [Route Table](route_table.html) with a [Subnet](subnet.html) within a [Virtual Network](virtual_network.html). + +-> **NOTE:** Subnet <-> Route Table associations currently need to be configured on both this resource and using the `route_table_id` field on the `azurerm_subnet` resource. The next major version of the AzureRM Provider (2.0) will remove the `route_table_id` field from the `azurerm_subnet` resource such that this resource is used to link resources in future. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_virtual_network" "test" { + name = "example-network" + address_space = ["10.0.0.0/16"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test" { + name = "frontend" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.0.2.0/24" + route_table_id = "${azurerm_route_table.test.id}" +} + +resource "azurerm_route_table" "test" { + name = "example-routetable" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + + route { + name = "example" + address_prefix = "10.100.0.0/14" + next_hop_type = "VirtualAppliance" + next_hop_in_ip_address = "10.10.1.1" + } +} + +resource "azurerm_subnet_route_table_association" "test" { + subnet_id = "${azurerm_subnet.test.id}" + route_table_id = "${azurerm_route_table.test.id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `route_table_id` - (Optional) The ID of the Route Table which should be associated with the Subnet. Changing this forces a new resource to be created. + +* `subnet_id` - (Required) The ID of the Subnet. Changing this forces a new resource to be created. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Subnet. + +## Import + +Subnet Route Table Associations can be imported using the `resource id` of the Subnet, e.g. + +```shell +terraform import azurerm_subnet_route_table_association.association1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Network/virtualNetworks/myvnet1/subnets/mysubnet1 +``` From 57233951d51d24e7f3b33e1d222d82273331655f Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Fri, 12 Oct 2018 23:26:31 -1000 Subject: [PATCH 31/35] Updating to include #1933 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39175f120f10..0b06a13eda0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ FEATURES: * **New Resource:** `azurerm_dev_test_windows_virtual_machine` [GH-2058] * **New Resource:** `azurerm_security_center_contact` [GH-2045] * **New Resource:** `azurerm_security_center_subscription_pricing` [GH-2043] +* **New Resource:** `azurerm_subnet_network_security_group_association` [GH-1933] +* **New Resource:** `azurerm_subnet_route_table_association ` [GH-1933] BUG FIXES: From 841b37459e42ef299f1334e32f2d227f6ac93cff Mon Sep 17 00:00:00 2001 From: kt Date: Sat, 13 Oct 2018 14:19:58 -0700 Subject: [PATCH 32/35] Address PR #2072 comments --- .../resource_arm_security_center_workspace.go | 26 +++++++++++++++---- ...urce_arm_security_center_workspace_test.go | 2 +- .../docs/r/security_center_contact.markdown | 4 +++ .../docs/r/security_center_workspace.markdown | 4 ++- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/azurerm/resource_arm_security_center_workspace.go b/azurerm/resource_arm_security_center_workspace.go index f9253ec80121..a5d5acd600f4 100644 --- a/azurerm/resource_arm_security_center_workspace.go +++ b/azurerm/resource_arm_security_center_workspace.go @@ -14,7 +14,7 @@ import ( //only valid name is default // Message="Invalid workspace settings name 'kttest' , only default is allowed " -const resourceArmSecurityCenterWorkspaceName = "default" +const securityCenterWorkspaceName = "default" func resourceArmSecurityCenterWorkspace() *schema.Resource { return &schema.Resource{ @@ -47,7 +47,23 @@ func resourceArmSecurityCenterWorkspaceCreateUpdate(d *schema.ResourceData, meta client := meta.(*ArmClient).securityCenterWorkspaceClient ctx := meta.(*ArmClient).StopContext - name := resourceArmSecurityCenterWorkspaceName + priceClient := meta.(*ArmClient).securityCenterPricingClient + + //get pricing tier, workspace can only be configured when tier is not Free. + //API does not error, it just doesn't set the workspace scope + price, err := priceClient.GetSubscriptionPricing(ctx, securityCenterConfigurationSubscriptionPricingName) + if err != nil { + return fmt.Errorf("Error reading Security Center Subscription pricing: %+v", err) + } + + if price.PricingProperties == nil { + return fmt.Errorf("Security Center Subscription pricing propertier is nil") + } + if price.PricingProperties.PricingTier == security.Free { + return fmt.Errorf("Security Center Subscription workspace cannot be set when pricing tier is `Free`") + } + + name := securityCenterWorkspaceName contact := security.WorkspaceSetting{ WorkspaceSettingProperties: &security.WorkspaceSettingProperties{ @@ -71,7 +87,7 @@ func resourceArmSecurityCenterWorkspaceCreateUpdate(d *schema.ResourceData, meta stateConf := &resource.StateChangeConf{ Pending: []string{"Waiting"}, Target: []string{"Populated"}, - Timeout: 60 * time.Minute, + Timeout: 15 * time.Minute, MinTimeout: 30 * time.Second, Refresh: func() (interface{}, string, error) { @@ -106,7 +122,7 @@ func resourceArmSecurityCenterWorkspaceRead(d *schema.ResourceData, meta interfa client := meta.(*ArmClient).securityCenterWorkspaceClient ctx := meta.(*ArmClient).StopContext - resp, err := client.Get(ctx, resourceArmSecurityCenterWorkspaceName) + resp, err := client.Get(ctx, securityCenterWorkspaceName) if err != nil { if utils.ResponseWasNotFound(resp.Response) { log.Printf("[DEBUG] Security Center Subscription Workspace was not found: %v", err) @@ -129,7 +145,7 @@ func resourceArmSecurityCenterWorkspaceDelete(_ *schema.ResourceData, meta inter client := meta.(*ArmClient).securityCenterWorkspaceClient ctx := meta.(*ArmClient).StopContext - resp, err := client.Delete(ctx, resourceArmSecurityCenterWorkspaceName) + resp, err := client.Delete(ctx, securityCenterWorkspaceName) if err != nil { if utils.ResponseWasNotFound(resp) { log.Printf("[DEBUG] Security Center Subscription Workspace was not found: %v", err) diff --git a/azurerm/resource_arm_security_center_workspace_test.go b/azurerm/resource_arm_security_center_workspace_test.go index c6eadaa56e27..9498c1efeb26 100644 --- a/azurerm/resource_arm_security_center_workspace_test.go +++ b/azurerm/resource_arm_security_center_workspace_test.go @@ -105,7 +105,7 @@ func testCheckAzureRMSecurityCenterWorkspaceDestroy(s *terraform.State) error { continue } - resp, err := client.Get(ctx, resourceArmSecurityCenterWorkspaceName) + resp, err := client.Get(ctx, securityCenterWorkspaceName) if err != nil { if utils.ResponseWasNotFound(resp.Response) { return nil diff --git a/website/docs/r/security_center_contact.markdown b/website/docs/r/security_center_contact.markdown index a7a3c081831a..fb9b07e942db 100644 --- a/website/docs/r/security_center_contact.markdown +++ b/website/docs/r/security_center_contact.markdown @@ -10,6 +10,10 @@ description: |- Manages the subscription's Security Center Contact. +~> **NOTE:** Owner access permission is required. + +~> **NOTE:** The subscription's pricing model can not be `Free` for this to have any affect and it may take up to 15-30 minutes after switching pricing tiers for it to work. + ## Example Usage ```hcl diff --git a/website/docs/r/security_center_workspace.markdown b/website/docs/r/security_center_workspace.markdown index f5f4c04a6a4c..854b1dc13ebc 100644 --- a/website/docs/r/security_center_workspace.markdown +++ b/website/docs/r/security_center_workspace.markdown @@ -10,6 +10,8 @@ description: |- Manages the subscription's Security Center Workspace. + + ## Example Usage ```hcl @@ -49,5 +51,5 @@ The following attributes are exported: The contact can be imported using the `resource id`, e.g. ```shell -terraform import azurerm_securitycenter_workspace.example /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Security/securityWorkspaces/default +terraform import azurerm_security_center_workspace.example /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Security/workspaceSettings/default ``` From e592b322bd00daddc65f73bc6a68529cf3797ab2 Mon Sep 17 00:00:00 2001 From: kt Date: Sat, 13 Oct 2018 19:31:28 -0700 Subject: [PATCH 33/35] go fmt --- azurerm/provider.go | 2 +- azurerm/resource_arm_security_center_workspace.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/azurerm/provider.go b/azurerm/provider.go index 94a9d5434b19..08cf4b539ec0 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -248,6 +248,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(), @@ -290,7 +291,6 @@ func Provider() terraform.ResourceProvider { "azurerm_virtual_network_gateway": resourceArmVirtualNetworkGateway(), "azurerm_virtual_network_gateway_connection": resourceArmVirtualNetworkGatewayConnection(), "azurerm_virtual_network_peering": resourceArmVirtualNetworkPeering(), - "azurerm_security_center_workspace": resourceArmSecurityCenterWorkspace(), }, } diff --git a/azurerm/resource_arm_security_center_workspace.go b/azurerm/resource_arm_security_center_workspace.go index a5d5acd600f4..2e605c1b72d4 100644 --- a/azurerm/resource_arm_security_center_workspace.go +++ b/azurerm/resource_arm_security_center_workspace.go @@ -51,7 +51,7 @@ func resourceArmSecurityCenterWorkspaceCreateUpdate(d *schema.ResourceData, meta //get pricing tier, workspace can only be configured when tier is not Free. //API does not error, it just doesn't set the workspace scope - price, err := priceClient.GetSubscriptionPricing(ctx, securityCenterConfigurationSubscriptionPricingName) + price, err := priceClient.GetSubscriptionPricing(ctx, securityCenterSubscriptionPricingName) if err != nil { return fmt.Errorf("Error reading Security Center Subscription pricing: %+v", err) } From 8d17f21c780e3c7162cf60595e43f9a12127d4c1 Mon Sep 17 00:00:00 2001 From: kt Date: Sat, 13 Oct 2018 20:25:03 -0700 Subject: [PATCH 34/35] combined security center pricing and workspace tests to prevent conflicts --- .../resource_arm_security_center_contact.go | 3 +- ...curity_center_subscription_pricing_test.go | 2 +- azurerm/resource_arm_security_center_test.go | 31 +++++++++++++++++ .../resource_arm_security_center_workspace.go | 6 ++-- ...urce_arm_security_center_workspace_test.go | 33 ++++++++++++++----- .../docs/r/security_center_contact.markdown | 4 +-- .../docs/r/security_center_workspace.markdown | 2 ++ 7 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 azurerm/resource_arm_security_center_test.go diff --git a/azurerm/resource_arm_security_center_contact.go b/azurerm/resource_arm_security_center_contact.go index 6d1d24529d01..027b9f37d691 100644 --- a/azurerm/resource_arm_security_center_contact.go +++ b/azurerm/resource_arm_security_center_contact.go @@ -2,11 +2,12 @@ package azurerm import ( "fmt" + "log" + "github.com/Azure/azure-sdk-for-go/services/preview/security/mgmt/2017-08-01-preview/security" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" - "log" ) //seems you can only set one contact: diff --git a/azurerm/resource_arm_security_center_subscription_pricing_test.go b/azurerm/resource_arm_security_center_subscription_pricing_test.go index cc3504667fd3..6629cdcafa44 100644 --- a/azurerm/resource_arm_security_center_subscription_pricing_test.go +++ b/azurerm/resource_arm_security_center_subscription_pricing_test.go @@ -9,7 +9,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func TestAccAzureRMSecurityCenterSubscriptionPricing_update(t *testing.T) { +func testAccAzureRMSecurityCenterSubscriptionPricing_update(t *testing.T) { resourceName := "azurerm_security_center_subscription_pricing.test" resource.Test(t, resource.TestCase{ diff --git a/azurerm/resource_arm_security_center_test.go b/azurerm/resource_arm_security_center_test.go new file mode 100644 index 000000000000..4a3ed04a4b07 --- /dev/null +++ b/azurerm/resource_arm_security_center_test.go @@ -0,0 +1,31 @@ +package azurerm + +import ( + "testing" +) + +func TestAccAzureRMSecurityCenter_pricingAndWorkspace(t *testing.T) { + // NOTE: this is a combined test rather than separate split out tests + // due to the workspace tests depending on the current pricing tier + testCases := map[string]map[string]func(t *testing.T){ + "pricing": { + "update": testAccAzureRMSecurityCenterSubscriptionPricing_update, + }, + "workspace": { + "basic": testAccAzureRMSecurityCenterWorkspace_basic, + "update": testAccAzureRMSecurityCenterWorkspace_update, + }, + } + + for group, m := range testCases { + m := m + t.Run(group, func(t *testing.T) { + for name, tc := range m { + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } + }) + } +} diff --git a/azurerm/resource_arm_security_center_workspace.go b/azurerm/resource_arm_security_center_workspace.go index 2e605c1b72d4..670deda4657d 100644 --- a/azurerm/resource_arm_security_center_workspace.go +++ b/azurerm/resource_arm_security_center_workspace.go @@ -2,14 +2,15 @@ package azurerm import ( "fmt" + "log" + "time" + "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 @@ -84,6 +85,7 @@ func resourceArmSecurityCenterWorkspaceCreateUpdate(d *schema.ResourceData, meta } } + //api returns "" for workspace id after an create/update and eventually the new value stateConf := &resource.StateChangeConf{ Pending: []string{"Waiting"}, Target: []string{"Populated"}, diff --git a/azurerm/resource_arm_security_center_workspace_test.go b/azurerm/resource_arm_security_center_workspace_test.go index 9498c1efeb26..01497ab5f9d3 100644 --- a/azurerm/resource_arm_security_center_workspace_test.go +++ b/azurerm/resource_arm_security_center_workspace_test.go @@ -2,16 +2,16 @@ package azurerm import ( "fmt" - "github.com/hashicorp/terraform/helper/acctest" "os" "testing" + "github.com/hashicorp/terraform/helper/acctest" "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) { +func testAccAzureRMSecurityCenterWorkspace_basic(t *testing.T) { resourceName := "azurerm_security_center_workspace.test" ri := acctest.RandInt() @@ -23,7 +23,7 @@ func TestAccAzureRMSecurityCenterWorkspace_basic(t *testing.T) { CheckDestroy: testCheckAzureRMSecurityCenterWorkspaceDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMSecurityCenterWorkspace_basic(ri, testLocation(), scope), + Config: testAccAzureRMSecurityCenterWorkspace_basicCfg(ri, testLocation(), scope), Check: resource.ComposeTestCheckFunc( testCheckAzureRMSecurityCenterWorkspaceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "scope", scope), @@ -34,11 +34,15 @@ func TestAccAzureRMSecurityCenterWorkspace_basic(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + //reset pricing to free + Config: testAccAzureRMSecurityCenterSubscriptionPricing_tier("Free"), + }, }, }) } -func TestAccAzureRMSecurityCenterWorkspace_update(t *testing.T) { +func testAccAzureRMSecurityCenterWorkspace_update(t *testing.T) { resourceName := "azurerm_security_center_workspace.test" ri := acctest.RandInt() @@ -49,14 +53,14 @@ func TestAccAzureRMSecurityCenterWorkspace_update(t *testing.T) { Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccAzureRMSecurityCenterWorkspace_basic(ri, testLocation(), scope), + Config: testAccAzureRMSecurityCenterWorkspace_basicCfg(ri, testLocation(), scope), Check: resource.ComposeTestCheckFunc( testCheckAzureRMSecurityCenterWorkspaceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "scope", scope), ), }, { - Config: testAccAzureRMSecurityCenterWorkspace_differentWorkspace(ri, testLocation(), scope), + Config: testAccAzureRMSecurityCenterWorkspace_differentWorkspaceCfg(ri, testLocation(), scope), Check: resource.ComposeTestCheckFunc( testCheckAzureRMSecurityCenterWorkspaceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "scope", scope), @@ -67,6 +71,10 @@ func TestAccAzureRMSecurityCenterWorkspace_update(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + //reset pricing to free + Config: testAccAzureRMSecurityCenterSubscriptionPricing_tier("Free"), + }, }, }) } @@ -120,8 +128,13 @@ func testCheckAzureRMSecurityCenterWorkspaceDestroy(s *terraform.State) error { return nil } -func testAccAzureRMSecurityCenterWorkspace_basic(rInt int, location, scope string) string { +func testAccAzureRMSecurityCenterWorkspace_basicCfg(rInt int, location, scope string) string { return fmt.Sprintf(` + +resource "azurerm_security_center_subscription_pricing" "test" { + tier = "Standard" +} + resource "azurerm_resource_group" "test" { name = "acctestRG-%[1]d" location = "%[2]s" @@ -141,8 +154,12 @@ resource "azurerm_security_center_workspace" "test" { `, rInt, location, scope) } -func testAccAzureRMSecurityCenterWorkspace_differentWorkspace(rInt int, location, scope string) string { +func testAccAzureRMSecurityCenterWorkspace_differentWorkspaceCfg(rInt int, location, scope string) string { return fmt.Sprintf(` +resource "azurerm_security_center_subscription_pricing" "test" { + tier = "Standard" +} + resource "azurerm_resource_group" "test" { name = "acctestRG-%[1]d" location = "%[2]s" diff --git a/website/docs/r/security_center_contact.markdown b/website/docs/r/security_center_contact.markdown index 73f77972c27b..52a5fdcc0d99 100644 --- a/website/docs/r/security_center_contact.markdown +++ b/website/docs/r/security_center_contact.markdown @@ -10,9 +10,7 @@ description: |- Manages the subscription's Security Center Contact. -~> **NOTE:** Owner access permission is required. - -~> **NOTE:** The subscription's pricing model can not be `Free` for this to have any affect and it may take up to 15-30 minutes after switching pricing tiers for it to work. +~> **NOTE:** Owner access permission is required. ## Example Usage diff --git a/website/docs/r/security_center_workspace.markdown b/website/docs/r/security_center_workspace.markdown index 854b1dc13ebc..6ed8aaaea36e 100644 --- a/website/docs/r/security_center_workspace.markdown +++ b/website/docs/r/security_center_workspace.markdown @@ -10,7 +10,9 @@ description: |- Manages the subscription's Security Center Workspace. +~> **NOTE:** Owner access permission is required. +~> **NOTE:** The subscription's pricing model can not be `Free` for this to have any affect. ## Example Usage From 6ed81291bfddfdccbd0ca4b87fc92cabeed505cf Mon Sep 17 00:00:00 2001 From: kt Date: Sat, 13 Oct 2018 20:56:00 -0700 Subject: [PATCH 35/35] Update CHANGELOG.md to include #2072 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b06a13eda0d..7d7b5f00b748 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ FEATURES: * **New Resource:** `azurerm_dev_test_windows_virtual_machine` [GH-2058] * **New Resource:** `azurerm_security_center_contact` [GH-2045] * **New Resource:** `azurerm_security_center_subscription_pricing` [GH-2043] +* **New Resource:** `azurerm_security_center_workspace` [GH-2072] * **New Resource:** `azurerm_subnet_network_security_group_association` [GH-1933] * **New Resource:** `azurerm_subnet_route_table_association ` [GH-1933]