-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Including fuzzing based conversion testing
- Loading branch information
Showing
4 changed files
with
376 additions
and
1 deletion.
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 |
---|---|---|
@@ -0,0 +1,125 @@ | ||
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 ProviderContainer struct { | ||
ID string | ||
ProviderName provider.ProviderName | ||
AtlasCIDRBlock string | ||
RegionName string // AWS | ||
Region string // Azure | ||
} | ||
|
||
func toAtlasConnection(peer *akov2.NetworkPeer) *admin.BaseNetworkPeeringConnectionSettings { | ||
switch peer.ProviderName { | ||
case provider.ProviderAWS: | ||
return &admin.BaseNetworkPeeringConnectionSettings{ | ||
ContainerId: peer.ContainerID, | ||
ProviderName: pointer.SetOrNil(string(peer.ProviderName), ""), | ||
AccepterRegionName: pointer.SetOrNil(peer.AccepterRegionName, ""), | ||
AwsAccountId: pointer.SetOrNil(peer.AWSAccountID, ""), | ||
RouteTableCidrBlock: pointer.SetOrNil(peer.RouteTableCIDRBlock, ""), | ||
VpcId: pointer.SetOrNil(peer.VpcID, ""), | ||
} | ||
case provider.ProviderGCP: | ||
return &admin.BaseNetworkPeeringConnectionSettings{ | ||
ContainerId: peer.ContainerID, | ||
ProviderName: pointer.SetOrNil(string(peer.ProviderName), ""), | ||
GcpProjectId: pointer.SetOrNil(peer.GCPProjectID, ""), | ||
NetworkName: pointer.SetOrNil(peer.NetworkName, ""), | ||
} | ||
case provider.ProviderAzure: | ||
return &admin.BaseNetworkPeeringConnectionSettings{ | ||
ContainerId: peer.ContainerID, | ||
ProviderName: pointer.SetOrNil(string(peer.ProviderName), ""), | ||
AzureDirectoryId: pointer.SetOrNil(peer.AzureDirectoryID, ""), | ||
AzureSubscriptionId: pointer.SetOrNil(peer.AzureSubscriptionID, ""), | ||
ResourceGroupName: pointer.SetOrNil(peer.ResourceGroupName, ""), | ||
VnetName: pointer.SetOrNil(peer.VNetName, ""), | ||
} | ||
default: | ||
panic(fmt.Errorf("unsupported provider %q", peer.ProviderName)) | ||
} | ||
} | ||
|
||
func fromAtlasConnection(conn *admin.BaseNetworkPeeringConnectionSettings) *akov2.NetworkPeer { | ||
switch provider.ProviderName(conn.GetProviderName()) { | ||
case provider.ProviderAWS: | ||
return &akov2.NetworkPeer{ | ||
ContainerID: conn.GetContainerId(), | ||
ProviderName: provider.ProviderName(conn.GetProviderName()), | ||
AccepterRegionName: conn.GetAccepterRegionName(), | ||
AWSAccountID: conn.GetAwsAccountId(), | ||
RouteTableCIDRBlock: conn.GetRouteTableCidrBlock(), | ||
VpcID: conn.GetVpcId(), | ||
} | ||
case provider.ProviderGCP: | ||
return &akov2.NetworkPeer{ | ||
ContainerID: conn.GetContainerId(), | ||
ProviderName: provider.ProviderName(conn.GetProviderName()), | ||
GCPProjectID: conn.GetGcpProjectId(), | ||
NetworkName: conn.GetNetworkName(), | ||
} | ||
case provider.ProviderAzure: | ||
return &akov2.NetworkPeer{ | ||
ContainerID: conn.GetContainerId(), | ||
ProviderName: provider.ProviderName(conn.GetProviderName()), | ||
AzureDirectoryID: conn.GetAzureDirectoryId(), | ||
AzureSubscriptionID: conn.GetAzureSubscriptionId(), | ||
ResourceGroupName: conn.GetResourceGroupName(), | ||
VNetName: conn.GetVnetName(), | ||
} | ||
default: | ||
panic(fmt.Errorf("unsupported provider %q", conn.GetProviderName())) | ||
} | ||
} | ||
|
||
func fromAtlasConnectionList(list []admin.BaseNetworkPeeringConnectionSettings) []akov2.NetworkPeer { | ||
if list == nil { | ||
return nil | ||
} | ||
peers := make([]akov2.NetworkPeer, 0, len(list)) | ||
for _, conn := range list { | ||
peers = append(peers, *fromAtlasConnection(&conn)) | ||
} | ||
return peers | ||
} | ||
|
||
func toAtlasContainer(container *ProviderContainer) *admin.CloudProviderContainer { | ||
return &admin.CloudProviderContainer{ | ||
Id: pointer.SetOrNil(container.ID, ""), | ||
ProviderName: pointer.SetOrNil(string(container.ProviderName), ""), | ||
AtlasCidrBlock: pointer.SetOrNil(container.AtlasCIDRBlock, ""), | ||
RegionName: pointer.SetOrNil(container.RegionName, ""), | ||
Region: pointer.SetOrNil(container.Region, ""), | ||
} | ||
} | ||
|
||
func fromAtlasContainer(container *admin.CloudProviderContainer) *ProviderContainer { | ||
return &ProviderContainer{ | ||
ID: container.GetId(), | ||
ProviderName: provider.ProviderName(container.GetProviderName()), | ||
AtlasCIDRBlock: container.GetAtlasCidrBlock(), | ||
RegionName: container.GetRegionName(), | ||
Region: container.GetRegion(), | ||
} | ||
} | ||
|
||
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,120 @@ | ||
package networkpeering | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
gofuzz "github.com/google/gofuzz" | ||
"github.com/stretchr/testify/assert" | ||
"go.mongodb.org/atlas-sdk/v20231115008/admin" | ||
|
||
akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1" | ||
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/provider" | ||
) | ||
|
||
const fuzzIterations = 100 | ||
|
||
var providerNames = []provider.ProviderName{ | ||
provider.ProviderAWS, | ||
provider.ProviderAzure, | ||
provider.ProviderGCP, | ||
} | ||
|
||
func FuzzConvertConnection(f *testing.F) { | ||
for i := 0; i < fuzzIterations; i++ { | ||
f.Add(([]byte)(fmt.Sprintf("seed sample %x", i)), i) | ||
} | ||
f.Fuzz(func(t *testing.T, data []byte, index int) { | ||
peerData := akov2.NetworkPeer{} | ||
gofuzz.NewFromGoFuzz(data).Fuzz(&peerData) | ||
peerData.ProviderName = providerNames[index%3] | ||
cleanupPeer(&peerData) | ||
result := fromAtlasConnection(toAtlasConnection(&peerData)) | ||
assert.Equal(t, &peerData, result, "failed for index=%d", index) | ||
}) | ||
} | ||
|
||
func FuzzConvertConnectionList(f *testing.F) { | ||
for i := 0; i < fuzzIterations; i++ { | ||
f.Add(([]byte)(fmt.Sprintf("seed sample %x", i)), i, (i%5)-1) | ||
} | ||
f.Fuzz(func(t *testing.T, data []byte, index int, size int) { | ||
conns := []admin.BaseNetworkPeeringConnectionSettings{} | ||
expected := []akov2.NetworkPeer{} | ||
if size < 0 { | ||
conns = nil | ||
expected = nil | ||
} else { | ||
for i := 0; i < size; i++ { | ||
peerData := akov2.NetworkPeer{} | ||
gofuzz.NewFromGoFuzz(data).Fuzz(&peerData) | ||
peerData.ProviderName = providerNames[index%3] | ||
cleanupPeer(&peerData) | ||
expectedConn := fromAtlasConnection(toAtlasConnection(&peerData)) | ||
expected = append(expected, *expectedConn) | ||
conns = append(conns, *toAtlasConnection(&peerData)) | ||
} | ||
} | ||
result := fromAtlasConnectionList(conns) | ||
assert.Equal(t, expected, result) | ||
}) | ||
} | ||
|
||
func FuzzConvertContainer(f *testing.F) { | ||
for i := 0; i < fuzzIterations; i++ { | ||
f.Add(([]byte)(fmt.Sprintf("seed sample %x", i)), i) | ||
} | ||
f.Fuzz(func(t *testing.T, data []byte, index int) { | ||
containerData := ProviderContainer{} | ||
gofuzz.NewFromGoFuzz(data).Fuzz(&containerData) | ||
containerData.ProviderName = providerNames[index%3] | ||
result := fromAtlasContainer(toAtlasContainer(&containerData)) | ||
assert.Equal(t, &containerData, result, "failed for index=%d", index) | ||
}) | ||
} | ||
|
||
func FuzzConvertContainerList(f *testing.F) { | ||
for i := 0; i < fuzzIterations; i++ { | ||
f.Add(([]byte)(fmt.Sprintf("seed sample %x", i)), i, (i%5)-1) | ||
} | ||
f.Fuzz(func(t *testing.T, data []byte, index int, size int) { | ||
containers := []admin.CloudProviderContainer{} | ||
expected := []ProviderContainer{} | ||
if size < 0 { | ||
containers = nil | ||
expected = nil | ||
} else { | ||
for i := 0; i < size; i++ { | ||
containerData := ProviderContainer{} | ||
gofuzz.NewFromGoFuzz(data).Fuzz(&containerData) | ||
containerData.ProviderName = 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 *akov2.NetworkPeer) { | ||
peer.ContainerRegion = "" | ||
peer.AtlasCIDRBlock = "" | ||
if peer.ProviderName != provider.ProviderAWS { | ||
peer.AccepterRegionName = "" | ||
peer.AWSAccountID = "" | ||
peer.RouteTableCIDRBlock = "" | ||
peer.VpcID = "" | ||
} | ||
if peer.ProviderName != provider.ProviderGCP { | ||
peer.GCPProjectID = "" | ||
peer.NetworkName = "" | ||
} | ||
if peer.ProviderName != provider.ProviderAzure { | ||
peer.AzureDirectoryID = "" | ||
peer.AzureSubscriptionID = "" | ||
peer.ResourceGroupName = "" | ||
peer.VNetName = "" | ||
} | ||
} |
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,130 @@ | ||
package networkpeering | ||
|
||
import ( | ||
"context" | ||
"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 PeerConnectionsService interface { | ||
CreatePeer(ctx context.Context, projectID string, conn *akov2.NetworkPeer) (*akov2.NetworkPeer, error) | ||
ListPeers(ctx context.Context, projectID string) ([]akov2.NetworkPeer, error) | ||
DeletePeer(ctx context.Context, projectID, containerID string) error | ||
} | ||
|
||
type PeeringContainerService interface { | ||
CreateContainer(ctx context.Context, projectID string, container *ProviderContainer) (*ProviderContainer, error) | ||
GetContainer(ctx context.Context, projectID, containerID string) (*ProviderContainer, error) | ||
ListContainers(ctx context.Context, projectID, providerName string) ([]ProviderContainer, error) | ||
DeleteContainers(ctx context.Context, projectID, containerID string) error | ||
} | ||
|
||
type NetworkPeeringService interface { | ||
PeerConnectionsService | ||
PeeringContainerService | ||
} | ||
|
||
type NetworkPeering struct { | ||
connsService admin.NetworkPeeringApi | ||
containersService admin.NetworkPeeringApi | ||
} | ||
|
||
func (np *NetworkPeering) CreatePeer(ctx context.Context, projectID string, conn *akov2.NetworkPeer) (*akov2.NetworkPeer, error) { | ||
newConn, _, err := np.connsService.CreatePeeringConnection(ctx, projectID, toAtlasConnection(conn)).Execute() | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to create network peer %v: %w", conn, err) | ||
} | ||
return fromAtlasConnection(newConn), nil | ||
} | ||
|
||
func (np *NetworkPeering) ListPeers(ctx context.Context, projectID string) ([]akov2.NetworkPeer, error) { | ||
var peersList []akov2.NetworkPeer | ||
providers := []provider.ProviderName{provider.ProviderAWS, provider.ProviderAzure, provider.ProviderGCP} | ||
for _, providerName := range providers { | ||
peers, err := np.listPeersForProvider(ctx, projectID, providerName) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to list network peers for %s: %w", string(providerName), err) | ||
} | ||
peersList = append(peersList, peers...) | ||
} | ||
return peersList, nil | ||
} | ||
|
||
func (np *NetworkPeering) listPeersForProvider(ctx context.Context, projectID string, providerName provider.ProviderName) ([]akov2.NetworkPeer, error) { | ||
results := []akov2.NetworkPeer{} | ||
pageNum := 1 | ||
listOpts := &admin.ListPeeringConnectionsApiParams{ | ||
GroupId: projectID, | ||
ProviderName: admin.PtrString(string(providerName)), | ||
PageNum: pointer.MakePtr(pageNum), | ||
} | ||
for { | ||
page, _, err := np.connsService.ListPeeringConnectionsWithParams(ctx, listOpts).Execute() | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to list network peers: %w", err) | ||
} | ||
results = append(results, fromAtlasConnectionList(page.GetResults())...) | ||
if len(results) >= page.GetTotalCount() { | ||
return results, nil | ||
} | ||
pageNum += 1 | ||
} | ||
} | ||
|
||
func (np *NetworkPeering) DeletePeer(ctx context.Context, projectID, containerID string) error { | ||
_, _, err := np.connsService.DeletePeeringConnection(ctx, projectID, containerID).Execute() | ||
if err != nil { | ||
return fmt.Errorf("failed to delete peering connection for container %s: %w", containerID, err) | ||
} | ||
return nil | ||
} | ||
|
||
func (np *NetworkPeering) CreateContainer(ctx context.Context, projectID string, container *ProviderContainer) (*ProviderContainer, error) { | ||
newContainer, _, err := np.containersService.CreatePeeringContainer(ctx, projectID, toAtlasContainer(container)).Execute() | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to create peering container %s: %w", container.ID, err) | ||
} | ||
return fromAtlasContainer(newContainer), nil | ||
} | ||
|
||
func (np *NetworkPeering) GetContainer(ctx context.Context, projectID, containerID string) (*ProviderContainer, error) { | ||
container, _, err := np.containersService.GetPeeringContainer(ctx, projectID, containerID).Execute() | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to get container for gcp status %s: %w", containerID, err) | ||
} | ||
return fromAtlasContainer(container), nil | ||
} | ||
|
||
func (np *NetworkPeering) ListContainers(ctx context.Context, projectID, providerName string) ([]ProviderContainer, error) { | ||
results := []ProviderContainer{} | ||
pageNum := 1 | ||
listOpts := &admin.ListPeeringContainerByCloudProviderApiParams{ | ||
GroupId: projectID, | ||
ProviderName: pointer.SetOrNil(providerName, ""), | ||
PageNum: pointer.MakePtr(pageNum), | ||
} | ||
for { | ||
page, _, err := np.containersService.ListPeeringContainerByCloudProviderWithParams(ctx, listOpts).Execute() | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to list containers: %w", err) | ||
} | ||
results = append(results, fromAtlasContainerList(page.GetResults())...) | ||
if len(results) >= page.GetTotalCount() { | ||
return results, nil | ||
} | ||
pageNum += 1 | ||
} | ||
} | ||
|
||
func (np *NetworkPeering) DeleteContainers(ctx context.Context, projectID, containerID string) error { | ||
_, _, err := np.connsService.DeletePeeringContainer(ctx, projectID, containerID).Execute() | ||
if err != nil { | ||
return fmt.Errorf("failed to delete container: %w", err) | ||
} | ||
return nil | ||
} |