Skip to content

Commit

Permalink
refactor: Split aws.go into multiple files
Browse files Browse the repository at this point in the history
Signed-off-by: Maximilian Blatt (external expert on behalf of DB Netz) <maximilian.blatt-extern@deutschebahn.com>
  • Loading branch information
MisterMX committed Aug 4, 2023
1 parent 6633d84 commit e730142
Show file tree
Hide file tree
Showing 23 changed files with 2,078 additions and 1,785 deletions.
1,272 changes: 0 additions & 1,272 deletions pkg/clients/aws_test.go

This file was deleted.

507 changes: 1 addition & 506 deletions pkg/clients/aws.go → pkg/clients/config.go

Large diffs are not rendered by default.

586 changes: 586 additions & 0 deletions pkg/clients/config_test.go

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions pkg/clients/ec2/cidr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
Copyright 2023 The Crossplane Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package ec2

import (
"net"
)

// CIDRBlocksEqual returns whether or not two CIDR blocks are equal:
// - Both CIDR blocks parse to an IP address and network
// - The string representation of the IP addresses are equal
// - The string representation of the networks are equal
func CIDRBlocksEqual(cidr1, cidr2 string) bool {
ip1, ipnet1, err := net.ParseCIDR(cidr1)
if err != nil {
return false
}
ip2, ipnet2, err := net.ParseCIDR(cidr2)
if err != nil {
return false
}

return ip2.String() == ip1.String() && ipnet2.String() == ipnet1.String()
}
51 changes: 51 additions & 0 deletions pkg/clients/ec2/tags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
Copyright 2023 The Crossplane Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package ec2

import (
"github.com/aws/aws-sdk-go-v2/aws"

ec2type "github.com/aws/aws-sdk-go-v2/service/ec2/types"
)

