mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-07 21:30:46 -08:00
feat(misconf): Update Azure network schema for new checks (#9791)
Signed-off-by: nikpivkin <nikita.pivkin@smartforce.io> Co-authored-by: Nikita Pivkin <nikita.pivkin@smartforce.io>
This commit is contained in:
@@ -2,6 +2,7 @@ package compute
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/aquasecurity/trivy/pkg/iac/providers/azure/compute"
|
"github.com/aquasecurity/trivy/pkg/iac/providers/azure/compute"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/iac/providers/azure/network"
|
||||||
"github.com/aquasecurity/trivy/pkg/iac/scanners/azure"
|
"github.com/aquasecurity/trivy/pkg/iac/scanners/azure"
|
||||||
iacTypes "github.com/aquasecurity/trivy/pkg/iac/types"
|
iacTypes "github.com/aquasecurity/trivy/pkg/iac/types"
|
||||||
)
|
)
|
||||||
@@ -93,25 +94,6 @@ func adaptLinuxVirtualMachine(resource azure.Resource) compute.LinuxVirtualMachi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractNetworkInterfaces(networkProfile azure.Value, metadata iacTypes.Metadata) []compute.NetworkInterface {
|
func extractNetworkInterfaces(_ azure.Value, _ iacTypes.Metadata) []network.NetworkInterface {
|
||||||
var networkInterfaces []compute.NetworkInterface
|
return nil
|
||||||
|
|
||||||
nicsArray := networkProfile.GetMapValue("networkInterfaces").AsList()
|
|
||||||
for _, nic := range nicsArray {
|
|
||||||
nicID := nic.GetMapValue("id").AsStringValue("", metadata)
|
|
||||||
if nicID.Value() != "" {
|
|
||||||
// Create a minimal NetworkInterface object with the ID information
|
|
||||||
// In ARM templates, we don't have direct access to subnet details like in Terraform
|
|
||||||
networkInterface := compute.NetworkInterface{
|
|
||||||
Metadata: nicID.GetMetadata(),
|
|
||||||
SubnetID: iacTypes.StringDefault("", nicID.GetMetadata()),
|
|
||||||
SecurityGroups: nil,
|
|
||||||
HasPublicIP: iacTypes.BoolDefault(false, nicID.GetMetadata()),
|
|
||||||
PublicIPAddress: iacTypes.StringDefault("", nicID.GetMetadata()),
|
|
||||||
}
|
|
||||||
networkInterfaces = append(networkInterfaces, networkInterface)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return networkInterfaces
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,22 +116,6 @@ func TestAdapt(t *testing.T) {
|
|||||||
LinuxVirtualMachines: []compute.LinuxVirtualMachine{{
|
LinuxVirtualMachines: []compute.LinuxVirtualMachine{{
|
||||||
VirtualMachine: compute.VirtualMachine{
|
VirtualMachine: compute.VirtualMachine{
|
||||||
CustomData: types.StringTest("test"),
|
CustomData: types.StringTest("test"),
|
||||||
NetworkInterfaces: []compute.NetworkInterface{
|
|
||||||
{
|
|
||||||
Metadata: types.NewTestMetadata(),
|
|
||||||
SubnetID: types.StringTest(""),
|
|
||||||
SecurityGroups: nil,
|
|
||||||
HasPublicIP: types.BoolTest(false),
|
|
||||||
PublicIPAddress: types.StringTest(""),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Metadata: types.NewTestMetadata(),
|
|
||||||
SubnetID: types.StringTest(""),
|
|
||||||
SecurityGroups: nil,
|
|
||||||
HasPublicIP: types.BoolTest(false),
|
|
||||||
PublicIPAddress: types.StringTest(""),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
OSProfileLinuxConfig: compute.OSProfileLinuxConfig{
|
OSProfileLinuxConfig: compute.OSProfileLinuxConfig{
|
||||||
DisablePasswordAuthentication: types.BoolTest(false),
|
DisablePasswordAuthentication: types.BoolTest(false),
|
||||||
@@ -140,22 +124,6 @@ func TestAdapt(t *testing.T) {
|
|||||||
WindowsVirtualMachines: []compute.WindowsVirtualMachine{{
|
WindowsVirtualMachines: []compute.WindowsVirtualMachine{{
|
||||||
VirtualMachine: compute.VirtualMachine{
|
VirtualMachine: compute.VirtualMachine{
|
||||||
CustomData: types.StringTest("test"),
|
CustomData: types.StringTest("test"),
|
||||||
NetworkInterfaces: []compute.NetworkInterface{
|
|
||||||
{
|
|
||||||
Metadata: types.NewTestMetadata(),
|
|
||||||
SubnetID: types.StringTest(""),
|
|
||||||
SecurityGroups: nil,
|
|
||||||
HasPublicIP: types.BoolTest(false),
|
|
||||||
PublicIPAddress: types.StringTest(""),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Metadata: types.NewTestMetadata(),
|
|
||||||
SubnetID: types.StringTest(""),
|
|
||||||
SecurityGroups: nil,
|
|
||||||
HasPublicIP: types.BoolTest(false),
|
|
||||||
PublicIPAddress: types.StringTest(""),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ func Adapt(deployment azure.Deployment) network.Network {
|
|||||||
return network.Network{
|
return network.Network{
|
||||||
SecurityGroups: adaptSecurityGroups(deployment),
|
SecurityGroups: adaptSecurityGroups(deployment),
|
||||||
NetworkWatcherFlowLogs: adaptNetworkWatcherFlowLogs(deployment),
|
NetworkWatcherFlowLogs: adaptNetworkWatcherFlowLogs(deployment),
|
||||||
|
NetworkInterfaces: adaptNetworkInterfaces(deployment),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +43,9 @@ func adaptSecurityGroupRules(deployment azure.Deployment) (rules []network.Secur
|
|||||||
|
|
||||||
func adaptSecurityGroupRule(resource azure.Resource) network.SecurityGroupRule {
|
func adaptSecurityGroupRule(resource azure.Resource) network.SecurityGroupRule {
|
||||||
sourceAddressPrefixes := resource.Properties.GetMapValue("sourceAddressPrefixes").AsStringValuesList("")
|
sourceAddressPrefixes := resource.Properties.GetMapValue("sourceAddressPrefixes").AsStringValuesList("")
|
||||||
sourceAddressPrefixes = append(sourceAddressPrefixes, resource.Properties.GetMapValue("sourceAddressPrefix").AsStringValue("", resource.Metadata))
|
if prefix := resource.Properties.GetMapValue("sourceAddressPrefix").AsStringValue("", resource.Metadata); prefix.IsNotEmpty() {
|
||||||
|
sourceAddressPrefixes = append(sourceAddressPrefixes, prefix)
|
||||||
|
}
|
||||||
|
|
||||||
var sourcePortRanges []common.PortRange
|
var sourcePortRanges []common.PortRange
|
||||||
for _, portRange := range resource.Properties.GetMapValue("sourcePortRanges").AsList() {
|
for _, portRange := range resource.Properties.GetMapValue("sourcePortRanges").AsList() {
|
||||||
@@ -56,7 +59,9 @@ func adaptSecurityGroupRule(resource azure.Resource) network.SecurityGroupRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destinationAddressPrefixes := resource.Properties.GetMapValue("destinationAddressPrefixes").AsStringValuesList("")
|
destinationAddressPrefixes := resource.Properties.GetMapValue("destinationAddressPrefixes").AsStringValuesList("")
|
||||||
destinationAddressPrefixes = append(destinationAddressPrefixes, resource.Properties.GetMapValue("destinationAddressPrefix").AsStringValue("", resource.Metadata))
|
if prefix := resource.Properties.GetMapValue("destinationAddressPrefix").AsStringValue("", resource.Metadata); prefix.IsNotEmpty() {
|
||||||
|
destinationAddressPrefixes = append(destinationAddressPrefixes, prefix)
|
||||||
|
}
|
||||||
|
|
||||||
var destinationPortRanges []common.PortRange
|
var destinationPortRanges []common.PortRange
|
||||||
for _, portRange := range resource.Properties.GetMapValue("destinationPortRanges").AsList() {
|
for _, portRange := range resource.Properties.GetMapValue("destinationPortRanges").AsList() {
|
||||||
@@ -99,12 +104,57 @@ func adaptNetworkWatcherFlowLogs(deployment azure.Deployment) (flowLogs []networ
|
|||||||
}
|
}
|
||||||
|
|
||||||
func adaptNetworkWatcherFlowLog(resource azure.Resource) network.NetworkWatcherFlowLog {
|
func adaptNetworkWatcherFlowLog(resource azure.Resource) network.NetworkWatcherFlowLog {
|
||||||
|
enabled := resource.Properties.GetMapValue("enabled").AsBoolValue(false, resource.Metadata)
|
||||||
|
retentionPolicy := resource.Properties.GetMapValue("retentionPolicy")
|
||||||
|
|
||||||
return network.NetworkWatcherFlowLog{
|
return network.NetworkWatcherFlowLog{
|
||||||
Metadata: resource.Metadata,
|
Metadata: resource.Metadata,
|
||||||
|
Enabled: enabled,
|
||||||
RetentionPolicy: network.RetentionPolicy{
|
RetentionPolicy: network.RetentionPolicy{
|
||||||
Metadata: resource.Metadata,
|
Metadata: resource.Metadata,
|
||||||
Enabled: resource.Properties.GetMapValue("retentionPolicy").GetMapValue("enabled").AsBoolValue(false, resource.Metadata),
|
Enabled: retentionPolicy.GetMapValue("enabled").AsBoolValue(false, resource.Metadata),
|
||||||
Days: resource.Properties.GetMapValue("retentionPolicy").GetMapValue("days").AsIntValue(0, resource.Metadata),
|
Days: retentionPolicy.GetMapValue("days").AsIntValue(0, resource.Metadata),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func adaptNetworkInterfaces(deployment azure.Deployment) []network.NetworkInterface {
|
||||||
|
var networkInterfaces []network.NetworkInterface
|
||||||
|
for _, resource := range deployment.GetResourcesByType("Microsoft.Network/networkInterfaces") {
|
||||||
|
networkInterfaces = append(networkInterfaces, adaptNetworkInterface(resource, deployment))
|
||||||
|
}
|
||||||
|
return networkInterfaces
|
||||||
|
}
|
||||||
|
|
||||||
|
func adaptNetworkInterface(resource azure.Resource, _ azure.Deployment) network.NetworkInterface {
|
||||||
|
ni := network.NetworkInterface{
|
||||||
|
Metadata: resource.Metadata,
|
||||||
|
EnableIPForwarding: resource.Properties.GetMapValue("enableIPForwarding").AsBoolValue(false, resource.Metadata),
|
||||||
|
HasPublicIP: iacTypes.BoolDefault(false, resource.Metadata),
|
||||||
|
PublicIPAddress: iacTypes.StringDefault("", resource.Metadata),
|
||||||
|
SubnetID: iacTypes.StringDefault("", resource.Metadata),
|
||||||
|
}
|
||||||
|
|
||||||
|
ipConfigs := resource.Properties.GetMapValue("ipConfigurations").AsList()
|
||||||
|
ni.IPConfigurations = make([]network.IPConfiguration, 0, len(ipConfigs))
|
||||||
|
|
||||||
|
for _, ipConfig := range ipConfigs {
|
||||||
|
if ipConfig.IsNull() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ipConfigProps := ipConfig.GetMapValue("properties")
|
||||||
|
ni.IPConfigurations = append(ni.IPConfigurations, network.IPConfiguration{
|
||||||
|
Metadata: resource.Metadata,
|
||||||
|
PublicIPAddress: ipConfigProps.GetMapValue("publicIPAddress").
|
||||||
|
GetMapValue("id").AsStringValue("", resource.Metadata),
|
||||||
|
SubnetID: ipConfigProps.GetMapValue("subnet").
|
||||||
|
GetMapValue("id").AsStringValue("", resource.Metadata),
|
||||||
|
Primary: ipConfigProps.GetMapValue("primary").AsBoolValue(false, resource.Metadata),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ni.Setup()
|
||||||
|
|
||||||
|
// Note: SecurityGroups are not resolved for ARM templates as related resource search
|
||||||
|
// is not yet implemented for ARM (parser cannot evaluate expressions/references)
|
||||||
|
return ni
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,16 +35,10 @@ func TestAdapt(t *testing.T) {
|
|||||||
}`,
|
}`,
|
||||||
expected: network.Network{
|
expected: network.Network{
|
||||||
NetworkWatcherFlowLogs: []network.NetworkWatcherFlowLog{{
|
NetworkWatcherFlowLogs: []network.NetworkWatcherFlowLog{{
|
||||||
RetentionPolicy: network.RetentionPolicy{
|
RetentionPolicy: network.RetentionPolicy{},
|
||||||
Days: types.IntTest(0),
|
|
||||||
Enabled: types.BoolTest(false),
|
|
||||||
},
|
|
||||||
}},
|
}},
|
||||||
SecurityGroups: []network.SecurityGroup{{
|
SecurityGroups: []network.SecurityGroup{{
|
||||||
Rules: []network.SecurityGroupRule{{
|
Rules: []network.SecurityGroupRule{{}},
|
||||||
DestinationAddresses: []types.StringValue{types.StringTest("")},
|
|
||||||
SourceAddresses: []types.StringValue{types.StringTest("")},
|
|
||||||
}},
|
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -147,6 +141,71 @@ func TestAdapt(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "network interface with ip configurations",
|
||||||
|
source: `{
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"type": "Microsoft.Network/networkInterfaces",
|
||||||
|
"properties": {
|
||||||
|
"enableIPForwarding": true,
|
||||||
|
"ipConfigurations": [
|
||||||
|
{
|
||||||
|
"name": "primary-ip",
|
||||||
|
"properties": {
|
||||||
|
"primary": true,
|
||||||
|
"subnet": {
|
||||||
|
"id": "/subscriptions/abc/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/subnet-primary"
|
||||||
|
},
|
||||||
|
"publicIPAddress": {
|
||||||
|
"id": "/subscriptions/abc/resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/pip-primary"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "secondary-ip",
|
||||||
|
"properties": {
|
||||||
|
"primary": false,
|
||||||
|
"subnet": {
|
||||||
|
"id": "/subscriptions/abc/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/subnet-secondary"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`,
|
||||||
|
expected: network.Network{
|
||||||
|
NetworkInterfaces: []network.NetworkInterface{
|
||||||
|
{
|
||||||
|
EnableIPForwarding: types.BoolTest(true),
|
||||||
|
|
||||||
|
// backward compatibility — filled from primary config
|
||||||
|
SubnetID: types.StringTest("/subscriptions/abc/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/subnet-primary"),
|
||||||
|
HasPublicIP: types.BoolTest(true),
|
||||||
|
PublicIPAddress: types.StringTest("/subscriptions/abc/resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/pip-primary"),
|
||||||
|
|
||||||
|
IPConfigurations: []network.IPConfiguration{
|
||||||
|
{
|
||||||
|
Primary: types.BoolTest(true),
|
||||||
|
SubnetID: types.StringTest(
|
||||||
|
"/subscriptions/abc/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/subnet-primary",
|
||||||
|
),
|
||||||
|
HasPublicIP: types.BoolTest(true),
|
||||||
|
PublicIPAddress: types.StringTest("/subscriptions/abc/resourceGroups/rg/providers/Microsoft.Network/publicIPAddresses/pip-primary"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Primary: types.BoolTest(false),
|
||||||
|
SubnetID: types.StringTest("/subscriptions/abc/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/subnet-secondary"),
|
||||||
|
HasPublicIP: types.BoolTest(false),
|
||||||
|
PublicIPAddress: types.StringTest(""),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package appservice
|
package appservice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/samber/lo"
|
|
||||||
|
|
||||||
"github.com/aquasecurity/trivy/pkg/iac/providers/azure/appservice"
|
"github.com/aquasecurity/trivy/pkg/iac/providers/azure/appservice"
|
||||||
"github.com/aquasecurity/trivy/pkg/iac/terraform"
|
"github.com/aquasecurity/trivy/pkg/iac/terraform"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/iac/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Adapt(modules terraform.Modules) appservice.AppService {
|
func Adapt(modules terraform.Modules) appservice.AppService {
|
||||||
@@ -31,30 +30,42 @@ func adaptFunctionApps(modules terraform.Modules) []appservice.FunctionApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func adaptService(resource *terraform.Block) appservice.Service {
|
func adaptService(resource *terraform.Block) appservice.Service {
|
||||||
siteBlock := resource.GetBlock("site_config")
|
service := appservice.Service{
|
||||||
identityBlock := resource.GetBlock("identity")
|
|
||||||
authBlock := resource.GetBlock("auth_settings")
|
|
||||||
return appservice.Service{
|
|
||||||
Metadata: resource.GetMetadata(),
|
Metadata: resource.GetMetadata(),
|
||||||
EnableClientCert: resource.GetAttribute("client_cert_enabled").AsBoolValueOrDefault(false, resource),
|
EnableClientCert: resource.GetAttribute("client_cert_enabled").AsBoolValueOrDefault(false, resource),
|
||||||
HTTPSOnly: resource.GetAttribute("https_only").AsBoolValueOrDefault(false, resource),
|
HTTPSOnly: resource.GetAttribute("https_only").AsBoolValueOrDefault(false, resource),
|
||||||
Identity: appservice.Identity{
|
|
||||||
Metadata: lo.TernaryF(identityBlock.IsNil(), resource.GetMetadata, identityBlock.GetMetadata),
|
|
||||||
Type: identityBlock.GetAttribute("type").AsStringValueOrDefault("", identityBlock),
|
|
||||||
},
|
|
||||||
Authentication: appservice.Authentication{
|
|
||||||
Metadata: lo.TernaryF(identityBlock.IsNil(), resource.GetMetadata, authBlock.GetMetadata),
|
|
||||||
Enabled: authBlock.GetAttribute("enabled").AsBoolValueOrDefault(false, authBlock),
|
|
||||||
},
|
|
||||||
Site: appservice.Site{
|
Site: appservice.Site{
|
||||||
Metadata: lo.TernaryF(identityBlock.IsNil(), resource.GetMetadata, siteBlock.GetMetadata),
|
Metadata: resource.GetMetadata(),
|
||||||
|
MinimumTLSVersion: types.StringDefault("1.2", resource.GetMetadata()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if identityBlock := resource.GetBlock("identity"); identityBlock.IsNotNil() {
|
||||||
|
service.Identity = appservice.Identity{
|
||||||
|
Metadata: identityBlock.GetMetadata(),
|
||||||
|
Type: identityBlock.GetAttribute("type").AsStringValueOrDefault("", identityBlock),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if authBlock := resource.GetBlock("auth_settings"); authBlock.IsNotNil() {
|
||||||
|
service.Authentication = appservice.Authentication{
|
||||||
|
Metadata: authBlock.GetMetadata(),
|
||||||
|
Enabled: authBlock.GetAttribute("enabled").AsBoolValueOrDefault(false, authBlock),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if siteBlock := resource.GetBlock("site_config"); siteBlock.IsNotNil() {
|
||||||
|
service.Site = appservice.Site{
|
||||||
|
Metadata: siteBlock.GetMetadata(),
|
||||||
EnableHTTP2: siteBlock.GetAttribute("http2_enabled").AsBoolValueOrDefault(false, siteBlock),
|
EnableHTTP2: siteBlock.GetAttribute("http2_enabled").AsBoolValueOrDefault(false, siteBlock),
|
||||||
MinimumTLSVersion: siteBlock.GetAttribute("min_tls_version").AsStringValueOrDefault("1.2", siteBlock),
|
MinimumTLSVersion: siteBlock.GetAttribute("min_tls_version").AsStringValueOrDefault("1.2", siteBlock),
|
||||||
PHPVersion: siteBlock.GetAttribute("php_version").AsStringValueOrDefault("", siteBlock),
|
PHPVersion: siteBlock.GetAttribute("php_version").AsStringValueOrDefault("", siteBlock),
|
||||||
PythonVersion: siteBlock.GetAttribute("python_version").AsStringValueOrDefault("", siteBlock),
|
PythonVersion: siteBlock.GetAttribute("python_version").AsStringValueOrDefault("", siteBlock),
|
||||||
FTPSState: siteBlock.GetAttribute("ftps_state").AsStringValueOrDefault("", siteBlock),
|
FTPSState: siteBlock.GetAttribute("ftps_state").AsStringValueOrDefault("", siteBlock),
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return service
|
||||||
}
|
}
|
||||||
|
|
||||||
func adaptFunctionApp(resource *terraform.Block) appservice.FunctionApp {
|
func adaptFunctionApp(resource *terraform.Block) appservice.FunctionApp {
|
||||||
|
|||||||
@@ -142,25 +142,24 @@ func adaptWindowsVM(resource *terraform.Block, modules terraform.Modules) comput
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveNetworkInterfaces(resource *terraform.Block, modules terraform.Modules) []compute.NetworkInterface {
|
func resolveNetworkInterfaces(resource *terraform.Block, modules terraform.Modules) []network.NetworkInterface {
|
||||||
var networkInterfaces []compute.NetworkInterface
|
|
||||||
|
|
||||||
nicIDsAttr := resource.GetAttribute("network_interface_ids")
|
nicIDsAttr := resource.GetAttribute("network_interface_ids")
|
||||||
if nicIDsAttr.IsNil() {
|
if nicIDsAttr.IsNil() {
|
||||||
return networkInterfaces
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var networkInterfaces []network.NetworkInterface
|
||||||
for _, nicIDVal := range nicIDsAttr.AsStringValues() {
|
for _, nicIDVal := range nicIDsAttr.AsStringValues() {
|
||||||
if referencedNIC, err := modules.GetReferencedBlock(nicIDsAttr, resource); err == nil {
|
if referencedNIC, err := modules.GetReferencedBlock(nicIDsAttr, resource); err == nil {
|
||||||
ni := adaptNetworkInterface(referencedNIC, modules)
|
ni := anetwork.AdaptNetworkInterface(referencedNIC, modules)
|
||||||
networkInterfaces = append(networkInterfaces, ni)
|
networkInterfaces = append(networkInterfaces, ni)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
networkInterfaces = append(networkInterfaces, compute.NetworkInterface{
|
networkInterfaces = append(networkInterfaces, network.NetworkInterface{
|
||||||
Metadata: iacTypes.NewUnmanagedMetadata(),
|
Metadata: iacTypes.NewUnmanagedMetadata(),
|
||||||
|
EnableIPForwarding: iacTypes.BoolDefault(false, nicIDVal.GetMetadata()),
|
||||||
SubnetID: iacTypes.StringDefault("", nicIDVal.GetMetadata()),
|
SubnetID: iacTypes.StringDefault("", nicIDVal.GetMetadata()),
|
||||||
SecurityGroups: nil,
|
|
||||||
HasPublicIP: iacTypes.BoolDefault(false, nicIDVal.GetMetadata()),
|
HasPublicIP: iacTypes.BoolDefault(false, nicIDVal.GetMetadata()),
|
||||||
PublicIPAddress: iacTypes.StringDefault("", nicIDVal.GetMetadata()),
|
PublicIPAddress: iacTypes.StringDefault("", nicIDVal.GetMetadata()),
|
||||||
})
|
})
|
||||||
@@ -168,44 +167,3 @@ func resolveNetworkInterfaces(resource *terraform.Block, modules terraform.Modul
|
|||||||
|
|
||||||
return networkInterfaces
|
return networkInterfaces
|
||||||
}
|
}
|
||||||
|
|
||||||
func adaptNetworkInterface(resource *terraform.Block, modules terraform.Modules) compute.NetworkInterface {
|
|
||||||
ni := compute.NetworkInterface{
|
|
||||||
Metadata: resource.GetMetadata(),
|
|
||||||
SubnetID: iacTypes.StringDefault("", resource.GetMetadata()),
|
|
||||||
SecurityGroups: nil,
|
|
||||||
HasPublicIP: iacTypes.BoolDefault(false, resource.GetMetadata()),
|
|
||||||
PublicIPAddress: iacTypes.StringDefault("", resource.GetMetadata()),
|
|
||||||
}
|
|
||||||
|
|
||||||
if nsgAttr := resource.GetAttribute("network_security_group_id"); nsgAttr.IsNotNil() {
|
|
||||||
if referencedNSG, err := modules.GetReferencedBlock(nsgAttr, resource); err == nil {
|
|
||||||
ni.SecurityGroups = []network.SecurityGroup{adaptSecurityGroupFromBlock(referencedNSG)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ipConfigs := resource.GetBlocks("ip_configuration")
|
|
||||||
if len(ipConfigs) > 0 {
|
|
||||||
ipConfig := ipConfigs[0]
|
|
||||||
if subnetAttr := ipConfig.GetAttribute("subnet_id"); subnetAttr.IsNotNil() {
|
|
||||||
ni.SubnetID = subnetAttr.AsStringValueOrDefault("", ipConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
if publicIPAttr := ipConfig.GetAttribute("public_ip_address_id"); publicIPAttr.IsNotNil() {
|
|
||||||
ni.HasPublicIP = iacTypes.Bool(true, publicIPAttr.GetMetadata())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ni
|
|
||||||
}
|
|
||||||
|
|
||||||
func adaptSecurityGroupFromBlock(resource *terraform.Block) network.SecurityGroup {
|
|
||||||
var rules []network.SecurityGroupRule
|
|
||||||
for _, ruleBlock := range resource.GetBlocks("security_rule") {
|
|
||||||
rules = append(rules, anetwork.AdaptSGRule(ruleBlock))
|
|
||||||
}
|
|
||||||
return network.SecurityGroup{
|
|
||||||
Metadata: resource.GetMetadata(),
|
|
||||||
Rules: rules,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -29,10 +29,8 @@ resource "azurerm_managed_disk" "example" {
|
|||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
expected: compute.ManagedDisk{
|
expected: compute.ManagedDisk{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
Encryption: compute.Encryption{
|
Encryption: compute.Encryption{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Enabled: iacTypes.BoolTest(false),
|
||||||
Enabled: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -42,10 +40,8 @@ resource "azurerm_managed_disk" "example" {
|
|||||||
resource "azurerm_managed_disk" "example" {
|
resource "azurerm_managed_disk" "example" {
|
||||||
}`,
|
}`,
|
||||||
expected: compute.ManagedDisk{
|
expected: compute.ManagedDisk{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
Encryption: compute.Encryption{
|
Encryption: compute.Encryption{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Enabled: iacTypes.BoolTest(true),
|
||||||
Enabled: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -87,13 +83,9 @@ resource "azurerm_virtual_machine" "example" {
|
|||||||
`,
|
`,
|
||||||
expected: compute.LinuxVirtualMachine{
|
expected: compute.LinuxVirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Metadata: iacTypes.NewTestMetadata(),
|
||||||
VirtualMachine: compute.VirtualMachine{
|
VirtualMachine: compute.VirtualMachine{},
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
CustomData: iacTypes.String("", iacTypes.NewTestMetadata()),
|
|
||||||
},
|
|
||||||
OSProfileLinuxConfig: compute.OSProfileLinuxConfig{
|
OSProfileLinuxConfig: compute.OSProfileLinuxConfig{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
DisablePasswordAuthentication: iacTypes.BoolTest(true),
|
||||||
DisablePasswordAuthentication: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -112,17 +104,11 @@ export DATABASE_PASSWORD=\"SomeSortOfPassword\"
|
|||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
expected: compute.LinuxVirtualMachine{
|
expected: compute.LinuxVirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
VirtualMachine: compute.VirtualMachine{
|
VirtualMachine: compute.VirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
CustomData: iacTypes.StringTest(
|
||||||
CustomData: iacTypes.String(
|
"export DATABASE_PASSWORD=\\\"SomeSortOfPassword\\\"\n"),
|
||||||
`export DATABASE_PASSWORD=\"SomeSortOfPassword\"
|
|
||||||
`, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
|
||||||
OSProfileLinuxConfig: compute.OSProfileLinuxConfig{
|
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
DisablePasswordAuthentication: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
|
OSProfileLinuxConfig: compute.OSProfileLinuxConfig{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -149,13 +135,6 @@ resource "azurerm_linux_virtual_machine" "example" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "azurerm_public_ip" "example" {
|
|
||||||
name = "acceptanceTestPublicIp1"
|
|
||||||
resource_group_name = azurerm_resource_group.example.name
|
|
||||||
location = azurerm_resource_group.example.location
|
|
||||||
allocation_method = "Static"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "azurerm_network_interface" "example" {
|
resource "azurerm_network_interface" "example" {
|
||||||
name = "example-nic"
|
name = "example-nic"
|
||||||
location = azurerm_resource_group.example.location
|
location = azurerm_resource_group.example.location
|
||||||
@@ -163,7 +142,7 @@ resource "azurerm_network_interface" "example" {
|
|||||||
|
|
||||||
ip_configuration {
|
ip_configuration {
|
||||||
name = "internal"
|
name = "internal"
|
||||||
public_ip_address_id = azurerm_public_ip.example.id
|
public_ip_address_id = "test-public-ip-id"
|
||||||
}
|
}
|
||||||
|
|
||||||
network_security_group_id = azurerm_network_security_group.example.id
|
network_security_group_id = azurerm_network_security_group.example.id
|
||||||
@@ -188,15 +167,17 @@ resource "azurerm_network_security_group" "example" {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
expected: compute.LinuxVirtualMachine{
|
expected: compute.LinuxVirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
VirtualMachine: compute.VirtualMachine{
|
VirtualMachine: compute.VirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
NetworkInterfaces: []network.NetworkInterface{
|
||||||
CustomData: iacTypes.String("", iacTypes.NewTestMetadata()),
|
|
||||||
NetworkInterfaces: []compute.NetworkInterface{
|
|
||||||
{
|
{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
HasPublicIP: iacTypes.BoolTest(true),
|
HasPublicIP: iacTypes.BoolTest(true),
|
||||||
PublicIPAddress: iacTypes.String("", iacTypes.NewTestMetadata()),
|
PublicIPAddress: iacTypes.StringTest("test-public-ip-id"),
|
||||||
|
IPConfigurations: []network.IPConfiguration{
|
||||||
|
{
|
||||||
|
HasPublicIP: iacTypes.BoolTest(true),
|
||||||
|
PublicIPAddress: iacTypes.StringTest("test-public-ip-id"),
|
||||||
|
},
|
||||||
|
},
|
||||||
SecurityGroups: []network.SecurityGroup{
|
SecurityGroups: []network.SecurityGroup{
|
||||||
{
|
{
|
||||||
Rules: []network.SecurityGroupRule{
|
Rules: []network.SecurityGroupRule{
|
||||||
@@ -215,8 +196,7 @@ resource "azurerm_network_security_group" "example" {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
OSProfileLinuxConfig: compute.OSProfileLinuxConfig{
|
OSProfileLinuxConfig: compute.OSProfileLinuxConfig{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
DisablePasswordAuthentication: iacTypes.BoolTest(true),
|
||||||
DisablePasswordAuthentication: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -237,16 +217,11 @@ resource "azurerm_linux_virtual_machine" "example" {
|
|||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
expected: compute.LinuxVirtualMachine{
|
expected: compute.LinuxVirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
VirtualMachine: compute.VirtualMachine{
|
VirtualMachine: compute.VirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
CustomData: iacTypes.String("", iacTypes.NewTestMetadata()),
|
|
||||||
// Empty array in Terraform is parsed as nil
|
// Empty array in Terraform is parsed as nil
|
||||||
NetworkInterfaces: nil,
|
|
||||||
},
|
},
|
||||||
OSProfileLinuxConfig: compute.OSProfileLinuxConfig{
|
OSProfileLinuxConfig: compute.OSProfileLinuxConfig{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
DisablePasswordAuthentication: iacTypes.BoolTest(true),
|
||||||
DisablePasswordAuthentication: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -281,11 +256,8 @@ export DATABASE_PASSWORD=\"SomeSortOfPassword\"
|
|||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
expected: compute.WindowsVirtualMachine{
|
expected: compute.WindowsVirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
VirtualMachine: compute.VirtualMachine{
|
VirtualMachine: compute.VirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
CustomData: iacTypes.StringTest("export DATABASE_PASSWORD=\\\"SomeSortOfPassword\\\"\n"),
|
||||||
CustomData: iacTypes.String(`export DATABASE_PASSWORD=\"SomeSortOfPassword\"
|
|
||||||
`, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -299,11 +271,8 @@ export GREETING="Hello there"
|
|||||||
EOF
|
EOF
|
||||||
}`,
|
}`,
|
||||||
expected: compute.WindowsVirtualMachine{
|
expected: compute.WindowsVirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
VirtualMachine: compute.VirtualMachine{
|
VirtualMachine: compute.VirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
CustomData: iacTypes.StringTest("export GREETING=\"Hello there\"\n"),
|
||||||
CustomData: iacTypes.String(`export GREETING="Hello there"
|
|
||||||
`, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -325,25 +294,10 @@ resource "azurerm_windows_virtual_machine" "example" {
|
|||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
expected: compute.WindowsVirtualMachine{
|
expected: compute.WindowsVirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
VirtualMachine: compute.VirtualMachine{
|
VirtualMachine: compute.VirtualMachine{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
NetworkInterfaces: []network.NetworkInterface{
|
||||||
CustomData: iacTypes.String("", iacTypes.NewTestMetadata()),
|
{},
|
||||||
NetworkInterfaces: []compute.NetworkInterface{
|
{},
|
||||||
{
|
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
SubnetID: iacTypes.String("", iacTypes.NewTestMetadata()),
|
|
||||||
SecurityGroups: nil,
|
|
||||||
HasPublicIP: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
|
|
||||||
PublicIPAddress: iacTypes.String("", iacTypes.NewTestMetadata()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
SubnetID: iacTypes.String("", iacTypes.NewTestMetadata()),
|
|
||||||
SecurityGroups: nil,
|
|
||||||
HasPublicIP: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
|
|
||||||
PublicIPAddress: iacTypes.String("", iacTypes.NewTestMetadata()),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package network
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
|
||||||
"github.com/aquasecurity/trivy/pkg/iac/adapters/common"
|
"github.com/aquasecurity/trivy/pkg/iac/adapters/common"
|
||||||
"github.com/aquasecurity/trivy/pkg/iac/providers/azure/network"
|
"github.com/aquasecurity/trivy/pkg/iac/providers/azure/network"
|
||||||
@@ -20,6 +21,7 @@ func Adapt(modules terraform.Modules) network.Network {
|
|||||||
groups: make(map[string]network.SecurityGroup),
|
groups: make(map[string]network.SecurityGroup),
|
||||||
}).adaptSecurityGroups(),
|
}).adaptSecurityGroups(),
|
||||||
NetworkWatcherFlowLogs: adaptWatcherLogs(modules),
|
NetworkWatcherFlowLogs: adaptWatcherLogs(modules),
|
||||||
|
NetworkInterfaces: adaptNetworkInterfaces(modules),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +92,7 @@ func (a *adapter) adaptSecurityGroup(resource *terraform.Block) {
|
|||||||
func adaptWatcherLog(resource *terraform.Block) network.NetworkWatcherFlowLog {
|
func adaptWatcherLog(resource *terraform.Block) network.NetworkWatcherFlowLog {
|
||||||
flowLog := network.NetworkWatcherFlowLog{
|
flowLog := network.NetworkWatcherFlowLog{
|
||||||
Metadata: resource.GetMetadata(),
|
Metadata: resource.GetMetadata(),
|
||||||
|
Enabled: resource.GetAttribute("enabled").AsBoolValueOrDefault(false, resource),
|
||||||
RetentionPolicy: network.RetentionPolicy{
|
RetentionPolicy: network.RetentionPolicy{
|
||||||
Metadata: resource.GetMetadata(),
|
Metadata: resource.GetMetadata(),
|
||||||
Enabled: iacTypes.BoolDefault(false, resource.GetMetadata()),
|
Enabled: iacTypes.BoolDefault(false, resource.GetMetadata()),
|
||||||
@@ -98,14 +101,68 @@ func adaptWatcherLog(resource *terraform.Block) network.NetworkWatcherFlowLog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if retentionPolicyBlock := resource.GetBlock("retention_policy"); retentionPolicyBlock.IsNotNil() {
|
if retentionPolicyBlock := resource.GetBlock("retention_policy"); retentionPolicyBlock.IsNotNil() {
|
||||||
flowLog.RetentionPolicy.Metadata = retentionPolicyBlock.GetMetadata()
|
flowLog.RetentionPolicy = network.RetentionPolicy{
|
||||||
|
Metadata: retentionPolicyBlock.GetMetadata(),
|
||||||
enabledAttr := retentionPolicyBlock.GetAttribute("enabled")
|
Enabled: retentionPolicyBlock.GetAttribute("enabled").
|
||||||
flowLog.RetentionPolicy.Enabled = enabledAttr.AsBoolValueOrDefault(false, retentionPolicyBlock)
|
AsBoolValueOrDefault(false, retentionPolicyBlock),
|
||||||
|
Days: retentionPolicyBlock.GetAttribute("days").
|
||||||
daysAttr := retentionPolicyBlock.GetAttribute("days")
|
AsIntValueOrDefault(0, retentionPolicyBlock),
|
||||||
flowLog.RetentionPolicy.Days = daysAttr.AsIntValueOrDefault(0, retentionPolicyBlock)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return flowLog
|
return flowLog
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func adaptNetworkInterfaces(modules terraform.Modules) []network.NetworkInterface {
|
||||||
|
var networkInterfaces []network.NetworkInterface
|
||||||
|
|
||||||
|
for _, module := range modules {
|
||||||
|
for _, resource := range module.GetResourcesByType("azurerm_network_interface") {
|
||||||
|
networkInterfaces = append(networkInterfaces, AdaptNetworkInterface(resource, modules))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return networkInterfaces
|
||||||
|
}
|
||||||
|
|
||||||
|
func AdaptNetworkInterface(resource *terraform.Block, modules terraform.Modules) network.NetworkInterface {
|
||||||
|
ni := network.NetworkInterface{
|
||||||
|
Metadata: resource.GetMetadata(),
|
||||||
|
// Support both ip_forwarding_enabled (new) and enable_ip_forwarding (old) attributes
|
||||||
|
EnableIPForwarding: resource.GetFirstAttributeOf("ip_forwarding_enabled", "enable_ip_forwarding").
|
||||||
|
AsBoolValueOrDefault(false, resource),
|
||||||
|
HasPublicIP: iacTypes.BoolDefault(false, resource.GetMetadata()),
|
||||||
|
PublicIPAddress: iacTypes.StringDefault("", resource.GetMetadata()),
|
||||||
|
SubnetID: iacTypes.StringDefault("", resource.GetMetadata()),
|
||||||
|
}
|
||||||
|
|
||||||
|
if nsgAttr := resource.GetAttribute("network_security_group_id"); nsgAttr.IsNotNil() {
|
||||||
|
if referencedNSG, err := modules.GetReferencedBlock(nsgAttr, resource); err == nil {
|
||||||
|
ni.SecurityGroups = []network.SecurityGroup{adaptSecurityGroupFromBlock(referencedNSG)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ipConfigs := resource.GetBlocks("ip_configuration")
|
||||||
|
ni.IPConfigurations = make([]network.IPConfiguration, 0, len(ipConfigs))
|
||||||
|
for _, ipConfig := range ipConfigs {
|
||||||
|
ni.IPConfigurations = append(ni.IPConfigurations, network.IPConfiguration{
|
||||||
|
Metadata: ipConfig.GetMetadata(),
|
||||||
|
PublicIPAddress: ipConfig.GetAttribute("public_ip_address_id").AsStringValueOrDefault("", ipConfig),
|
||||||
|
SubnetID: ipConfig.GetAttribute("subnet_id").AsStringValueOrDefault("", ipConfig),
|
||||||
|
Primary: ipConfig.GetAttribute("primary").AsBoolValueOrDefault(false, ipConfig),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ni.Setup()
|
||||||
|
return ni
|
||||||
|
}
|
||||||
|
|
||||||
|
func adaptSecurityGroupFromBlock(resource *terraform.Block) network.SecurityGroup {
|
||||||
|
return network.SecurityGroup{
|
||||||
|
Metadata: resource.GetMetadata(),
|
||||||
|
Rules: lo.Map(resource.GetBlocks("security_rule"),
|
||||||
|
func(b *terraform.Block, _ int) network.SecurityGroupRule {
|
||||||
|
return AdaptSGRule(b)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ func Test_Adapt(t *testing.T) {
|
|||||||
resource "azurerm_network_watcher_flow_log" "example" {
|
resource "azurerm_network_watcher_flow_log" "example" {
|
||||||
resource_group_name = azurerm_resource_group.example.name
|
resource_group_name = azurerm_resource_group.example.name
|
||||||
name = "example-log"
|
name = "example-log"
|
||||||
|
enabled = true
|
||||||
|
|
||||||
retention_policy {
|
retention_policy {
|
||||||
enabled = true
|
enabled = true
|
||||||
@@ -51,44 +52,38 @@ func Test_Adapt(t *testing.T) {
|
|||||||
expected: network.Network{
|
expected: network.Network{
|
||||||
SecurityGroups: []network.SecurityGroup{
|
SecurityGroups: []network.SecurityGroup{
|
||||||
{
|
{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
Rules: []network.SecurityGroupRule{
|
Rules: []network.SecurityGroupRule{
|
||||||
{
|
{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Allow: iacTypes.BoolTest(true),
|
||||||
Outbound: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
|
|
||||||
Allow: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
|
||||||
SourceAddresses: []iacTypes.StringValue{
|
SourceAddresses: []iacTypes.StringValue{
|
||||||
iacTypes.String("4.53.160.75", iacTypes.NewTestMetadata()),
|
iacTypes.StringTest("4.53.160.75"),
|
||||||
},
|
},
|
||||||
DestinationAddresses: []iacTypes.StringValue{
|
DestinationAddresses: []iacTypes.StringValue{
|
||||||
iacTypes.String("*", iacTypes.NewTestMetadata()),
|
iacTypes.StringTest("*"),
|
||||||
},
|
},
|
||||||
SourcePorts: []common.PortRange{
|
SourcePorts: []common.PortRange{
|
||||||
{
|
{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
Start: iacTypes.IntTest(0),
|
Start: iacTypes.IntTest(0),
|
||||||
End: iacTypes.IntTest(65535),
|
End: iacTypes.IntTest(65535),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
DestinationPorts: []common.PortRange{
|
DestinationPorts: []common.PortRange{
|
||||||
{
|
{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
Start: iacTypes.IntTest(3389),
|
Start: iacTypes.IntTest(3389),
|
||||||
End: iacTypes.IntTest(3389),
|
End: iacTypes.IntTest(3389),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Protocol: iacTypes.String("TCP", iacTypes.NewTestMetadata()),
|
Protocol: iacTypes.StringTest("TCP"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NetworkWatcherFlowLogs: []network.NetworkWatcherFlowLog{
|
NetworkWatcherFlowLogs: []network.NetworkWatcherFlowLog{
|
||||||
{
|
{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Enabled: iacTypes.BoolTest(true),
|
||||||
RetentionPolicy: network.RetentionPolicy{
|
RetentionPolicy: network.RetentionPolicy{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Enabled: iacTypes.BoolTest(true),
|
||||||
Enabled: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
Days: iacTypes.IntTest(7),
|
||||||
Days: iacTypes.Int(7, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -96,23 +91,66 @@ func Test_Adapt(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "defaults",
|
name: "defaults",
|
||||||
terraform: `
|
terraform: `resource "azurerm_network_security_group" "example" {
|
||||||
resource "azurerm_network_security_group" "example" {
|
|
||||||
name = "tf-appsecuritygroup"
|
name = "tf-appsecuritygroup"
|
||||||
security_rule {
|
security_rule {}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`,
|
`,
|
||||||
expected: network.Network{
|
expected: network.Network{
|
||||||
SecurityGroups: []network.SecurityGroup{
|
SecurityGroups: []network.SecurityGroup{
|
||||||
{
|
{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
|
||||||
Rules: []network.SecurityGroupRule{
|
Rules: []network.SecurityGroupRule{
|
||||||
|
{
|
||||||
|
Allow: iacTypes.BoolTest(true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "network interface",
|
||||||
|
terraform: `resource "azurerm_network_interface" "example" {
|
||||||
|
name = "example-nic"
|
||||||
|
location = "eastus"
|
||||||
|
resource_group_name = "example-rg"
|
||||||
|
|
||||||
|
ip_configuration {
|
||||||
|
name = "primary-ip"
|
||||||
|
primary = true
|
||||||
|
subnet_id = "subnet-primary-id"
|
||||||
|
public_ip_address_id = "public-ip-primary-id"
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_configuration {
|
||||||
|
name = "secondary-ip"
|
||||||
|
subnet_id = "subnet-secondary-id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
expected: network.Network{
|
||||||
|
NetworkInterfaces: []network.NetworkInterface{
|
||||||
{
|
{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Metadata: iacTypes.NewTestMetadata(),
|
||||||
Outbound: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
|
// legacy fields filled from primary
|
||||||
Allow: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
SubnetID: iacTypes.String("subnet-primary-id", iacTypes.NewTestMetadata()),
|
||||||
Protocol: iacTypes.String("", iacTypes.NewTestMetadata()),
|
HasPublicIP: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
||||||
|
PublicIPAddress: iacTypes.String("public-ip-primary-id", iacTypes.NewTestMetadata()),
|
||||||
|
|
||||||
|
IPConfigurations: []network.IPConfiguration{
|
||||||
|
{
|
||||||
|
Metadata: iacTypes.NewTestMetadata(),
|
||||||
|
SubnetID: iacTypes.String("subnet-primary-id", iacTypes.NewTestMetadata()),
|
||||||
|
Primary: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
||||||
|
HasPublicIP: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
||||||
|
PublicIPAddress: iacTypes.String("public-ip-primary-id", iacTypes.NewTestMetadata()),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Metadata: iacTypes.NewTestMetadata(),
|
||||||
|
SubnetID: iacTypes.String("subnet-secondary-id", iacTypes.NewTestMetadata()),
|
||||||
|
Primary: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
|
||||||
|
HasPublicIP: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
|
||||||
|
PublicIPAddress: iacTypes.String("", iacTypes.NewTestMetadata()),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -140,6 +178,7 @@ func Test_adaptWatcherLog(t *testing.T) {
|
|||||||
name: "defined",
|
name: "defined",
|
||||||
terraform: `
|
terraform: `
|
||||||
resource "azurerm_network_watcher_flow_log" "watcher" {
|
resource "azurerm_network_watcher_flow_log" "watcher" {
|
||||||
|
enabled = true
|
||||||
retention_policy {
|
retention_policy {
|
||||||
enabled = true
|
enabled = true
|
||||||
days = 90
|
days = 90
|
||||||
@@ -147,11 +186,10 @@ func Test_adaptWatcherLog(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
expected: network.NetworkWatcherFlowLog{
|
expected: network.NetworkWatcherFlowLog{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Enabled: iacTypes.BoolTest(true),
|
||||||
RetentionPolicy: network.RetentionPolicy{
|
RetentionPolicy: network.RetentionPolicy{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Enabled: iacTypes.BoolTest(true),
|
||||||
Enabled: iacTypes.Bool(true, iacTypes.NewTestMetadata()),
|
Days: iacTypes.IntTest(90),
|
||||||
Days: iacTypes.Int(90, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -164,11 +202,10 @@ func Test_adaptWatcherLog(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
expected: network.NetworkWatcherFlowLog{
|
expected: network.NetworkWatcherFlowLog{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Enabled: iacTypes.BoolTest(false),
|
||||||
RetentionPolicy: network.RetentionPolicy{
|
RetentionPolicy: network.RetentionPolicy{
|
||||||
Metadata: iacTypes.NewTestMetadata(),
|
Enabled: iacTypes.BoolTest(false),
|
||||||
Enabled: iacTypes.Bool(false, iacTypes.NewTestMetadata()),
|
Days: iacTypes.IntTest(0),
|
||||||
Days: iacTypes.Int(0, iacTypes.NewTestMetadata()),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,15 +14,7 @@ type Compute struct {
|
|||||||
type VirtualMachine struct {
|
type VirtualMachine struct {
|
||||||
Metadata iacTypes.Metadata
|
Metadata iacTypes.Metadata
|
||||||
CustomData iacTypes.StringValue // NOT base64 encoded
|
CustomData iacTypes.StringValue // NOT base64 encoded
|
||||||
NetworkInterfaces []NetworkInterface
|
NetworkInterfaces []network.NetworkInterface
|
||||||
}
|
|
||||||
|
|
||||||
type NetworkInterface struct {
|
|
||||||
Metadata iacTypes.Metadata
|
|
||||||
SubnetID iacTypes.StringValue
|
|
||||||
SecurityGroups []network.SecurityGroup
|
|
||||||
HasPublicIP iacTypes.BoolValue
|
|
||||||
PublicIPAddress iacTypes.StringValue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LinuxVirtualMachine struct {
|
type LinuxVirtualMachine struct {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/samber/lo"
|
||||||
|
|
||||||
"github.com/aquasecurity/trivy/pkg/iac/adapters/common"
|
"github.com/aquasecurity/trivy/pkg/iac/adapters/common"
|
||||||
iacTypes "github.com/aquasecurity/trivy/pkg/iac/types"
|
iacTypes "github.com/aquasecurity/trivy/pkg/iac/types"
|
||||||
)
|
)
|
||||||
@@ -8,6 +10,7 @@ import (
|
|||||||
type Network struct {
|
type Network struct {
|
||||||
SecurityGroups []SecurityGroup
|
SecurityGroups []SecurityGroup
|
||||||
NetworkWatcherFlowLogs []NetworkWatcherFlowLog
|
NetworkWatcherFlowLogs []NetworkWatcherFlowLog
|
||||||
|
NetworkInterfaces []NetworkInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
type SecurityGroup struct {
|
type SecurityGroup struct {
|
||||||
@@ -28,6 +31,7 @@ type SecurityGroupRule struct {
|
|||||||
|
|
||||||
type NetworkWatcherFlowLog struct {
|
type NetworkWatcherFlowLog struct {
|
||||||
Metadata iacTypes.Metadata
|
Metadata iacTypes.Metadata
|
||||||
|
Enabled iacTypes.BoolValue
|
||||||
RetentionPolicy RetentionPolicy
|
RetentionPolicy RetentionPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,3 +40,57 @@ type RetentionPolicy struct {
|
|||||||
Enabled iacTypes.BoolValue
|
Enabled iacTypes.BoolValue
|
||||||
Days iacTypes.IntValue
|
Days iacTypes.IntValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NetworkInterface struct {
|
||||||
|
Metadata iacTypes.Metadata
|
||||||
|
EnableIPForwarding iacTypes.BoolValue
|
||||||
|
SecurityGroups []SecurityGroup
|
||||||
|
|
||||||
|
// Backward compatibility fields.
|
||||||
|
// These fields represent the primary IP configuration
|
||||||
|
// (or the first one if 'primary' was not explicitly set).
|
||||||
|
SubnetID iacTypes.StringValue
|
||||||
|
HasPublicIP iacTypes.BoolValue
|
||||||
|
PublicIPAddress iacTypes.StringValue
|
||||||
|
|
||||||
|
IPConfigurations []IPConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ni *NetworkInterface) Setup() {
|
||||||
|
for i := range ni.IPConfigurations {
|
||||||
|
c := &ni.IPConfigurations[i]
|
||||||
|
publicIP := c.PublicIPAddress
|
||||||
|
c.HasPublicIP = lo.Ternary(
|
||||||
|
publicIP.GetMetadata().IsResolvable(),
|
||||||
|
iacTypes.Bool(publicIP.IsNotEmpty(), publicIP.GetMetadata()),
|
||||||
|
iacTypes.BoolUnresolvable(c.Metadata),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if primaryIpConfig, exists := ni.findPrimaryIpConfig(); exists {
|
||||||
|
ni.SubnetID = primaryIpConfig.SubnetID
|
||||||
|
ni.PublicIPAddress = primaryIpConfig.PublicIPAddress
|
||||||
|
ni.HasPublicIP = primaryIpConfig.HasPublicIP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ni *NetworkInterface) findPrimaryIpConfig() (IPConfiguration, bool) {
|
||||||
|
for _, c := range ni.IPConfigurations {
|
||||||
|
if c.Primary.Value() {
|
||||||
|
return c, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ni.IPConfigurations) > 0 {
|
||||||
|
return ni.IPConfigurations[0], true
|
||||||
|
}
|
||||||
|
return IPConfiguration{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPConfiguration struct {
|
||||||
|
Metadata iacTypes.Metadata
|
||||||
|
SubnetID iacTypes.StringValue
|
||||||
|
Primary iacTypes.BoolValue
|
||||||
|
HasPublicIP iacTypes.BoolValue
|
||||||
|
PublicIPAddress iacTypes.StringValue
|
||||||
|
}
|
||||||
|
|||||||
@@ -4737,34 +4737,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"github.com.aquasecurity.trivy.pkg.iac.providers.azure.compute.NetworkInterface": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"__defsec_metadata": {
|
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.Metadata"
|
|
||||||
},
|
|
||||||
"haspublicip": {
|
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.BoolValue"
|
|
||||||
},
|
|
||||||
"publicipaddress": {
|
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"
|
|
||||||
},
|
|
||||||
"securitygroups": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.SecurityGroup"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"subnetid": {
|
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"github.com.aquasecurity.trivy.pkg.iac.providers.azure.compute.OSProfileLinuxConfig": {
|
"github.com.aquasecurity.trivy.pkg.iac.providers.azure.compute.OSProfileLinuxConfig": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -4793,7 +4765,7 @@
|
|||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.compute.NetworkInterface"
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.NetworkInterface"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5364,6 +5336,13 @@
|
|||||||
"github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.Network": {
|
"github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.Network": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"networkinterfaces": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.NetworkInterface"
|
||||||
|
}
|
||||||
|
},
|
||||||
"networkwatcherflowlogs": {
|
"networkwatcherflowlogs": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@@ -5380,6 +5359,38 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.NetworkInterface": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"__defsec_metadata": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.Metadata"
|
||||||
|
},
|
||||||
|
"enableipforwarding": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.BoolValue"
|
||||||
|
},
|
||||||
|
"haspublicip": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.BoolValue"
|
||||||
|
},
|
||||||
|
"publicipaddress": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"
|
||||||
|
},
|
||||||
|
"securitygroups": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.SecurityGroup"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"subnetid": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.StringValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.NetworkWatcherFlowLog": {
|
"github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.NetworkWatcherFlowLog": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -5387,6 +5398,10 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.Metadata"
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.Metadata"
|
||||||
},
|
},
|
||||||
|
"enabled": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.types.BoolValue"
|
||||||
|
},
|
||||||
"retentionpolicy": {
|
"retentionpolicy": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.RetentionPolicy"
|
"$ref": "#/definitions/github.com.aquasecurity.trivy.pkg.iac.providers.azure.network.RetentionPolicy"
|
||||||
|
|||||||
@@ -138,9 +138,6 @@ func (b *Block) Reference() Reference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Block) GetMetadata() iacTypes.Metadata {
|
func (b *Block) GetMetadata() iacTypes.Metadata {
|
||||||
if b.IsNil() {
|
|
||||||
return iacTypes.NewUnmanagedMetadata()
|
|
||||||
}
|
|
||||||
return b.metadata
|
return b.metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user