-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CLOUDP-280230: Network peering translation layer (#1884)
* Fix indirect go mod ref and update licenses * CLOUDP-280230: Network peering translation layer * Improve contract test helper Signed-off-by: jose.vazquez <[email protected]> * Add network peering contract tests Signed-off-by: jose.vazquez <[email protected]> --------- Signed-off-by: jose.vazquez <[email protected]>
- Loading branch information
Showing
21 changed files
with
1,294 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
100644 8b729a99c24b7dbc21e36509be5899392215190f go.mod | ||
100644 c22a2d48ac68bce318aa0942dfd8a5366a68e291 go.mod |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
package networkpeering | ||
|
||
import ( | ||
"fmt" | ||
|
||
"go.mongodb.org/atlas-sdk/v20231115008/admin" | ||
|
||
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/pointer" | ||
akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" | ||
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/provider" | ||
) | ||
|
||
type NetworkPeer struct { | ||
akov2.AtlasNetworkPeeringConfig | ||
ID string | ||
} | ||
|
||
func NewNetworkPeer(id string, cfg *akov2.AtlasNetworkPeeringConfig) *NetworkPeer { | ||
return &NetworkPeer{ | ||
AtlasNetworkPeeringConfig: *cfg, | ||
ID: id, | ||
} | ||
} | ||
|
||
type ProviderContainer struct { | ||
akov2.AtlasProviderContainerConfig | ||
ID string | ||
Provider string | ||
} | ||
|
||
func NewProviderContainer(id string, provider string, cfg *akov2.AtlasProviderContainerConfig) *ProviderContainer { | ||
return &ProviderContainer{ | ||
AtlasProviderContainerConfig: *cfg, | ||
ID: id, | ||
Provider: provider, | ||
} | ||
} | ||
|
||
func toAtlasConnection(peer *NetworkPeer) (*admin.BaseNetworkPeeringConnectionSettings, error) { | ||
switch peer.Provider { | ||
case string(provider.ProviderAWS): | ||
if peer.AWSConfiguration == nil { | ||
return nil, fmt.Errorf("unsupported AWS peer with AWSConfiguration unset") | ||
} | ||
return &admin.BaseNetworkPeeringConnectionSettings{ | ||
ContainerId: peer.ContainerID, | ||
ProviderName: pointer.SetOrNil(peer.Provider, ""), | ||
AccepterRegionName: pointer.SetOrNil(peer.AWSConfiguration.AccepterRegionName, ""), | ||
AwsAccountId: pointer.SetOrNil(peer.AWSConfiguration.AWSAccountID, ""), | ||
RouteTableCidrBlock: pointer.SetOrNil(peer.AWSConfiguration.RouteTableCIDRBlock, ""), | ||
VpcId: pointer.SetOrNil(peer.AWSConfiguration.VpcID, ""), | ||
}, nil | ||
case string(provider.ProviderGCP): | ||
if peer.GCPConfiguration == nil { | ||
return nil, fmt.Errorf("unsupported Google peer with GCPConfiguration unset") | ||
} | ||
return &admin.BaseNetworkPeeringConnectionSettings{ | ||
ContainerId: peer.ContainerID, | ||
ProviderName: pointer.SetOrNil(peer.Provider, ""), | ||
GcpProjectId: pointer.SetOrNil(peer.GCPConfiguration.GCPProjectID, ""), | ||
NetworkName: pointer.SetOrNil(peer.GCPConfiguration.NetworkName, ""), | ||
}, nil | ||
case string(provider.ProviderAzure): | ||
if peer.AzureConfiguration == nil { | ||
return nil, fmt.Errorf("unsupported Azure peer with AzureConfiguration unset") | ||
} | ||
return &admin.BaseNetworkPeeringConnectionSettings{ | ||
ContainerId: peer.ContainerID, | ||
ProviderName: pointer.SetOrNil(peer.Provider, ""), | ||
AzureDirectoryId: pointer.SetOrNil(peer.AzureConfiguration.AzureDirectoryID, ""), | ||
AzureSubscriptionId: pointer.SetOrNil(peer.AzureConfiguration.AzureSubscriptionID, ""), | ||
ResourceGroupName: pointer.SetOrNil(peer.AzureConfiguration.ResourceGroupName, ""), | ||
VnetName: pointer.SetOrNil(peer.AzureConfiguration.VNetName, ""), | ||
}, nil | ||
default: | ||
return nil, fmt.Errorf("unsupported provider %q", peer.Provider) | ||
} | ||
} | ||
|
||
func fromAtlasConnection(conn *admin.BaseNetworkPeeringConnectionSettings) (*NetworkPeer, error) { | ||
switch provider.ProviderName(conn.GetProviderName()) { | ||
case provider.ProviderAWS: | ||
return &NetworkPeer{ | ||
ID: conn.GetId(), | ||
AtlasNetworkPeeringConfig: akov2.AtlasNetworkPeeringConfig{ | ||
ContainerID: conn.GetContainerId(), | ||
Provider: conn.GetProviderName(), | ||
AWSConfiguration: &akov2.AWSNetworkPeeringConfiguration{ | ||
AccepterRegionName: conn.GetAccepterRegionName(), | ||
AWSAccountID: conn.GetAwsAccountId(), | ||
RouteTableCIDRBlock: conn.GetRouteTableCidrBlock(), | ||
VpcID: conn.GetVpcId(), | ||
}, | ||
}, | ||
}, nil | ||
case provider.ProviderGCP: | ||
return &NetworkPeer{ | ||
ID: conn.GetId(), | ||
AtlasNetworkPeeringConfig: akov2.AtlasNetworkPeeringConfig{ | ||
ContainerID: conn.GetContainerId(), | ||
Provider: conn.GetProviderName(), | ||
GCPConfiguration: &akov2.GCPNetworkPeeringConfiguration{ | ||
GCPProjectID: conn.GetGcpProjectId(), | ||
NetworkName: conn.GetNetworkName(), | ||
}, | ||
}, | ||
}, nil | ||
case provider.ProviderAzure: | ||
return &NetworkPeer{ | ||
ID: conn.GetId(), | ||
AtlasNetworkPeeringConfig: akov2.AtlasNetworkPeeringConfig{ | ||
ContainerID: conn.GetContainerId(), | ||
Provider: conn.GetProviderName(), | ||
AzureConfiguration: &akov2.AzureNetworkPeeringConfiguration{ | ||
AzureDirectoryID: conn.GetAzureDirectoryId(), | ||
AzureSubscriptionID: conn.GetAzureSubscriptionId(), | ||
ResourceGroupName: conn.GetResourceGroupName(), | ||
VNetName: conn.GetVnetName(), | ||
}, | ||
}, | ||
}, nil | ||
default: | ||
return nil, fmt.Errorf("unsupported provider %q", conn.GetProviderName()) | ||
} | ||
} | ||
|
||
func fromAtlasConnectionList(list []admin.BaseNetworkPeeringConnectionSettings) ([]NetworkPeer, error) { | ||
if list == nil { | ||
return nil, nil | ||
} | ||
peers := make([]NetworkPeer, 0, len(list)) | ||
for i, conn := range list { | ||
c, err := fromAtlasConnection(&conn) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to convert connection list item %d: %w", i, err) | ||
} | ||
peers = append(peers, *c) | ||
} | ||
return peers, nil | ||
} | ||
|
||
func toAtlasContainer(container *ProviderContainer) *admin.CloudProviderContainer { | ||
cpc := &admin.CloudProviderContainer{ | ||
Id: pointer.SetOrNil(container.ID, ""), | ||
ProviderName: pointer.SetOrNil(container.Provider, ""), | ||
AtlasCidrBlock: pointer.SetOrNil(container.AtlasCIDRBlock, ""), | ||
} | ||
if cpc.GetProviderName() == string(provider.ProviderAWS) { | ||
cpc.RegionName = pointer.SetOrNil(container.ContainerRegion, "") | ||
} else { | ||
cpc.Region = pointer.SetOrNil(container.ContainerRegion, "") | ||
} | ||
return cpc | ||
} | ||
|
||
func fromAtlasContainer(container *admin.CloudProviderContainer) *ProviderContainer { | ||
region := container.GetRegion() | ||
if container.GetProviderName() == string(provider.ProviderAWS) { | ||
region = container.GetRegionName() | ||
} | ||
return &ProviderContainer{ | ||
ID: container.GetId(), | ||
Provider: container.GetProviderName(), | ||
AtlasProviderContainerConfig: akov2.AtlasProviderContainerConfig{ | ||
AtlasCIDRBlock: container.GetAtlasCidrBlock(), | ||
ContainerRegion: region, | ||
}, | ||
} | ||
} | ||
|
||
func fromAtlasContainerList(list []admin.CloudProviderContainer) []ProviderContainer { | ||
if list == nil { | ||
return nil | ||
} | ||
containers := make([]ProviderContainer, 0, len(list)) | ||
for _, container := range list { | ||
containers = append(containers, *fromAtlasContainer(&container)) | ||
} | ||
return containers | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package networkpeering | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
gofuzz "github.com/google/gofuzz" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
"go.mongodb.org/atlas-sdk/v20231115008/admin" | ||
|
||
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/provider" | ||
) | ||
|
||
const fuzzIterations = 100 | ||
|
||
var providerNames = []string{ | ||
string(provider.ProviderAWS), | ||
string(provider.ProviderAzure), | ||
string(provider.ProviderGCP), | ||
} | ||
|
||
func FuzzConvertConnection(f *testing.F) { | ||
for i := uint(0); i < fuzzIterations; i++ { | ||
f.Add(([]byte)(fmt.Sprintf("seed sample %x", i)), i) | ||
} | ||
f.Fuzz(func(t *testing.T, data []byte, index uint) { | ||
peerData := NetworkPeer{} | ||
gofuzz.NewFromGoFuzz(data).Fuzz(&peerData) | ||
peerData.Provider = providerNames[index%3] | ||
cleanupPeer(&peerData) | ||
atlasConn, err := toAtlasConnection(&peerData) | ||
require.NoError(t, err) | ||
result, err := fromAtlasConnection(atlasConn) | ||
require.NoError(t, err) | ||
assert.Equal(t, &peerData, result, "failed for index=%d", index) | ||
}) | ||
} | ||
|
||
func FuzzConvertListOfConnections(f *testing.F) { | ||
for i := uint(0); i < fuzzIterations; i++ { | ||
f.Add(([]byte)(fmt.Sprintf("seed sample %x", i)), i, (i % 5)) | ||
} | ||
f.Fuzz(func(t *testing.T, data []byte, index uint, size uint) { | ||
conns := []admin.BaseNetworkPeeringConnectionSettings{} | ||
expected := []NetworkPeer{} | ||
for i := uint(0); i < size; i++ { | ||
peerData := NetworkPeer{} | ||
gofuzz.NewFromGoFuzz(data).Fuzz(&peerData) | ||
peerData.Provider = providerNames[index%3] | ||
cleanupPeer(&peerData) | ||
atlasConn, err := toAtlasConnection(&peerData) | ||
require.NoError(t, err) | ||
expectedConn, err := fromAtlasConnection(atlasConn) | ||
require.NoError(t, err) | ||
expected = append(expected, *expectedConn) | ||
atlasConnItem, err := toAtlasConnection(&peerData) | ||
require.NoError(t, err) | ||
conns = append(conns, *atlasConnItem) | ||
} | ||
result, err := fromAtlasConnectionList(conns) | ||
require.NoError(t, err) | ||
assert.Equal(t, expected, result) | ||
}) | ||
} | ||
|
||
func FuzzConvertContainer(f *testing.F) { | ||
for i := uint(0); i < fuzzIterations; i++ { | ||
f.Add(([]byte)(fmt.Sprintf("seed sample %x", i)), i) | ||
} | ||
f.Fuzz(func(t *testing.T, data []byte, index uint) { | ||
containerData := ProviderContainer{} | ||
gofuzz.NewFromGoFuzz(data).Fuzz(&containerData) | ||
containerData.Provider = providerNames[index%3] | ||
result := fromAtlasContainer(toAtlasContainer(&containerData)) | ||
assert.Equal(t, &containerData, result, "failed for index=%d", index) | ||
}) | ||
} | ||
|
||
func FuzzConvertListOfContainers(f *testing.F) { | ||
for i := uint(0); i < fuzzIterations; i++ { | ||
f.Add(([]byte)(fmt.Sprintf("seed sample %x", i)), i, (i % 5)) | ||
} | ||
f.Fuzz(func(t *testing.T, data []byte, index uint, size uint) { | ||
containers := []admin.CloudProviderContainer{} | ||
expected := []ProviderContainer{} | ||
for i := uint(0); i < size; i++ { | ||
containerData := ProviderContainer{} | ||
gofuzz.NewFromGoFuzz(data).Fuzz(&containerData) | ||
containerData.Provider = providerNames[index%3] | ||
expectedContainer := fromAtlasContainer(toAtlasContainer(&containerData)) | ||
expected = append(expected, *expectedContainer) | ||
containers = append(containers, *toAtlasContainer(&containerData)) | ||
} | ||
result := fromAtlasContainerList(containers) | ||
assert.Equal(t, expected, result) | ||
}) | ||
} | ||
|
||
func cleanupPeer(peer *NetworkPeer) { | ||
peer.ID = "" | ||
if peer.Provider != string(provider.ProviderAWS) { | ||
peer.AWSConfiguration = nil | ||
} | ||
if peer.Provider != string(provider.ProviderGCP) { | ||
peer.GCPConfiguration = nil | ||
} | ||
if peer.Provider != string(provider.ProviderAzure) { | ||
peer.AzureConfiguration = nil | ||
} | ||
} |
Oops, something went wrong.