Skip to content

Commit 9acc861

Browse files
BCDA-9484: Migrate aws sdk to v2 (#1235)
## 🎫 Ticket https://jira.cms.gov/browse/BCDA-9484 ## 🛠 Changes Migrate all AWS packages to v2. Various refactoring and cleanup. ## ℹ️ Context AWS v1 are out of service as of end of July 2025. <!-- If any of the following security implications apply, this PR must not be merged without Stephen Walter's approval. Explain in this section and add @SJWalter11 as a reviewer. - Adds a new software dependency or dependencies. - Modifies or invalidates one or more of our security controls. - Stores or transmits data that was not stored or transmitted before. - Requires additional review of security implications for other reasons. --> ## 🧪 Validation Local linting and testing.
1 parent 719d336 commit 9acc861

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1021
-2268
lines changed

.golangci.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ linters:
2323
- linters:
2424
- errcheck
2525
text: "conf.UnsetEnv|conf.SetEnv" # these are used and unchecked in over 280 test files
26-
# disable package deprecation for aws-sdk-go until https://jira.cms.gov/browse/BCDA-9484 is finished
27-
- linters:
28-
- staticcheck
29-
text: "aws-sdk-go"
30-
#- end disable for BCDA-9484
3126
formatters:
3227
enable:
3328
- gofmt

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"go.testEnvVars": {
33
"ENV": "local",
4-
"LOCAL_STACK_ENDPOINT": "http://localhost:4566",
4+
"AWS_ENDPOINT_URL": "http://localhost:4566",
55
"DB": "postgresql://postgres:toor@localhost:15432",
66
"DB_HOST_URL": "postgresql://postgres:toor@localhost:15432?sslmode=disable",
77
"TEST_DB_URL": "postgresql://postgres:toor@localhost:15432/bcda_test?sslmode=disable",

bcda/aws/metrics.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package bcdaaws
2+
3+
import (
4+
"context"
5+
6+
"github.com/aws/aws-sdk-go-v2/aws"
7+
"github.com/aws/aws-sdk-go-v2/config"
8+
"github.com/aws/aws-sdk-go-v2/service/cloudwatch"
9+
"github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
10+
)
11+
12+
type Sampler struct {
13+
Ctx context.Context
14+
Namespace string
15+
Unit string
16+
Service *cloudwatch.Client
17+
}
18+
19+
func PutMetricSample(
20+
ctx context.Context,
21+
namespace string,
22+
name string,
23+
unit types.StandardUnit,
24+
value float64,
25+
dimensions []types.Dimension,
26+
) error {
27+
data := types.MetricDatum{
28+
Dimensions: dimensions,
29+
MetricName: &name,
30+
Unit: unit,
31+
Value: &value,
32+
}
33+
34+
input := &cloudwatch.PutMetricDataInput{
35+
MetricData: []types.MetricDatum{data},
36+
Namespace: aws.String(namespace),
37+
}
38+
39+
cfg, err := config.LoadDefaultConfig(ctx)
40+
if err != nil {
41+
return err
42+
}
43+
44+
client := cloudwatch.NewFromConfig(cfg)
45+
46+
_, err = client.PutMetricData(ctx, input)
47+
48+
return err
49+
}

bcda/aws/metrics_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package bcdaaws
2+
3+
import (
4+
"testing"
5+
6+
"github.com/aws/aws-sdk-go-v2/aws"
7+
"github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestPutMetricSample(t *testing.T) {
12+
err := PutMetricSample(
13+
t.Context(),
14+
"Namespace",
15+
"Name",
16+
"Count",
17+
float64(32),
18+
[]types.Dimension{{Name: aws.String("name"), Value: aws.String("value")}},
19+
)
20+
assert.Nil(t, err)
21+
}

bcda/aws/parameters.go

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,24 @@
11
package bcdaaws
22

33
import (
4+
"context"
45
"fmt"
56

6-
"github.com/aws/aws-sdk-go/aws/session"
7-
"github.com/aws/aws-sdk-go/service/ssm"
7+
"github.com/aws/aws-sdk-go-v2/service/ssm"
88
)
99

10-
// Makes this easier to mock and unit test
11-
var ssmNew = ssm.New
12-
var ssmsvcGetParameter = (*ssm.SSM).GetParameter
13-
var ssmsvcGetParameters = (*ssm.SSM).GetParameters
14-
15-
func GetParameter(s *session.Session, keyname string) (string, error) {
16-
ssmsvc := ssmNew(s)
17-
10+
// Returns the value of a single parameter from the SSM Parameter Store
11+
func GetParameter(ctx context.Context, client *ssm.Client, keyname string) (string, error) {
1812
withDecryption := true
19-
result, err := ssmsvcGetParameter(ssmsvc, &ssm.GetParameterInput{
13+
result, err := client.GetParameter(ctx, &ssm.GetParameterInput{
2014
Name: &keyname,
2115
WithDecryption: &withDecryption,
2216
})
23-
2417
if err != nil {
2518
return "", fmt.Errorf("error retrieving parameter %s from parameter store: %w", keyname, err)
2619
}
2720

2821
val := *result.Parameter.Value
29-
3022
if val == "" {
3123
return "", fmt.Errorf("no parameter store value found for %s", keyname)
3224
}
@@ -35,12 +27,9 @@ func GetParameter(s *session.Session, keyname string) (string, error) {
3527
}
3628

3729
// Returns a list of parameters from the SSM Parameter Store
38-
func GetParameters(s *session.Session, keynames []*string) (map[string]string, error) {
39-
// Create an SSM client and pull down keys from the param store
40-
ssmsvc := ssmNew(s)
41-
30+
func GetParameters(ctx context.Context, client *ssm.Client, keynames []string) (map[string]string, error) {
4231
withDecryption := true
43-
params, err := ssmsvcGetParameters(ssmsvc, &ssm.GetParametersInput{
32+
output, err := client.GetParameters(ctx, &ssm.GetParametersInput{
4433
Names: keynames,
4534
WithDecryption: &withDecryption,
4635
})
@@ -49,19 +38,20 @@ func GetParameters(s *session.Session, keynames []*string) (map[string]string, e
4938
}
5039

5140
// Unknown keys will come back as invalid, make sure we error on them
52-
if len(params.InvalidParameters) > 0 {
41+
if len(output.InvalidParameters) > 0 {
5342
invalidParamsStr := ""
54-
for i := 0; i < len(params.InvalidParameters); i++ {
55-
invalidParamsStr += fmt.Sprintf("%s,\n", *params.InvalidParameters[i])
43+
for i := 0; i < len(output.InvalidParameters); i++ {
44+
invalidParamsStr += fmt.Sprintf("%s,\n", output.InvalidParameters[i])
5645
}
5746
return nil, fmt.Errorf("invalid parameters error: %s", invalidParamsStr)
5847
}
5948

6049
// Build the parameter map that we're going to return
6150
paramMap := make(map[string]string)
6251

63-
for _, item := range params.Parameters {
52+
for _, item := range output.Parameters {
6453
paramMap[*item.Name] = *item.Value
6554
}
55+
6656
return paramMap, nil
6757
}

bcda/aws/parameters_test.go

Lines changed: 38 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -2,146 +2,87 @@ package bcdaaws
22

33
import (
44
"errors"
5-
"fmt"
65
"testing"
76

8-
"github.com/aws/aws-sdk-go/aws"
9-
"github.com/aws/aws-sdk-go/aws/client"
10-
"github.com/aws/aws-sdk-go/service/ssm"
7+
"github.com/CMSgov/bcda-app/bcda/testUtils"
118
"github.com/stretchr/testify/assert"
129
)
1310

1411
func TestGetParameter(t *testing.T) {
1512
key1 := "key1"
16-
parm1 := "parm1"
13+
val1 := "val1"
14+
cleanupParam1 := testUtils.SetParameter(t, key1, val1)
15+
defer cleanupParam1()
1716

1817
tests := []struct {
19-
keyname string
20-
expectedValue string
21-
expectedErr error
22-
ssmNew func(p client.ConfigProvider, cfgs ...*aws.Config) *ssm.SSM
23-
ssmsvcGetParameter func(c *ssm.SSM, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error)
18+
desc string
19+
keyname string
20+
expectedValue string
21+
expectedErr error
2422
}{
2523
{
26-
// Happy path
24+
desc: "Happy path",
2725
keyname: key1,
28-
expectedValue: parm1,
26+
expectedValue: val1,
2927
expectedErr: nil,
30-
ssmNew: func(p client.ConfigProvider, cfgs ...*aws.Config) *ssm.SSM { return nil },
31-
ssmsvcGetParameter: func(c *ssm.SSM, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) {
32-
parm := ssm.Parameter{
33-
Name: &key1, Value: &parm1,
34-
}
35-
getParametersOutput := ssm.GetParameterOutput{Parameter: &parm}
36-
return &getParametersOutput, nil
37-
},
3828
},
3929
{
40-
// GetParameter fails
41-
keyname: key1,
42-
expectedValue: "",
43-
expectedErr: errors.New("error retrieving parameter key1 from parameter store: error"),
44-
ssmNew: func(p client.ConfigProvider, cfgs ...*aws.Config) *ssm.SSM { return nil },
45-
ssmsvcGetParameter: func(c *ssm.SSM, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) {
46-
return nil, errors.New("error")
47-
},
48-
},
49-
{
50-
// Empty parameter
51-
keyname: key1,
30+
desc: "Missing parameter",
31+
keyname: "asdf",
5232
expectedValue: "",
53-
expectedErr: fmt.Errorf("no parameter store value found for %s", key1),
54-
ssmNew: func(p client.ConfigProvider, cfgs ...*aws.Config) *ssm.SSM { return nil },
55-
ssmsvcGetParameter: func(c *ssm.SSM, input *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) {
56-
val := ""
57-
parm := ssm.Parameter{
58-
Name: &key1, Value: &val,
59-
}
60-
61-
getParameterOutput := ssm.GetParameterOutput{Parameter: &parm}
62-
return &getParameterOutput, nil
63-
},
33+
expectedErr: errors.New("error retrieving parameter asdf from parameter store"),
6434
},
6535
}
6636

37+
client := testUtils.TestSSMClient(t, testUtils.TestAWSConfig(t))
6738
for _, test := range tests {
68-
ssmNew = test.ssmNew
69-
ssmsvcGetParameter = test.ssmsvcGetParameter
70-
71-
value, err := GetParameter(nil, test.keyname)
39+
value, err := GetParameter(t.Context(), client, test.keyname)
7240
assert.Equal(t, test.expectedValue, value)
7341

7442
if test.expectedErr == nil {
7543
assert.Nil(t, err)
7644
} else {
77-
assert.Equal(t, test.expectedErr.Error(), err.Error())
45+
assert.Contains(t, err.Error(), test.expectedErr.Error())
7846
}
7947
}
8048
}
8149

8250
func TestGetParameters(t *testing.T) {
8351
key1 := "key1"
8452
key2 := "key2"
85-
parm1 := "parm1"
86-
parm2 := "parm2"
53+
val1 := "val1"
54+
val2 := "val2"
55+
56+
cleanupParam1 := testUtils.SetParameter(t, key1, val1)
57+
cleanupParam2 := testUtils.SetParameter(t, key2, val2)
58+
defer cleanupParam1()
59+
defer cleanupParam2()
8760

8861
tests := []struct {
89-
keys []*string
90-
parms map[string]string
91-
err error
92-
ssmNew func(p client.ConfigProvider, cfgs ...*aws.Config) *ssm.SSM
93-
ssmsvcGetParameters func(c *ssm.SSM, input *ssm.GetParametersInput) (*ssm.GetParametersOutput, error)
62+
desc string
63+
keys []string
64+
vals map[string]string
65+
err error
9466
}{
9567
{
96-
// Happy path
97-
keys: []*string{&key1, &key2},
98-
parms: map[string]string{key1: parm1, key2: parm2},
99-
err: nil,
100-
ssmNew: func(p client.ConfigProvider, cfgs ...*aws.Config) *ssm.SSM { return nil },
101-
ssmsvcGetParameters: func(c *ssm.SSM, input *ssm.GetParametersInput) (*ssm.GetParametersOutput, error) {
102-
parms := []*ssm.Parameter{
103-
{Name: &key1, Value: &parm1},
104-
{Name: &key2, Value: &parm2},
105-
}
106-
getParametersOutput := ssm.GetParametersOutput{Parameters: parms}
107-
return &getParametersOutput, nil
108-
},
109-
},
110-
{
111-
// GetParameters fails
112-
keys: []*string{&key1, &key2},
113-
parms: nil,
114-
err: errors.New("error connecting to parameter store: error"),
115-
ssmNew: func(p client.ConfigProvider, cfgs ...*aws.Config) *ssm.SSM { return nil },
116-
ssmsvcGetParameters: func(c *ssm.SSM, input *ssm.GetParametersInput) (*ssm.GetParametersOutput, error) {
117-
return nil, errors.New("error")
118-
},
68+
desc: "Happy path",
69+
keys: []string{key1, key2},
70+
vals: map[string]string{key1: val1, key2: val2},
71+
err: nil,
11972
},
12073
{
121-
// Invalid parameter
122-
keys: []*string{&key1, &key2},
123-
parms: nil,
124-
err: fmt.Errorf("invalid parameters error: %s,\n", key2),
125-
ssmNew: func(p client.ConfigProvider, cfgs ...*aws.Config) *ssm.SSM { return nil },
126-
ssmsvcGetParameters: func(c *ssm.SSM, input *ssm.GetParametersInput) (*ssm.GetParametersOutput, error) {
127-
parms := []*ssm.Parameter{
128-
{Name: &key1, Value: &parm1},
129-
}
130-
invalidParms := []*string{&key2}
131-
132-
getParametersOutput := ssm.GetParametersOutput{Parameters: parms, InvalidParameters: invalidParms}
133-
return &getParametersOutput, nil
134-
},
74+
desc: "Invalid parameter",
75+
keys: []string{"invalid", key2},
76+
vals: nil,
77+
err: errors.New("invalid parameters error: invalid,\n"),
13578
},
13679
}
13780

81+
client := testUtils.TestSSMClient(t, testUtils.TestAWSConfig(t))
13882
for _, test := range tests {
139-
ssmNew = test.ssmNew
140-
ssmsvcGetParameters = test.ssmsvcGetParameters
141-
142-
parms, err := GetParameters(nil, test.keys)
83+
vals, err := GetParameters(t.Context(), client, test.keys)
14384

144-
assert.Equal(t, test.parms, parms)
85+
assert.Equal(t, test.vals, vals)
14586
assert.Equal(t, test.err, err)
14687
}
14788
}

bcda/aws/session.go

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)