Skip to content

Commit f8e189d

Browse files
feat: add vpc support
feat: add vpc support
2 parents c54fd9c + c35d835 commit f8e189d

9 files changed

Lines changed: 192 additions & 35 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ Check `config.sample.yaml` for reference.
2020

2121
Given below are supported input types,
2222

23-
- LOGS : ECS (Elastic Common Schema) formated logs based on zap.
23+
- LOGS : ECS (Elastic Common Schema) formated logs based on zap
2424
- METRICS: Generate metrics similar to a CloudWatch metrics entry
2525
- ALB : Generate AWS ALB formatted log with some random content
26+
- VPC: Generate AWS VPC formatted logs with randomized content
2627

2728
Other input configuration,
2829

config.sample.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
input:
22
# Input type.
3-
# Supports - LOGS, METRICS, ALB
3+
# Supports - LOGS, METRICS, ALB, VPC
44
type: LOGS
55
# Delay between a data point.
66
# Defaults to 5s

generators/elb.go

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,11 @@ package generators
22

33
import (
44
"fmt"
5-
"math/rand"
6-
"time"
75
)
86

97
type ALBGen struct {
108
}
119

12-
func NewALBGen() *ALBGen {
13-
return &ALBGen{}
14-
}
15-
1610
func (a *ALBGen) Get() ([]byte, error) {
1711
customizer := albCustomizer{
1812
logType: randomALBType(),
@@ -90,27 +84,3 @@ func buildALBLogLine(input albCustomizer) string {
9084

9185
return logLine
9286
}
93-
94-
// randomizers
95-
96-
func iso8601Now() string {
97-
return time.Now().UTC().Format("2006-01-02T15:04:05.000000Z")
98-
}
99-
100-
func randomALBType() string {
101-
types := []string{"http", "https", "h2"}
102-
return types[rand.Intn(len(types))]
103-
}
104-
105-
func randomIP() string {
106-
return fmt.Sprintf("%d.%d.%d.%d",
107-
rand.Intn(256),
108-
rand.Intn(256),
109-
rand.Intn(256),
110-
rand.Intn(256),
111-
)
112-
}
113-
114-
func randomPort() int {
115-
return rand.Intn(65535-1024) + 1024
116-
}

generators/elb_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package generators
22

33
import (
4-
"github.com/stretchr/testify/require"
4+
"strings"
55
"testing"
6+
7+
"github.com/stretchr/testify/require"
68
)
79

810
// refer http example of https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-log-entry-format
@@ -25,6 +27,6 @@ func Test_buildALB(t *testing.T) {
2527
requestID: "TID_1234abcd5678ef90",
2628
})
2729

28-
require.Equal(t, upstreamALBHTTP, line)
30+
require.Equal(t, upstreamALBHTTP, strings.TrimSpace(line))
2931
})
3032
}

generators/generator.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const (
1212
logs = "LOGS"
1313
metrics = "METRICS"
1414
alb = "ALB"
15+
vpc = "VPC"
1516
)
1617