// DiffEC2Tags returns []ec2type.Tag that should be added or removed.
func DiffEC2Tags(local []ec2type.Tag, remote []ec2type.Tag) (add []ec2type.Tag, remove []ec2type.Tag) {
var tagsToAdd = make(map[string]string, len(local))
add = []ec2type.Tag{}
remove = []ec2type.Tag{}
for _, j := range local {
tagsToAdd[aws.ToString(j.Key)] = aws.ToString(j.Value)
}
for _, j := range remote {
switch val, ok := tagsToAdd[aws.ToString(j.Key)]; {
case ok && val == aws.ToString(j.Value):
delete(tagsToAdd, aws.ToString(j.Key))
case !ok:
remove = append(remove, ec2type.Tag{
Key: j.Key,
Value: nil,
})
}
}
for i, j := range tagsToAdd {
add = append(add, ec2type.Tag{
Key: aws.String(i),
Value: aws.String(j),
})
}
return
}
253 changes: 253 additions & 0 deletions pkg/clients/ec2/tags_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
/*
Copyright 2023 The Crossplane Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package ec2

import (
"testing"

"github.com/aws/aws-sdk-go-v2/aws"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/aws/smithy-go/document"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"k8s.io/utils/pointer"
)

func TestDiffEC2Tags(t *testing.T) {
type args struct {
local []ec2types.Tag
remote []ec2types.Tag
}
type want struct {
add []ec2types.Tag
remove []ec2types.Tag
}
cases := map[string]struct {
args
want
}{
"EmptyLocalAndRemote": {
args: args{
local: []ec2types.Tag{},
remote: []ec2types.Tag{},
},
want: want{
add: []ec2types.Tag{},
remove: []ec2types.Tag{},
},
},
"TagsWithSameKeyValuesAndLength": {
args: args{
local: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
},
remote: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
},
},
want: want{
add: []ec2types.Tag{},
remove: []ec2types.Tag{},
},
},
"TagsWithSameKeyDifferentValuesAndSameLength": {
args: args{
local: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
},
remote: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somenames"),
},
},
},
want: want{
add: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
},
remove: []ec2types.Tag{},
},
},
"EmptyRemoteAndMultipleInputs": {
args: args{
local: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
{
Key: aws.String("tags"),
Value: aws.String("True"),
},
},
remote: []ec2types.Tag{},
},
want: want{
add: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
{
Key: aws.String("tags"),
Value: aws.String("True"),
},
},
remove: []ec2types.Tag{},
},
},
"EmptyLocalAndMultipleRemote": {
args: args{
local: []ec2types.Tag{},
remote: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
{
Key: aws.String("tags"),
Value: aws.String("True"),
},
},
},
want: want{
add: []ec2types.Tag{},
remove: []ec2types.Tag{
{
Key: aws.String("name"),
Value: nil,
},
{
Key: aws.String("tags"),
Value: nil,
},
},
},
},
"LocalHaveMoreTags": {
args: args{
local: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
{
Key: aws.String("tags"),
Value: aws.String("True"),
},
},
remote: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
{
Key: aws.String("val"),
Value: aws.String("key"),
},
{
Key: aws.String("val1"),
Value: aws.String("key2"),
},
},
},
want: want{
add: []ec2types.Tag{
{
Key: aws.String("tags"),
Value: aws.String("True"),
},
},
remove: []ec2types.Tag{
{
Key: aws.String("val"),
Value: nil,
},
{
Key: aws.String("val1"),
Value: nil,
},
},
},
},
"RemoteHaveMoreTags": {
args: args{
local: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
{
Key: aws.String("val"),
Value: aws.String("key"),
},
},
remote: []ec2types.Tag{
{
Key: aws.String("name"),
Value: aws.String("somename"),
},
{
Key: aws.String("tags"),
Value: aws.String("True"),
},
{
Key: aws.String("val"),
Value: aws.String("key"),
},
},
},
want: want{
add: []ec2types.Tag{},
remove: []ec2types.Tag{
{
Key: aws.String("tags"),
Value: nil,
},
},
},
},
}

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
tagCmp := cmpopts.SortSlices(func(i, j ec2types.Tag) bool {
return pointer.StringDeref(i.Key, "") < pointer.StringDeref(j.Key, "")
})
add, remove := DiffEC2Tags(tc.args.local, tc.args.remote)
if diff := cmp.Diff(tc.want.add, add, tagCmp, cmpopts.IgnoreTypes(document.NoSerde{})); diff != "" {
t.Errorf("r: -want, +got:\n%s", diff)
}
if diff := cmp.Diff(tc.want.remove, remove, tagCmp, cmpopts.IgnoreTypes(document.NoSerde{})); diff != "" {
t.Errorf("r: -want, +got:\n%s", diff)
}
})
}
}
50 changes: 50 additions & 0 deletions pkg/clients/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
Copyright 2023 The Crossplane Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package aws

import (
"strings"

"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/smithy-go"
"github.com/pkg/errors"
)

// Wrap will remove the request-specific information from the error and only then
// wrap it.
func Wrap(err error, msg string) error {
// NOTE(muvaf): nil check is done for performance, otherwise errors.As makes
// a few reflection calls before returning false, letting awsErr be nil.
if err == nil {
return nil
}
var awsErr smithy.APIError
if errors.As(err, &awsErr) {
return errors.Wrap(awsErr, msg)
}
// AWS SDK v1 uses different interfaces than v2 and it doesn't unwrap to
// the underlying error. So, we need to strip off the unique request ID
// manually.
if v1RequestError, ok := err.(awserr.RequestFailure); ok { //nolint:errorlint
// TODO(negz): This loses context about the underlying error
// type, preventing us from using errors.As to figure out what
// kind of error it is. Could we do this without losing
// context?
return errors.Wrap(errors.New(strings.ReplaceAll(err.Error(), v1RequestError.RequestID(), "")), msg)
}
return errors.Wrap(err, msg)
}
Loading

0 comments on commit e730142

Please sign in to comment.