Skip to content

Commit

Permalink
feat: azurerm_eventhub_namespace rules
Browse files Browse the repository at this point in the history
  • Loading branch information
pregress committed Nov 5, 2024
1 parent 3cc330a commit a47807c
Show file tree
Hide file tree
Showing 6 changed files with 313 additions and 0 deletions.
6 changes: 6 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Rules

## azurerm_eventhub_namespace
|Name|Description|Severity|Enabled|Link|
| --- | --- | --- | --- | --- |
|azurerm_eventhub_namespace_public_network_access_enabled|Consider disabling public network access on eventhubs. |NOTICE|||
|azurerm_eventhub_namespace_minimum_tls_version|Enforce TLS 1.2 on event hubs |WARNING|||

## azurerm_key_vault
|Name|Description|Severity|Enabled|Link|
| --- | --- | --- | --- | --- |
Expand Down
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ func createRuleSet() *tflint.BuiltinRuleSet {
Name: "azurerm-security",
Version: "0.1.3",
Rules: []tflint.Rule{
rules.NewAzurermEventhubNamespacePublicNetworkAccessEnabled(),
rules.NewAzurermEventhubNamespaceUnsecureTLS(),
rules.NewAzurermKeyVaultPublicNetworkAccessEnabled(),
rules.NewAzurermLinuxFunctionAppFtpsState(),
rules.NewAzurermLinuxFunctionAppHTTPSOnly(),
Expand Down
90 changes: 90 additions & 0 deletions rules/azurerm_eventhub_namespace_minimum_tls_version.go
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"
)

// AzurermEventhubNamespaceUnsecureTLS checks the pattern is valid
type AzurermEventhubNamespaceUnsecureTLS struct {
tflint.DefaultRule

resourceType string
attributeName string
enum []string
}

// NewAzurermEventhubNamespaceUnsecureTLS returns new rule with default attributes
func NewAzurermEventhubNamespaceUnsecureTLS() *AzurermEventhubNamespaceUnsecureTLS {
return &AzurermEventhubNamespaceUnsecureTLS{
resourceType: "azurerm_eventhub_namespace",
attributeName: "min_tls_version",
enum: []string{
"TLS1_2",
"TLS1_3",
},
}
}

// Name returns the rule name
func (r *AzurermEventhubNamespaceUnsecureTLS) Name() string {
return "azurerm_eventhub_namespace_unsecure_tls"
}

// Enabled returns whether the rule is enabled by default
func (r *AzurermEventhubNamespaceUnsecureTLS) Enabled() bool {
return true
}

// Severity returns the rule severity
func (r *AzurermEventhubNamespaceUnsecureTLS) Severity() tflint.Severity {
return tflint.WARNING
}

// Link returns the rule reference link
func (r *AzurermEventhubNamespaceUnsecureTLS) Link() string {
return ""
}

// Check checks the pattern is valid
func (r *AzurermEventhubNamespaceUnsecureTLS) Check(runner tflint.Runner) error {
resources, err := runner.GetResourceContent(r.resourceType, &hclext.BodySchema{
Attributes: []hclext.AttributeSchema{
{Name: r.attributeName},
},
}, nil)
if err != nil {
return err
}

for _, resource := range resources.Blocks {
attribute, exists := resource.Body.Attributes[r.attributeName]
if !exists {
continue
}
err := runner.EvaluateExpr(attribute.Expr, func (val string) error {
found := false
for _, item := range r.enum {
if item == val {
found = true
}
}
if !found {
runner.EmitIssue(
r,
fmt.Sprintf(`"%s" is an insecure value as min_tls_version`, val),
attribute.Expr.Range(),
)
}
return nil
}, nil)
if err != nil {
return err
}
}

return nil
}
57 changes: 57 additions & 0 deletions rules/azurerm_eventhub_namespace_minimum_tls_version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package rules

import (
"testing"

hcl "github.com/hashicorp/hcl/v2"
"github.com/terraform-linters/tflint-plugin-sdk/helper"
)

func Test_AzurermEventhubNamespaceUnsecureTLS(t *testing.T) {
tests := []struct {
Name string
Content string
Expected helper.Issues
}{
{
Name: "insecure TLS version found",
Content: `
resource "azurerm_eventhub_namespace" "example" {
min_tls_version = "TLS1_0"
}`,
Expected: helper.Issues{
{
Rule: NewAzurermEventhubNamespaceUnsecureTLS(),
Message: `"TLS1_0" is an insecure value as min_tls_version`,
Range: hcl.Range{
Filename: "resource.tf",
Start: hcl.Pos{Line: 3, Column: 23},
End: hcl.Pos{Line: 3, Column: 31},
},
},
},
},
{
Name: "secure TLS version",
Content: `
resource "azurerm_eventhub_namespace" "example" {
min_tls_version = "TLS1_2"
}`,
Expected: helper.Issues{},
},
}

rule := NewAzurermEventhubNamespaceUnsecureTLS()

for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
runner := helper.TestRunner(t, map[string]string{"resource.tf": test.Content})

if err := rule.Check(runner); err != nil {
t.Fatalf("Unexpected error occurred: %s", err)
}

helper.AssertIssues(t, test.Expected, runner.Issues)
})
}
}
84 changes: 84 additions & 0 deletions rules/azurerm_eventhub_namespace_public_network_access_enabled.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package rules

