Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions internal/database/convert_any.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (

azcorearm "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"

"github.com/Azure/ARO-HCP/internal/api"
"github.com/Azure/ARO-HCP/internal/api/fleet"
"github.com/Azure/ARO-HCP/internal/api/kubeapplier"
"github.com/Azure/ARO-HCP/internal/utils"
Expand All @@ -30,15 +29,6 @@ func CosmosToInternal[InternalAPIType, CosmosAPIType any](obj *CosmosAPIType) (*
var internalObj any
var err error
switch cosmosObj := any(obj).(type) {
case *ExternalAuth:
internalObj, err = CosmosToInternalExternalAuth(cosmosObj)

case *HCPCluster:
internalObj, err = CosmosToInternalCluster(cosmosObj)

case *NodePool:
internalObj, err = CosmosToInternalNodePool(cosmosObj)

case *TypedDocument:
var expectedObj InternalAPIType
switch castObj := any(expectedObj).(type) {
Expand Down Expand Up @@ -86,14 +76,6 @@ func InternalToCosmos[InternalAPIType, CosmosAPIType any](obj *InternalAPIType)
var cosmosObj any
var err error
switch internalObj := any(obj).(type) {
case *api.HCPOpenShiftClusterExternalAuth:
cosmosObj, err = InternalToCosmosExternalAuth(internalObj)

case *api.HCPOpenShiftCluster:
cosmosObj, err = InternalToCosmosCluster(internalObj)

case *api.HCPOpenShiftClusterNodePool:
cosmosObj, err = InternalToCosmosNodePool(internalObj)

case *fleet.Stamp:
cosmosObj, err = InternalToCosmosFleet(internalObj)
Expand Down
100 changes: 0 additions & 100 deletions internal/database/convert_cluster.go

This file was deleted.

180 changes: 0 additions & 180 deletions internal/database/convert_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,191 +15,11 @@
package database

import (
"bytes"
"encoding/json"
"math/rand"
"strings"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"

"k8s.io/apimachinery/pkg/api/equality"

"sigs.k8s.io/randfill"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
azcorearm "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"

"github.com/Azure/ARO-HCP/internal/api"
"github.com/Azure/ARO-HCP/internal/api/arm"
)

// fuzzerFor can randomly populate api objects that are destined for version.
func fuzzerFor(funcs []interface{}, src rand.Source) *randfill.Filler {
f := randfill.New().NilChance(.5).NumElements(0, 1)
if src != nil {
f.RandSource(src)
}
f.Funcs(funcs...)
return f
}

func TestRoundTripClusterInternalCosmosInternal(t *testing.T) {
seed := rand.Int63()
t.Logf("seed: %d", seed)

fuzzer := fuzzerFor([]interface{}{
func(j *azcorearm.ResourceID, c randfill.Continue) {
*j = *api.Must(azcorearm.ParseResourceID("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg"))
},
func(j *arm.Resource, c randfill.Continue) {
c.FillNoCustom(j)
j.ID = api.Must(azcorearm.ParseResourceID("/subscriptions/0465bc32-c654-41b8-8d87-9815d7abe8f6/resourceGroups/some-resource-group/providers/Microsoft.RedHatOpenShift/hcpOpenShiftClusters/change-channel"))
j.Name = "change-channel"
j.Type = "Microsoft.RedHatOpenShift/hcpOpenShiftClusters"
},
func(j *api.HCPOpenShiftClusterServiceProviderProperties, c randfill.Continue) {
c.FillNoCustom(j)
if j == nil {
return
}
// we must always have an internal ID
foo := api.Must(api.NewInternalID("/api/clusters_mgmt/v1/clusters/r" + strings.ReplaceAll(c.String(10), "/", "-")))
j.ClusterServiceID = &foo
},
func(j *api.CosmosMetadata, c randfill.Continue) {
c.FillNoCustom(j)
j.ResourceID = api.Must(azcorearm.ParseResourceID("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg"))
j.ExistingCosmosUID = ""
j.CosmosETag = ""
},
func(j *api.HCPOpenShiftCluster, c randfill.Continue) {
c.FillNoCustom(j)
if j == nil {
return
}
// Canonical defaults are applied on Cosmos read, so ensure
// defaulted fields are never zero during round-trip testing.
if len(j.CustomerProperties.Network.NetworkType) == 0 {
j.CustomerProperties.Network.NetworkType = api.NetworkTypeOVNKubernetes
}
if len(j.CustomerProperties.API.Visibility) == 0 {
j.CustomerProperties.API.Visibility = api.VisibilityPublic
}
if len(j.CustomerProperties.Platform.OutboundType) == 0 {
j.CustomerProperties.Platform.OutboundType = api.OutboundTypeLoadBalancer
}
if len(j.CustomerProperties.ClusterImageRegistry.State) == 0 {
j.CustomerProperties.ClusterImageRegistry.State = api.ClusterImageRegistryStateEnabled
}
if len(j.CustomerProperties.Etcd.DataEncryption.KeyManagementMode) == 0 {
j.CustomerProperties.Etcd.DataEncryption.KeyManagementMode = api.EtcdDataEncryptionKeyManagementModeTypePlatformManaged
}
if j.CustomerProperties.Etcd.DataEncryption.CustomerManaged != nil &&
j.CustomerProperties.Etcd.DataEncryption.CustomerManaged.Kms != nil &&
len(j.CustomerProperties.Etcd.DataEncryption.CustomerManaged.Kms.Visibility) == 0 {
j.CustomerProperties.Etcd.DataEncryption.CustomerManaged.Kms.Visibility = api.KeyVaultVisibilityPublic
}
for i := range j.CustomerProperties.ImageDigestMirrors {
if len(j.CustomerProperties.ImageDigestMirrors[i].MirrorSourcePolicy) == 0 {
j.CustomerProperties.ImageDigestMirrors[i].MirrorSourcePolicy = api.MirrorSourcePolicyAllowContactingSource
}
}
},
func(j *arm.ManagedServiceIdentity, c randfill.Continue) {
c.FillNoCustom(j)

// we only round trip keys, so only fill in keys
if j != nil && j.UserAssignedIdentities != nil {
for k := range j.UserAssignedIdentities {
j.UserAssignedIdentities[k] = nil
}
}
},
}, rand.NewSource(seed))

// Try a few times, since runTest uses random values.
for i := 0; i < 20; i++ {
original := &api.HCPOpenShiftCluster{}
fuzzer.Fill(original)
roundTripInternalToCosmosToInternal[api.HCPOpenShiftCluster, HCPCluster](t, original)
}
}

func roundTripInternalToCosmosToInternal[InternalAPIType, CosmosAPIType any](t *testing.T, original *InternalAPIType) {
originalBeforeJSON, _ := json.MarshalIndent(original, "", " ")

intermediate, err := InternalToCosmos[InternalAPIType, CosmosAPIType](original)
require.NoError(t, err)
intermediateBeforeJSON, _ := json.MarshalIndent(intermediate, "", " ")

final, err := CosmosToInternal[InternalAPIType, CosmosAPIType](intermediate)
require.NoError(t, err)

// this value is set during conversion, so we need clear for comparison
switch cast := any(final).(type) {
case *api.HCPOpenShiftCluster:
cast.ExistingCosmosUID = ""
case *api.HCPOpenShiftClusterNodePool:
cast.ExistingCosmosUID = ""
case *api.HCPOpenShiftClusterExternalAuth:
cast.ExistingCosmosUID = ""
}
//finalJSON, _ := json.MarshalIndent(final, "", " ")

// we compare the JSON here because many of these types have private fields that cannot be introspected
if !equality.Semantic.DeepEqual(original, final) {
//t.Logf("original\n%s", string(originalBeforeJSON))
//t.Logf("intermediate\n%s", string(intermediateBeforeJSON))
//t.Logf("final\n%s", string(finalJSON))
t.Errorf("Round trip failed: %v", cmp.Diff(original, final, api.CmpDiffOptions...))
}

// now check to be sure we didn't mutate the originals. The copies still aren't deep, but at least we didn't nuke the inputs
originalAfterJSON, _ := json.MarshalIndent(original, "", " ")
if !bytes.Equal(originalBeforeJSON, originalAfterJSON) {
t.Logf("original\n%s", string(originalBeforeJSON))
t.Logf("originalAfter\n%s", string(originalAfterJSON))
t.Errorf("original was modified: %v", cmp.Diff(originalBeforeJSON, originalAfterJSON))
}

// now check to be sure we didn't mutate the originals. The copies still aren't deep, but at least we didn't nuke the inputs
intermediateAfterJSON, _ := json.MarshalIndent(intermediate, "", " ")
if !bytes.Equal(intermediateBeforeJSON, intermediateAfterJSON) {
t.Logf("intermediate\n%s", string(intermediateBeforeJSON))
t.Logf("intermediateAfter\n%s", string(intermediateAfterJSON))
t.Errorf("intermediate was modified: %v", cmp.Diff(intermediateBeforeJSON, intermediateAfterJSON))
}
}

func TestCosmosToInternalClusterPreservesETag(t *testing.T) {
expectedETag := azcore.ETag("test-etag-value-12345")
resourceID := api.Must(azcorearm.ParseResourceID("/subscriptions/0465bc32-c654-41b8-8d87-9815d7abe8f6/resourceGroups/rg/providers/Microsoft.RedHatOpenShift/hcpOpenShiftClusters/my-cluster"))

cosmosObj := &HCPCluster{
TypedDocument: TypedDocument{
BaseDocument: BaseDocument{
CosmosETag: expectedETag,
},
},
HCPClusterProperties: HCPClusterProperties{
HCPOpenShiftCluster: api.HCPOpenShiftCluster{
CosmosMetadata: arm.CosmosMetadata{
ResourceID: resourceID,
},
},
IntermediateResourceDoc: &ResourceDocument{
ResourceID: resourceID,
},
},
}

internalObj, err := CosmosToInternalCluster(cosmosObj)
require.NoError(t, err)
require.Equal(t, expectedETag, internalObj.GetCosmosData().CosmosETag)
}

func TestClusterEnsureDefaults(t *testing.T) {
tests := []struct {
name string
Expand Down
Loading