-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding Operational Insight Workspace (a.k.a Log Analytics) (#331)
* Adding operationalinsight workspace * Set SKU as default * Follow the naming Rule with using location Sceme * Use resourceGroupNameSchema() * Remove comment. I'll write the comment to the documentation. * Adding SKU types validation * Refactor: Remove getSku(). We don't need to write this, we can use SkuEnum instead. * Follow the coding style. * Remove unnecessary comment * Error message improvement to dump more for error struct. * Make error more dump for error struct * Using utility method. * Adding workspace name validation * Follow the naming rule * Adjust SDK version for operational insight * Change provider name and fix the Acceptance testing error Talked with the Log Analytics production team, they'd love to go log analytics. I change the name. However, the REST-API name is operational analytics. I change the schema name as log analytics however, keep the source code as operational insights for the consistency of the Azure SDK naming. Also, I fix the Acceptance testing error. The root cause of the problem is the Retention in days. It is not stated however, we can use 30 - 730. I add validation function and test for that. https://blogs.msdn.microsoft.com/canberrapfe/2017/01/25/change-oms-log-analytics-retention-period-in-the-azure-portal/ The blog says 31 - 730, however 30 is default value it works. * Adding the log anaylytics documentation * Fix Travis-CI issue. It prevent make vet works. * Edit the message for fit the error root cause * Changing name into OperationalInsight to LogAnalytics * Change the validation function to validation library * Fix in case of SKU is null * Fix tyop and Fix the Operational Insight in Log messages * Fix Documentation hightlight. * Comparing the Resource Group name in a case-insensitive manor * Minor documentation cleanup * `azurerm_log_analytics` -> `azurerm_log_analytics_workspace`
- Loading branch information
1 parent
2506354
commit 9a3a748
Showing
15 changed files
with
2,510 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package azurerm | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/acctest" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
) | ||
|
||
func TestAccAzureRMLogAnalyticsWorkspace_importRequiredOnly(t *testing.T) { | ||
resourceName := "azurerm_log_analytics_workspace.test" | ||
|
||
ri := acctest.RandInt() | ||
config := testAccAzureRMLogAnalyticsWorkspace_requiredOnly(ri, testLocation()) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testCheckAzureRMLogAnalyticsWorkspaceDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: config, | ||
}, | ||
|
||
{ | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAzureRMLogAnalyticsWorkspace_importRetentionInDaysComplete(t *testing.T) { | ||
resourceName := "azurerm_log_analytics_workspace.test" | ||
|
||
ri := acctest.RandInt() | ||
config := testAccAzureRMLogAnalyticsWorkspace_retentionInDaysComplete(ri, testLocation()) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testCheckAzureRMLogAnalyticsWorkspaceDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: config, | ||
}, | ||
|
||
{ | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
package azurerm | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"regexp" | ||
|
||
"github.com/Azure/azure-sdk-for-go/arm/operationalinsights" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
"github.com/hashicorp/terraform/helper/validation" | ||
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" | ||
) | ||
|
||
func resourceArmLogAnalyticsWorkspace() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceArmLogAnalyticsWorkspaceCreateUpdate, | ||
Read: resourceArmLogAnalyticsWorkspaceRead, | ||
Update: resourceArmLogAnalyticsWorkspaceCreateUpdate, | ||
Delete: resourceArmLogAnalyticsWorkspaceDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validateAzureRmLogAnalyticsWorkspaceName, | ||
}, | ||
|
||
"location": locationSchema(), | ||
|
||
"resource_group_name": resourceGroupNameDiffSuppressSchema(), | ||
|
||
"sku": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.StringInSlice([]string{ | ||
string(operationalinsights.Free), | ||
string(operationalinsights.PerNode), | ||
string(operationalinsights.Premium), | ||
string(operationalinsights.Standalone), | ||
string(operationalinsights.Standard), | ||
string(operationalinsights.Unlimited), | ||
}, true), | ||
DiffSuppressFunc: ignoreCaseDiffSuppressFunc, | ||
}, | ||
|
||
"retention_in_days": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Computed: true, | ||
ValidateFunc: validation.IntBetween(30, 730), | ||
}, | ||
|
||
"workspace_id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"portal_url": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"primary_shared_key": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"secondary_shared_key": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"tags": tagsSchema(), | ||
}, | ||
} | ||
} | ||
|
||
func resourceArmLogAnalyticsWorkspaceCreateUpdate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*ArmClient).workspacesClient | ||
log.Printf("[INFO] preparing arguments for AzureRM Log Analytics workspace creation.") | ||
|
||
name := d.Get("name").(string) | ||
location := d.Get("location").(string) | ||
resGroup := d.Get("resource_group_name").(string) | ||
|
||
skuName := d.Get("sku").(string) | ||
sku := &operationalinsights.Sku{ | ||
Name: operationalinsights.SkuNameEnum(skuName), | ||
} | ||
|
||
retentionInDays := int32(d.Get("retention_in_days").(int)) | ||
|
||
tags := d.Get("tags").(map[string]interface{}) | ||
|
||
parameters := operationalinsights.Workspace{ | ||
Name: &name, | ||
Location: &location, | ||
Tags: expandTags(tags), | ||
WorkspaceProperties: &operationalinsights.WorkspaceProperties{ | ||
Sku: sku, | ||
RetentionInDays: &retentionInDays, | ||
}, | ||
} | ||
|
||
_, error := client.CreateOrUpdate(resGroup, name, parameters, make(chan struct{})) | ||
err := <-error | ||
if err != nil { | ||
return err | ||
} | ||
|
||
read, err := client.Get(resGroup, name) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if read.ID == nil { | ||
return fmt.Errorf("Cannot read Log Analytics Workspace '%s' (resource group %s) ID", name, resGroup) | ||
} | ||
|
||
d.SetId(*read.ID) | ||
|
||
return resourceArmLogAnalyticsWorkspaceRead(d, meta) | ||
|
||
} | ||
|
||
func resourceArmLogAnalyticsWorkspaceRead(d *schema.ResourceData, meta interface{}) error { | ||
|
||
client := meta.(*ArmClient).workspacesClient | ||
id, err := parseAzureResourceID(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
resGroup := id.ResourceGroup | ||
name := id.Path["workspaces"] | ||
|
||
resp, err := client.Get(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 workspaces '%s': %+v", name, err) | ||
} | ||
|
||
d.Set("name", resp.Name) | ||
d.Set("location", resp.Location) | ||
d.Set("resource_group_name", resGroup) | ||
d.Set("workspace_id", resp.CustomerID) | ||
d.Set("portal_url", resp.PortalURL) | ||
if sku := resp.Sku; sku != nil { | ||
d.Set("sku", sku.Name) | ||
} | ||
d.Set("retention_in_days", resp.RetentionInDays) | ||
|
||
sharedKeys, err := client.GetSharedKeys(resGroup, name) | ||
if err != nil { | ||
log.Printf("[ERROR] Unable to List Shared keys for Log Analytics workspaces %s: %+v", name, err) | ||
} else { | ||
d.Set("primary_shared_key", sharedKeys.PrimarySharedKey) | ||
d.Set("secondary_shared_key", sharedKeys.SecondarySharedKey) | ||
} | ||
|
||
flattenAndSetTags(d, resp.Tags) | ||
return nil | ||
} | ||
|
||
func resourceArmLogAnalyticsWorkspaceDelete(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*ArmClient).workspacesClient | ||
|
||
id, err := parseAzureResourceID(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
resGroup := id.ResourceGroup | ||
name := id.Path["workspaces"] | ||
|
||
resp, err := client.Delete(resGroup, name) | ||
|
||
if err != nil { | ||
if utils.ResponseWasNotFound(resp) { | ||
return nil | ||
} | ||
|
||
return fmt.Errorf("Error issuing AzureRM delete request for Log Analytics Workspaces '%s': %+v", name, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func validateAzureRmLogAnalyticsWorkspaceName(v interface{}, k string) (ws []string, errors []error) { | ||
value := v.(string) | ||
|
||
r, _ := regexp.Compile("^[A-Za-z0-9][A-Za-z0-9-]+[A-Za-z0-9]$") | ||
if !r.MatchString(value) { | ||
errors = append(errors, fmt.Errorf("Workspace Name can only contain alphabet, number, and '-' character. You can not use '-' as the start and end of the name")) | ||
} | ||
|
||
length := len(value) | ||
if length > 63 || 4 > length { | ||
errors = append(errors, fmt.Errorf("Workspace Name can only be between 4 and 63 letters")) | ||
} | ||
|
||
return | ||
} |
Oops, something went wrong.