generated from terraform-linters/tflint-ruleset-template
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a rule to check that the name of a windows virtual machine is va…
…lid (#332) * Adds a rule to check that the name of a windows virtual machine is valid * Adds azurerm_windows_virtual_machine_invalid_name to doc_README.md.tmpl * fix(azurerm_windows_virtual_machine_invalid_name): corrects regex inside error message
- Loading branch information
1 parent
9ef01fb
commit 793a327
Showing
7 changed files
with
208 additions
and
0 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
32 changes: 32 additions & 0 deletions
32
docs/rules/azurerm_windows_virtual_machine_invalid_name.md
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,32 @@ | ||
# azurerm_windows_virtual_machine_invalid_name | ||
|
||
Warns about values that appear to be invalid based on [Naming rules and restrictions for Azure resources](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftcompute). | ||
|
||
In this rule, the string must match the regular expression `^[a-zA-Z0-9]{0,1}[a-zA-Z0-9-]{0,13}[a-zA-Z0-9]$`. | ||
|
||
## Example | ||
|
||
```hcl | ||
resource "azurerm_windows_virtual_machine" "foo" { | ||
name = "dummy-" // invalid value | ||
} | ||
``` | ||
|
||
``` | ||
$ tflint | ||
1 issue(s) found: | ||
Error: "dummy-" does not match valid pattern ^[a-zA-Z0-9]{0,1}[a-zA-Z0-9-]{0,13}[a-zA-Z0-9]$ (azurerm_windows_virtual_machine_invalid_name) | ||
on template.tf line 2: | ||
2: name = "dummy-" // invalid value | ||
``` | ||
|
||
## Why | ||
|
||
Requests containing invalid values will return an error when calling the API by `terraform apply`. | ||
|
||
## How To Fix | ||
|
||
Replace the warned value with a valid value. In this example a valid name could be "dummy-1", because it matches the valid pattern ^[a-zA-Z0-9]{0,1}[a-zA-Z0-9-]{0,13}[a-zA-Z0-9]$. |
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,90 @@ | ||
package rules | ||
|
||
import ( | ||
"fmt" | ||
"github.com/terraform-linters/tflint-plugin-sdk/hclext" | ||
"github.com/terraform-linters/tflint-plugin-sdk/tflint" | ||
"github.com/terraform-linters/tflint-ruleset-azurerm/project" | ||
"regexp" | ||
) | ||
|
||
// AzurermWindowsVirtualMachineInvalidNameRule checks the hostname is valid | ||
type AzurermWindowsVirtualMachineInvalidNameRule struct { | ||
tflint.DefaultRule | ||
|
||
pattern *regexp.Regexp | ||
resourceType string | ||
attributeName string | ||
attributeComputerName string | ||
} | ||
|
||
// NewAzurermWindowsVirtualMachineInvalidNameRule returns new rule with default attributes | ||
func NewAzurermWindowsVirtualMachineInvalidNameRule() *AzurermWindowsVirtualMachineInvalidNameRule { | ||
return &AzurermWindowsVirtualMachineInvalidNameRule{ | ||
resourceType: "azurerm_windows_virtual_machine", | ||
attributeName: "name", | ||
attributeComputerName: "computer_name", | ||
pattern: regexp.MustCompile(`^[a-zA-Z0-9]{0,1}[a-zA-Z0-9-]{0,13}[a-zA-Z0-9]$`), | ||
} | ||
} | ||
|
||
// Name returns the rule name | ||
func (r *AzurermWindowsVirtualMachineInvalidNameRule) Name() string { | ||
return "azurerm_windows_virtual_machine_invalid_name" | ||
} | ||
|
||
// Enabled returns whether the rule is enabled by default | ||
func (r *AzurermWindowsVirtualMachineInvalidNameRule) Enabled() bool { | ||
return true | ||
} | ||
|
||
// Severity returns the rule severity | ||
func (r *AzurermWindowsVirtualMachineInvalidNameRule) Severity() tflint.Severity { | ||
return tflint.ERROR | ||
} | ||
|
||
// Link returns the rule reference link | ||
func (r *AzurermWindowsVirtualMachineInvalidNameRule) Link() string { | ||
return project.ReferenceLink(r.Name()) | ||
} | ||
|
||
// Check checks the name is valid | ||
func (r *AzurermWindowsVirtualMachineInvalidNameRule) Check(runner tflint.Runner) error { | ||
resources, err := runner.GetResourceContent(r.resourceType, &hclext.BodySchema{ | ||
Attributes: []hclext.AttributeSchema{ | ||
{Name: r.attributeName}, | ||
{Name: r.attributeComputerName}, | ||
}, | ||
}, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, resource := range resources.Blocks { | ||
_, exists := resource.Body.Attributes[r.attributeComputerName] | ||
if exists { | ||
continue | ||
} | ||
|
||
primaryAttribute, exists := resource.Body.Attributes[r.attributeName] | ||
if !exists { | ||
continue | ||
} | ||
|
||
err := runner.EvaluateExpr(primaryAttribute.Expr, func(val string) error { | ||
if !r.pattern.MatchString(val) { | ||
runner.EmitIssue( | ||
r, | ||
fmt.Sprintf(`"%s" does not match valid pattern %s`, val, `^[a-zA-Z0-9]{0,1}[a-zA-Z0-9-]{0,13}[a-zA-Z0-9]$`), | ||
primaryAttribute.Expr.Range(), | ||
) | ||
} | ||
return nil | ||
}, nil) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} |
82 changes: 82 additions & 0 deletions
82
rules/azurerm_windows_virtual_machine_invalid_name_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package rules | ||
|
||
import ( | ||
"testing" | ||
|
||
hcl "github.com/hashicorp/hcl/v2" | ||
"github.com/terraform-linters/tflint-plugin-sdk/helper" | ||
) | ||
|
||
func Test_AzurermWindowsVirtualMachineInvalidName(t *testing.T) { | ||
cases := []struct { | ||
Name string | ||
Content string | ||
Expected helper.Issues | ||
}{ | ||
{ | ||
Name: "InvalidName - Ends with hyphen", | ||
Content: ` | ||
resource "azurerm_windows_virtual_machine" "vm" { | ||
name = "dummy-" | ||
}`, | ||
Expected: helper.Issues{ | ||
{ | ||
Rule: NewAzurermWindowsVirtualMachineInvalidNameRule(), | ||
Message: `"dummy-" does not match valid pattern ^[a-zA-Z0-9]{0,1}[a-zA-Z0-9-]{0,13}[a-zA-Z0-9]$`, | ||
Range: hcl.Range{ | ||
Filename: "resource.tf", | ||
Start: hcl.Pos{Line: 3, Column: 10}, | ||
End: hcl.Pos{Line: 3, Column: 18}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
Name: "InvalidName - too long", | ||
Content: ` | ||
resource "azurerm_windows_virtual_machine" "vm" { | ||
name = "dummyhostname123" | ||
}`, | ||
Expected: helper.Issues{ | ||
{ | ||
Rule: NewAzurermWindowsVirtualMachineInvalidNameRule(), | ||
Message: `"dummyhostname123" does not match valid pattern ^[a-zA-Z0-9]{0,1}[a-zA-Z0-9-]{0,13}[a-zA-Z0-9]$`, | ||
Range: hcl.Range{ | ||
Filename: "resource.tf", | ||
Start: hcl.Pos{Line: 3, Column: 10}, | ||
End: hcl.Pos{Line: 3, Column: 28}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
Name: "ValidName - Name is valid", | ||
Content: ` | ||
resource "azurerm_windows_virtual_machine" "vm" { | ||
name = "dummyhostname1" | ||
}`, | ||
Expected: helper.Issues{}, | ||
}, | ||
{ | ||
Name: "ValidName - Hostname is specified", | ||
Content: ` | ||
resource "azurerm_windows_virtual_machine" "vm" { | ||
name = "dummy-" | ||
computer_name = "dummyhostname1" | ||
}`, | ||
Expected: helper.Issues{}, | ||
}, | ||
} | ||
|
||
rule := NewAzurermWindowsVirtualMachineInvalidNameRule() | ||
|
||
for _, tc := range cases { | ||
runner := helper.TestRunner(t, map[string]string{"resource.tf": tc.Content}) | ||
|
||
if err := rule.Check(runner); err != nil { | ||
t.Fatalf("Unexpected error occurred: %s", err) | ||
} | ||
|
||
helper.AssertIssues(t, tc.Expected, runner.Issues) | ||
} | ||
} |
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
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