From 686678c21d14ebf875e8b04d418c8ac5391fc54a Mon Sep 17 00:00:00 2001 From: Sepke Date: Mon, 29 Jan 2018 16:16:06 +0100 Subject: [PATCH 001/156] pull role definitions from an api --- .../data_source_builtin_role_definition.go | 83 +++---------------- 1 file changed, 10 insertions(+), 73 deletions(-) diff --git a/azurerm/data_source_builtin_role_definition.go b/azurerm/data_source_builtin_role_definition.go index f47112cd992c8..810347dfdfbc1 100644 --- a/azurerm/data_source_builtin_role_definition.go +++ b/azurerm/data_source_builtin_role_definition.go @@ -135,85 +135,22 @@ func dataSourceArmBuiltInRoleDefinitionRead(d *schema.ResourceData, meta interfa ctx := meta.(*ArmClient).StopContext name := d.Get("name").(string) - roleDefinitionIds := map[string]string{ - // TODO: pull this list from an API - "Auditor": "/providers/Microsoft.Authorization/roleDefinitions/8da36ee2-a5e5-4c9d-ad4a-6d281636c8b1", - "CloudAware Collector Storage Account Keys Access": "/providers/Microsoft.Authorization/roleDefinitions/caea9d35-7d6c-4bd5-ac15-1e92cb428f43", - "DB Admin": "/providers/Microsoft.Authorization/roleDefinitions/d80f878a-b665-46fd-a179-5b231a7a126e", - "Network Security Operator": "/providers/Microsoft.Authorization/roleDefinitions/ff1e2e01-fceb-4dc1-a91a-ffb9ca766f7d", - "API Management Service Contributor": "/providers/Microsoft.Authorization/roleDefinitions/312a565d-c81f-4fd8-895a-4e21e48d571c", - "API Management Service Operator Role": "/providers/Microsoft.Authorization/roleDefinitions/e022efe7-f5ba-4159-bbe4-b44f577e9b61", - "API Management Service Reader Role": "/providers/Microsoft.Authorization/roleDefinitions/71522526-b88f-4d52-b57f-d31fc3546d0d", - "Application Insights Component Contributor": "/providers/Microsoft.Authorization/roleDefinitions/ae349356-3a1b-4a5e-921d-050484c6347e", - "Application Insights Snapshot Debugger": "/providers/Microsoft.Authorization/roleDefinitions/08954f03-6346-4c2e-81c0-ec3a5cfae23b", - "Automation Job Operator": "/providers/Microsoft.Authorization/roleDefinitions/4fe576fe-1146-4730-92eb-48519fa6bf9f", - "Automation Operator": "/providers/Microsoft.Authorization/roleDefinitions/d3881f73-407a-4167-8283-e981cbba0404", - "Automation Runbook Operator": "/providers/Microsoft.Authorization/roleDefinitions/5fb5aef8-1081-4b8e-bb16-9d5d0385bab5", - "Azure Stack Registration Owner": "/providers/Microsoft.Authorization/roleDefinitions/6f12a6df-dd06-4f3e-bcb1-ce8be600526a", - "Backup Contributor": "/providers/Microsoft.Authorization/roleDefinitions/5e467623-bb1f-42f4-a55d-6e525e11384b", - "Backup Operator": "/providers/Microsoft.Authorization/roleDefinitions/00c29273-979b-4161-815c-10b084fb9324", - "Backup Reader": "/providers/Microsoft.Authorization/roleDefinitions/a795c7a0-d4a2-40c1-ae25-d81f01202912", - "Billing Reader": "/providers/Microsoft.Authorization/roleDefinitions/fa23ad8b-c56e-40d8-ac0c-ce449e1d2c64", - "BizTalk Contributor": "/providers/Microsoft.Authorization/roleDefinitions/5e3c6656-6cfa-4708-81fe-0de47ac73342", - "CDN Endpoint Contributor": "/providers/Microsoft.Authorization/roleDefinitions/426e0c7f-0c7e-4658-b36f-ff54d6c29b45", - "CDN Endpoint Reader": "/providers/Microsoft.Authorization/roleDefinitions/871e35f6-b5c1-49cc-a043-bde969a0f2cd", - "CDN Profile Contributor": "/providers/Microsoft.Authorization/roleDefinitions/ec156ff8-a8d1-4d15-830c-5b80698ca432", - "CDN Profile Reader": "/providers/Microsoft.Authorization/roleDefinitions/8f96442b-4075-438f-813d-ad51ab4019af", - "Classic Network Contributor": "/providers/Microsoft.Authorization/roleDefinitions/b34d265f-36f7-4a0d-a4d4-e158ca92e90f", - "Classic Storage Account Contributor": "/providers/Microsoft.Authorization/roleDefinitions/86e8f5dc-a6e9-4c67-9d15-de283e8eac25", - "Classic Storage Account Key Operator Service Role": "/providers/Microsoft.Authorization/roleDefinitions/985d6b00-f706-48f5-a6fe-d0ca12fb668d", - "Classic Virtual Machine Contributor": "/providers/Microsoft.Authorization/roleDefinitions/d73bb868-a0df-4d4d-bd69-98a00b01fccb", - "ClearDB MySQL DB Contributor": "/providers/Microsoft.Authorization/roleDefinitions/9106cda0-8a86-4e81-b686-29a22c54effe", - "Contributor": "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c", - "Cosmos DB Account Reader Role": "/providers/Microsoft.Authorization/roleDefinitions/fbdf93bf-df7d-467e-a4d2-9458aa1360c8", - "Data Factory Contributor": "/providers/Microsoft.Authorization/roleDefinitions/673868aa-7521-48a0-acc6-0f60742d39f5", - "Data Lake Analytics Developer": "/providers/Microsoft.Authorization/roleDefinitions/47b7735b-770e-4598-a7da-8b91488b4c88", - "DevTest Labs User": "/providers/Microsoft.Authorization/roleDefinitions/76283e04-6283-4c54-8f91-bcf1374a3c64", - "DNS Zone Contributor": "/providers/Microsoft.Authorization/roleDefinitions/befefa01-2a29-4197-83a8-272ff33ce314", - "DocumentDB Account Contributor": "/providers/Microsoft.Authorization/roleDefinitions/5bd9cd88-fe45-4216-938b-f97437e15450", - "Intelligent Systems Account Contributor": "/providers/Microsoft.Authorization/roleDefinitions/03a6d094-3444-4b3d-88af-7477090a9e5e", - "Key Vault Contributor": "/providers/Microsoft.Authorization/roleDefinitions/f25e0fa2-a7c8-4377-a976-54943a77a395", - "Lab Accounts User": "/providers/Microsoft.Authorization/roleDefinitions/b97fb8bc-a8b2-4522-a38b-dd33c7e65ead", - "Log Analytics Contributor": "/providers/Microsoft.Authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293", - "Log Analytics Reader": "/providers/Microsoft.Authorization/roleDefinitions/73c42c96-874c-492b-b04d-ab87d138a893", - "Logic App Contributor": "/providers/Microsoft.Authorization/roleDefinitions/87a39d53-fc1b-424a-814c-f7e04687dc9e", - "Logic App Operator": "/providers/Microsoft.Authorization/roleDefinitions/515c2055-d9d4-4321-b1b9-bd0c9a0f79fe", - "Managed Identity Contributor": "/providers/Microsoft.Authorization/roleDefinitions/e40ec5ca-96e0-45a2-b4ff-59039f2c2b59", - "Managed Identity Operator": "/providers/Microsoft.Authorization/roleDefinitions/f1a07417-d97a-45cb-824c-7a7467783830", - "Monitoring Contributor": "/providers/Microsoft.Authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa", - "Monitoring Reader": "/providers/Microsoft.Authorization/roleDefinitions/43d0d8ad-25c7-4714-9337-8ba259a9fe05", - "Network Contributor": "/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7", - "New Relic APM Account Contributor": "/providers/Microsoft.Authorization/roleDefinitions/5d28c62d-5b37-4476-8438-e587778df237", - "Owner": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635", - "Reader": "/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7", - "Redis Cache Contributor": "/providers/Microsoft.Authorization/roleDefinitions/e0f68234-74aa-48ed-b826-c38b57376e17", - "Scheduler Job Collections Contributor": "/providers/Microsoft.Authorization/roleDefinitions/188a0f2f-5c9e-469b-ae67-2aa5ce574b94", - "Search Service Contributor": "/providers/Microsoft.Authorization/roleDefinitions/7ca78c08-252a-4471-8644-bb5ff32d4ba0", - "Security Admin": "/providers/Microsoft.Authorization/roleDefinitions/fb1c8493-542b-48eb-b624-b4c8fea62acd", - "Security Manager": "/providers/Microsoft.Authorization/roleDefinitions/e3d13bf0-dd5a-482e-ba6b-9b8433878d10", - "Security Reader": "/providers/Microsoft.Authorization/roleDefinitions/39bc4728-0917-49c7-9d2c-d95423bc2eb4", - "Site Recovery Contributor": "/providers/Microsoft.Authorization/roleDefinitions/6670b86e-a3f7-4917-ac9b-5d6ab1be4567", - "Site Recovery Operator": "/providers/Microsoft.Authorization/roleDefinitions/494ae006-db33-4328-bf46-533a6560a3ca", - "Site Recovery Reader": "/providers/Microsoft.Authorization/roleDefinitions/dbaa88c4-0c30-4179-9fb3-46319faa6149", - "SQL DB Contributor": "/providers/Microsoft.Authorization/roleDefinitions/9b7fa17d-e63e-47b0-bb0a-15c516ac86ec", - "SQL Security Manager": "/providers/Microsoft.Authorization/roleDefinitions/056cd41c-7e88-42e1-933e-88ba6a50c9c3", - "SQL Server Contributor": "/providers/Microsoft.Authorization/roleDefinitions/6d8ee4ec-f05a-4a1d-8b00-a9b17e38b437", - "Storage Account Contributor": "/providers/Microsoft.Authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab", - "Storage Account Key Operator Service Role": "/providers/Microsoft.Authorization/roleDefinitions/81a9662b-bebf-436f-a333-f67b29880f12", - "Support Request Contributor": "/providers/Microsoft.Authorization/roleDefinitions/cfd33db0-3dd1-45e3-aa9d-cdbdf3b6f24e", - "Traffic Manager Contributor": "/providers/Microsoft.Authorization/roleDefinitions/a4b10055-b0c7-44c2-b00f-c7b5b3550cf7", - "User Access Administrator": "/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9", - "VirtualMachineContributor": "/providers/Microsoft.Authorization/roleDefinitions/9980e02c-c2be-4d73-94e8-173b1dc7cf3c", - "Web Plan Contributor": "/providers/Microsoft.Authorization/roleDefinitions/2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b", - "Website Contributor": "/providers/Microsoft.Authorization/roleDefinitions/de139f84-1756-47ae-9be6-808fbbe84772", + filter := fmt.Sprintf("roleName eq '%s'", name) + roleDefinitions, err := client.List(ctx, "", filter) + if err != nil { + return fmt.Errorf("Error loading Role Definition List: %+v", err) + } + if len(roleDefinitions.Values()) != 1 { + return fmt.Errorf("Error loading Role Definition List: could not find role '%s'", name) } - roleDefinitionId := roleDefinitionIds[name] + + roleDefinitionId := *roleDefinitions.Values()[0].ID d.SetId(roleDefinitionId) role, err := client.GetByID(ctx, roleDefinitionId) if err != nil { - return fmt.Errorf("Error loadng Role Definition: %+v", err) + return fmt.Errorf("Error loading Role Definition: %+v", err) } if props := role.Properties; props != nil { From 102b6d755fd8e0fdabe4992ed266b2f1e9393813 Mon Sep 17 00:00:00 2001 From: Sepke Date: Mon, 26 Feb 2018 15:22:30 +0100 Subject: [PATCH 002/156] Dissallow Preview Roles in role_assignment --- azurerm/resource_arm_role_assignment.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/azurerm/resource_arm_role_assignment.go b/azurerm/resource_arm_role_assignment.go index e428baffdef9b..34fce15b56233 100644 --- a/azurerm/resource_arm_role_assignment.go +++ b/azurerm/resource_arm_role_assignment.go @@ -3,6 +3,7 @@ package azurerm import ( "fmt" "log" + "strings" "github.com/Azure/azure-sdk-for-go/services/authorization/mgmt/2015-07-01/authorization" "github.com/hashicorp/go-uuid" @@ -47,6 +48,7 @@ func resourceArmRoleAssignment() *schema.Resource { Optional: true, ForceNew: true, ConflictsWith: []string{"role_definition_id"}, + ValidateFunc: validateRoleDefinitionName, }, "principal_id": { @@ -70,13 +72,14 @@ func resourceArmRoleAssignmentCreate(d *schema.ResourceData, meta interface{}) e if v, ok := d.GetOk("role_definition_id"); ok { roleDefinitionId = v.(string) } else if v, ok := d.GetOk("role_definition_name"); ok { - filter := fmt.Sprintf("roleName eq '%s'", v.(string)) + value := v.(string) + filter := fmt.Sprintf("roleName eq '%s'", value) roleDefinitions, err := roleDefinitionsClient.List(ctx, "", filter) if err != nil { return fmt.Errorf("Error loading Role Definition List: %+v", err) } if len(roleDefinitions.Values()) != 1 { - return fmt.Errorf("Error loading Role Definition List: could not find role '%s'", name) + return fmt.Errorf("Error loading Role Definition List: could not find role '%s'", value) } roleDefinitionId = *roleDefinitions.Values()[0].ID } else { @@ -161,3 +164,15 @@ func resourceArmRoleAssignmentDelete(d *schema.ResourceData, meta interface{}) e return nil } + +func validateRoleDefinitionName(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)} + } + + if ok := strings.Contains(v, "(Preview)"); ok { + return nil, []error{fmt.Errorf("Preview roles are not supported")} + } + return nil, nil +} From 9004404a2eccbac676f7d201d8732e981f7f503f Mon Sep 17 00:00:00 2001 From: Lawrence Gripper Date: Wed, 7 Mar 2018 17:36:26 +0000 Subject: [PATCH 003/156] Initial work on Log Analytics solutions provider --- azurerm/config.go | 38 +- azurerm/provider.go | 1 + .../resource_arm_log_analytics_solution.go | 196 ++++++++ ...esource_arm_log_analytics_solution_test.go | 133 ++++++ .../operationsmanagement/client.go | 57 +++ .../managementassociations.go | 341 ++++++++++++++ .../managementconfigurations.go | 336 ++++++++++++++ .../operationsmanagement/models.go | 183 ++++++++ .../operationsmanagement/operations.go | 98 ++++ .../operationsmanagement/solutions.go | 419 ++++++++++++++++++ .../operationsmanagement/version.go | 28 ++ vendor/vendor.json | 6 + 12 files changed, 1835 insertions(+), 1 deletion(-) create mode 100644 azurerm/resource_arm_log_analytics_solution.go create mode 100644 azurerm/resource_arm_log_analytics_solution_test.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/managementassociations.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/managementconfigurations.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/models.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/operations.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/version.go diff --git a/azurerm/config.go b/azurerm/config.go index 82fa2a54fb62a..16ead67892e03 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -29,6 +29,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-04-30-preview/mysql" "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network" "github.com/Azure/azure-sdk-for-go/services/operationalinsights/mgmt/2015-11-01-preview/operationalinsights" + "github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement" "github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-04-30-preview/postgresql" "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2016-04-01/redis" "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-06-01/subscriptions" @@ -82,6 +83,7 @@ type ArmClient struct { eventHubNamespacesClient eventhub.NamespacesClient workspacesClient operationalinsights.WorkspacesClient + solutionsClient operationsmanagement.SolutionsClient redisClient redis.Client redisFirewallClient redis.FirewallRuleClient @@ -736,7 +738,41 @@ func (c *ArmClient) registerOperationalInsightsClients(endpoint, subscriptionId opwc := operationalinsights.NewWorkspacesClient(subscriptionId) c.configureClient(&opwc.Client, auth) c.workspacesClient = opwc -} + + solutionsClient := operationsmanagement.NewSolutionsClient(subscriptionId, "Microsoft.OperationsManagement", "solutions", "testing") + c.configureClient(&solutionsClient.Client, auth) + c.solutionsClient = solutionsClient + // c.solutionsClient.RequestInspector = LogRequestPreparer() + // c.solutionsClient.ResponseInspector = LogResponseDecorator() +} + +// func LogRequestPreparer() autorest.PrepareDecorator { +// return func(p autorest.Preparer) autorest.Preparer { +// return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { +// // resDump, _ := httputil.DumpRequestOut(r, true) +// // log.Println(string(resDump)) +// // return r, nil + +// r, err := p.Prepare(r) +// if err == nil { +// resDump, _ := httputil.DumpRequestOut(r, true) +// log.Println(string(resDump)) +// } +// return r, err +// }) +// } +// } + +// func LogResponseDecorator() autorest.RespondDecorator { +// return func(p autorest.Responder) autorest.Responder { +// return autorest.ResponderFunc(func(r *http.Response) error { +// _ = p.Respond(r) +// dump, _ := httputil.DumpResponse(r, true) +// log.Println(string(dump)) +// return nil +// }) +// } +// } func (c *ArmClient) registerRedisClients(endpoint, subscriptionId string, auth autorest.Authorizer, sender autorest.Sender) { redisClient := redis.NewClientWithBaseURI(endpoint, subscriptionId) diff --git a/azurerm/provider.go b/azurerm/provider.go index b7ac20ac2feeb..580175cbda9bf 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -151,6 +151,7 @@ func Provider() terraform.ResourceProvider { "azurerm_lb_rule": resourceArmLoadBalancerRule(), "azurerm_local_network_gateway": resourceArmLocalNetworkGateway(), "azurerm_log_analytics_workspace": resourceArmLogAnalyticsWorkspace(), + "azurerm_log_analytics_solution": resourceArmLogAnalyticsSolution(), "azurerm_managed_disk": resourceArmManagedDisk(), "azurerm_management_lock": resourceArmManagementLock(), "azurerm_metric_alertrule": resourceArmMetricAlertRule(), diff --git a/azurerm/resource_arm_log_analytics_solution.go b/azurerm/resource_arm_log_analytics_solution.go new file mode 100644 index 0000000000000..9cd572323669e --- /dev/null +++ b/azurerm/resource_arm_log_analytics_solution.go @@ -0,0 +1,196 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmLogAnalyticsSolution() *schema.Resource { + return &schema.Resource{ + Create: resourceArmLogAnalyticsSolutionCreateUpdate, + Read: resourceArmLogAnalyticsSolutionRead, + Update: resourceArmLogAnalyticsSolutionCreateUpdate, + Delete: resourceArmLogAnalyticsSolutionDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "location": locationSchema(), + + "resource_group_name": resourceGroupNameDiffSuppressSchema(), + + "plan": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "publisher": { + Type: schema.TypeString, + Required: true, + }, + "promotion_code": { + Type: schema.TypeString, + Optional: true, + }, + "product": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + + "workspace_resource_id": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func resourceArmLogAnalyticsSolutionCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).solutionsClient + ctx := meta.(*ArmClient).StopContext + log.Printf("[INFO] preparing arguments for AzureRM Log Analytics solution creation.") + + name := d.Get("name").(string) + location := d.Get("location").(string) + resGroup := d.Get("resource_group_name").(string) + workspaceID := d.Get("workspace_resource_id").(string) + + solutionPlan := expandAzureRmLogAnalyticsSolutionPlan(d) + + parameters := operationsmanagement.Solution{ + Name: &name, + Location: &location, + Plan: &solutionPlan, + Properties: &operationsmanagement.SolutionProperties{ + WorkspaceResourceID: &workspaceID, + }, + } + + solution, err := client.CreateOrUpdate(ctx, resGroup, name, parameters) + if err != nil { + return err + } + + if solution.ID == nil { + return fmt.Errorf("Cannot read Log Analytics Solution '%s' (resource group %s) ID", name, resGroup) + } + + d.SetId(*solution.ID) + + return resourceArmLogAnalyticsSolutionRead(d, meta) + +} + +func resourceArmLogAnalyticsSolutionRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).solutionsClient + ctx := meta.(*ArmClient).StopContext + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["solutions"] + + resp, err := client.Get(ctx, resGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on AzureRM Log Analytics solutions '%s': %+v", name, err) + } + + if resp.Plan == nil { + return fmt.Errorf("Error making Read request on AzureRM Log Analytics solutions '%s': %+v Plan was nil", name, err) + } + + d.Set("name", resp.Name) + d.Set("location", resp.Location) + d.Set("resource_group_name", resGroup) + d.Set("workspace_resource_id", resp.ID) + d.Set("plan", flattenAzureRmLogAnalyticsSolutionPlan(*resp.Plan)) + return nil +} + +func resourceArmLogAnalyticsSolutionDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).solutionsClient + ctx := meta.(*ArmClient).StopContext + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["solutions"] + + resp, err := client.Delete(ctx, resGroup, name) + + if err != nil { + if utils.ResponseWasNotFound(resp) { + return nil + } + + return fmt.Errorf("Error issuing AzureRM delete request for Log Analytics Solution '%s': %+v", name, err) + } + + return nil +} + +func expandAzureRmLogAnalyticsSolutionPlan(d *schema.ResourceData) operationsmanagement.SolutionPlan { + plans := d.Get("plan").([]interface{}) + plan := plans[0].(map[string]interface{}) + + expandedPlan := operationsmanagement.SolutionPlan{} + + if name := plan["name"].(string); len(name) > 0 { + expandedPlan.Name = &name + } + + if publisher := plan["publisher"].(string); len(publisher) > 0 { + expandedPlan.Publisher = &publisher + } + + if promotionCode := plan["promotion_code"].(string); len(promotionCode) > 0 { + expandedPlan.PromotionCode = &promotionCode + } else { + blankString := "" + expandedPlan.PromotionCode = &blankString + } + + if product := plan["product"].(string); len(product) > 0 { + expandedPlan.Product = &product + } + + return expandedPlan +} + +func flattenAzureRmLogAnalyticsSolutionPlan(plan operationsmanagement.SolutionPlan) []interface{} { + plans := make([]interface{}, 0) + values := make(map[string]interface{}) + + values["name"] = *plan.Name + values["product"] = *plan.Product + values["promotion_code"] = *plan.PromotionCode + values["publisher"] = *plan.Publisher + + return append(plans, values) +} diff --git a/azurerm/resource_arm_log_analytics_solution_test.go b/azurerm/resource_arm_log_analytics_solution_test.go new file mode 100644 index 0000000000000..f8e027fc5a02e --- /dev/null +++ b/azurerm/resource_arm_log_analytics_solution_test.go @@ -0,0 +1,133 @@ +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 TestAccAzureRMLogAnalyticsSolution(t *testing.T) { + ri := acctest.RandInt() + // config := testAccAzureRMLogAnalyticsSolution(ri, testLocation()) + config := testAccAzureRMLogAnalyticsSolution(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMLogAnalyticsWorkspaceDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLogAnalyticsWorkspaceExists("azurerm_log_analytics_workspace.test"), + ), + }, + }, + }) +} + +func testCheckAzureRMLogAnalyticsSolutionDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).solutionsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_log_analytics_solution" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(ctx, resourceGroup, name) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Log Analytics solution still exists:\n%#v", resp) + } + } + + return nil +} + +func testCheckAzureRMLogAnalyticsSolutionExists(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) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Log Analytics Workspace: '%s'", name) + } + + conn := testAccProvider.Meta().(*ArmClient).solutionsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := conn.Get(ctx, resourceGroup, name) + if err != nil { + return fmt.Errorf("Bad: Get on Log Analytics Solutions Client: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Log Analytics Solutions '%s' (resource group: '%s') does not exist", name, resourceGroup) + } + + return nil + } +} + +func testAccAzureRMLogAnalyticsSolution(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "oms-acctestRG-%d" + location = "%s" +} + +resource "azurerm_log_analytics_workspace" "workspace" { + name = "acctest-dep-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Free" +} + +resource "azurerm_log_analytics_solution" "solution" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_resource_id = "${azurerm_log_analytics_workspace.workspace.id}" + + plan { + name = "Containers" + publisher = "Microsoft" + product = "OMSGallery/Containers" + } +} +`, rInt, location, rInt, rInt) +} + +func testAccAzureRMLogAnalyticsSolution_Temp(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_log_analytics_solution" "solution" { + name = "acctest" + location = "westeurope" + resource_group_name = "lg-terraformtest" + workspace_resource_id = "/subscriptions/5774ad8f-d51e-4456-a72e-0447910568d3/resourcegroups/acctestrg-8930075193794579467/providers/microsoft.operationalinsights/workspaces/acctest-dep-8930075193794579467" + + plan { + name = "Containers" + publisher = "Microsoft" + promotion_code = "" + product = "OMSGallery/Containers" + } +} +`) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/client.go b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/client.go new file mode 100644 index 0000000000000..819be16528c85 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/client.go @@ -0,0 +1,57 @@ +// Package operationsmanagement implements the Azure ARM Operationsmanagement service API version 2015-11-01-preview. +// +// Operations Management Client +package operationsmanagement + +// 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 Operationsmanagement + DefaultBaseURI = "https://management.azure.com" +) + +// BaseClient is the base client for Operationsmanagement. +type BaseClient struct { + autorest.Client + BaseURI string + SubscriptionID string + ProviderName string + ResourceType string + ResourceName string +} + +// New creates an instance of the BaseClient client. +func New(subscriptionID string, providerName string, resourceType string, resourceName string) BaseClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID, providerName, resourceType, resourceName) +} + +// NewWithBaseURI creates an instance of the BaseClient client. +func NewWithBaseURI(baseURI string, subscriptionID string, providerName string, resourceType string, resourceName string) BaseClient { + return BaseClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + SubscriptionID: subscriptionID, + ProviderName: providerName, + ResourceType: resourceType, + ResourceName: resourceName, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/managementassociations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/managementassociations.go new file mode 100644 index 0000000000000..4d8c8d9072efa --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/managementassociations.go @@ -0,0 +1,341 @@ +package operationsmanagement + +// 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" +) + +// ManagementAssociationsClient is the operations Management Client +type ManagementAssociationsClient struct { + BaseClient +} + +// NewManagementAssociationsClient creates an instance of the ManagementAssociationsClient client. +func NewManagementAssociationsClient(subscriptionID string, providerName string, resourceType string, resourceName string) ManagementAssociationsClient { + return NewManagementAssociationsClientWithBaseURI(DefaultBaseURI, subscriptionID, providerName, resourceType, resourceName) +} + +// NewManagementAssociationsClientWithBaseURI creates an instance of the ManagementAssociationsClient client. +func NewManagementAssociationsClientWithBaseURI(baseURI string, subscriptionID string, providerName string, resourceType string, resourceName string) ManagementAssociationsClient { + return ManagementAssociationsClient{NewWithBaseURI(baseURI, subscriptionID, providerName, resourceType, resourceName)} +} + +// CreateOrUpdate creates or updates the ManagementAssociation. +// +// resourceGroupName is the name of the resource group to get. The name is case insensitive. managementAssociationName +// is user ManagementAssociation Name. parameters is the parameters required to create ManagementAssociation extension. +func (client ManagementAssociationsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, managementAssociationName string, parameters ManagementAssociation) (result ManagementAssociation, err error) { + if err := validation.Validate([]validation.Validation{ + {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: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.ApplicationID", Name: validation.Null, Rule: true, Chain: nil}}}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "operationsmanagement.ManagementAssociationsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, managementAssociationName, parameters) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ManagementAssociationsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, managementAssociationName string, parameters ManagementAssociation) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "managementAssociationName": autorest.Encode("path", managementAssociationName), + "providerName": autorest.Encode("path", client.ProviderName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "resourceName": autorest.Encode("path", client.ResourceName), + "resourceType": autorest.Encode("path", client.ResourceType), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{providerName}/{resourceType}/{resourceName}/providers/Microsoft.OperationsManagement/ManagementAssociations/{managementAssociationName}", pathParameters), + autorest.WithJSON(parameters), + 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 ManagementAssociationsClient) 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 ManagementAssociationsClient) CreateOrUpdateResponder(resp *http.Response) (result ManagementAssociation, 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 ManagementAssociation in the subscription. +// +// resourceGroupName is the name of the resource group to get. The name is case insensitive. managementAssociationName +// is user ManagementAssociation Name. +func (client ManagementAssociationsClient) Delete(ctx context.Context, resourceGroupName string, managementAssociationName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {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.NewErrorWithValidationError(err, "operationsmanagement.ManagementAssociationsClient", "Delete") + } + + req, err := client.DeletePreparer(ctx, resourceGroupName, managementAssociationName) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ManagementAssociationsClient) DeletePreparer(ctx context.Context, resourceGroupName string, managementAssociationName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "managementAssociationName": autorest.Encode("path", managementAssociationName), + "providerName": autorest.Encode("path", client.ProviderName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "resourceName": autorest.Encode("path", client.ResourceName), + "resourceType": autorest.Encode("path", client.ResourceType), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-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/{providerName}/{resourceType}/{resourceName}/providers/Microsoft.OperationsManagement/ManagementAssociations/{managementAssociationName}", 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 ManagementAssociationsClient) 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 ManagementAssociationsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get retrieves the user ManagementAssociation. +// +// resourceGroupName is the name of the resource group to get. The name is case insensitive. managementAssociationName +// is user ManagementAssociation Name. +func (client ManagementAssociationsClient) Get(ctx context.Context, resourceGroupName string, managementAssociationName string) (result ManagementAssociation, err error) { + if err := validation.Validate([]validation.Validation{ + {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.NewErrorWithValidationError(err, "operationsmanagement.ManagementAssociationsClient", "Get") + } + + req, err := client.GetPreparer(ctx, resourceGroupName, managementAssociationName) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ManagementAssociationsClient) GetPreparer(ctx context.Context, resourceGroupName string, managementAssociationName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "managementAssociationName": autorest.Encode("path", managementAssociationName), + "providerName": autorest.Encode("path", client.ProviderName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "resourceName": autorest.Encode("path", client.ResourceName), + "resourceType": autorest.Encode("path", client.ResourceType), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-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/{providerName}/{resourceType}/{resourceName}/providers/Microsoft.OperationsManagement/ManagementAssociations/{managementAssociationName}", 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 ManagementAssociationsClient) 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 ManagementAssociationsClient) GetResponder(resp *http.Response) (result ManagementAssociation, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListBySubscription retrieves the ManagementAssociatons list. +func (client ManagementAssociationsClient) ListBySubscription(ctx context.Context) (result ManagementAssociationPropertiesList, err error) { + req, err := client.ListBySubscriptionPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "ListBySubscription", nil, "Failure preparing request") + return + } + + resp, err := client.ListBySubscriptionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "ListBySubscription", resp, "Failure sending request") + return + } + + result, err = client.ListBySubscriptionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementAssociationsClient", "ListBySubscription", resp, "Failure responding to request") + } + + return +} + +// ListBySubscriptionPreparer prepares the ListBySubscription request. +func (client ManagementAssociationsClient) ListBySubscriptionPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.OperationsManagement/ManagementAssociations", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListBySubscriptionSender sends the ListBySubscription request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementAssociationsClient) ListBySubscriptionSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListBySubscriptionResponder handles the response to the ListBySubscription request. The method always +// closes the http.Response Body. +func (client ManagementAssociationsClient) ListBySubscriptionResponder(resp *http.Response) (result ManagementAssociationPropertiesList, 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/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/managementconfigurations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/managementconfigurations.go new file mode 100644 index 0000000000000..a53e640676179 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/managementconfigurations.go @@ -0,0 +1,336 @@ +package operationsmanagement + +// 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" +) + +// ManagementConfigurationsClient is the operations Management Client +type ManagementConfigurationsClient struct { + BaseClient +} + +// NewManagementConfigurationsClient creates an instance of the ManagementConfigurationsClient client. +func NewManagementConfigurationsClient(subscriptionID string, providerName string, resourceType string, resourceName string) ManagementConfigurationsClient { + return NewManagementConfigurationsClientWithBaseURI(DefaultBaseURI, subscriptionID, providerName, resourceType, resourceName) +} + +// NewManagementConfigurationsClientWithBaseURI creates an instance of the ManagementConfigurationsClient client. +func NewManagementConfigurationsClientWithBaseURI(baseURI string, subscriptionID string, providerName string, resourceType string, resourceName string) ManagementConfigurationsClient { + return ManagementConfigurationsClient{NewWithBaseURI(baseURI, subscriptionID, providerName, resourceType, resourceName)} +} + +// CreateOrUpdate creates or updates the ManagementConfiguration. +// +// resourceGroupName is the name of the resource group to get. The name is case insensitive. +// managementConfigurationName is user Management Configuration Name. parameters is the parameters required to create +// OMS Solution. +func (client ManagementConfigurationsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, managementConfigurationName string, parameters ManagementConfiguration) (result ManagementConfiguration, err error) { + if err := validation.Validate([]validation.Validation{ + {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: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.ParentResourceType", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.Properties.Parameters", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.Properties.Template", Name: validation.Null, Rule: true, Chain: nil}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "operationsmanagement.ManagementConfigurationsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, managementConfigurationName, parameters) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ManagementConfigurationsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, managementConfigurationName string, parameters ManagementConfiguration) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "managementConfigurationName": autorest.Encode("path", managementConfigurationName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.OperationsManagement/ManagementConfigurations/{managementConfigurationName}", pathParameters), + autorest.WithJSON(parameters), + 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 ManagementConfigurationsClient) 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 ManagementConfigurationsClient) CreateOrUpdateResponder(resp *http.Response) (result ManagementConfiguration, 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 ManagementConfiguration in the subscription. +// +// resourceGroupName is the name of the resource group to get. The name is case insensitive. +// managementConfigurationName is user Management Configuration Name. +func (client ManagementConfigurationsClient) Delete(ctx context.Context, resourceGroupName string, managementConfigurationName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {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.NewErrorWithValidationError(err, "operationsmanagement.ManagementConfigurationsClient", "Delete") + } + + req, err := client.DeletePreparer(ctx, resourceGroupName, managementConfigurationName) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ManagementConfigurationsClient) DeletePreparer(ctx context.Context, resourceGroupName string, managementConfigurationName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "managementConfigurationName": autorest.Encode("path", managementConfigurationName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-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.OperationsManagement/ManagementConfigurations/{managementConfigurationName}", 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 ManagementConfigurationsClient) 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 ManagementConfigurationsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get retrieves the user ManagementConfiguration. +// +// resourceGroupName is the name of the resource group to get. The name is case insensitive. +// managementConfigurationName is user Management Configuration Name. +func (client ManagementConfigurationsClient) Get(ctx context.Context, resourceGroupName string, managementConfigurationName string) (result ManagementConfiguration, err error) { + if err := validation.Validate([]validation.Validation{ + {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.NewErrorWithValidationError(err, "operationsmanagement.ManagementConfigurationsClient", "Get") + } + + req, err := client.GetPreparer(ctx, resourceGroupName, managementConfigurationName) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ManagementConfigurationsClient) GetPreparer(ctx context.Context, resourceGroupName string, managementConfigurationName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "managementConfigurationName": autorest.Encode("path", managementConfigurationName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-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.OperationsManagement/ManagementConfigurations/{managementConfigurationName}", 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 ManagementConfigurationsClient) 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 ManagementConfigurationsClient) GetResponder(resp *http.Response) (result ManagementConfiguration, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListBySubscription retrieves the ManagementConfigurations list. +func (client ManagementConfigurationsClient) ListBySubscription(ctx context.Context) (result ManagementConfigurationPropertiesList, err error) { + req, err := client.ListBySubscriptionPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "ListBySubscription", nil, "Failure preparing request") + return + } + + resp, err := client.ListBySubscriptionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "ListBySubscription", resp, "Failure sending request") + return + } + + result, err = client.ListBySubscriptionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.ManagementConfigurationsClient", "ListBySubscription", resp, "Failure responding to request") + } + + return +} + +// ListBySubscriptionPreparer prepares the ListBySubscription request. +func (client ManagementConfigurationsClient) ListBySubscriptionPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.OperationsManagement/ManagementConfigurations", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListBySubscriptionSender sends the ListBySubscription request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementConfigurationsClient) ListBySubscriptionSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListBySubscriptionResponder handles the response to the ListBySubscription request. The method always +// closes the http.Response Body. +func (client ManagementConfigurationsClient) ListBySubscriptionResponder(resp *http.Response) (result ManagementConfigurationPropertiesList, 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/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/models.go new file mode 100644 index 0000000000000..aa5e5a2114af2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/models.go @@ -0,0 +1,183 @@ +package operationsmanagement + +// 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" +) + +// ArmTemplateParameter parameter to pass to ARM template +type ArmTemplateParameter struct { + // Name - name of the parameter. + Name *string `json:"name,omitempty"` + // Value - value for the parameter. In Jtoken + Value *string `json:"value,omitempty"` +} + +// CodeMessageError the error body contract. +type CodeMessageError struct { + // Error - The error details for a failed request. + Error *CodeMessageErrorError `json:"error,omitempty"` +} + +// CodeMessageErrorError the error details for a failed request. +type CodeMessageErrorError struct { + // Code - The error type. + Code *string `json:"code,omitempty"` + // Message - The error message. + Message *string `json:"message,omitempty"` +} + +// ManagementAssociation the container for solution. +type ManagementAssociation 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 - Resource location + Location *string `json:"location,omitempty"` + // Properties - Properties for ManagementAssociation object supported by the OperationsManagement resource provider. + Properties *ManagementAssociationProperties `json:"properties,omitempty"` +} + +// ManagementAssociationProperties managementAssociation properties supported by the OperationsManagement resource +// provider. +type ManagementAssociationProperties struct { + // ApplicationID - The applicationId of the appliance for this association. + ApplicationID *string `json:"applicationId,omitempty"` +} + +// ManagementAssociationPropertiesList the list of ManagementAssociation response +type ManagementAssociationPropertiesList struct { + autorest.Response `json:"-"` + // Value - List of Management Association properites within the subscription. + Value *[]ManagementAssociation `json:"value,omitempty"` +} + +// ManagementConfiguration the container for solution. +type ManagementConfiguration 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 - Resource location + Location *string `json:"location,omitempty"` + // Properties - Properties for ManagementConfiguration object supported by the OperationsManagement resource provider. + Properties *ManagementConfigurationProperties `json:"properties,omitempty"` +} + +// ManagementConfigurationProperties managementConfiguration properties supported by the OperationsManagement resource +// provider. +type ManagementConfigurationProperties struct { + // ApplicationID - The applicationId of the appliance for this Management. + ApplicationID *string `json:"applicationId,omitempty"` + // ParentResourceType - The type of the parent resource. + ParentResourceType *string `json:"parentResourceType,omitempty"` + // Parameters - Parameters to run the ARM template + Parameters *[]ArmTemplateParameter `json:"parameters,omitempty"` + // ProvisioningState - The provisioning state for the ManagementConfiguration. + ProvisioningState *string `json:"provisioningState,omitempty"` + // Template - The Json object containing the ARM template to deploy + Template *map[string]interface{} `json:"template,omitempty"` +} + +// ManagementConfigurationPropertiesList the list of ManagementConfiguration response +type ManagementConfigurationPropertiesList struct { + autorest.Response `json:"-"` + // Value - List of Management Configuration properites within the subscription. + Value *[]ManagementConfiguration `json:"value,omitempty"` +} + +// Operation supported operation of OperationsManagement resource provider. +type Operation struct { + // Name - Operation name: {provider}/{resource}/{operation} + Name *string `json:"name,omitempty"` + // Display - Display metadata associated with the operation. + Display *OperationDisplay `json:"display,omitempty"` +} + +// OperationDisplay display metadata associated with the operation. +type OperationDisplay struct { + // Provider - Service provider: Microsoft OperationsManagement. + Provider *string `json:"provider,omitempty"` + // Resource - Resource on which the operation is performed etc. + Resource *string `json:"resource,omitempty"` + // Operation - Type of operation: get, read, delete, etc. + Operation *string `json:"operation,omitempty"` +} + +// OperationListResult result of the request to list solution operations. +type OperationListResult struct { + autorest.Response `json:"-"` + // Value - List of solution operations supported by the OperationsManagement resource provider. + Value *[]Operation `json:"value,omitempty"` +} + +// Solution the container for solution. +type Solution 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 - Resource location + Location *string `json:"location,omitempty"` + // Plan - Plan for solution object supported by the OperationsManagement resource provider. + Plan *SolutionPlan `json:"plan,omitempty"` + // Properties - Properties for solution object supported by the OperationsManagement resource provider. + Properties *SolutionProperties `json:"properties,omitempty"` +} + +// SolutionPlan plan for solution object supported by the OperationsManagement resource provider. +type SolutionPlan struct { + // Name - name of the solution to be created. For Microsoft published solution it should be in the format of solutionType(workspaceName). SolutionType part is case sensitive. For third party solution, it can be anything. + Name *string `json:"name,omitempty"` + // Publisher - Publisher name. For gallery solution, it is Microsoft. + Publisher *string `json:"publisher,omitempty"` + // PromotionCode - promotionCode, Not really used now, can you left as empty + PromotionCode *string `json:"promotionCode,omitempty"` + // Product - name of the solution to enabled/add. For Microsoft published gallery solution it should be in the format of OMSGallery/. This is case sensitive + Product *string `json:"product,omitempty"` +} + +// SolutionProperties solution properties supported by the OperationsManagement resource provider. +type SolutionProperties struct { + // WorkspaceResourceID - The azure resourceId for the workspace where the solution will be deployed/enabled. + WorkspaceResourceID *string `json:"workspaceResourceId,omitempty"` + // ProvisioningState - The provisioning state for the solution. + ProvisioningState *string `json:"provisioningState,omitempty"` + // ContainedResources - The azure resources that will be contained within the solutions. They will be locked and gets deleted automatically when the solution is deleted. + ContainedResources *[]string `json:"containedResources,omitempty"` + // ReferencedResources - The resources that will be referenced from this solution. Deleting any of those solution out of band will break the solution. + ReferencedResources *[]string `json:"referencedResources,omitempty"` +} + +// SolutionPropertiesList the list of solution response +type SolutionPropertiesList struct { + autorest.Response `json:"-"` + // Value - List of solution properites within the subscription. + Value *[]Solution `json:"value,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/operations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/operations.go new file mode 100644 index 0000000000000..f64d685b2d26f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/operations.go @@ -0,0 +1,98 @@ +package operationsmanagement + +// 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 operations Management Client +type OperationsClient struct { + BaseClient +} + +// NewOperationsClient creates an instance of the OperationsClient client. +func NewOperationsClient(subscriptionID string, providerName string, resourceType string, resourceName string) OperationsClient { + return NewOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID, providerName, resourceType, resourceName) +} + +// NewOperationsClientWithBaseURI creates an instance of the OperationsClient client. +func NewOperationsClientWithBaseURI(baseURI string, subscriptionID string, providerName string, resourceType string, resourceName string) OperationsClient { + return OperationsClient{NewWithBaseURI(baseURI, subscriptionID, providerName, resourceType, resourceName)} +} + +// List lists all of the available OperationsManagement Rest API operations. +func (client OperationsClient) List(ctx context.Context) (result OperationListResult, err error) { + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.OperationsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.OperationsClient", "List", resp, "Failure sending request") + return + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.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-11-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.OperationsManagement/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 OperationListResult, 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/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go new file mode 100644 index 0000000000000..570837913bcbd --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go @@ -0,0 +1,419 @@ +package operationsmanagement + +// 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" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" +) + +// SolutionsClient is the operations Management Client +type SolutionsClient struct { + BaseClient +} + +// NewSolutionsClient creates an instance of the SolutionsClient client. +func NewSolutionsClient(subscriptionID string, providerName string, resourceType string, resourceName string) SolutionsClient { + return NewSolutionsClientWithBaseURI(DefaultBaseURI, subscriptionID, providerName, resourceType, resourceName) +} + +// NewSolutionsClientWithBaseURI creates an instance of the SolutionsClient client. +func NewSolutionsClientWithBaseURI(baseURI string, subscriptionID string, providerName string, resourceType string, resourceName string) SolutionsClient { + return SolutionsClient{NewWithBaseURI(baseURI, subscriptionID, providerName, resourceType, resourceName)} +} + +// CreateOrUpdate creates or updates the Solution. +// +// resourceGroupName is the name of the resource group to get. The name is case insensitive. solutionName is user +// Solution Name. parameters is the parameters required to create OMS Solution. +func (client SolutionsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, solutionName string, parameters Solution) (result Solution, err error) { + if err := validation.Validate([]validation.Validation{ + {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: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "parameters.Properties.WorkspaceResourceID", Name: validation.Null, Rule: true, Chain: nil}}}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "operationsmanagement.SolutionsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, solutionName, parameters) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + // dump, err := httputil.DumpRequest(req, true) + // log.Println(string(dump)) + + // if err != nil { + // panic(err) + // } + // bytes, _ := ioutil.ReadAll(req.Body) + + // stringLength := len(string(bytes)) + // log.Println(stringLength) + // log.Println(string(bytes)) + // log.Println(err) + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client SolutionsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, solutionName string, parameters Solution) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "solutionName": autorest.Encode("path", solutionName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.OperationsManagement/solutions/{solutionName}", pathParameters), + autorest.WithJSON(parameters), + 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 SolutionsClient) 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 SolutionsClient) CreateOrUpdateResponder(resp *http.Response) (result Solution, 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 solution in the subscription. +// +// resourceGroupName is the name of the resource group to get. The name is case insensitive. solutionName is user +// Solution Name. +func (client SolutionsClient) Delete(ctx context.Context, resourceGroupName string, solutionName string) (result autorest.Response, err error) { + if err := validation.Validate([]validation.Validation{ + {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.NewErrorWithValidationError(err, "operationsmanagement.SolutionsClient", "Delete") + } + + req, err := client.DeletePreparer(ctx, resourceGroupName, solutionName) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client SolutionsClient) DeletePreparer(ctx context.Context, resourceGroupName string, solutionName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "solutionName": autorest.Encode("path", solutionName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-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.OperationsManagement/solutions/{solutionName}", 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 SolutionsClient) 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 SolutionsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get retrieves the user solution. +// +// resourceGroupName is the name of the resource group to get. The name is case insensitive. solutionName is user +// Solution Name. +func (client SolutionsClient) Get(ctx context.Context, resourceGroupName string, solutionName string) (result Solution, err error) { + if err := validation.Validate([]validation.Validation{ + {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.NewErrorWithValidationError(err, "operationsmanagement.SolutionsClient", "Get") + } + + req, err := client.GetPreparer(ctx, resourceGroupName, solutionName) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client SolutionsClient) GetPreparer(ctx context.Context, resourceGroupName string, solutionName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "solutionName": autorest.Encode("path", solutionName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-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.OperationsManagement/solutions/{solutionName}", 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 SolutionsClient) 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 SolutionsClient) GetResponder(resp *http.Response) (result Solution, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroup retrieves the solution list. It will retrieve both first party and third party solutions +// +// resourceGroupName is the name of the resource group to get. The name is case insensitive. +func (client SolutionsClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result SolutionPropertiesList, err error) { + if err := validation.Validate([]validation.Validation{ + {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.NewErrorWithValidationError(err, "operationsmanagement.SolutionsClient", "ListByResourceGroup") + } + + req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client SolutionsClient) 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-11-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.OperationsManagement/solutions", 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 SolutionsClient) 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 SolutionsClient) ListByResourceGroupResponder(resp *http.Response) (result SolutionPropertiesList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListBySubscription retrieves the solution list. It will retrieve both first party and third party solutions +func (client SolutionsClient) ListBySubscription(ctx context.Context) (result SolutionPropertiesList, err error) { + req, err := client.ListBySubscriptionPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "ListBySubscription", nil, "Failure preparing request") + return + } + + resp, err := client.ListBySubscriptionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "ListBySubscription", resp, "Failure sending request") + return + } + + result, err = client.ListBySubscriptionResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "operationsmanagement.SolutionsClient", "ListBySubscription", resp, "Failure responding to request") + } + + return +} + +// ListBySubscriptionPreparer prepares the ListBySubscription request. +func (client SolutionsClient) ListBySubscriptionPreparer(ctx context.Context) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2015-11-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.OperationsManagement/solutions", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListBySubscriptionSender sends the ListBySubscription request. The method will close the +// http.Response Body if it receives an error. +func (client SolutionsClient) ListBySubscriptionSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req, + azure.DoRetryWithRegistration(client.Client)) +} + +// ListBySubscriptionResponder handles the response to the ListBySubscription request. The method always +// closes the http.Response Body. +func (client SolutionsClient) ListBySubscriptionResponder(resp *http.Response) (result SolutionPropertiesList, 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/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/version.go b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/version.go new file mode 100644 index 0000000000000..d8d97ca5153ed --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/version.go @@ -0,0 +1,28 @@ +package operationsmanagement + +// 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/v12.5.0-beta services" +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return "v12.5.0-beta" +} diff --git a/vendor/vendor.json b/vendor/vendor.json index f12b71c3c54fd..4c8526326ce43 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -154,6 +154,12 @@ "version": "v12.5.0-beta", "versionExact": "v12.5.0-beta" }, + { + "checksumSHA1": "WMfs+FCE3stapwrAvAS3fjFZlHk=", + "path": "github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement", + "revision": "21b68149ccf7c16b3f028bb4c7fd0ab458fe308f", + "revisionTime": "2018-02-12T16:31:56Z" + }, { "checksumSHA1": "qOcKrxfayIRgAKlAZu9XYTSfeA0=", "path": "github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-04-30-preview/postgresql", From c7974e4bea5ae234ff98deea40174db4afbc5140 Mon Sep 17 00:00:00 2001 From: Lawrence Gripper Date: Wed, 7 Mar 2018 19:39:55 +0000 Subject: [PATCH 004/156] Removed debug code from sdk. Worked around error in SDK return type --- .../resource_arm_log_analytics_solution.go | 12 +++++- ...esource_arm_log_analytics_solution_test.go | 38 +++++++++---------- .../operationsmanagement/solutions.go | 13 ------- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/azurerm/resource_arm_log_analytics_solution.go b/azurerm/resource_arm_log_analytics_solution.go index 9cd572323669e..ceced40bdcdd4 100644 --- a/azurerm/resource_arm_log_analytics_solution.go +++ b/azurerm/resource_arm_log_analytics_solution.go @@ -40,18 +40,22 @@ func resourceArmLogAnalyticsSolution() *schema.Resource { "name": { Type: schema.TypeString, Required: true, + ForceNew: true, }, "publisher": { Type: schema.TypeString, Required: true, + ForceNew: true, }, "promotion_code": { Type: schema.TypeString, Optional: true, + ForceNew: true, }, "product": { Type: schema.TypeString, Required: true, + ForceNew: true, }, }, }, @@ -86,11 +90,15 @@ func resourceArmLogAnalyticsSolutionCreateUpdate(d *schema.ResourceData, meta in }, } - solution, err := client.CreateOrUpdate(ctx, resGroup, name, parameters) - if err != nil { + res, err := client.CreateOrUpdate(ctx, resGroup, name, parameters) + //Currently this is required to work around successful creation resulting in an error + // being returned + if err != nil && res.StatusCode != 201 { return err } + solution, _ := client.Get(ctx, resGroup, name) + if solution.ID == nil { return fmt.Errorf("Cannot read Log Analytics Solution '%s' (resource group %s) ID", name, resGroup) } diff --git a/azurerm/resource_arm_log_analytics_solution_test.go b/azurerm/resource_arm_log_analytics_solution_test.go index f8e027fc5a02e..92ac0373ae079 100644 --- a/azurerm/resource_arm_log_analytics_solution_test.go +++ b/azurerm/resource_arm_log_analytics_solution_test.go @@ -12,17 +12,16 @@ import ( func TestAccAzureRMLogAnalyticsSolution(t *testing.T) { ri := acctest.RandInt() - // config := testAccAzureRMLogAnalyticsSolution(ri, testLocation()) config := testAccAzureRMLogAnalyticsSolution(ri, testLocation()) resource.Test(t, resource.TestCase{ Providers: testAccProviders, - CheckDestroy: testCheckAzureRMLogAnalyticsWorkspaceDestroy, + CheckDestroy: testCheckAzureRMLogAnalyticsSolutionDestroy, Steps: []resource.TestStep{ { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLogAnalyticsWorkspaceExists("azurerm_log_analytics_workspace.test"), + testCheckAzureRMLogAnalyticsSolutionExists("azurerm_log_analytics_solution.solution"), ), }, }, @@ -114,20 +113,19 @@ resource "azurerm_log_analytics_solution" "solution" { `, rInt, location, rInt, rInt) } -func testAccAzureRMLogAnalyticsSolution_Temp(rInt int, location string) string { - return fmt.Sprintf(` -resource "azurerm_log_analytics_solution" "solution" { - name = "acctest" - location = "westeurope" - resource_group_name = "lg-terraformtest" - workspace_resource_id = "/subscriptions/5774ad8f-d51e-4456-a72e-0447910568d3/resourcegroups/acctestrg-8930075193794579467/providers/microsoft.operationalinsights/workspaces/acctest-dep-8930075193794579467" - - plan { - name = "Containers" - publisher = "Microsoft" - promotion_code = "" - product = "OMSGallery/Containers" - } -} -`) -} +// func testAccAzureRMLogAnalyticsSolution_Temp(rInt int, location string) string { +// return fmt.Sprintf(` +// resource "azurerm_log_analytics_solution" "solution" { +// name = "acctest" +// location = "westeurope" +// resource_group_name = "lg-terraformtest" +// workspace_resource_id = "/subscriptions/5774ad8f-d51e-4456-a72e-0447910568d3/resourcegroups/lg-terraformtest/providers/microsoft.operationalinsights/workspaces/lg-testoms" + +// plan { +// name = "Containers" +// publisher = "Microsoft" +// product = "OMSGallery/Containers" +// } +// } +// `) +// } diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go index 570837913bcbd..3a392d2e4e9bf 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go @@ -63,19 +63,6 @@ func (client SolutionsClient) CreateOrUpdate(ctx context.Context, resourceGroupN return } - // dump, err := httputil.DumpRequest(req, true) - // log.Println(string(dump)) - - // if err != nil { - // panic(err) - // } - // bytes, _ := ioutil.ReadAll(req.Body) - - // stringLength := len(string(bytes)) - // log.Println(stringLength) - // log.Println(string(bytes)) - // log.Println(err) - resp, err := client.CreateOrUpdateSender(req) if err != nil { result.Response = autorest.Response{Response: resp} From abe02777641de2ff1b19558d0cfb8c7400c007ae Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Wed, 7 Mar 2018 12:40:04 -0700 Subject: [PATCH 005/156] Refactoring CDN Endpoints --- azurerm/resource_arm_cdn_endpoint.go | 324 +++++++++++++-------------- 1 file changed, 159 insertions(+), 165 deletions(-) diff --git a/azurerm/resource_arm_cdn_endpoint.go b/azurerm/resource_arm_cdn_endpoint.go index e7efc1dfc605d..3d49761926ff1 100644 --- a/azurerm/resource_arm_cdn_endpoint.go +++ b/azurerm/resource_arm_cdn_endpoint.go @@ -4,11 +4,11 @@ import ( "bytes" "fmt" "log" - "strings" "github.com/Azure/azure-sdk-for-go/services/cdn/mgmt/2017-04-02/cdn" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) @@ -97,10 +97,15 @@ func resourceArmCdnEndpoint() *schema.Resource { }, "querystring_caching_behaviour": { - Type: schema.TypeString, - Optional: true, - Default: "IgnoreQueryString", - ValidateFunc: validateCdnEndpointQuerystringCachingBehaviour, + Type: schema.TypeString, + Optional: true, + Default: string(cdn.IgnoreQueryString), + ValidateFunc: validation.StringInSlice([]string{ + string(cdn.BypassCaching), + string(cdn.IgnoreQueryString), + string(cdn.NotSet), + string(cdn.UseQueryString), + }, false), }, "content_types_to_compress": { @@ -137,76 +142,111 @@ func resourceArmCdnEndpointCreate(d *schema.ResourceData, meta interface{}) erro name := d.Get("name").(string) location := d.Get("location").(string) - resGroup := d.Get("resource_group_name").(string) + resourceGroup := d.Get("resource_group_name").(string) profileName := d.Get("profile_name").(string) - http_allowed := d.Get("is_http_allowed").(bool) - https_allowed := d.Get("is_https_allowed").(bool) - compression_enabled := d.Get("is_compression_enabled").(bool) - caching_behaviour := d.Get("querystring_caching_behaviour").(string) + httpAllowed := d.Get("is_http_allowed").(bool) + httpsAllowed := d.Get("is_https_allowed").(bool) + compressionEnabled := d.Get("is_compression_enabled").(bool) + cachingBehaviour := d.Get("querystring_caching_behaviour").(string) + originHostHeader := d.Get("origin_host_header").(string) + originPath := d.Get("origin_path").(string) tags := d.Get("tags").(map[string]interface{}) - properties := cdn.EndpointProperties{ - IsHTTPAllowed: &http_allowed, - IsHTTPSAllowed: &https_allowed, - IsCompressionEnabled: &compression_enabled, - QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(caching_behaviour), + endpoint := cdn.Endpoint{ + Location: &location, + EndpointProperties: &cdn.EndpointProperties{ + IsHTTPAllowed: &httpAllowed, + IsHTTPSAllowed: &httpsAllowed, + IsCompressionEnabled: &compressionEnabled, + QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(cachingBehaviour), + OriginHostHeader: utils.String(originHostHeader), + OriginPath: utils.String(originPath), + //GeoFilters: []cdn.GeoFilter{{ + // Action: cdn.Allow || cdn.Block + // CountryCodes: []string{} + // RelativePath: "" + //}} + //ProbePath: "" + }, + Tags: expandTags(tags), } - origins, originsErr := expandAzureRmCdnEndpointOrigins(d) - if originsErr != nil { - return fmt.Errorf("Error Building list of CDN Endpoint Origins: %s", originsErr) + origins, err := expandAzureRmCdnEndpointOrigins(d) + if err != nil { + return fmt.Errorf("Error Building list of CDN Endpoint Origins: %s", err) } if len(origins) > 0 { - properties.Origins = &origins + endpoint.EndpointProperties.Origins = &origins } - if v, ok := d.GetOk("origin_host_header"); ok { - host_header := v.(string) - properties.OriginHostHeader = &host_header + if v, ok := d.GetOk("content_types_to_compress"); ok { + contentTypes := expandArmCdnEndpointContentTypesToCompress(v) + endpoint.EndpointProperties.ContentTypesToCompress = &contentTypes } - if v, ok := d.GetOk("origin_path"); ok { - origin_path := v.(string) - properties.OriginPath = &origin_path + future, err := client.Create(ctx, resourceGroup, profileName, name, endpoint) + if err != nil { + return fmt.Errorf("Error creating CDN Endpoint %q (Profile %q / Resource Group %q): %+v", name, profileName, resourceGroup, err) } - if v, ok := d.GetOk("content_types_to_compress"); ok { - var content_types []string - ctypes := v.(*schema.Set).List() - for _, ct := range ctypes { - str := ct.(string) - content_types = append(content_types, str) - } + err = future.WaitForCompletion(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting for CDN Endpoint %q (Profile %q / Resource Group %q) to finish creating: %+v", name, profileName, resourceGroup, err) + } - properties.ContentTypesToCompress = &content_types + read, err := client.Get(ctx, resourceGroup, profileName, name) + if err != nil { + return fmt.Errorf("Error retrieving CDN Endpoint %q (Profile %q / Resource Group %q): %+v", name, profileName, resourceGroup, err) } - cdnEndpoint := cdn.Endpoint{ - Location: &location, - EndpointProperties: &properties, - Tags: expandTags(tags), + d.SetId(*read.ID) + + return resourceArmCdnEndpointRead(d, meta) +} + +func resourceArmCdnEndpointUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cdnEndpointsClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + profileName := d.Get("profile_name").(string) + httpAllowed := d.Get("is_http_allowed").(bool) + httpsAllowed := d.Get("is_https_allowed").(bool) + compressionEnabled := d.Get("is_compression_enabled").(bool) + cachingBehaviour := d.Get("querystring_caching_behaviour").(string) + hostHeader := d.Get("origin_host_header").(string) + originPath := d.Get("origin_path").(string) + tags := d.Get("tags").(map[string]interface{}) + + endpoint := cdn.EndpointUpdateParameters{ + EndpointPropertiesUpdateParameters: &cdn.EndpointPropertiesUpdateParameters{ + IsHTTPAllowed: &httpAllowed, + IsHTTPSAllowed: &httpsAllowed, + IsCompressionEnabled: &compressionEnabled, + QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(cachingBehaviour), + OriginHostHeader: &hostHeader, + OriginPath: &originPath, + }, + Tags: expandTags(tags), } - future, err := client.Create(ctx, resGroup, profileName, name, cdnEndpoint) - if err != nil { - return err + if d.HasChange("content_types_to_compress") { + v := d.Get("content_types_to_compress") + contentTypes := expandArmCdnEndpointContentTypesToCompress(v) + endpoint.EndpointPropertiesUpdateParameters.ContentTypesToCompress = &contentTypes } - err = future.WaitForCompletion(ctx, client.Client) + future, err := client.Update(ctx, resGroup, profileName, name, endpoint) if err != nil { - return err + return fmt.Errorf("Error updating CDN Endpoint %q (Profile %q / Resource Group %q): %s", name, profileName, resGroup, err) } - read, err := client.Get(ctx, resGroup, profileName, name) + err = future.WaitForCompletion(ctx, client.Client) if err != nil { - return err - } - if read.ID == nil { - return fmt.Errorf("Cannot read CND Endpoint %s/%s (resource group %s) ID", profileName, name, resGroup) + return fmt.Errorf("Error waiting for the CDN Endpoint %q (Profile %q / Resource Group %q) to finish updating: %+v", name, profileName, resGroup, err) } - d.SetId(*read.ID) - return resourceArmCdnEndpointRead(d, meta) } @@ -218,104 +258,53 @@ func resourceArmCdnEndpointRead(d *schema.ResourceData, meta interface{}) error if err != nil { return err } - resGroup := id.ResourceGroup + resourceGroup := id.ResourceGroup name := id.Path["endpoints"] profileName := id.Path["profiles"] if profileName == "" { profileName = id.Path["Profiles"] } - log.Printf("[INFO] Trying to find the AzureRM CDN Endpoint %s (Profile: %s, RG: %s)", name, profileName, resGroup) - resp, err := client.Get(ctx, resGroup, profileName, name) + log.Printf("[INFO] Retrieving CDN Endpoint %q (Profile %q / Resource Group %q)", name, profileName, resourceGroup) + resp, err := client.Get(ctx, resourceGroup, profileName, name) if err != nil { if utils.ResponseWasNotFound(resp.Response) { d.SetId("") return nil } - return fmt.Errorf("Error making Read request on Azure CDN Endpoint %s: %s", name, err) + + return fmt.Errorf("Error making Read request on Azure CDN Endpoint %q (Profile %q / Resource Group %q): %+v", name, profileName, resourceGroup, err) } d.Set("name", resp.Name) - d.Set("resource_group_name", resGroup) - d.Set("location", azureRMNormalizeLocation(*resp.Location)) + d.Set("resource_group_name", resourceGroup) d.Set("profile_name", profileName) - d.Set("host_name", resp.EndpointProperties.HostName) - d.Set("is_compression_enabled", resp.EndpointProperties.IsCompressionEnabled) - d.Set("is_http_allowed", resp.EndpointProperties.IsHTTPAllowed) - d.Set("is_https_allowed", resp.EndpointProperties.IsHTTPSAllowed) - d.Set("querystring_caching_behaviour", resp.EndpointProperties.QueryStringCachingBehavior) - if resp.EndpointProperties.OriginHostHeader != nil && *resp.EndpointProperties.OriginHostHeader != "" { - d.Set("origin_host_header", resp.EndpointProperties.OriginHostHeader) - } - if resp.EndpointProperties.OriginPath != nil && *resp.EndpointProperties.OriginPath != "" { - d.Set("origin_path", resp.EndpointProperties.OriginPath) - } - if resp.EndpointProperties.ContentTypesToCompress != nil { - d.Set("content_types_to_compress", flattenAzureRMCdnEndpointContentTypes(resp.EndpointProperties.ContentTypesToCompress)) - } - d.Set("origin", flattenAzureRMCdnEndpointOrigin(resp.EndpointProperties.Origins)) - - flattenAndSetTags(d, resp.Tags) - - return nil -} - -func resourceArmCdnEndpointUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*ArmClient).cdnEndpointsClient - ctx := meta.(*ArmClient).StopContext - name := d.Get("name").(string) - resGroup := d.Get("resource_group_name").(string) - profileName := d.Get("profile_name").(string) - http_allowed := d.Get("is_http_allowed").(bool) - https_allowed := d.Get("is_https_allowed").(bool) - compression_enabled := d.Get("is_compression_enabled").(bool) - caching_behaviour := d.Get("querystring_caching_behaviour").(string) - newTags := d.Get("tags").(map[string]interface{}) - - properties := cdn.EndpointPropertiesUpdateParameters{ - IsHTTPAllowed: &http_allowed, - IsHTTPSAllowed: &https_allowed, - IsCompressionEnabled: &compression_enabled, - QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(caching_behaviour), - } - - if d.HasChange("origin_host_header") { - host_header := d.Get("origin_host_header").(string) - properties.OriginHostHeader = &host_header + if location := resp.Location; location != nil { + d.Set("location", azureRMNormalizeLocation(*location)) } - if d.HasChange("origin_path") { - origin_path := d.Get("origin_path").(string) - properties.OriginPath = &origin_path - } + if props := resp.EndpointProperties; props != nil { + d.Set("host_name", props.HostName) + d.Set("is_compression_enabled", props.IsCompressionEnabled) + d.Set("is_http_allowed", props.IsHTTPAllowed) + d.Set("is_https_allowed", props.IsHTTPSAllowed) + d.Set("querystring_caching_behaviour", props.QueryStringCachingBehavior) + d.Set("origin_host_header", props.OriginHostHeader) + d.Set("origin_path", props.OriginPath) - if d.HasChange("content_types_to_compress") { - var content_types []string - ctypes := d.Get("content_types_to_compress").(*schema.Set).List() - for _, ct := range ctypes { - str := ct.(string) - content_types = append(content_types, str) + contentTypes := flattenAzureRMCdnEndpointContentTypes(props.ContentTypesToCompress) + if err := d.Set("content_types_to_compress", contentTypes); err != nil { + return fmt.Errorf("Error flattening `content_types_to_compress`: %+v", err) + } + origins := flattenAzureRMCdnEndpointOrigin(props.Origins) + if err := d.Set("origin", origins); err != nil { + return fmt.Errorf("Error flattening `origin`: %+v", err) } - - properties.ContentTypesToCompress = &content_types - } - - updateProps := cdn.EndpointUpdateParameters{ - Tags: expandTags(newTags), - EndpointPropertiesUpdateParameters: &properties, - } - - future, err := client.Update(ctx, resGroup, profileName, name, updateProps) - if err != nil { - return fmt.Errorf("Error issuing Azure ARM update request to update CDN Endpoint %q: %s", name, err) } - err = future.WaitForCompletion(ctx, client.Client) - if err != nil { - return fmt.Errorf("Error issuing Azure ARM update request to update CDN Endpoint %q: %s", name, err) - } + flattenAndSetTags(d, resp.Tags) - return resourceArmCdnEndpointRead(d, meta) + return nil } func resourceArmCdnEndpointDelete(d *schema.ResourceData, meta interface{}) error { @@ -326,19 +315,19 @@ func resourceArmCdnEndpointDelete(d *schema.ResourceData, meta interface{}) erro if err != nil { return err } - resGroup := id.ResourceGroup + resourceGroup := id.ResourceGroup profileName := id.Path["profiles"] if profileName == "" { profileName = id.Path["Profiles"] } name := id.Path["endpoints"] - future, err := client.Delete(ctx, resGroup, profileName, name) + future, err := client.Delete(ctx, resourceGroup, profileName, name) if err != nil { if response.WasNotFound(future.Response()) { return nil } - return fmt.Errorf("Error issuing AzureRM delete request for CDN Endpoint %q: %s", name, err) + return fmt.Errorf("Error deleting CDN Endpoint %q (Profile %q / Resource Group %q): %+v", name, profileName, resourceGroup, err) } err = future.WaitForCompletion(ctx, client.Client) @@ -346,24 +335,18 @@ func resourceArmCdnEndpointDelete(d *schema.ResourceData, meta interface{}) erro if response.WasNotFound(future.Response()) { return nil } - return fmt.Errorf("Error issuing AzureRM delete request for CDN Endpoint %q: %s", name, err) + return fmt.Errorf("Error waiting for CDN Endpoint %q (Profile %q / Resource Group %q) to be deleted: %+v", name, profileName, resourceGroup, err) } return nil } - -func validateCdnEndpointQuerystringCachingBehaviour(v interface{}, k string) (ws []string, errors []error) { - value := strings.ToLower(v.(string)) - cachingTypes := map[string]bool{ - "ignorequerystring": true, - "bypasscaching": true, - "usequerystring": true, - } - - if !cachingTypes[value] { - errors = append(errors, fmt.Errorf("CDN Endpoint querystringCachingBehaviours can only be IgnoreQueryString, BypassCaching or UseQueryString")) +func expandArmCdnEndpointContentTypesToCompress(v interface{}) []string { + var contentTypes []string + inputContentTypes := v.(*schema.Set).List() + for _, ct := range inputContentTypes { + str := ct.(string) + contentTypes = append(contentTypes, str) } - return } func resourceArmCdnEndpointOriginHash(v interface{}) int { @@ -372,37 +355,37 @@ func resourceArmCdnEndpointOriginHash(v interface{}) int { buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) buf.WriteString(fmt.Sprintf("%s-", m["host_name"].(string))) + // TODO: can we remove this; and do we need a state migration? + return hashcode.String(buf.String()) } func expandAzureRmCdnEndpointOrigins(d *schema.ResourceData) ([]cdn.DeepCreatedOrigin, error) { configs := d.Get("origin").(*schema.Set).List() - origins := make([]cdn.DeepCreatedOrigin, 0, len(configs)) + origins := make([]cdn.DeepCreatedOrigin, 0) for _, configRaw := range configs { data := configRaw.(map[string]interface{}) - host_name := data["host_name"].(string) - + hostName := data["host_name"].(string) properties := cdn.DeepCreatedOriginProperties{ - HostName: &host_name, + HostName: utils.String(hostName), } if v, ok := data["https_port"]; ok { - https_port := int32(v.(int)) - properties.HTTPSPort = &https_port - + port := v.(int) + properties.HTTPSPort = utils.Int32(int32(port)) } if v, ok := data["http_port"]; ok { - http_port := int32(v.(int)) - properties.HTTPPort = &http_port + port := v.(int) + properties.HTTPPort = utils.Int32(int32(port)) } name := data["name"].(string) origin := cdn.DeepCreatedOrigin{ - Name: &name, + Name: utils.String(name), DeepCreatedOriginProperties: &properties, } @@ -412,22 +395,33 @@ func expandAzureRmCdnEndpointOrigins(d *schema.ResourceData) ([]cdn.DeepCreatedO return origins, nil } -func flattenAzureRMCdnEndpointOrigin(list *[]cdn.DeepCreatedOrigin) []map[string]interface{} { - result := make([]map[string]interface{}, 0, len(*list)) - for _, i := range *list { - l := map[string]interface{}{ - "name": *i.Name, - "host_name": *i.DeepCreatedOriginProperties.HostName, - } - - if i.DeepCreatedOriginProperties.HTTPPort != nil { - l["http_port"] = *i.DeepCreatedOriginProperties.HTTPPort +func flattenAzureRMCdnEndpointOrigin(input *[]cdn.DeepCreatedOrigin) []map[string]interface{} { + result := make([]map[string]interface{}, 0) + + if list := input; list != nil { + for _, i := range *list { + l := map[string]interface{}{} + + if name := i.Name; name != nil { + l["name"] = *name + } + + if props := i.DeepCreatedOriginProperties; props != nil { + if hostName := props.HostName; hostName != nil { + l["host_name"] = *hostName + } + if port := props.HTTPPort; port != nil { + l["http_port"] = int(*port) + } + if port := props.HTTPSPort; port != nil { + l["https_port"] = int(*port) + } + } + + result = append(result, l) } - if i.DeepCreatedOriginProperties.HTTPSPort != nil { - l["https_port"] = *i.DeepCreatedOriginProperties.HTTPSPort - } - result = append(result, l) } + return result } From 0c1b87eb107f643921adff0ca9824ce2573cf36b Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Wed, 7 Mar 2018 12:44:42 -0700 Subject: [PATCH 006/156] Adding support for the ProbePath field --- azurerm/resource_arm_cdn_endpoint.go | 22 ++++++++++++++++------ website/docs/r/cdn_endpoint.html.markdown | 4 +++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/azurerm/resource_arm_cdn_endpoint.go b/azurerm/resource_arm_cdn_endpoint.go index 3d49761926ff1..e8fdcfd751f70 100644 --- a/azurerm/resource_arm_cdn_endpoint.go +++ b/azurerm/resource_arm_cdn_endpoint.go @@ -124,6 +124,12 @@ func resourceArmCdnEndpoint() *schema.Resource { Default: false, }, + "probe_path": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "host_name": { Type: schema.TypeString, Computed: true, @@ -150,6 +156,7 @@ func resourceArmCdnEndpointCreate(d *schema.ResourceData, meta interface{}) erro cachingBehaviour := d.Get("querystring_caching_behaviour").(string) originHostHeader := d.Get("origin_host_header").(string) originPath := d.Get("origin_path").(string) + probePath := d.Get("probe_path").(string) tags := d.Get("tags").(map[string]interface{}) endpoint := cdn.Endpoint{ @@ -161,12 +168,12 @@ func resourceArmCdnEndpointCreate(d *schema.ResourceData, meta interface{}) erro QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(cachingBehaviour), OriginHostHeader: utils.String(originHostHeader), OriginPath: utils.String(originPath), + ProbePath: utils.String(probePath), //GeoFilters: []cdn.GeoFilter{{ // Action: cdn.Allow || cdn.Block // CountryCodes: []string{} // RelativePath: "" //}} - //ProbePath: "" }, Tags: expandTags(tags), } @@ -217,16 +224,18 @@ func resourceArmCdnEndpointUpdate(d *schema.ResourceData, meta interface{}) erro cachingBehaviour := d.Get("querystring_caching_behaviour").(string) hostHeader := d.Get("origin_host_header").(string) originPath := d.Get("origin_path").(string) + probePath := d.Get("probe_path").(string) tags := d.Get("tags").(map[string]interface{}) endpoint := cdn.EndpointUpdateParameters{ EndpointPropertiesUpdateParameters: &cdn.EndpointPropertiesUpdateParameters{ - IsHTTPAllowed: &httpAllowed, - IsHTTPSAllowed: &httpsAllowed, - IsCompressionEnabled: &compressionEnabled, + IsHTTPAllowed: utils.Bool(httpAllowed), + IsHTTPSAllowed: utils.Bool(httpsAllowed), + IsCompressionEnabled: utils.Bool(compressionEnabled), QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(cachingBehaviour), - OriginHostHeader: &hostHeader, - OriginPath: &originPath, + OriginHostHeader: utils.String(hostHeader), + OriginPath: utils.String(originPath), + ProbePath: utils.String(probePath), }, Tags: expandTags(tags), } @@ -291,6 +300,7 @@ func resourceArmCdnEndpointRead(d *schema.ResourceData, meta interface{}) error d.Set("querystring_caching_behaviour", props.QueryStringCachingBehavior) d.Set("origin_host_header", props.OriginHostHeader) d.Set("origin_path", props.OriginPath) + d.Set("probe_path", props.ProbePath) contentTypes := flattenAzureRMCdnEndpointContentTypes(props.ContentTypesToCompress) if err := d.Set("content_types_to_compress", contentTypes); err != nil { diff --git a/website/docs/r/cdn_endpoint.html.markdown b/website/docs/r/cdn_endpoint.html.markdown index 964b562222bbf..96f0a54028f92 100644 --- a/website/docs/r/cdn_endpoint.html.markdown +++ b/website/docs/r/cdn_endpoint.html.markdown @@ -7,7 +7,7 @@ description: |- --- -# azurerm\_cdn\_endpoint +# azurerm_cdn_endpoint A CDN Endpoint is the entity within a CDN Profile containing configuration information regarding caching behaviors and origins. The CDN Endpoint is exposed using the URL format .azureedge.net by default, but custom domains can also be created. @@ -72,6 +72,8 @@ Each `origin` block supports fields documented below. * `origin_path` - (Optional) The path used at for origin requests. +* `probe_path` - (Optional) the path to a file hosted on the origin which helps accelerate delivery of the dynamic content and calculate the most optimal routes for the CDN. This is relative to the `origin_path`. + * `querystring_caching_behaviour` - (Optional) Sets query string caching behavior. Allowed values are `IgnoreQueryString`, `BypassCaching` and `UseQueryString`. Defaults to `IgnoreQueryString`. * `content_types_to_compress` - (Optional) An array of strings that indicates a content types on which compression will be applied. The value for the elements should be MIME types. From 86c4b1b18e552612e6df9a37b7b82c1ce9610552 Mon Sep 17 00:00:00 2001 From: Edwin Date: Thu, 8 Mar 2018 01:03:21 +0800 Subject: [PATCH 007/156] azurerm: support notify-keyspace-events configuration on Redis --- azurerm/resource_arm_redis_cache.go | 9 ++++ azurerm/resource_arm_redis_cache_test.go | 52 +++++++++++++++++++++++- website/docs/r/redis_cache.html.markdown | 1 + 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/azurerm/resource_arm_redis_cache.go b/azurerm/resource_arm_redis_cache.go index a536a86d03d73..99d0435055581 100644 --- a/azurerm/resource_arm_redis_cache.go +++ b/azurerm/resource_arm_redis_cache.go @@ -121,6 +121,10 @@ func resourceArmRedisCache() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "notify_keyspace_events": { + Type: schema.TypeString, + Optional: true, + }, }, }, }, @@ -509,6 +513,10 @@ func expandRedisConfiguration(d *schema.ResourceData) *map[string]*string { output["rdb-storage-connection-string"] = utils.String(v.(string)) } + if v, ok := d.GetOk("redis_configuration.0.notify_keyspace_events"); ok { + output["notify-keyspace-events"] = utils.String(v.(string)) + } + return &output } @@ -553,6 +561,7 @@ func flattenRedisConfiguration(configuration *map[string]*string) map[string]*st redisConfiguration["rdb_backup_frequency"] = config["rdb-backup-frequency"] redisConfiguration["rdb_backup_max_snapshot_count"] = config["rdb-backup-max-snapshot-count"] redisConfiguration["rdb_storage_connection_string"] = config["rdb-storage-connection-string"] + redisConfiguration["notify_keyspace_events"] = config["notify-keyspace-events"] return redisConfiguration } diff --git a/azurerm/resource_arm_redis_cache_test.go b/azurerm/resource_arm_redis_cache_test.go index ae345d8484ec3..67cc1ca2d59bb 100644 --- a/azurerm/resource_arm_redis_cache_test.go +++ b/azurerm/resource_arm_redis_cache_test.go @@ -374,6 +374,26 @@ func testCheckAzureRMRedisCacheDestroy(s *terraform.State) error { return nil } +func TestAccAzureRMRedisCache_SubscribeAllEvents(t *testing.T) { + ri := acctest.RandInt() + rs := acctest.RandString(4) + config := testAccAzureRMRedisCacheSubscribeAllEvents(ri, rs, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMRedisCacheDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMRedisCacheExists("azurerm_redis_cache.test"), + ), + }, + }, + }) +} + func testAccAzureRMRedisCache_basic(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -563,7 +583,6 @@ resource "azurerm_resource_group" "test" { name = "acctestRG-%d" location = "%s" } - resource "azurerm_redis_cache" "test" { name = "acctestRedis-%d" location = "${azurerm_resource_group.test.location}" @@ -578,7 +597,6 @@ resource "azurerm_redis_cache" "test" { maxmemory_delta = 2 maxmemory_policy = "allkeys-lru" } - patch_schedule { day_of_week = "Tuesday" start_hour_utc = 8 @@ -586,3 +604,33 @@ resource "azurerm_redis_cache" "test" { } `, rInt, location, rInt) } + +func testAccAzureRMRedisCacheSubscribeAllEvents(rInt int, rString string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} +resource "azurerm_storage_account" "test" { + name = "unlikely23exst2acct%s" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_type = "Standard_GRS" + tags { + environment = "staging" + } +} +resource "azurerm_redis_cache" "test" { + name = "acctestRedis-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + capacity = 3 + family = "P" + sku_name = "Premium" + enable_non_ssl_port = false + redis_configuration { + notify_keyspace_events = "KAE" + } +} +`, rInt, location, rString, rInt) +} diff --git a/website/docs/r/redis_cache.html.markdown b/website/docs/r/redis_cache.html.markdown index 7e53a18895aef..7fb4d856cc1e0 100644 --- a/website/docs/r/redis_cache.html.markdown +++ b/website/docs/r/redis_cache.html.markdown @@ -182,6 +182,7 @@ The pricing group for the Redis Family - either "C" or "P" at present. * `rdb_backup_frequency` - (Optional) The Backup Frequency in Minutes. Only supported on Premium SKU's. Possible values are: `15`, `30`, `60`, `360`, `720` and `1440`. * `rdb_backup_max_snapshot_count` - (Optional) The maximum number of snapshots to create as a backup. Only supported for Premium SKU's. * `rdb_storage_connection_string` - (Optional) The Connection String to the Storage Account. Only supported for Premium SKU's. In the format: `DefaultEndpointsProtocol=https;BlobEndpoint=${azurerm_storage_account.test.primary_blob_endpoint};AccountName=${azurerm_storage_account.test.name};AccountKey=${azurerm_storage_account.test.primary_access_key}`. +* `notify_keyspace_events` - (Optional) Keyspace notifications allows clients to subscribe to Pub/Sub channels in order to receive events affecting the Redis data set in some way. [Reference](https://redis.io/topics/notifications#configuration) ```hcl redis_configuration { From 068bf395c96c31f5c844df96195f916489ce3e32 Mon Sep 17 00:00:00 2001 From: Lawrence Gripper Date: Thu, 8 Mar 2018 12:03:43 +0000 Subject: [PATCH 008/156] Created example and fixed issue with naming on create. --- .../resource_arm_log_analytics_solution.go | 25 +++++++++----- ...esource_arm_log_analytics_solution_test.go | 16 ++++----- .../main.tf | 33 +++++++++++++++++++ .../outputs.tf | 10 ++++++ 4 files changed, 68 insertions(+), 16 deletions(-) create mode 100644 examples/log-analytics-container-monitoring/main.tf create mode 100644 examples/log-analytics-container-monitoring/outputs.tf diff --git a/azurerm/resource_arm_log_analytics_solution.go b/azurerm/resource_arm_log_analytics_solution.go index ceced40bdcdd4..3dd388f195be5 100644 --- a/azurerm/resource_arm_log_analytics_solution.go +++ b/azurerm/resource_arm_log_analytics_solution.go @@ -22,9 +22,13 @@ func resourceArmLogAnalyticsSolution() *schema.Resource { Schema: map[string]*schema.Schema{ "name": { + Type: schema.TypeString, + Computed: true, + }, + + "solution_name": { Type: schema.TypeString, Required: true, - ForceNew: true, }, "location": locationSchema(), @@ -39,8 +43,7 @@ func resourceArmLogAnalyticsSolution() *schema.Resource { Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, - Required: true, - ForceNew: true, + Computed: true, }, "publisher": { Type: schema.TypeString, @@ -61,6 +64,11 @@ func resourceArmLogAnalyticsSolution() *schema.Resource { }, }, + "workspace_name": { + Type: schema.TypeString, + Required: true, + }, + "workspace_resource_id": { Type: schema.TypeString, Required: true, @@ -74,13 +82,16 @@ func resourceArmLogAnalyticsSolutionCreateUpdate(d *schema.ResourceData, meta in ctx := meta.(*ArmClient).StopContext log.Printf("[INFO] preparing arguments for AzureRM Log Analytics solution creation.") - name := d.Get("name").(string) + // The resource requires both .name and .plan.name are set in the format + // "SolutionName(WorkspaceName)". Feedback will be submitted to the OMS team as IMO this isn't ideal. + name := fmt.Sprintf("%s(%s)", d.Get("solution_name").(string), d.Get("workspace_name").(string)) + solutionPlan := expandAzureRmLogAnalyticsSolutionPlan(d) + solutionPlan.Name = &name + location := d.Get("location").(string) resGroup := d.Get("resource_group_name").(string) workspaceID := d.Get("workspace_resource_id").(string) - solutionPlan := expandAzureRmLogAnalyticsSolutionPlan(d) - parameters := operationsmanagement.Solution{ Name: &name, Location: &location, @@ -135,7 +146,6 @@ func resourceArmLogAnalyticsSolutionRead(d *schema.ResourceData, meta interface{ d.Set("name", resp.Name) d.Set("location", resp.Location) d.Set("resource_group_name", resGroup) - d.Set("workspace_resource_id", resp.ID) d.Set("plan", flattenAzureRmLogAnalyticsSolutionPlan(*resp.Plan)) return nil } @@ -195,7 +205,6 @@ func flattenAzureRmLogAnalyticsSolutionPlan(plan operationsmanagement.SolutionPl plans := make([]interface{}, 0) values := make(map[string]interface{}) - values["name"] = *plan.Name values["product"] = *plan.Product values["promotion_code"] = *plan.PromotionCode values["publisher"] = *plan.Publisher diff --git a/azurerm/resource_arm_log_analytics_solution_test.go b/azurerm/resource_arm_log_analytics_solution_test.go index 92ac0373ae079..a0feace7c0ca4 100644 --- a/azurerm/resource_arm_log_analytics_solution_test.go +++ b/azurerm/resource_arm_log_analytics_solution_test.go @@ -21,7 +21,7 @@ func TestAccAzureRMLogAnalyticsSolution(t *testing.T) { { Config: config, Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLogAnalyticsSolutionExists("azurerm_log_analytics_solution.solution"), + testCheckAzureRMLogAnalyticsSolutionExists("azurerm_log_analytics_solution.test"), ), }, }, @@ -91,26 +91,26 @@ resource "azurerm_resource_group" "test" { location = "%s" } -resource "azurerm_log_analytics_workspace" "workspace" { +resource "azurerm_log_analytics_workspace" "test" { name = "acctest-dep-%d" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" sku = "Free" } -resource "azurerm_log_analytics_solution" "solution" { - name = "acctest-%d" +resource "azurerm_log_analytics_solution" "test" { + solution_name = "Containers" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" - workspace_resource_id = "${azurerm_log_analytics_workspace.workspace.id}" - + workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" + plan { - name = "Containers" publisher = "Microsoft" product = "OMSGallery/Containers" } } -`, rInt, location, rInt, rInt) +`, rInt, location, rInt) } // func testAccAzureRMLogAnalyticsSolution_Temp(rInt int, location string) string { diff --git a/examples/log-analytics-container-monitoring/main.tf b/examples/log-analytics-container-monitoring/main.tf new file mode 100644 index 0000000000000..782f30afafafd --- /dev/null +++ b/examples/log-analytics-container-monitoring/main.tf @@ -0,0 +1,33 @@ +resource "azurerm_resource_group" "test" { + name = "k8s-log-analytics-test" + location = "westeurope" +} + +resource "random_id" "workspace" { + keepers = { + # Generate a new id each time we switch to a new resource group + group_name = "${azurerm_resource_group.test.name}" + } + + byte_length = 8 +} + +resource "azurerm_log_analytics_workspace" "test" { + name = "k8s-workspace-${random_id.workspace.hex}" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Free" +} + +resource "azurerm_log_analytics_solution" "test" { + solution_name = "Containers" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" + + plan { + publisher = "Microsoft" + product = "OMSGallery/Containers" + } +} \ No newline at end of file diff --git a/examples/log-analytics-container-monitoring/outputs.tf b/examples/log-analytics-container-monitoring/outputs.tf new file mode 100644 index 0000000000000..d6adecaf6ec4f --- /dev/null +++ b/examples/log-analytics-container-monitoring/outputs.tf @@ -0,0 +1,10 @@ + +// These outputs can be used to deploy the monitoring Daemonset into your k8s cluster +// https://docs.microsoft.com/en-us/azure/aks/tutorial-kubernetes-monitor +output "workspace_id" { + value = "${azurerm_log_analytics_workspace.test.workspace_id}" +} + +output "workspace_key" { + value = "${azurerm_log_analytics_workspace.test.primary_shared_key}" +} From 30afb16efbb32c091db54f5e3e4737d5706c84cb Mon Sep 17 00:00:00 2001 From: Lawrence Gripper Date: Thu, 8 Mar 2018 12:15:49 +0000 Subject: [PATCH 009/156] Removed logging code --- azurerm/config.go | 32 +------------------ .../operationsmanagement/solutions.go | 3 +- 2 files changed, 2 insertions(+), 33 deletions(-) diff --git a/azurerm/config.go b/azurerm/config.go index 16ead67892e03..91fa50d4e0402 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -742,37 +742,7 @@ func (c *ArmClient) registerOperationalInsightsClients(endpoint, subscriptionId solutionsClient := operationsmanagement.NewSolutionsClient(subscriptionId, "Microsoft.OperationsManagement", "solutions", "testing") c.configureClient(&solutionsClient.Client, auth) c.solutionsClient = solutionsClient - // c.solutionsClient.RequestInspector = LogRequestPreparer() - // c.solutionsClient.ResponseInspector = LogResponseDecorator() -} - -// func LogRequestPreparer() autorest.PrepareDecorator { -// return func(p autorest.Preparer) autorest.Preparer { -// return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { -// // resDump, _ := httputil.DumpRequestOut(r, true) -// // log.Println(string(resDump)) -// // return r, nil - -// r, err := p.Prepare(r) -// if err == nil { -// resDump, _ := httputil.DumpRequestOut(r, true) -// log.Println(string(resDump)) -// } -// return r, err -// }) -// } -// } - -// func LogResponseDecorator() autorest.RespondDecorator { -// return func(p autorest.Responder) autorest.Responder { -// return autorest.ResponderFunc(func(r *http.Response) error { -// _ = p.Respond(r) -// dump, _ := httputil.DumpResponse(r, true) -// log.Println(string(dump)) -// return nil -// }) -// } -// } +} func (c *ArmClient) registerRedisClients(endpoint, subscriptionId string, auth autorest.Authorizer, sender autorest.Sender) { redisClient := redis.NewClientWithBaseURI(endpoint, subscriptionId) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go index 3a392d2e4e9bf..be6f5501e6e4b 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement/solutions.go @@ -19,11 +19,10 @@ package operationsmanagement import ( "context" - "net/http" - "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/validation" + "net/http" ) // SolutionsClient is the operations Management Client From 051e77c24678fc4215fb1dbcd9a5bd569db7c20c Mon Sep 17 00:00:00 2001 From: Lawrence Gripper Date: Thu, 8 Mar 2018 13:25:32 +0000 Subject: [PATCH 010/156] Created docs for resource --- .../resource_arm_log_analytics_solution.go | 1 + .../r/log_analytics_solution.html.markdown | 75 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 website/docs/r/log_analytics_solution.html.markdown diff --git a/azurerm/resource_arm_log_analytics_solution.go b/azurerm/resource_arm_log_analytics_solution.go index 3dd388f195be5..2e5894c4899d8 100644 --- a/azurerm/resource_arm_log_analytics_solution.go +++ b/azurerm/resource_arm_log_analytics_solution.go @@ -29,6 +29,7 @@ func resourceArmLogAnalyticsSolution() *schema.Resource { "solution_name": { Type: schema.TypeString, Required: true, + ForceNew: true, }, "location": locationSchema(), diff --git a/website/docs/r/log_analytics_solution.html.markdown b/website/docs/r/log_analytics_solution.html.markdown new file mode 100644 index 0000000000000..2d5e227fec40d --- /dev/null +++ b/website/docs/r/log_analytics_solution.html.markdown @@ -0,0 +1,75 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_log_analytics_solution" +sidebar_current: "docs-azurerm-resource-oms-log-analytics-solution" +description: |- + Creates a new Log Analytics (formally Operational Insights) Solution. +--- + +# azurerm_log_analytics_solution + +Creates a new Log Analytics (formally Operational Insights) Solution. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "k8s-log-analytics-test" + location = "westeurope" +} + +resource "random_id" "workspace" { + keepers = { + # Generate a new id each time we switch to a new resource group + group_name = "${azurerm_resource_group.test.name}" + } + + byte_length = 8 +} + +resource "azurerm_log_analytics_workspace" "test" { + name = "k8s-workspace-${random_id.workspace.hex}" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Free" +} + +resource "azurerm_log_analytics_solution" "test" { + solution_name = "Containers" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" + + plan { + publisher = "Microsoft" + product = "OMSGallery/Containers" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `solution_name` - (Required) Specifies the name of the solution to be deployed. See [here for options](https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-add-solutions). Note: Resource tested with only `Container` solution. Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which the Log Analytics solution is created. Changing this forces a new resource to be created. Note: The solution and it's related workspace can only exist in the same resource group. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `workspace_resource_id` - (Required) The full resource ID of the Log Analytics workspace with which the solution will be linked. For example: `/subscriptions/00000000-0000-0000-0000-00000000/resourcegroups/examplegroupname/providers/Microsoft.OperationalInsights/workspaces/exampleWorkspaceName` + +* `workspace_resource_name` - (Required) The full name of the Log Analytics workspace with which the solution will be linked. For example: `exampleWorkspaceName` + +* `plan.publisher` - (Required) The publisher of the solution. For example `Microsoft`. Changing this forces a new resource to be created. + +* `plan.product` - (Required) The product name of the solution. For example `OMSGallery/Containers`. Changing this forces a new resource to be created. + +* `plan.promotion_code` - (Optional) A promotion code to be used with the solution. + +## Attributes Reference + +The following attributes are exported: + +* `name` and `plan.name` - These are identical and are generated from the `plan.product` and the `workspace_resource_name`. From 6ee0f102d87e0ec1858aa383fbcca1fdb5a4a215 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Thu, 8 Mar 2018 10:13:16 -0700 Subject: [PATCH 011/156] Splitting the storage account fields --- azurerm/resource_arm_redis_cache_test.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/azurerm/resource_arm_redis_cache_test.go b/azurerm/resource_arm_redis_cache_test.go index 67cc1ca2d59bb..63c1f26e718d4 100644 --- a/azurerm/resource_arm_redis_cache_test.go +++ b/azurerm/resource_arm_redis_cache_test.go @@ -615,22 +615,23 @@ resource "azurerm_storage_account" "test" { name = "unlikely23exst2acct%s" resource_group_name = "${azurerm_resource_group.test.name}" location = "${azurerm_resource_group.test.location}" - account_type = "Standard_GRS" + account_tier = "Standard" + account_replication_type = "GRS" tags { environment = "staging" } } resource "azurerm_redis_cache" "test" { - name = "acctestRedis-%d" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - capacity = 3 - family = "P" - sku_name = "Premium" - enable_non_ssl_port = false - redis_configuration { - notify_keyspace_events = "KAE" - } + name = "acctestRedis-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + capacity = 3 + family = "P" + sku_name = "Premium" + enable_non_ssl_port = false + redis_configuration { + notify_keyspace_events = "KAE" + } } `, rInt, location, rString, rInt) } From 1e88ebac0f241b6a0547cf00146452fc87ef3633 Mon Sep 17 00:00:00 2001 From: Tom Harvey Date: Thu, 8 Mar 2018 10:40:34 -0700 Subject: [PATCH 012/156] Updating to include #949 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a6848158173d..422d1cc6f1472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ IMPROVEMENTS: * `azurerm_network_security_group` - support for security rules including Application Security Groups [GH-925] * `azurerm_network_security_rule` - support for security rules including Application Security Groups [GH-925] * `azurerm_public_ip` - adding support for Availability Zones [GH-811] +* `azurerm_redis_cache` - add support for `notify-keyspace-events` [GH-949] * `azurerm_virtual_machine` - adding support for Availability Zones [GH-811] * `azurerm_virtual_machine_scale_set` - adding support for Availability Zones [GH-811] From 9db47256d1277849d902e58c6b0ffe18d2ace2f9 Mon Sep 17 00:00:00 2001 From: lawrencegripper Date: Fri, 9 Mar 2018 12:55:28 +0000 Subject: [PATCH 013/156] Fixed review feedback. Added new basic test & example. Updated docs. --- .../resource_arm_log_analytics_solution.go | 68 ++++++++++++------- ...esource_arm_log_analytics_solution_test.go | 68 +++++++++++++------ .../main.tf | 35 +++++++--- vendor/vendor.json | 4 +- .../r/log_analytics_solution.html.markdown | 54 +++++++-------- 5 files changed, 145 insertions(+), 84 deletions(-) diff --git a/azurerm/resource_arm_log_analytics_solution.go b/azurerm/resource_arm_log_analytics_solution.go index 2e5894c4899d8..f34e5266e33e2 100644 --- a/azurerm/resource_arm_log_analytics_solution.go +++ b/azurerm/resource_arm_log_analytics_solution.go @@ -3,6 +3,7 @@ package azurerm import ( "fmt" "log" + "strings" "github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement" @@ -21,11 +22,6 @@ func resourceArmLogAnalyticsSolution() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Computed: true, - }, - "solution_name": { Type: schema.TypeString, Required: true, @@ -68,11 +64,19 @@ func resourceArmLogAnalyticsSolution() *schema.Resource { "workspace_name": { Type: schema.TypeString, Required: true, + ForceNew: true, }, "workspace_resource_id": { Type: schema.TypeString, Required: true, + ForceNew: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if strings.ToLower(old) == strings.ToLower(new) { + return true + } + return false + }, }, }, } @@ -141,13 +145,33 @@ func resourceArmLogAnalyticsSolutionRead(d *schema.ResourceData, meta interface{ } if resp.Plan == nil { - return fmt.Errorf("Error making Read request on AzureRM Log Analytics solutions '%s': %+v Plan was nil", name, err) + return fmt.Errorf("Error making Read request on AzureRM Log Analytics solutions '%s': Plan was nil", name) } - d.Set("name", resp.Name) d.Set("location", resp.Location) d.Set("resource_group_name", resGroup) - d.Set("plan", flattenAzureRmLogAnalyticsSolutionPlan(*resp.Plan)) + + // Reversing the mapping used to get .solution_name + // expecting resp.Name to be in format "SolutionName(WorkspaceName)". + if resp.Name != nil && strings.Contains(*resp.Name, "(") { + if parts := strings.Split(*resp.Name, "("); len(parts) == 2 { + d.Set("solution_name", parts[0]) + workspaceName := strings.TrimPrefix(parts[1], "(") + workspaceName = strings.TrimSuffix(workspaceName, ")") + d.Set("workspace_name", workspaceName) + } else { + return fmt.Errorf("Error making Read request on AzureRM Log Analytics solutions '%v': isn't in expected format 'Solution(WorkspaceName)'", resp.Name) + } + } else { + return fmt.Errorf("Error making Read request on AzureRM Log Analytics solutions '%v': isn't in expected format 'Solution(WorkspaceName)'", resp.Name) + } + + if props := resp.Properties; props != nil { + d.Set("workspace_resource_id", props.WorkspaceResourceID) + } + if plan := resp.Plan; plan != nil { + d.Set("plan", flattenAzureRmLogAnalyticsSolutionPlan(*resp.Plan)) + } return nil } @@ -178,25 +202,16 @@ func expandAzureRmLogAnalyticsSolutionPlan(d *schema.ResourceData) operationsman plans := d.Get("plan").([]interface{}) plan := plans[0].(map[string]interface{}) - expandedPlan := operationsmanagement.SolutionPlan{} - - if name := plan["name"].(string); len(name) > 0 { - expandedPlan.Name = &name - } - - if publisher := plan["publisher"].(string); len(publisher) > 0 { - expandedPlan.Publisher = &publisher - } - - if promotionCode := plan["promotion_code"].(string); len(promotionCode) > 0 { - expandedPlan.PromotionCode = &promotionCode - } else { - blankString := "" - expandedPlan.PromotionCode = &blankString - } + name := plan["name"].(string) + publisher := plan["publisher"].(string) + promotionCode := plan["promotion_code"].(string) + product := plan["product"].(string) - if product := plan["product"].(string); len(product) > 0 { - expandedPlan.Product = &product + expandedPlan := operationsmanagement.SolutionPlan{ + Name: utils.String(name), + PromotionCode: utils.String(promotionCode), + Publisher: utils.String(publisher), + Product: utils.String(product), } return expandedPlan @@ -206,6 +221,7 @@ func flattenAzureRmLogAnalyticsSolutionPlan(plan operationsmanagement.SolutionPl plans := make([]interface{}, 0) values := make(map[string]interface{}) + values["name"] = plan.Name values["product"] = *plan.Product values["promotion_code"] = *plan.PromotionCode values["publisher"] = *plan.Publisher diff --git a/azurerm/resource_arm_log_analytics_solution_test.go b/azurerm/resource_arm_log_analytics_solution_test.go index a0feace7c0ca4..910b015e81c14 100644 --- a/azurerm/resource_arm_log_analytics_solution_test.go +++ b/azurerm/resource_arm_log_analytics_solution_test.go @@ -10,9 +10,27 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccAzureRMLogAnalyticsSolution(t *testing.T) { +func TestAccAzureRMLogAnalyticsSolution_basic_containerMonitoring(t *testing.T) { ri := acctest.RandInt() - config := testAccAzureRMLogAnalyticsSolution(ri, testLocation()) + config := testAccAzureRMLogAnalyticsSolution_containerMonitoring(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMLogAnalyticsSolutionDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLogAnalyticsSolutionExists("azurerm_log_analytics_solution.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMLogAnalyticsSolution_basic_security(t *testing.T) { + ri := acctest.RandInt() + config := testAccAzureRMLogAnalyticsSolution_security(ri, testLocation()) resource.Test(t, resource.TestCase{ Providers: testAccProviders, @@ -84,7 +102,7 @@ func testCheckAzureRMLogAnalyticsSolutionExists(name string) resource.TestCheckF } } -func testAccAzureRMLogAnalyticsSolution(rInt int, location string) string { +func testAccAzureRMLogAnalyticsSolution_containerMonitoring(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { name = "oms-acctestRG-%d" @@ -113,19 +131,31 @@ resource "azurerm_log_analytics_solution" "test" { `, rInt, location, rInt) } -// func testAccAzureRMLogAnalyticsSolution_Temp(rInt int, location string) string { -// return fmt.Sprintf(` -// resource "azurerm_log_analytics_solution" "solution" { -// name = "acctest" -// location = "westeurope" -// resource_group_name = "lg-terraformtest" -// workspace_resource_id = "/subscriptions/5774ad8f-d51e-4456-a72e-0447910568d3/resourcegroups/lg-terraformtest/providers/microsoft.operationalinsights/workspaces/lg-testoms" - -// plan { -// name = "Containers" -// publisher = "Microsoft" -// product = "OMSGallery/Containers" -// } -// } -// `) -// } +func testAccAzureRMLogAnalyticsSolution_security(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "oms-acctestRG-%d" + location = "%s" +} + +resource "azurerm_log_analytics_workspace" "test" { + name = "acctest-dep-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Free" +} + +resource "azurerm_log_analytics_solution" "test" { + solution_name = "Security" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" + + plan { + publisher = "Microsoft" + product = "OMSGallery/Security" + } +} +`, rInt, location, rInt) +} diff --git a/examples/log-analytics-container-monitoring/main.tf b/examples/log-analytics-container-monitoring/main.tf index 782f30afafafd..52bb40b6f1e3f 100644 --- a/examples/log-analytics-container-monitoring/main.tf +++ b/examples/log-analytics-container-monitoring/main.tf @@ -1,6 +1,6 @@ resource "azurerm_resource_group" "test" { - name = "k8s-log-analytics-test" - location = "westeurope" + name = "k8s-log-analytics-test" + location = "westeurope" } resource "random_id" "workspace" { @@ -11,16 +11,29 @@ resource "random_id" "workspace" { byte_length = 8 } - + resource "azurerm_log_analytics_workspace" "test" { - name = "k8s-workspace-${random_id.workspace.hex}" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - sku = "Free" + name = "k8s-workspace-${random_id.workspace.hex}" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Free" } - + resource "azurerm_log_analytics_solution" "test" { - solution_name = "Containers" + solution_name = "Containers" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" + + plan { + publisher = "Microsoft" + product = "OMSGallery/Containers" + } +} + +resource "azurerm_log_analytics_solution" "test2" { + solution_name = "Security" location = "${azurerm_resource_group.test.location}" resource_group_name = "${azurerm_resource_group.test.name}" workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}" @@ -28,6 +41,6 @@ resource "azurerm_log_analytics_solution" "test" { plan { publisher = "Microsoft" - product = "OMSGallery/Containers" + product = "OMSGallery/Security" } -} \ No newline at end of file +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 4c8526326ce43..48b4f40ec7d54 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -158,7 +158,9 @@ "checksumSHA1": "WMfs+FCE3stapwrAvAS3fjFZlHk=", "path": "github.com/Azure/azure-sdk-for-go/services/operationsmanagement/mgmt/2015-11-01-preview/operationsmanagement", "revision": "21b68149ccf7c16b3f028bb4c7fd0ab458fe308f", - "revisionTime": "2018-02-12T16:31:56Z" + "revisionTime": "2018-02-16T17:41:56Z", + "version": "v12.5.0-beta", + "versionExact": "v12.5.0-beta" }, { "checksumSHA1": "qOcKrxfayIRgAKlAZu9XYTSfeA0=", diff --git a/website/docs/r/log_analytics_solution.html.markdown b/website/docs/r/log_analytics_solution.html.markdown index 2d5e227fec40d..9f79156fded22 100644 --- a/website/docs/r/log_analytics_solution.html.markdown +++ b/website/docs/r/log_analytics_solution.html.markdown @@ -14,8 +14,8 @@ Creates a new Log Analytics (formally Operational Insights) Solution. ```hcl resource "azurerm_resource_group" "test" { - name = "k8s-log-analytics-test" - location = "westeurope" + name = "k8s-log-analytics-test" + location = "westeurope" } resource "random_id" "workspace" { @@ -26,25 +26,25 @@ resource "random_id" "workspace" { byte_length = 8 } - + resource "azurerm_log_analytics_workspace" "test" { - name = "k8s-workspace-${random_id.workspace.hex}" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - sku = "Free" + name = "k8s-workspace-${random_id.workspace.hex}" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Free" } - + resource "azurerm_log_analytics_solution" "test" { - solution_name = "Containers" - location = "${azurerm_resource_group.test.location}" - resource_group_name = "${azurerm_resource_group.test.name}" - workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}" - workspace_name = "${azurerm_log_analytics_workspace.test.name}" - - plan { - publisher = "Microsoft" - product = "OMSGallery/Containers" - } + solution_name = "Containers" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}" + workspace_name = "${azurerm_log_analytics_workspace.test.name}" + + plan { + publisher = "Microsoft" + product = "OMSGallery/Containers" + } } ``` @@ -52,24 +52,24 @@ resource "azurerm_log_analytics_solution" "test" { The following arguments are supported: -* `solution_name` - (Required) Specifies the name of the solution to be deployed. See [here for options](https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-add-solutions). Note: Resource tested with only `Container` solution. Changing this forces a new resource to be created. +* `solution_name` - (Required) Specifies the name of the solution to be deployed. See [here for options](https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-add-solutions).Changing this forces a new resource to be created. * `resource_group_name` - (Required) The name of the resource group in which the Log Analytics solution is created. Changing this forces a new resource to be created. Note: The solution and it's related workspace can only exist in the same resource group. * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `workspace_resource_id` - (Required) The full resource ID of the Log Analytics workspace with which the solution will be linked. For example: `/subscriptions/00000000-0000-0000-0000-00000000/resourcegroups/examplegroupname/providers/Microsoft.OperationalInsights/workspaces/exampleWorkspaceName` +* `workspace_resource_id` - (Required) The full resource ID of the Log Analytics workspace with which the solution will be linked. Changing this forces a new resource to be created. -* `workspace_resource_name` - (Required) The full name of the Log Analytics workspace with which the solution will be linked. For example: `exampleWorkspaceName` +* `workspace_resource_name` - (Required) The full name of the Log Analytics workspace with which the solution will be linked. Changing this forces a new resource to be created. -* `plan.publisher` - (Required) The publisher of the solution. For example `Microsoft`. Changing this forces a new resource to be created. +* `plan` - A `plan` block as documented below. -* `plan.product` - (Required) The product name of the solution. For example `OMSGallery/Containers`. Changing this forces a new resource to be created. +--- -* `plan.promotion_code` - (Optional) A promotion code to be used with the solution. +A `plan` block includes: -## Attributes Reference +* `publisher` - (Required) The publisher of the solution. For example `Microsoft`. Changing this forces a new resource to be created. -The following attributes are exported: +* `product` - (Required) The product name of the solution. For example `OMSGallery/Containers`. Changing this forces a new resource to be created. -* `name` and `plan.name` - These are identical and are generated from the `plan.product` and the `workspace_resource_name`. +* `promotion_code` - (Optional) A promotion code to be used with the solution. From d2e4c33db6cc7f64e225b989a36ddc0778d536d3 Mon Sep 17 00:00:00 2001 From: Khalid J Hosein Date: Fri, 9 Mar 2018 12:55:52 -0500 Subject: [PATCH 014/156] Add StorageV2 as new option for account_kind param --- website/docs/r/storage_account.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/storage_account.html.markdown b/website/docs/r/storage_account.html.markdown index bbd8b7663df0e..e50db68b150dd 100644 --- a/website/docs/r/storage_account.html.markdown +++ b/website/docs/r/storage_account.html.markdown @@ -45,7 +45,7 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `account_kind` - (Optional) Defines the Kind of account. Valid options are `Storage` +* `account_kind` - (Optional) Defines the Kind of account. Valid options are `Storage`, `StorageV2` and `BlobStorage`. Changing this forces a new resource to be created. Defaults to `Storage`. From d0a1c40e7c23515b56babefb2a3963de320b8b3b Mon Sep 17 00:00:00 2001 From: Scott Godbold Date: Fri, 9 Mar 2018 14:21:04 -0500 Subject: [PATCH 015/156] Fixes azure vm documentation for custom images --- website/docs/r/virtual_machine.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/virtual_machine.html.markdown b/website/docs/r/virtual_machine.html.markdown index a35f9c1fe6ea6..990eb69c419ac 100644 --- a/website/docs/r/virtual_machine.html.markdown +++ b/website/docs/r/virtual_machine.html.markdown @@ -179,7 +179,7 @@ resource "azurerm_virtual_machine" "test" { # Uncomment this line to delete the data disks automatically when deleting the VM # delete_data_disks_on_termination = true - storage_profile_image_reference { + storage_image_reference { id="${data.azurerm_image.image.id}" } From d0bcdab0f15a6fdec7bc884c234427815fdb7b2c Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 9 Mar 2018 15:49:25 -0800 Subject: [PATCH 016/156] Updated CHANGELOG.md to include #940 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 422d1cc6f1472..c941775e7b220 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ FEATURES: * **New Data Source:** `azurerm_cdn_profile` [GH-950] * **New Data Source:** `azurerm_network_interface` [GH-854] * **New Data Source:** `azurerm_public_ips` [GH-304] +* **New Data Source:** `azurerm_subscriptions` [GH-940] * **New Resource:** `azurerm_sql_active_directory_administrator` [GH-765] BUG FIXES: From 2ad240dccdc656f4dac4a7bbc6635da1bd1fb1de Mon Sep 17 00:00:00 2001 From: kt Date: Fri, 9 Mar 2018 15:52:41 -0800 Subject: [PATCH 017/156] Tweaked line ending alignment --- website/docs/r/storage_account.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/r/storage_account.html.markdown b/website/docs/r/storage_account.html.markdown index e50db68b150dd..9edc041306688 100644 --- a/website/docs/r/storage_account.html.markdown +++ b/website/docs/r/storage_account.html.markdown @@ -45,9 +45,9 @@ The following arguments are supported: * `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. -* `account_kind` - (Optional) Defines the Kind of account. Valid options are `Storage`, `StorageV2` - and `BlobStorage`. Changing this forces a new resource to be created. Defaults - to `Storage`. +* `account_kind` - (Optional) Defines the Kind of account. Valid options are `Storage`, + `StorageV2` and `BlobStorage`. Changing this forces a new resource to be created. + Defaults to `Storage`. * `account_tier` - (Required) Defines the Tier to use for this storage account. Valid options are `Standard` and `Premium`. Changing this forces a new resource to be created From 76c27eed888f1105e55183bdbce280b451325df6 Mon Sep 17 00:00:00 2001 From: kt Date: Sun, 11 Mar 2018 14:17:25 -0700 Subject: [PATCH 018/156] Added new resource azurerm_scheduler_job_collection --- azurerm/config.go | 11 + azurerm/provider.go | 1 + .../resource_arm_scheduler_job_collection.go | 267 ++++++++++++++++++ ...ource_arm_scheduler_job_collection_test.go | 139 +++++++++ examples/scheduler-jobs/main.tf | 19 ++ examples/scheduler-jobs/outputs.tf | 4 + examples/scheduler-jobs/variables.tf | 11 + website/azurerm.erb | 9 + .../r/scheduler_job_collection.html.markdown | 75 +++++ 9 files changed, 536 insertions(+) create mode 100644 azurerm/resource_arm_scheduler_job_collection.go create mode 100644 azurerm/resource_arm_scheduler_job_collection_test.go create mode 100644 examples/scheduler-jobs/main.tf create mode 100644 examples/scheduler-jobs/outputs.tf create mode 100644 examples/scheduler-jobs/variables.tf create mode 100644 website/docs/r/scheduler_job_collection.html.markdown diff --git a/azurerm/config.go b/azurerm/config.go index 82fa2a54fb62a..52ab486cb6463 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -34,6 +34,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-06-01/subscriptions" "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-09-01/locks" "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2017-05-10/resources" + "github.com/Azure/azure-sdk-for-go/services/scheduler/mgmt/2016-03-01/scheduler" "github.com/Azure/azure-sdk-for-go/services/search/mgmt/2015-08-19/search" "github.com/Azure/azure-sdk-for-go/services/servicebus/mgmt/2017-04-01/servicebus" "github.com/Azure/azure-sdk-for-go/services/sql/mgmt/2015-05-01-preview/sql" @@ -170,6 +171,9 @@ type ArmClient struct { serviceBusTopicsClient servicebus.TopicsClient serviceBusSubscriptionsClient servicebus.SubscriptionsClient + //Scheduler + schedulerJobCollectionsClient scheduler.JobCollectionsClient + // Storage storageServiceClient storage.AccountsClient storageUsageClient storage.UsageClient @@ -355,6 +359,7 @@ func getArmClient(c *authentication.Config) (*ArmClient, error) { client.registerResourcesClients(endpoint, c.SubscriptionID, auth) client.registerSearchClients(endpoint, c.SubscriptionID, auth) client.registerServiceBusClients(endpoint, c.SubscriptionID, auth) + client.registerSchedulerClients(endpoint, c.SubscriptionID, auth) client.registerStorageClients(endpoint, c.SubscriptionID, auth) client.registerTrafficManagerClients(endpoint, c.SubscriptionID, auth) client.registerWebClients(endpoint, c.SubscriptionID, auth) @@ -802,6 +807,12 @@ func (c *ArmClient) registerServiceBusClients(endpoint, subscriptionId string, a c.serviceBusSubscriptionsClient = subscriptionsClient } +func (c *ArmClient) registerSchedulerClients(endpoint, subscriptionId string, auth autorest.Authorizer) { + jobsClient := scheduler.NewJobCollectionsClientWithBaseURI(endpoint, subscriptionId) + c.configureClient(&jobsClient.Client, auth) + c.schedulerJobCollectionsClient = jobsClient +} + func (c *ArmClient) registerStorageClients(endpoint, subscriptionId string, auth autorest.Authorizer) { accountsClient := storage.NewAccountsClientWithBaseURI(endpoint, subscriptionId) c.configureClient(&accountsClient.Client, auth) diff --git a/azurerm/provider.go b/azurerm/provider.go index b7ac20ac2feeb..fab2519de6fa4 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -181,6 +181,7 @@ func Provider() terraform.ResourceProvider { "azurerm_servicebus_topic": resourceArmServiceBusTopic(), "azurerm_servicebus_topic_authorization_rule": resourceArmServiceBusTopicAuthorizationRule(), "azurerm_snapshot": resourceArmSnapshot(), + "azurerm_scheduler_job_collection": resourceArmSchedulerJobCollection(), "azurerm_sql_database": resourceArmSqlDatabase(), "azurerm_sql_elasticpool": resourceArmSqlElasticPool(), "azurerm_sql_firewall_rule": resourceArmSqlFirewallRule(), diff --git a/azurerm/resource_arm_scheduler_job_collection.go b/azurerm/resource_arm_scheduler_job_collection.go new file mode 100644 index 0000000000000..5efbe6ebef3f4 --- /dev/null +++ b/azurerm/resource_arm_scheduler_job_collection.go @@ -0,0 +1,267 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/services/scheduler/mgmt/2016-03-01/scheduler" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmSchedulerJobCollection() *schema.Resource { + return &schema.Resource{ + Create: resourceArmSchedulerJobCollectionCreateUpdate, + Read: resourceArmSchedulerJobCollectionRead, + Update: resourceArmSchedulerJobCollectionCreateUpdate, + Delete: resourceArmSchedulerJobCollectionDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "location": locationSchema(), + + "resource_group_name": resourceGroupNameSchema(), + + "tags": tagsSchema(), + + "sku": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + ValidateFunc: validation.StringInSlice([]string{ + string(scheduler.Free), + string(scheduler.Standard), + string(scheduler.P10Premium), + string(scheduler.P20Premium), + }, true), + }, + + //optional + "state": { + Type: schema.TypeString, + Optional: true, + Default: "enabled", + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + ValidateFunc: validation.StringInSlice([]string{ + string(scheduler.Enabled), + string(scheduler.Suspended), + string(scheduler.Disabled), + string(scheduler.Deleted), + }, true), + }, + + "quota": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + + //max_job_occurrence doesn't seem to do anything and always remains empty + + "max_job_count": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(0), + }, + + "max_recurrence_frequency": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + ValidateFunc: validation.StringInSlice([]string{ + string(scheduler.Minute), + string(scheduler.Hour), + string(scheduler.Day), + string(scheduler.Week), + string(scheduler.Month), + }, true), + }, + + //should this be max_retry_interval ? given that is what the documentation implies + "max_recurrence_interval": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(1), //changes depending on the frequency, unknown maximums + }, + }, + }, + }, + }, + } +} + +func resourceArmSchedulerJobCollectionCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).schedulerJobCollectionsClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + location := d.Get("location").(string) + resourceGroup := d.Get("resource_group_name").(string) + tags := d.Get("tags").(map[string]interface{}) + + log.Printf("[DEBUG] Creating/updating Scheduler Job Collection %q (resource group %q)", name, resourceGroup) + + sku := scheduler.Sku{ + Name: scheduler.SkuDefinition(d.Get("sku").(string)), + } + + properties := scheduler.JobCollectionProperties{ + Sku: &sku, + } + if state, ok := d.Get("state").(string); ok { + properties.State = scheduler.JobCollectionState(state) + } + + if qb, ok := d.Get("quota").([]interface{}); ok && len(qb) > 0 { + recurrence := scheduler.JobMaxRecurrence{} + quota := scheduler.JobCollectionQuota{ + MaxRecurrence: &recurrence, + } + + quotaBlock := qb[0].(map[string]interface{}) + + if v, ok := quotaBlock["max_job_count"].(int); ok { + quota.MaxJobCount = utils.Int32(int32(v)) + } + + if v, ok := quotaBlock["max_recurrence_frequency"].(string); ok { + recurrence.Frequency = scheduler.RecurrenceFrequency(v) + } + if v, ok := quotaBlock["max_recurrence_interval"].(int); ok { + recurrence.Interval = utils.Int32(int32(v)) + } + + properties.Quota = "a + } + + collection := scheduler.JobCollectionDefinition{ + Location: utils.String(location), + Tags: expandTags(tags), + Properties: &properties, + } + + //create job collection + collection, err := client.CreateOrUpdate(ctx, resourceGroup, name, collection) + if err != nil { + return fmt.Errorf("Error creating/updating Scheduler Job Collection %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + //ensure collection actually exists and we have the correct ID + collection, err = client.Get(ctx, resourceGroup, name) + if err != nil { + return err + } + + d.SetId(*collection.ID) + + return resourceArmSchedulerJobCollectionPopulate(d, resourceGroup, &collection) +} + +func resourceArmSchedulerJobCollectionRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).schedulerJobCollectionsClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + + name := id.Path["jobCollections"] + resourceGroup := id.ResourceGroup + + log.Printf("[DEBUG] Reading Scheduler Job Collection %q (resource group %q)", name, resourceGroup) + + collection, err := client.Get(ctx, resourceGroup, name) + if err != nil { + //TODO why is this in utils not response? + if utils.ResponseWasNotFound(collection.Response) { + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on Scheduler Job Collection Group %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + return resourceArmSchedulerJobCollectionPopulate(d, resourceGroup, &collection) +} + +func resourceArmSchedulerJobCollectionPopulate(d *schema.ResourceData, resourceGroup string, collection *scheduler.JobCollectionDefinition) error { + + //standard properties + d.Set("name", collection.Name) + d.Set("location", azureRMNormalizeLocation(*collection.Location)) + d.Set("resource_group_name", resourceGroup) + flattenAndSetTags(d, collection.Tags) + + //resource specific + if properties := collection.Properties; properties != nil { + if sku := properties.Sku; sku != nil { + d.Set("sku", sku.Name) + } + d.Set("state", string(properties.State)) + + if quota := properties.Quota; quota != nil { + quotaBlock := make(map[string]interface{}) + + if v := quota.MaxJobCount; v != nil { + quotaBlock["max_job_count"] = *v + } + + if recurrence := quota.MaxRecurrence; recurrence != nil { + if v := recurrence.Interval; v != nil { + quotaBlock["max_recurrence_interval"] = *v + } + + quotaBlock["max_recurrence_frequency"] = string(recurrence.Frequency) + } + + d.Set("quota", []interface{}{quotaBlock}) + } + } + + return nil +} + +func resourceArmSchedulerJobCollectionDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).schedulerJobCollectionsClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + + name := id.Path["jobCollections"] + resourceGroup := id.ResourceGroup + + log.Printf("[DEBUG] Deleting Scheduler Job Collection %q (resource group %q)", name, resourceGroup) + + future, err := client.Delete(ctx, resourceGroup, name) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error issuing delete request for Scheduler Job Collection %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + err = future.WaitForCompletion(ctx, client.Client) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error waiting for deletion of Scheduler Job Collection %q (Resource Group %q): %+v", name, resourceGroup, err) + } + } + + return nil +} diff --git a/azurerm/resource_arm_scheduler_job_collection_test.go b/azurerm/resource_arm_scheduler_job_collection_test.go new file mode 100644 index 0000000000000..4fdce2bec217c --- /dev/null +++ b/azurerm/resource_arm_scheduler_job_collection_test.go @@ -0,0 +1,139 @@ +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 TestAccAzureRMSchedulerJobCollection_basic(t *testing.T) { + ri := acctest.RandInt() + resourceName := "azurerm_scheduler_job_collection.test" + config := testAccAzureRMSchedulerJobCollection_basic(ri, testLocation(), "") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSchedulerJobCollectionDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSchedulerJobCollectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + }, + }) +} + +func TestAccAzureRMSchedulerJobCollection_complete(t *testing.T) { + ri := acctest.RandInt() + resourceName := "azurerm_scheduler_job_collection.test" + config := testAccAzureRMSchedulerJobCollection_complete(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSchedulerJobCollectionDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSchedulerJobCollectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + }, + }) +} + +func testCheckAzureRMSchedulerJobCollectionDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_scheduler_job_collection" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + client := testAccProvider.Meta().(*ArmClient).applicationSecurityGroupsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, name) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return fmt.Errorf("Scheduler Job Collection still exists:\n%#v", resp) + } + + return nil +} + +func testCheckAzureRMSchedulerJobCollectionExists(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: %q", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Scheduler Job Collection: %q", name) + } + + client := testAccProvider.Meta().(*ArmClient).schedulerJobCollectionsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + resp, err := client.Get(ctx, resourceGroup, name) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Scheduler Job Collection %q (resource group: %q) was not found: %+v", name, resourceGroup, err) + } + + return fmt.Errorf("Bad: Get on schedulerJobCollectionsClient: %+v", err) + } + + return nil + } +} + +func testAccAzureRMSchedulerJobCollection_basic(rInt int, location string, additional string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_scheduler_job_collection" "test" { + name = "acctest-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +%s +} +`, rInt, location, rInt, additional) +} + +func testAccAzureRMSchedulerJobCollection_complete(rInt int, location string) string { + return testAccAzureRMSchedulerJobCollection_basic(rInt, location, ` + state = "disabled" + quota { + max_recurrence_frequency = "hour" + max_recurrence_interval = 10 + max_job_count = 10 + } +`) +} diff --git a/examples/scheduler-jobs/main.tf b/examples/scheduler-jobs/main.tf new file mode 100644 index 0000000000000..df86c12af34bd --- /dev/null +++ b/examples/scheduler-jobs/main.tf @@ -0,0 +1,19 @@ + +resource "azurerm_resource_group" "rg" { + name = "${var.resource_group_name}" + location = "${var.resource_group_location}" +} + +resource "azurerm_scheduler_job_collection" "jobs" { + name = "example_job_collection" + location = "${azurerm_resource_group.rg.location}" + resource_group_name = "${azurerm_resource_group.rg.name}" + sku = "free" + state = "enabled" + + quota { + max_job_count = 5 + max_recurrence_frequency = "hour" + max_recurrence_interval = 24 + } +} diff --git a/examples/scheduler-jobs/outputs.tf b/examples/scheduler-jobs/outputs.tf new file mode 100644 index 0000000000000..feb8f4d27f831 --- /dev/null +++ b/examples/scheduler-jobs/outputs.tf @@ -0,0 +1,4 @@ + +output "job_collection-id" { + value = "${azurerm_scheduler_job_collection.jobs.id}" +} \ No newline at end of file diff --git a/examples/scheduler-jobs/variables.tf b/examples/scheduler-jobs/variables.tf new file mode 100644 index 0000000000000..e2c3abb36620c --- /dev/null +++ b/examples/scheduler-jobs/variables.tf @@ -0,0 +1,11 @@ +variable "resource_group_name" { + type = "string" + description = "Name of the azure resource group." + default = "tfex-job_collection" +} + +variable "resource_group_location" { + type = "string" + description = "Location of the azure resource group." + default = "westus" +} diff --git a/website/azurerm.erb b/website/azurerm.erb index 9912e43d87114..35a21265e364c 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -612,6 +612,15 @@ + > + Scheduler Resources + + + > Storage Resources