forked from gruntwork-io/terratest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
count.go
87 lines (73 loc) · 2.31 KB
/
count.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package terraform
import (
"errors"
"regexp"
"strconv"
"testing"
"github.com/stretchr/testify/require"
)
// ResourceCount represents counts of resources affected by terraform apply/plan/destroy command.
type ResourceCount struct {
Add int
Change int
Destroy int
}
// Regular expressions for terraform commands stdout pattern matching.
const (
applyRegexp = `Apply complete! Resources: (\d+) added, (\d+) changed, (\d+) destroyed\.`
destroyRegexp = `Destroy complete! Resources: (\d+) destroyed\.`
planWithChangesRegexp = `(\033\[1m)?Plan:(\033\[0m)? (\d+) to add, (\d+) to change, (\d+) to destroy\.`
planWithNoChangesRegexp = `No changes\. Infrastructure is up-to-date\.`
)
const getResourceCountErrMessage = "Can't parse Terraform output"
// GetResourceCount parses stdout/stderr of apply/plan/destroy commands and returns number of affected resources.
// This will fail the test if given stdout/stderr isn't a valid output of apply/plan/destroy.
func GetResourceCount(t *testing.T, cmdout string) *ResourceCount {
cnt, err := GetResourceCountE(t, cmdout)
require.NoError(t, err)
return cnt
}
// GetResourceCountE parses stdout/stderr of apply/plan/destroy commands and returns number of affected resources.
func GetResourceCountE(t *testing.T, cmdout string) (*ResourceCount, error) {
cnt := ResourceCount{}
terraformCommandPatterns := []struct {
regexpStr string
addPosition int
changePosition int
destroyPosition int
}{
{applyRegexp, 1, 2, 3},
{destroyRegexp, -1, -1, 1},
{planWithChangesRegexp, 3, 4, 5},
{planWithNoChangesRegexp, -1, -1, -1},
}
for _, tc := range terraformCommandPatterns {
pattern, err := regexp.Compile(tc.regexpStr)
if err != nil {
return nil, err
}
matches := pattern.FindStringSubmatch(cmdout)
if matches != nil {
if tc.addPosition != -1 {
cnt.Add, err = strconv.Atoi(matches[tc.addPosition])
if err != nil {
return nil, err
}
}
if tc.changePosition != -1 {
cnt.Change, err = strconv.Atoi(matches[tc.changePosition])
if err != nil {
return nil, err
}
}
if tc.destroyPosition != -1 {
cnt.Destroy, err = strconv.Atoi(matches[tc.destroyPosition])
if err != nil {
return nil, err
}
}
return &cnt, nil
}
}
return nil, errors.New(getResourceCountErrMessage)
}