github.com/aquasecurity/trivy-iac@v0.8.1-0.20240127024015-3d8e412cf0ab/internal/adapters/terraform/aws/ec2/vpc_test.go (about)

     1  package ec2
     2  
     3  import (
     4  	"testing"
     5  
     6  	defsecTypes "github.com/aquasecurity/defsec/pkg/types"
     7  
     8  	"github.com/aquasecurity/defsec/pkg/providers/aws/ec2"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/aquasecurity/trivy-iac/internal/adapters/terraform/tftestutil"
    14  	"github.com/aquasecurity/trivy-iac/test/testutil"
    15  )
    16  
    17  func Test_AdaptVPC(t *testing.T) {
    18  	tests := []struct {
    19  		name      string
    20  		terraform string
    21  		expected  ec2.EC2
    22  	}{
    23  		{
    24  			name: "defined",
    25  			terraform: `
    26  			resource "aws_flow_log" "this" {
    27  				vpc_id = aws_vpc.main.id
    28  			}
    29  			resource "aws_default_vpc" "default" {
    30  				tags = {
    31  				  Name = "Default VPC"
    32  				}
    33  			  }
    34  
    35  			  resource "aws_vpc" "main" {
    36  				cidr_block = "4.5.6.7/32"
    37  			  }
    38  
    39  			resource "aws_security_group" "example" {
    40  				name        = "http"
    41  				description = "Allow inbound HTTP traffic"
    42  			  
    43  				ingress {
    44  				  description = "Rule #1"
    45  				  from_port   = 80
    46  				  to_port     = 80
    47  				  protocol    = "tcp"
    48  				  cidr_blocks = [aws_vpc.main.cidr_block]
    49  				}
    50  
    51  				egress {
    52  					cidr_blocks = ["1.2.3.4/32"]
    53  				}
    54  			  }
    55  
    56  			resource "aws_network_acl_rule" "example" {
    57  				egress         = false
    58  				protocol       = "tcp"
    59  				from_port      = 22
    60  				to_port        = 22
    61  				rule_action    = "allow"
    62  				cidr_block     = "10.0.0.0/16"
    63  			}
    64  
    65  			resource "aws_security_group_rule" "example" {
    66  				type              = "ingress"
    67  				description = "Rule #2"
    68  				security_group_id = aws_security_group.example.id
    69  				from_port         = 22
    70  				to_port           = 22
    71  				protocol          = "tcp"
    72  				cidr_blocks = [
    73  				  "1.2.3.4/32",
    74  				  "4.5.6.7/32",
    75  				]
    76  			  }
    77  `,
    78  			expected: ec2.EC2{
    79  				VPCs: []ec2.VPC{
    80  					{
    81  						Metadata:        defsecTypes.NewTestMetadata(),
    82  						IsDefault:       defsecTypes.Bool(true, defsecTypes.NewTestMetadata()),
    83  						ID:              defsecTypes.String("", defsecTypes.NewTestMetadata()),
    84  						FlowLogsEnabled: defsecTypes.Bool(false, defsecTypes.NewTestMetadata()),
    85  					},
    86  					{
    87  						Metadata:        defsecTypes.NewTestMetadata(),
    88  						IsDefault:       defsecTypes.Bool(false, defsecTypes.NewTestMetadata()),
    89  						ID:              defsecTypes.String("", defsecTypes.NewTestMetadata()),
    90  						FlowLogsEnabled: defsecTypes.Bool(true, defsecTypes.NewTestMetadata()),
    91  					},
    92  				},
    93  				SecurityGroups: []ec2.SecurityGroup{
    94  					{
    95  						Metadata:    defsecTypes.NewTestMetadata(),
    96  						Description: defsecTypes.String("Allow inbound HTTP traffic", defsecTypes.NewTestMetadata()),
    97  						IsDefault:   defsecTypes.Bool(false, defsecTypes.NewTestMetadata()),
    98  						VPCID:       defsecTypes.String("", defsecTypes.NewTestMetadata()),
    99  						IngressRules: []ec2.SecurityGroupRule{
   100  							{
   101  								Metadata: defsecTypes.NewTestMetadata(),
   102  
   103  								Description: defsecTypes.String("Rule #1", defsecTypes.NewTestMetadata()),
   104  								CIDRs: []defsecTypes.StringValue{
   105  									defsecTypes.String("4.5.6.7/32", defsecTypes.NewTestMetadata()),
   106  								},
   107  							},
   108  							{
   109  								Metadata: defsecTypes.NewTestMetadata(),
   110  
   111  								Description: defsecTypes.String("Rule #2", defsecTypes.NewTestMetadata()),
   112  								CIDRs: []defsecTypes.StringValue{
   113  									defsecTypes.String("1.2.3.4/32", defsecTypes.NewTestMetadata()),
   114  									defsecTypes.String("4.5.6.7/32", defsecTypes.NewTestMetadata()),
   115  								},
   116  							},
   117  						},
   118  
   119  						EgressRules: []ec2.SecurityGroupRule{
   120  							{
   121  								Metadata:    defsecTypes.NewTestMetadata(),
   122  								Description: defsecTypes.String("", defsecTypes.NewTestMetadata()),
   123  								CIDRs: []defsecTypes.StringValue{
   124  									defsecTypes.String("1.2.3.4/32", defsecTypes.NewTestMetadata()),
   125  								},
   126  							},
   127  						},
   128  					},
   129  				},
   130  				NetworkACLs: []ec2.NetworkACL{
   131  					{
   132  						Metadata: defsecTypes.NewTestMetadata(),
   133  						Rules: []ec2.NetworkACLRule{
   134  							{
   135  								Metadata: defsecTypes.NewTestMetadata(),
   136  								Type:     defsecTypes.String("ingress", defsecTypes.NewTestMetadata()),
   137  								Action:   defsecTypes.String("allow", defsecTypes.NewTestMetadata()),
   138  								Protocol: defsecTypes.String("tcp", defsecTypes.NewTestMetadata()),
   139  								CIDRs: []defsecTypes.StringValue{
   140  									defsecTypes.String("10.0.0.0/16", defsecTypes.NewTestMetadata()),
   141  								},
   142  							},
   143  						},
   144  						IsDefaultRule: defsecTypes.Bool(false, defsecTypes.NewTestMetadata()),
   145  					},
   146  				},
   147  			},
   148  		},
   149  		{
   150  			name: "defaults",
   151  			terraform: `
   152  			resource "aws_security_group" "example" {
   153  				ingress {
   154  				}
   155  
   156  				egress {
   157  				}
   158  			  }
   159  
   160  			resource "aws_network_acl_rule" "example" {
   161  			}
   162  `,
   163  			expected: ec2.EC2{
   164  				SecurityGroups: []ec2.SecurityGroup{
   165  					{
   166  						Metadata:    defsecTypes.NewTestMetadata(),
   167  						Description: defsecTypes.String("Managed by Terraform", defsecTypes.NewTestMetadata()),
   168  						IsDefault:   defsecTypes.Bool(false, defsecTypes.NewTestMetadata()),
   169  						VPCID:       defsecTypes.String("", defsecTypes.NewTestMetadata()),
   170  						IngressRules: []ec2.SecurityGroupRule{
   171  							{
   172  								Metadata:    defsecTypes.NewTestMetadata(),
   173  								Description: defsecTypes.String("", defsecTypes.NewTestMetadata()),
   174  							},
   175  						},
   176  
   177  						EgressRules: []ec2.SecurityGroupRule{
   178  							{
   179  								Metadata:    defsecTypes.NewTestMetadata(),
   180  								Description: defsecTypes.String("", defsecTypes.NewTestMetadata()),
   181  							},
   182  						},
   183  					},
   184  				},
   185  				NetworkACLs: []ec2.NetworkACL{
   186  					{
   187  						Metadata: defsecTypes.NewTestMetadata(),
   188  						Rules: []ec2.NetworkACLRule{
   189  							{
   190  								Metadata: defsecTypes.NewTestMetadata(),
   191  								Type:     defsecTypes.String("ingress", defsecTypes.NewTestMetadata()),
   192  								Action:   defsecTypes.String("", defsecTypes.NewTestMetadata()),
   193  								Protocol: defsecTypes.String("-1", defsecTypes.NewTestMetadata()),
   194  							},
   195  						},
   196  						IsDefaultRule: defsecTypes.Bool(false, defsecTypes.NewTestMetadata()),
   197  					},
   198  				},
   199  			},
   200  		},
   201  		{
   202  			name: "aws_flow_log refer to locals",
   203  			terraform: `
   204  locals {
   205    vpc_id = try(aws_vpc.this.id, "")
   206  }
   207  
   208  resource "aws_vpc" "this" {
   209  }
   210  
   211  resource "aws_flow_log" "this" {
   212    vpc_id = local.vpc_id
   213  }
   214  `,
   215  			expected: ec2.EC2{
   216  				VPCs: []ec2.VPC{
   217  					{
   218  						Metadata:        defsecTypes.NewTestMetadata(),
   219  						IsDefault:       defsecTypes.Bool(false, defsecTypes.NewTestMetadata()),
   220  						ID:              defsecTypes.String("", defsecTypes.NewTestMetadata()),
   221  						FlowLogsEnabled: defsecTypes.Bool(true, defsecTypes.NewTestMetadata()),
   222  					},
   223  				},
   224  			},
   225  		},
   226  	}
   227  
   228  	for _, test := range tests {
   229  		t.Run(test.name, func(t *testing.T) {
   230  			modules := tftestutil.CreateModulesFromSource(t, test.terraform, ".tf")
   231  			adapted := Adapt(modules)
   232  			testutil.AssertDefsecEqual(t, test.expected, adapted)
   233  		})
   234  	}
   235  }
   236  
   237  func TestVPCLines(t *testing.T) {
   238  	src := `
   239  	resource "aws_default_vpc" "default" {
   240  	  }
   241  
   242  	resource "aws_vpc" "main" {
   243  		cidr_block = "4.5.6.7/32"
   244  	  }
   245  
   246  	resource "aws_security_group" "example" {
   247  		name        = "http"
   248  		description = "Allow inbound HTTP traffic"
   249  	  
   250  		ingress {
   251  		  description = "HTTP from VPC"
   252  		  from_port   = 80
   253  		  to_port     = 80
   254  		  protocol    = "tcp"
   255  		  cidr_blocks = [aws_vpc.main.cidr_block]
   256  		}
   257  
   258  		egress {
   259  			cidr_blocks = ["1.2.3.4/32"]
   260  		}
   261  	  }
   262  
   263  	resource "aws_security_group_rule" "example" {
   264  		type              = "ingress"
   265  		security_group_id = aws_security_group.example.id
   266  		from_port         = 22
   267  		to_port           = 22
   268  		protocol          = "tcp"
   269  		cidr_blocks = [
   270  		  "1.2.3.4/32",
   271  		  "4.5.6.7/32",
   272  		]
   273  	  }
   274  	  
   275  	  resource "aws_network_acl_rule" "example" {
   276  		egress         = false
   277  		protocol       = "tcp"
   278  		from_port      = 22
   279  		to_port        = 22
   280  		rule_action    = "allow"
   281  		cidr_block     = "10.0.0.0/16"
   282  	}`
   283  
   284  	modules := tftestutil.CreateModulesFromSource(t, src, ".tf")
   285  	adapted := Adapt(modules)
   286  
   287  	require.Len(t, adapted.VPCs, 2)
   288  	require.Len(t, adapted.SecurityGroups, 1)
   289  	require.Len(t, adapted.NetworkACLs, 1)
   290  
   291  	defaultVPC := adapted.VPCs[0]
   292  	securityGroup := adapted.SecurityGroups[0]
   293  	networkACL := adapted.NetworkACLs[0]
   294  
   295  	assert.Equal(t, 2, defaultVPC.Metadata.Range().GetStartLine())
   296  	assert.Equal(t, 3, defaultVPC.Metadata.Range().GetEndLine())
   297  
   298  	assert.Equal(t, 9, securityGroup.Metadata.Range().GetStartLine())
   299  	assert.Equal(t, 24, securityGroup.Metadata.Range().GetEndLine())
   300  
   301  	assert.Equal(t, 11, securityGroup.Description.GetMetadata().Range().GetStartLine())
   302  	assert.Equal(t, 11, securityGroup.Description.GetMetadata().Range().GetEndLine())
   303  
   304  	assert.Equal(t, 13, securityGroup.IngressRules[0].Metadata.Range().GetStartLine())
   305  	assert.Equal(t, 19, securityGroup.IngressRules[0].Metadata.Range().GetEndLine())
   306  
   307  	assert.Equal(t, 14, securityGroup.IngressRules[0].Description.GetMetadata().Range().GetStartLine())
   308  	assert.Equal(t, 14, securityGroup.IngressRules[0].Description.GetMetadata().Range().GetEndLine())
   309  
   310  	assert.Equal(t, 18, securityGroup.IngressRules[0].CIDRs[0].GetMetadata().Range().GetStartLine())
   311  	assert.Equal(t, 18, securityGroup.IngressRules[0].CIDRs[0].GetMetadata().Range().GetEndLine())
   312  
   313  	assert.Equal(t, 26, securityGroup.IngressRules[1].Metadata.Range().GetStartLine())
   314  	assert.Equal(t, 36, securityGroup.IngressRules[1].Metadata.Range().GetEndLine())
   315  
   316  	assert.Equal(t, 32, securityGroup.IngressRules[1].CIDRs[0].GetMetadata().Range().GetStartLine())
   317  	assert.Equal(t, 35, securityGroup.IngressRules[1].CIDRs[0].GetMetadata().Range().GetEndLine())
   318  
   319  	assert.Equal(t, 21, securityGroup.EgressRules[0].Metadata.Range().GetStartLine())
   320  	assert.Equal(t, 23, securityGroup.EgressRules[0].Metadata.Range().GetEndLine())
   321  
   322  	assert.Equal(t, 22, securityGroup.EgressRules[0].CIDRs[0].GetMetadata().Range().GetStartLine())
   323  	assert.Equal(t, 22, securityGroup.EgressRules[0].CIDRs[0].GetMetadata().Range().GetEndLine())
   324  
   325  	assert.Equal(t, 38, networkACL.Rules[0].Metadata.Range().GetStartLine())
   326  	assert.Equal(t, 45, networkACL.Rules[0].Metadata.Range().GetEndLine())
   327  
   328  	assert.Equal(t, 39, networkACL.Rules[0].Type.GetMetadata().Range().GetStartLine())
   329  	assert.Equal(t, 39, networkACL.Rules[0].Type.GetMetadata().Range().GetEndLine())
   330  
   331  	assert.Equal(t, 40, networkACL.Rules[0].Protocol.GetMetadata().Range().GetStartLine())
   332  	assert.Equal(t, 40, networkACL.Rules[0].Protocol.GetMetadata().Range().GetEndLine())
   333  
   334  	assert.Equal(t, 43, networkACL.Rules[0].Action.GetMetadata().Range().GetStartLine())
   335  	assert.Equal(t, 43, networkACL.Rules[0].Action.GetMetadata().Range().GetEndLine())
   336  
   337  	assert.Equal(t, 44, networkACL.Rules[0].CIDRs[0].GetMetadata().Range().GetStartLine())
   338  	assert.Equal(t, 44, networkACL.Rules[0].CIDRs[0].GetMetadata().Range().GetEndLine())
   339  }