1718
type input interface {
@@ -25,7 +26,9 @@ func GeneratorFor(config *conf.Config) (*Generator, error) {
2526
case metrics:
2627
return newGenerator(NewMetricGenerator()), nil
2728
case alb:
28-
return newGenerator(NewALBGen()), nil
29+
return newGenerator(&ALBGen{}), nil
30+
case vpc:
31+
return newGenerator(&VPCGen{}), nil
2932
}
3033

3134
return nil, fmt.Errorf("unknown generator type: %s", config.Input.Type)

generators/utils.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package generators
2+
3+
import (
4+
"fmt"
5+
"math/rand"
6+
"time"
7+
)
8+
9+
// randomizers
10+
11+
func iso8601Now() string {
12+
return time.Now().UTC().Format("2006-01-02T15:04:05.000000Z")
13+
}
14+
15+
func unixSeconds() int64 {
16+
return time.Now().Unix()
17+
}
18+
19+
func randomALBType() string {
20+
types := []string{"http", "https", "h2"}
21+
return types[rand.Intn(len(types))]
22+
}
23+
24+
func randomVPCAction() string {
25+
types := []string{"ACCEPT", "REJECT"}
26+
return types[rand.Intn(len(types))]
27+
}
28+
29+
func randomIP() string {
30+
return fmt.Sprintf("%d.%d.%d.%d",
31+
rand.Intn(256),
32+
rand.Intn(256),
33+
rand.Intn(256),
34+
rand.Intn(256),
35+
)
36+
}
37+
38+
func randomPort() int {
39+
return rand.Intn(65535-1024) + 1024
40+
}
41+
42+
func randomAWSAccountID() string {
43+
// Generate a 12-digit number, ensuring the first digit is not 0
44+
accountID := rand.Intn(9) + 1
45+
for i := 1; i < 12; i++ {
46+
accountID = accountID*10 + rand.Intn(10)
47+
}
48+
return fmt.Sprintf("%012d", accountID)
49+
}

generators/vpc.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package generators
2+
3+
import (
4+
"fmt"
5+
"math/rand/v2"
6+
)
7+
8+
type VPCGen struct {
9+
}
10+
11+
func (V VPCGen) Get() ([]byte, error) {
12+
customizer := vpcCustomizer{
13+
Version: 2,
14+
AccountID: randomAWSAccountID(),
15+
InterfaceID: "eni-123456789123",
16+
SrcAddr: randomIP(),
17+
DstAddr: randomIP(),
18+
SrcPort: randomPort(),
19+
DstPort: randomPort(),
20+
Protocol: 6, // TCP
21+
Packets: rand.IntN(100) + 1,
22+
Bytes: rand.IntN(1000) + 1,
23+
Start: unixSeconds(),
24+
End: unixSeconds(),
25+
Action: randomVPCAction(),
26+
LogStatus: "ok",
27+
}
28+
29+
return []byte(buildVPCLogLine(customizer)), nil
30+
}
31+
32+
type vpcCustomizer struct {
33+
Version int
34+
AccountID string
35+
InterfaceID string
36+
SrcAddr string
37+
DstAddr string
38+
SrcPort int
39+
DstPort int
40+
Protocol int
41+
Packets int
42+
Bytes int
43+
Start int64
44+
End int64
45+
Action string
46+
LogStatus string
47+
}
48+
49+
func buildVPCLogLine(vpcCustomizer vpcCustomizer) string {
50+
return fmt.Sprintf(
51+
"%d %s %s %s %s %d %d %d %d %d %d %d %s %s\n",
52+
vpcCustomizer.Version,
53+
vpcCustomizer.AccountID,
54+
vpcCustomizer.InterfaceID,
55+
vpcCustomizer.SrcAddr,
56+
vpcCustomizer.DstAddr,
57+
vpcCustomizer.SrcPort,
58+
vpcCustomizer.DstPort,
59+
vpcCustomizer.Protocol,
60+
vpcCustomizer.Packets,
61+
vpcCustomizer.Bytes,
62+
vpcCustomizer.Start,
63+
vpcCustomizer.End,
64+
vpcCustomizer.Action,
65+
vpcCustomizer.LogStatus,
66+
)
67+
}

generators/vpc_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package generators
2+
3+
import (
4+
"github.com/stretchr/testify/require"
5+
"strings"
6+
"testing"
7+
)
8+
9+
// refer example of https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs-records-examples.html#flow-log-example-accepted-rejected
10+
const acceptedVPC = "2 123456789010 eni-1235b8ca123456789 172.31.16.139 172.31.16.21 20641 22 6 20 4249 1418530010 1418530070 ACCEPT OK"
11+
const rejectedVPC = "2 123456789010 eni-1235b8ca123456789 172.31.9.69 172.31.9.12 49761 3389 6 20 4249 1418530010 1418530070 REJECT OK"
12+
13+
func Test_buildVPC(t *testing.T) {
14+
t.Run("Validate AWS documented VPC - Accepted", func(t *testing.T) {
15+
line := buildVPCLogLine(vpcCustomizer{
16+
Version: 2,
17+
AccountID: "123456789010",
18+
InterfaceID: "eni-1235b8ca123456789",
19+
SrcAddr: "172.31.16.139",
20+
DstAddr: "172.31.16.21",
21+
SrcPort: 20641,
22+
DstPort: 22,
23+
Protocol: 6,
24+
Packets: 20,
25+
Bytes: 4249,
26+
Start: 1418530010,
27+
End: 1418530070,
28+
Action: "ACCEPT",
29+
LogStatus: "OK",
30+
})
31+
32+
require.Equal(t, acceptedVPC, strings.TrimSpace(line))
33+
})
34+
35+
t.Run("Validate AWS documented VPC - Accepted", func(t *testing.T) {
36+
line := buildVPCLogLine(vpcCustomizer{
37+
Version: 2,
38+
AccountID: "123456789010",
39+
InterfaceID: "eni-1235b8ca123456789",
40+
SrcAddr: "172.31.9.69",
41+
DstAddr: "172.31.9.12",
42+
SrcPort: 49761,
43+
DstPort: 3389,
44+
Protocol: 6,
45+
Packets: 20,
46+
Bytes: 4249,
47+
Start: 1418530010,
48+
End: 1418530070,
49+
Action: "REJECT",
50+
LogStatus: "OK",
51+
})
52+
53+
require.Equal(t, rejectedVPC, strings.TrimSpace(line))
54+
})
55+
}

out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2 866154009731 eni-123456789123 122.147.55.223 161.213.213.198 10837 11867 6 82 423 1754493585 1754493585 ACCEPT ok2 406296230703 eni-123456789123 171.29.102.171 173.1.244.58 49802 63307 6 11 348 1754493587 1754493587 REJECT ok2 688844753206 eni-123456789123 125.233.181.242 106.25.106.53 9858 59728 6 97 102 1754493589 1754493589 ACCEPT ok2 650351127900 eni-123456789123 95.242.245.50 158.141.47.124 26851 31833 6 81 757 1754493591 1754493591 ACCEPT ok2 579358143784 eni-123456789123 119.182.190.54 123.147.204.38 18875 3941 6 82 781 1754493593 1754493593 REJECT ok2 806390614281 eni-123456789123 73.153.212.98 26.103.36.146 43760 24727 6 50 759 1754493607 1754493607 REJECT ok
2+
2 169850649817 eni-123456789123 202.206.90.205 146.125.211.239 8157 22081 6 39 488 1754493609 1754493609 REJECT ok
3+
2 322917440216 eni-123456789123 207.212.232.147 204.2.167.206 20731 22807 6 39 174 1754493611 1754493611 REJECT ok
4+
2 150662564985 eni-123456789123 14.120.225.220 193.206.191.127 5040 54311 6 73 754 1754493613 1754493613 REJECT ok
5+
2 485182205743 eni-123456789123 99.133.215.126 54.84.219.179 56885 57832 6 96 851 1754493615 1754493615 REJECT ok
6+
2 690116715612 eni-123456789123 231.179.233.87 53.66.245.131 54146 21419 6 44 14 1754493617 1754493617 REJECT ok
7+
2 947001158844 eni-123456789123 227.167.221.168 36.123.9.125 27192 64697 6 63 137 1754493619 1754493619 REJECT ok
8+
2 281855856164 eni-123456789123 184.61.26.194 233.50.143.110 50643 46412 6 52 976 1754493621 1754493621 ACCEPT ok
9+
2 572450921823 eni-123456789123 124.112.132.101 42.213.105.229 8314 53925 6 18 803 1754493623 1754493623 ACCEPT ok
10+
2 313589345846 eni-123456789123 59.51.238.79 171.158.169.10 38274 42245 6 28 917 1754493625 1754493625 ACCEPT ok

0 commit comments

Comments
 (0)