import (
"github.com/terraform-linters/tflint-plugin-sdk/hclext"
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
)

// AzurermEventhubNamespacePublicNetworkAccessEnabled checks that transparent data encryption is enabled
type AzurermEventhubNamespacePublicNetworkAccessEnabled struct {
tflint.DefaultRule

resourceType string
attributeName string
}

// NewAzurermEventhubNamespacePublicNetworkAccessEnabled returns a new rule instance
func NewAzurermEventhubNamespacePublicNetworkAccessEnabled() *AzurermEventhubNamespacePublicNetworkAccessEnabled {
return &AzurermEventhubNamespacePublicNetworkAccessEnabled{
resourceType: "azurerm_eventhub_namespace",
attributeName: "public_network_access_enabled",
}
}

// Name returns the rule name
func (r *AzurermEventhubNamespacePublicNetworkAccessEnabled) Name() string {
return "azurerm_eventhub_namespace_public_network_access_enabled"
}

// Enabled returns whether the rule is enabled by default
func (r *AzurermEventhubNamespacePublicNetworkAccessEnabled) Enabled() bool {
return true
}

// Severity returns the rule severity
func (r *AzurermEventhubNamespacePublicNetworkAccessEnabled) Severity() tflint.Severity {
return tflint.NOTICE
}

// Link returns the rule reference link
func (r *AzurermEventhubNamespacePublicNetworkAccessEnabled) Link() string {
return ""
}

// Check checks if transparent data encryption is enabled
func (r *AzurermEventhubNamespacePublicNetworkAccessEnabled) Check(runner tflint.Runner) error {
resources, err := runner.GetResourceContent(r.resourceType, &hclext.BodySchema{
Attributes: []hclext.AttributeSchema{
{Name: r.attributeName},
},
}, nil)
if err != nil {
return err
}

for _, resource := range resources.Blocks {
attribute, exists := resource.Body.Attributes[r.attributeName]
if !exists {
// Emit an issue if the attribute does not exist
runner.EmitIssue(
r,
"public_network_access_enabled is not defined and defaults to true, consider disabling it",
resource.DefRange,
)
continue
}

err := runner.EvaluateExpr(attribute.Expr, func(val bool) error {
if val {
runner.EmitIssue(
r,
"Consider changing public_network_access_enabled to false",
attribute.Expr.Range(),
)
}
return nil
}, nil)

if err != nil {
return err
}
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package rules

import (
"testing"

hcl "github.com/hashicorp/hcl/v2"
"github.com/terraform-linters/tflint-plugin-sdk/helper"
)

func Test_AzurermEventhubNamespacePublicNetworkAccessEnabled(t *testing.T) {
tests := []struct {
Name string
Content string
Expected helper.Issues
}{
{
Name: "public network access disabled",
Content: `
resource "azurerm_eventhub_namespace" "example" {
public_network_access_enabled = true
}`,
Expected: helper.Issues{
{
Rule: NewAzurermEventhubNamespacePublicNetworkAccessEnabled(),
Message: "Consider changing public_network_access_enabled to false",
Range: hcl.Range{
Filename: "resource.tf",
Start: hcl.Pos{Line: 3, Column: 37},
End: hcl.Pos{Line: 3, Column: 41},
},
},
},
},
{
Name: "public network access missing",
Content: `
resource "azurerm_eventhub_namespace" "example" {
}`,
Expected: helper.Issues{
{
Rule: NewAzurermEventhubNamespacePublicNetworkAccessEnabled(),
Message: "public_network_access_enabled is not defined and defaults to true, consider disabling it",
Range: hcl.Range{
Filename: "resource.tf",
Start: hcl.Pos{Line: 2, Column: 1},
End: hcl.Pos{Line: 2, Column: 48},
},
},
},
},
{
Name: "public network access disabled",
Content: `
resource "azurerm_eventhub_namespace" "example" {
public_network_access_enabled = false
}`,
Expected: helper.Issues{},
},
}

rule := NewAzurermEventhubNamespacePublicNetworkAccessEnabled()

for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
runner := helper.TestRunner(t, map[string]string{"resource.tf": test.Content})

if err := rule.Check(runner); err != nil {
t.Fatalf("Unexpected error occurred: %s", err)
}

helper.AssertIssues(t, test.Expected, runner.Issues)
})
}
}

0 comments on commit a47807c

Please sign in to comment.