-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
302 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
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,28 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
package azqr | ||
|
||
import ( | ||
"github.com/Azure/azqr/internal/scanners" | ||
"github.com/Azure/azqr/internal/scanners/vwan" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func init() { | ||
scanCmd.AddCommand(vwanCmd) | ||
} | ||
|
||
var vwanCmd = &cobra.Command{ | ||
Use: "vwan", | ||
Short: "Scan Azure Virtual WAN", | ||
Long: "Scan Azure Virtual WAN", | ||
Args: cobra.NoArgs, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
serviceScanners := []scanners.IAzureScanner{ | ||
&vwan.VirtualWanScanner{}, | ||
} | ||
|
||
scan(cmd, serviceScanners) | ||
}, | ||
} |
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,89 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
package vwan | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/Azure/azqr/internal/scanners" | ||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork" | ||
) | ||
|
||
// GetRules - Returns the rules for the VirtualWanScanner | ||
func (a *VirtualWanScanner) GetRules() map[string]scanners.AzureRule { | ||
return map[string]scanners.AzureRule{ | ||
"DiagnosticSettings": { | ||
Id: "vwa-001", | ||
Category: scanners.RulesCategoryReliability, | ||
Subcategory: scanners.RulesSubcategoryReliabilityDiagnosticLogs, | ||
Description: "Virtual Wan should have diagnostic settings enabled", | ||
Severity: scanners.SeverityMedium, | ||
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) { | ||
service := target.(*armnetwork.VirtualWAN) | ||
_, ok := scanContext.DiagnosticsSettings[strings.ToLower(*service.ID)] | ||
return !ok, "" | ||
}, | ||
Url: "https://learn.microsoft.com/en-us/azure/virtual-wan/monitor-virtual-wan", | ||
}, | ||
"AvailabilityZones": { | ||
Id: "vwa-002", | ||
Category: scanners.RulesCategoryReliability, | ||
Subcategory: scanners.RulesSubcategoryReliabilityAvailabilityZones, | ||
Description: "Virtual Wan should have availability zones enabled", | ||
Severity: scanners.SeverityHigh, | ||
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) { | ||
return false, "" | ||
}, | ||
Url: "https://learn.microsoft.com/en-us/azure/virtual-wan/virtual-wan-faq#how-are-availability-zones-and-resiliency-handled-in-virtual-wan", | ||
}, | ||
"SLA": { | ||
Id: "vwa-003", | ||
Category: scanners.RulesCategoryReliability, | ||
Subcategory: scanners.RulesSubcategoryReliabilitySLA, | ||
Description: "Virtual Wan should have a SLA", | ||
Severity: scanners.SeverityHigh, | ||
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) { | ||
return false, "99.95%" | ||
}, | ||
Url: "https://learn.microsoft.com/en-us/azure/virtual-wan/virtual-wan-faq#how-is-virtual-wan-sla-calculated", | ||
}, | ||
"SKU": { | ||
Id: "vwa-005", | ||
Category: scanners.RulesCategoryReliability, | ||
Subcategory: scanners.RulesSubcategoryReliabilitySKU, | ||
Description: "Virtual Wan Type", | ||
Severity: scanners.SeverityHigh, | ||
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) { | ||
i := target.(*armnetwork.VirtualWAN) | ||
return false, string(*i.Properties.Type) | ||
}, | ||
Url: "https://learn.microsoft.com/en-us/azure/virtual-wan/virtual-wan-about#basicstandard", | ||
}, | ||
"CAF": { | ||
Id: "vwa-006", | ||
Category: scanners.RulesCategoryOperationalExcellence, | ||
Subcategory: scanners.RulesSubcategoryOperationalExcellenceCAF, | ||
Description: "Virtual Wan Name should comply with naming conventions", | ||
Severity: scanners.SeverityLow, | ||
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) { | ||
c := target.(*armnetwork.VirtualWAN) | ||
caf := strings.HasPrefix(*c.Name, "vwa") | ||
return !caf, "" | ||
}, | ||
Url: "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations", | ||
}, | ||
"vwa-007": { | ||
Id: "vwa-007", | ||
Category: scanners.RulesCategoryOperationalExcellence, | ||
Subcategory: scanners.RulesSubcategoryOperationalExcellenceTags, | ||
Description: "Virtual Wan should have tags", | ||
Severity: scanners.SeverityLow, | ||
Eval: func(target interface{}, scanContext *scanners.ScanContext) (bool, string) { | ||
c := target.(*armnetwork.VirtualWAN) | ||
return c.Tags == nil || len(c.Tags) == 0, "" | ||
}, | ||
Url: "https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json", | ||
}, | ||
} | ||
} |
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,117 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
package vwan | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/Azure/azqr/internal/scanners" | ||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork" | ||
"github.com/Azure/go-autorest/autorest/to" | ||
) | ||
|
||
func TestVirtualWanScanner_Rules(t *testing.T) { | ||
type fields struct { | ||
rule string | ||
target interface{} | ||
scanContext *scanners.ScanContext | ||
} | ||
type want struct { | ||
broken bool | ||
result string | ||
} | ||
tests := []struct { | ||
name string | ||
fields fields | ||
want want | ||
}{ | ||
{ | ||
name: "VirtualWanScanner DiagnosticSettings", | ||
fields: fields{ | ||
rule: "DiagnosticSettings", | ||
target: &armnetwork.VirtualWAN{ | ||
ID: to.StringPtr("test"), | ||
}, | ||
scanContext: &scanners.ScanContext{ | ||
DiagnosticsSettings: map[string]bool{ | ||
"test": true, | ||
}, | ||
}, | ||
}, | ||
want: want{ | ||
broken: false, | ||
result: "", | ||
}, | ||
}, | ||
{ | ||
name: "VirtualWanScanner Availability Zones", | ||
fields: fields{ | ||
rule: "AvailabilityZones", | ||
target: &armnetwork.VirtualWAN{}, | ||
scanContext: &scanners.ScanContext{}, | ||
}, | ||
want: want{ | ||
broken: false, | ||
result: "", | ||
}, | ||
}, | ||
{ | ||
name: "VirtualWanScanner SLA 99.95%", | ||
fields: fields{ | ||
rule: "SLA", | ||
target: &armnetwork.VirtualWAN{}, | ||
scanContext: &scanners.ScanContext{}, | ||
}, | ||
want: want{ | ||
broken: false, | ||
result: "99.95%", | ||
}, | ||
}, | ||
{ | ||
name: "VirtualWanScanner SKU", | ||
fields: fields{ | ||
rule: "SKU", | ||
target: &armnetwork.VirtualWAN{ | ||
Properties: &armnetwork.VirtualWanProperties{ | ||
Type: to.StringPtr("Standard"), | ||
}, | ||
}, | ||
scanContext: &scanners.ScanContext{}, | ||
}, | ||
want: want{ | ||
broken: false, | ||
result: "Standard", | ||
}, | ||
}, | ||
{ | ||
name: "VirtualWanScanner CAF", | ||
fields: fields{ | ||
rule: "CAF", | ||
target: &armnetwork.VirtualWAN{ | ||
Name: to.StringPtr("vwa-test"), | ||
}, | ||
scanContext: &scanners.ScanContext{}, | ||
}, | ||
want: want{ | ||
broken: false, | ||
result: "", | ||
}, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
s := &VirtualWanScanner{} | ||
rules := s.GetRules() | ||
b, w := rules[tt.fields.rule].Eval(tt.fields.target, tt.fields.scanContext) | ||
got := want{ | ||
broken: b, | ||
result: w, | ||
} | ||
if !reflect.DeepEqual(got, tt.want) { | ||
t.Errorf("VirtualWanScanner Rule.Eval() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |
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,66 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
package vwan | ||
|
||
import ( | ||
"github.com/rs/zerolog/log" | ||
|
||
"github.com/Azure/azqr/internal/scanners" | ||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork" | ||
) | ||
|
||
// VirtualWanScanner - Scanner for WebPubSub | ||
type VirtualWanScanner struct { | ||
config *scanners.ScannerConfig | ||
client *armnetwork.VirtualWansClient | ||
} | ||
|
||
// Init - Initializes the VirtualWanScanner | ||
func (c *VirtualWanScanner) Init(config *scanners.ScannerConfig) error { | ||
c.config = config | ||
var err error | ||
c.client, err = armnetwork.NewVirtualWansClient(config.SubscriptionID, config.Cred, config.ClientOptions) | ||
return err | ||
} | ||
|
||
// Scan - Scans all WebPubSub in a Resource Group | ||
func (c *VirtualWanScanner) Scan(resourceGroupName string, scanContext *scanners.ScanContext) ([]scanners.AzureServiceResult, error) { | ||
log.Info().Msgf("Scanning WebPubSub in Resource Group %s", resourceGroupName) | ||
|
||
WebPubSub, err := c.list(resourceGroupName) | ||
if err != nil { | ||
return nil, err | ||
} | ||
engine := scanners.RuleEngine{} | ||
rules := c.GetRules() | ||
results := []scanners.AzureServiceResult{} | ||
|
||
for _, w := range WebPubSub { | ||
rr := engine.EvaluateRules(rules, w, scanContext) | ||
|
||
results = append(results, scanners.AzureServiceResult{ | ||
SubscriptionID: c.config.SubscriptionID, | ||
ResourceGroup: resourceGroupName, | ||
ServiceName: *w.Name, | ||
Type: *w.Type, | ||
Location: *w.Location, | ||
Rules: rr, | ||
}) | ||
} | ||
return results, nil | ||
} | ||
|
||
func (c *VirtualWanScanner) list(resourceGroupName string) ([]*armnetwork.VirtualWAN, error) { | ||
pager := c.client.NewListByResourceGroupPager(resourceGroupName, nil) | ||
|
||
vwas := make([]*armnetwork.VirtualWAN, 0) | ||
for pager.More() { | ||
resp, err := pager.NextPage(c.config.Ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
vwas = append(vwas, resp.Value...) | ||
} | ||
return vwas, nil | ||
} |