mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-27 00:19:36 -05:00
3a5753045e
rules_go added a SIGTERM handler that has a goroutine that survives the scope of the goleak check. Currently, the best known workaround is to ignore this goroutine. https://github.com/uber-go/goleak/issues/119 https://github.com/bazelbuild/rules_go/pull/3749 https://github.com/bazelbuild/rules_go/pull/3827#issuecomment-1894002120
1002 lines
31 KiB
Go
1002 lines
31 KiB
Go
/*
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
package azure
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
|
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
|
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5"
|
|
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5"
|
|
"github.com/edgelesssys/constellation/v2/internal/cloud"
|
|
"github.com/edgelesssys/constellation/v2/internal/cloud/metadata"
|
|
"github.com/edgelesssys/constellation/v2/internal/role"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/goleak"
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
goleak.VerifyTestMain(m, goleak.IgnoreAnyFunction("github.com/bazelbuild/rules_go/go/tools/bzltestutil.RegisterTimeoutHandler.func1"))
|
|
}
|
|
|
|
func TestGetInstance(t *testing.T) {
|
|
someErr := errors.New("failed")
|
|
sampleProviderID := "azure:///subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set-name/virtualMachines/instance-id"
|
|
successVMAPI := &stubVirtualMachineScaleSetVMsAPI{
|
|
getVM: armcompute.VirtualMachineScaleSetVM{
|
|
Name: to.Ptr("scale-set-name-instance-id"),
|
|
ID: to.Ptr("/subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set-name/virtualMachines/instance-id"),
|
|
Properties: &armcompute.VirtualMachineScaleSetVMProperties{
|
|
OSProfile: &armcompute.OSProfile{
|
|
ComputerName: to.Ptr("scale-set-name-instance-id"),
|
|
},
|
|
NetworkProfile: &armcompute.NetworkProfile{
|
|
NetworkInterfaces: []*armcompute.NetworkInterfaceReference{
|
|
{
|
|
ID: to.Ptr("/subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Network/networkInterfaces/nic-name"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Tags: map[string]*string{
|
|
cloud.TagRole: to.Ptr(role.Worker.String()),
|
|
},
|
|
},
|
|
}
|
|
successNetworkAPI := &stubNetworkInterfacesAPI{
|
|
getInterface: armnetwork.Interface{
|
|
Properties: &armnetwork.InterfacePropertiesFormat{
|
|
IPConfigurations: []*armnetwork.InterfaceIPConfiguration{
|
|
{
|
|
Properties: &armnetwork.InterfaceIPConfigurationPropertiesFormat{
|
|
Primary: to.Ptr(true),
|
|
PrivateIPAddress: to.Ptr("192.0.2.1"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
testCases := map[string]struct {
|
|
scaleSetsVMAPI *stubVirtualMachineScaleSetVMsAPI
|
|
networkInterfacesAPI *stubNetworkInterfacesAPI
|
|
IMDSAPI *stubIMDSAPI
|
|
providerID string
|
|
wantInstance metadata.InstanceMetadata
|
|
wantErr bool
|
|
}{
|
|
"success worker": {
|
|
scaleSetsVMAPI: successVMAPI,
|
|
networkInterfacesAPI: successNetworkAPI,
|
|
providerID: sampleProviderID,
|
|
IMDSAPI: &stubIMDSAPI{},
|
|
wantInstance: metadata.InstanceMetadata{
|
|
Name: "scale-set-name-instance-id",
|
|
ProviderID: sampleProviderID,
|
|
Role: role.Worker,
|
|
VPCIP: "192.0.2.1",
|
|
},
|
|
},
|
|
"success control-plane": {
|
|
scaleSetsVMAPI: &stubVirtualMachineScaleSetVMsAPI{
|
|
getVM: armcompute.VirtualMachineScaleSetVM{
|
|
Name: to.Ptr("scale-set-name-instance-id"),
|
|
ID: to.Ptr("/subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set-name/virtualMachines/instance-id"),
|
|
Properties: &armcompute.VirtualMachineScaleSetVMProperties{
|
|
OSProfile: &armcompute.OSProfile{
|
|
ComputerName: to.Ptr("scale-set-name-instance-id"),
|
|
},
|
|
NetworkProfile: &armcompute.NetworkProfile{
|
|
NetworkInterfaces: []*armcompute.NetworkInterfaceReference{
|
|
{
|
|
ID: to.Ptr("/subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Network/networkInterfaces/nic-name"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Tags: map[string]*string{
|
|
cloud.TagRole: to.Ptr(role.ControlPlane.String()),
|
|
},
|
|
},
|
|
},
|
|
IMDSAPI: &stubIMDSAPI{},
|
|
networkInterfacesAPI: successNetworkAPI,
|
|
providerID: sampleProviderID,
|
|
wantInstance: metadata.InstanceMetadata{
|
|
Name: "scale-set-name-instance-id",
|
|
ProviderID: sampleProviderID,
|
|
Role: role.ControlPlane,
|
|
VPCIP: "192.0.2.1",
|
|
},
|
|
},
|
|
"invalid provider ID": {
|
|
scaleSetsVMAPI: successVMAPI,
|
|
IMDSAPI: &stubIMDSAPI{},
|
|
networkInterfacesAPI: successNetworkAPI,
|
|
providerID: "invalid",
|
|
wantErr: true,
|
|
},
|
|
"vm API error": {
|
|
scaleSetsVMAPI: &stubVirtualMachineScaleSetVMsAPI{getErr: someErr},
|
|
IMDSAPI: &stubIMDSAPI{},
|
|
networkInterfacesAPI: successNetworkAPI,
|
|
providerID: sampleProviderID,
|
|
wantErr: true,
|
|
},
|
|
"network API error": {
|
|
scaleSetsVMAPI: successVMAPI,
|
|
networkInterfacesAPI: &stubNetworkInterfacesAPI{getErr: someErr},
|
|
IMDSAPI: &stubIMDSAPI{},
|
|
providerID: sampleProviderID,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
metadata := Cloud{
|
|
imds: tc.IMDSAPI,
|
|
scaleSetsVMAPI: tc.scaleSetsVMAPI,
|
|
netIfacAPI: tc.networkInterfacesAPI,
|
|
}
|
|
instance, err := metadata.getInstance(context.Background(), tc.providerID)
|
|
if tc.wantErr {
|
|
assert.Error(err)
|
|
return
|
|
}
|
|
assert.NoError(err)
|
|
assert.Equal(tc.wantInstance, instance)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUID(t *testing.T) {
|
|
testCases := map[string]struct {
|
|
imdsAPI *stubIMDSAPI
|
|
wantErr bool
|
|
}{
|
|
"success": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
uidVal: "uid",
|
|
},
|
|
},
|
|
"error": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
uidErr: errors.New("failed"),
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
cloud := &Cloud{
|
|
imds: tc.imdsAPI,
|
|
}
|
|
uid, err := cloud.UID(context.Background())
|
|
if tc.wantErr {
|
|
assert.Error(err)
|
|
return
|
|
}
|
|
assert.NoError(err)
|
|
assert.Equal(tc.imdsAPI.uidVal, uid)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestInitSecretHash(t *testing.T) {
|
|
testCases := map[string]struct {
|
|
imdsAPI *stubIMDSAPI
|
|
wantErr bool
|
|
}{
|
|
"success": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
initSecretHashVal: "initSecretHash",
|
|
},
|
|
},
|
|
"error": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
initSecretHashErr: errors.New("failed"),
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
cloud := &Cloud{
|
|
imds: tc.imdsAPI,
|
|
}
|
|
initSecretHash, err := cloud.InitSecretHash(context.Background())
|
|
if tc.wantErr {
|
|
assert.Error(err)
|
|
return
|
|
}
|
|
assert.NoError(err)
|
|
assert.Equal([]byte(tc.imdsAPI.initSecretHashVal), initSecretHash)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestList(t *testing.T) {
|
|
someErr := errors.New("failed")
|
|
networkIfaceResponse := &stubNetworkInterfacesAPI{
|
|
getInterface: armnetwork.Interface{
|
|
Name: to.Ptr("interface-name"),
|
|
Properties: &armnetwork.InterfacePropertiesFormat{
|
|
IPConfigurations: []*armnetwork.InterfaceIPConfiguration{
|
|
{
|
|
Properties: &armnetwork.InterfaceIPConfigurationPropertiesFormat{
|
|
PrivateIPAddress: to.Ptr("192.0.2.0"),
|
|
Primary: to.Ptr(true),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
scaleSetsResponse := &stubScaleSetsAPI{
|
|
pager: &stubVirtualMachineScaleSetsClientListPager{
|
|
list: []armcompute.VirtualMachineScaleSet{{
|
|
Name: to.Ptr("scale-set"),
|
|
Tags: map[string]*string{
|
|
cloud.TagUID: to.Ptr("uid"),
|
|
cloud.TagRole: to.Ptr("worker"),
|
|
},
|
|
}},
|
|
},
|
|
}
|
|
scaleSetVM := armcompute.VirtualMachineScaleSetVM{
|
|
Name: to.Ptr("scale-set_0"),
|
|
InstanceID: to.Ptr("instance-id"),
|
|
ID: to.Ptr("/subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set/virtualMachines/0"),
|
|
Properties: &armcompute.VirtualMachineScaleSetVMProperties{
|
|
NetworkProfile: &armcompute.NetworkProfile{
|
|
NetworkInterfaces: []*armcompute.NetworkInterfaceReference{
|
|
{
|
|
ID: to.Ptr("/subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set/virtualMachines/0/networkInterfaces/interface-name"),
|
|
},
|
|
},
|
|
},
|
|
OSProfile: &armcompute.OSProfile{
|
|
ComputerName: to.Ptr("scale-set-0"),
|
|
},
|
|
},
|
|
Tags: map[string]*string{
|
|
cloud.TagUID: to.Ptr("uid"),
|
|
cloud.TagRole: to.Ptr("worker"),
|
|
},
|
|
}
|
|
|
|
workerInstance := metadata.InstanceMetadata{
|
|
Name: "scale-set-0",
|
|
ProviderID: "azure:///subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/scale-set/virtualMachines/0",
|
|
Role: role.Worker,
|
|
VPCIP: "192.0.2.0",
|
|
}
|
|
|
|
testCases := map[string]struct {
|
|
imdsAPI *stubIMDSAPI
|
|
networkInterfacesAPI *stubNetworkInterfacesAPI
|
|
scaleSetsAPI *stubScaleSetsAPI
|
|
scaleSetsVMAPI *stubVirtualMachineScaleSetVMsAPI
|
|
wantErr bool
|
|
wantInstances []metadata.InstanceMetadata
|
|
}{
|
|
"list single instance": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
networkInterfacesAPI: networkIfaceResponse,
|
|
scaleSetsAPI: scaleSetsResponse,
|
|
scaleSetsVMAPI: &stubVirtualMachineScaleSetVMsAPI{
|
|
pager: &stubVirtualMachineScaleSetVMPager{
|
|
list: []armcompute.VirtualMachineScaleSetVM{scaleSetVM},
|
|
},
|
|
},
|
|
wantInstances: []metadata.InstanceMetadata{workerInstance},
|
|
},
|
|
"list multiple instances": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
networkInterfacesAPI: networkIfaceResponse,
|
|
scaleSetsAPI: scaleSetsResponse,
|
|
scaleSetsVMAPI: &stubVirtualMachineScaleSetVMsAPI{
|
|
pager: &stubVirtualMachineScaleSetVMPager{
|
|
list: []armcompute.VirtualMachineScaleSetVM{
|
|
scaleSetVM,
|
|
{
|
|
Name: to.Ptr("control-set_0"),
|
|
InstanceID: to.Ptr("0"),
|
|
ID: to.Ptr("/subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/control-set/virtualMachines/0"),
|
|
Properties: &armcompute.VirtualMachineScaleSetVMProperties{
|
|
NetworkProfile: &armcompute.NetworkProfile{
|
|
NetworkInterfaces: []*armcompute.NetworkInterfaceReference{
|
|
{
|
|
ID: to.Ptr("/subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/control-set/virtualMachines/0/networkInterfaces/interface-name"),
|
|
},
|
|
},
|
|
},
|
|
OSProfile: &armcompute.OSProfile{
|
|
ComputerName: to.Ptr("control-set-0"),
|
|
},
|
|
},
|
|
Tags: map[string]*string{
|
|
cloud.TagUID: to.Ptr("uid"),
|
|
cloud.TagRole: to.Ptr("control-plane"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantInstances: []metadata.InstanceMetadata{
|
|
workerInstance,
|
|
{
|
|
Name: "control-set-0",
|
|
ProviderID: "azure:///subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/control-set/virtualMachines/0",
|
|
Role: role.ControlPlane,
|
|
VPCIP: "192.0.2.0",
|
|
},
|
|
},
|
|
},
|
|
"imds resource group fails": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupErr: someErr,
|
|
uidVal: "uid",
|
|
},
|
|
networkInterfacesAPI: networkIfaceResponse,
|
|
scaleSetsAPI: scaleSetsResponse,
|
|
scaleSetsVMAPI: &stubVirtualMachineScaleSetVMsAPI{
|
|
pager: &stubVirtualMachineScaleSetVMPager{
|
|
list: []armcompute.VirtualMachineScaleSetVM{scaleSetVM},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
"imds uid fails": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidErr: someErr,
|
|
},
|
|
networkInterfacesAPI: networkIfaceResponse,
|
|
scaleSetsAPI: scaleSetsResponse,
|
|
scaleSetsVMAPI: &stubVirtualMachineScaleSetVMsAPI{
|
|
pager: &stubVirtualMachineScaleSetVMPager{
|
|
list: []armcompute.VirtualMachineScaleSetVM{scaleSetVM},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
"listScaleSetVMs fails": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
networkInterfacesAPI: networkIfaceResponse,
|
|
scaleSetsAPI: scaleSetsResponse,
|
|
scaleSetsVMAPI: &stubVirtualMachineScaleSetVMsAPI{
|
|
pager: &stubVirtualMachineScaleSetVMPager{fetchErr: someErr},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
azureMetadata := Cloud{
|
|
imds: tc.imdsAPI,
|
|
netIfacAPI: tc.networkInterfacesAPI,
|
|
scaleSetsAPI: tc.scaleSetsAPI,
|
|
scaleSetsVMAPI: tc.scaleSetsVMAPI,
|
|
}
|
|
instances, err := azureMetadata.List(context.Background())
|
|
|
|
if tc.wantErr {
|
|
assert.Error(err)
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
assert.ElementsMatch(tc.wantInstances, instances)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetNetworkSecurityGroupName(t *testing.T) {
|
|
name := "network-security-group-name"
|
|
testCases := map[string]struct {
|
|
securityGroupsAPI securityGroupsAPI
|
|
wantName string
|
|
wantErr bool
|
|
}{
|
|
"GetNetworkSecurityGroupName works": {
|
|
securityGroupsAPI: &stubSecurityGroupsAPI{
|
|
pager: &stubSecurityGroupsClientListPager{
|
|
list: []armnetwork.SecurityGroup{
|
|
{
|
|
Tags: map[string]*string{
|
|
cloud.TagUID: to.Ptr("uid"),
|
|
},
|
|
Name: to.Ptr(name),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantName: name,
|
|
},
|
|
"no security group": {
|
|
securityGroupsAPI: &stubSecurityGroupsAPI{
|
|
pager: &stubSecurityGroupsClientListPager{},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
"security group API error": {
|
|
securityGroupsAPI: &stubSecurityGroupsAPI{
|
|
pager: &stubSecurityGroupsClientListPager{fetchErr: errors.New("failed")},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
"missing name in security group struct": {
|
|
securityGroupsAPI: &stubSecurityGroupsAPI{
|
|
pager: &stubSecurityGroupsClientListPager{
|
|
list: []armnetwork.SecurityGroup{{}},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
metadata := Cloud{
|
|
secGroupAPI: tc.securityGroupsAPI,
|
|
}
|
|
name, err := metadata.getNetworkSecurityGroupName(context.Background(), "resource-group", "uid")
|
|
if tc.wantErr {
|
|
assert.Error(err)
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
assert.Equal(tc.wantName, name)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetSubnetworkCIDR(t *testing.T) {
|
|
subnetworkCIDR := "192.0.2.0/24"
|
|
name := "name"
|
|
testCases := map[string]struct {
|
|
virtualNetworksAPI virtualNetworksAPI
|
|
imdsAPI imdsAPI
|
|
wantNetworkCIDR string
|
|
wantErr bool
|
|
}{
|
|
"GetSubnetworkCIDR works": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
virtualNetworksAPI: &stubVirtualNetworksAPI{
|
|
pager: &stubVirtualNetworksClientListPager{
|
|
list: []armnetwork.VirtualNetwork{{
|
|
Name: to.Ptr(name),
|
|
Tags: map[string]*string{
|
|
cloud.TagUID: to.Ptr("uid"),
|
|
},
|
|
Properties: &armnetwork.VirtualNetworkPropertiesFormat{
|
|
Subnets: []*armnetwork.Subnet{
|
|
{Properties: &armnetwork.SubnetPropertiesFormat{AddressPrefix: to.Ptr(subnetworkCIDR)}},
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
wantNetworkCIDR: subnetworkCIDR,
|
|
},
|
|
"no virtual networks found": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
virtualNetworksAPI: &stubVirtualNetworksAPI{
|
|
pager: &stubVirtualNetworksClientListPager{},
|
|
},
|
|
wantErr: true,
|
|
wantNetworkCIDR: subnetworkCIDR,
|
|
},
|
|
"malformed network struct": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
virtualNetworksAPI: &stubVirtualNetworksAPI{
|
|
pager: &stubVirtualNetworksClientListPager{list: []armnetwork.VirtualNetwork{{}}},
|
|
},
|
|
wantErr: true,
|
|
wantNetworkCIDR: subnetworkCIDR,
|
|
},
|
|
}
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
metadata := Cloud{
|
|
imds: tc.imdsAPI,
|
|
virtNetAPI: tc.virtualNetworksAPI,
|
|
}
|
|
subnetworkCIDR, err := metadata.getSubnetworkCIDR(context.Background())
|
|
if tc.wantErr {
|
|
assert.Error(err)
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
assert.Equal(tc.wantNetworkCIDR, subnetworkCIDR)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetLoadBalancerEndpoint(t *testing.T) {
|
|
someErr := errors.New("failed")
|
|
goodLB := armnetwork.LoadBalancer{
|
|
Name: to.Ptr("load-balancer"),
|
|
Tags: map[string]*string{
|
|
cloud.TagUID: to.Ptr("uid"),
|
|
},
|
|
Properties: &armnetwork.LoadBalancerPropertiesFormat{
|
|
FrontendIPConfigurations: []*armnetwork.FrontendIPConfiguration{
|
|
{
|
|
Properties: &armnetwork.FrontendIPConfigurationPropertiesFormat{
|
|
PublicIPAddress: &armnetwork.PublicIPAddress{ID: to.Ptr("/subscriptions/subscription/resourceGroups/resourceGroup/providers/Microsoft.Network/publicIPAddresses/pubIPName")},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
goodIP := armnetwork.PublicIPAddressesClientGetResponse{
|
|
PublicIPAddress: armnetwork.PublicIPAddress{
|
|
Properties: &armnetwork.PublicIPAddressPropertiesFormat{
|
|
IPAddress: to.Ptr("192.0.2.1"),
|
|
},
|
|
},
|
|
}
|
|
|
|
testCases := map[string]struct {
|
|
loadBalancerAPI loadBalancerAPI
|
|
publicIPAddressesAPI publicIPAddressesAPI
|
|
imdsAPI imdsAPI
|
|
wantIP string
|
|
wantErr bool
|
|
}{
|
|
"GetLoadBalancerEndpoint works": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
loadBalancerAPI: &stubLoadBalancersAPI{
|
|
pager: &stubLoadBalancersClientListPager{
|
|
list: []armnetwork.LoadBalancer{goodLB},
|
|
},
|
|
},
|
|
publicIPAddressesAPI: &stubPublicIPAddressesAPI{getResponse: goodIP},
|
|
wantIP: "192.0.2.1",
|
|
},
|
|
"incorrect uid": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
loadBalancerAPI: &stubLoadBalancersAPI{
|
|
pager: &stubLoadBalancersClientListPager{
|
|
list: []armnetwork.LoadBalancer{{
|
|
Name: to.Ptr("load-balancer"),
|
|
Tags: map[string]*string{
|
|
cloud.TagUID: to.Ptr("not-the-searched-uid"),
|
|
},
|
|
Properties: &armnetwork.LoadBalancerPropertiesFormat{
|
|
FrontendIPConfigurations: []*armnetwork.FrontendIPConfiguration{
|
|
{
|
|
Properties: &armnetwork.FrontendIPConfigurationPropertiesFormat{
|
|
PublicIPAddress: &armnetwork.PublicIPAddress{ID: to.Ptr("/subscriptions/subscription/resourceGroups/resourceGroup/providers/Microsoft.Network/publicIPAddresses/pubIPName")},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
publicIPAddressesAPI: &stubPublicIPAddressesAPI{getResponse: goodIP},
|
|
wantErr: true,
|
|
},
|
|
"no load balancer": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
loadBalancerAPI: &stubLoadBalancersAPI{
|
|
pager: &stubLoadBalancersClientListPager{},
|
|
},
|
|
publicIPAddressesAPI: &stubPublicIPAddressesAPI{getResponse: goodIP},
|
|
wantErr: true,
|
|
},
|
|
"no public IP address found": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
loadBalancerAPI: &stubLoadBalancersAPI{
|
|
pager: &stubLoadBalancersClientListPager{
|
|
list: []armnetwork.LoadBalancer{goodLB},
|
|
},
|
|
},
|
|
publicIPAddressesAPI: &stubPublicIPAddressesAPI{getErr: someErr},
|
|
wantErr: true,
|
|
},
|
|
"found public IP has no address field": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidVal: "uid",
|
|
},
|
|
loadBalancerAPI: &stubLoadBalancersAPI{
|
|
pager: &stubLoadBalancersClientListPager{
|
|
list: []armnetwork.LoadBalancer{goodLB},
|
|
},
|
|
},
|
|
publicIPAddressesAPI: &stubPublicIPAddressesAPI{getResponse: armnetwork.PublicIPAddressesClientGetResponse{
|
|
PublicIPAddress: armnetwork.PublicIPAddress{
|
|
Properties: &armnetwork.PublicIPAddressPropertiesFormat{},
|
|
},
|
|
}},
|
|
wantErr: true,
|
|
},
|
|
"imds resource group error": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupErr: someErr,
|
|
uidVal: "uid",
|
|
},
|
|
loadBalancerAPI: &stubLoadBalancersAPI{
|
|
pager: &stubLoadBalancersClientListPager{
|
|
list: []armnetwork.LoadBalancer{goodLB},
|
|
},
|
|
},
|
|
publicIPAddressesAPI: &stubPublicIPAddressesAPI{getResponse: goodIP},
|
|
wantErr: true,
|
|
},
|
|
"imds uid error": {
|
|
imdsAPI: &stubIMDSAPI{
|
|
resourceGroupVal: "resource-group",
|
|
uidErr: someErr,
|
|
},
|
|
loadBalancerAPI: &stubLoadBalancersAPI{
|
|
pager: &stubLoadBalancersClientListPager{
|
|
list: []armnetwork.LoadBalancer{goodLB},
|
|
},
|
|
},
|
|
publicIPAddressesAPI: &stubPublicIPAddressesAPI{getResponse: goodIP},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
metadata := Cloud{
|
|
imds: tc.imdsAPI,
|
|
loadBalancerAPI: tc.loadBalancerAPI,
|
|
pubIPAPI: tc.publicIPAddressesAPI,
|
|
}
|
|
gotHost, gotPort, err := metadata.GetLoadBalancerEndpoint(context.Background())
|
|
if tc.wantErr {
|
|
assert.Error(err)
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
assert.Equal(tc.wantIP, gotHost)
|
|
assert.Equal("6443", gotPort)
|
|
})
|
|
}
|
|
}
|
|
|
|
type stubIMDSAPI struct {
|
|
providerIDErr error
|
|
providerIDVal string
|
|
subscriptionIDErr error
|
|
subscriptionIDVal string
|
|
resourceGroupErr error
|
|
resourceGroupVal string
|
|
uidErr error
|
|
uidVal string
|
|
nameErr error
|
|
nameVal string
|
|
initSecretHashVal string
|
|
initSecretHashErr error
|
|
}
|
|
|
|
func (a *stubIMDSAPI) providerID(_ context.Context) (string, error) {
|
|
return a.providerIDVal, a.providerIDErr
|
|
}
|
|
|
|
func (a *stubIMDSAPI) subscriptionID(_ context.Context) (string, error) {
|
|
return a.subscriptionIDVal, a.subscriptionIDErr
|
|
}
|
|
|
|
func (a *stubIMDSAPI) resourceGroup(_ context.Context) (string, error) {
|
|
return a.resourceGroupVal, a.resourceGroupErr
|
|
}
|
|
|
|
func (a *stubIMDSAPI) uid(_ context.Context) (string, error) {
|
|
return a.uidVal, a.uidErr
|
|
}
|
|
|
|
func (a *stubIMDSAPI) name(_ context.Context) (string, error) {
|
|
return a.nameVal, a.nameErr
|
|
}
|
|
|
|
func (a *stubIMDSAPI) initSecretHash(_ context.Context) (string, error) {
|
|
return a.initSecretHashVal, a.initSecretHashErr
|
|
}
|
|
|
|
type stubVirtualMachineScaleSetVMPager struct {
|
|
list []armcompute.VirtualMachineScaleSetVM
|
|
fetchErr error
|
|
more bool
|
|
}
|
|
|
|
func (p *stubVirtualMachineScaleSetVMPager) moreFunc() func(armcompute.VirtualMachineScaleSetVMsClientListResponse) bool {
|
|
return func(armcompute.VirtualMachineScaleSetVMsClientListResponse) bool {
|
|
return p.more
|
|
}
|
|
}
|
|
|
|
func (p *stubVirtualMachineScaleSetVMPager) fetcherFunc() func(context.Context, *armcompute.VirtualMachineScaleSetVMsClientListResponse,
|
|
) (armcompute.VirtualMachineScaleSetVMsClientListResponse, error) {
|
|
return func(context.Context, *armcompute.VirtualMachineScaleSetVMsClientListResponse) (armcompute.VirtualMachineScaleSetVMsClientListResponse, error) {
|
|
page := make([]*armcompute.VirtualMachineScaleSetVM, len(p.list))
|
|
for i := range p.list {
|
|
page[i] = &p.list[i]
|
|
}
|
|
return armcompute.VirtualMachineScaleSetVMsClientListResponse{
|
|
VirtualMachineScaleSetVMListResult: armcompute.VirtualMachineScaleSetVMListResult{
|
|
Value: page,
|
|
},
|
|
}, p.fetchErr
|
|
}
|
|
}
|
|
|
|
type stubVirtualMachineScaleSetVMsAPI struct {
|
|
getVM armcompute.VirtualMachineScaleSetVM
|
|
getErr error
|
|
pager *stubVirtualMachineScaleSetVMPager
|
|
}
|
|
|
|
func (a *stubVirtualMachineScaleSetVMsAPI) Get(context.Context, string, string, string, *armcompute.VirtualMachineScaleSetVMsClientGetOptions,
|
|
) (armcompute.VirtualMachineScaleSetVMsClientGetResponse, error) {
|
|
return armcompute.VirtualMachineScaleSetVMsClientGetResponse{
|
|
VirtualMachineScaleSetVM: a.getVM,
|
|
}, a.getErr
|
|
}
|
|
|
|
func (a *stubVirtualMachineScaleSetVMsAPI) NewListPager(string, string, *armcompute.VirtualMachineScaleSetVMsClientListOptions,
|
|
) *runtime.Pager[armcompute.VirtualMachineScaleSetVMsClientListResponse] {
|
|
return runtime.NewPager(runtime.PagingHandler[armcompute.VirtualMachineScaleSetVMsClientListResponse]{
|
|
More: a.pager.moreFunc(),
|
|
Fetcher: a.pager.fetcherFunc(),
|
|
})
|
|
}
|
|
|
|
type stubNetworkInterfacesAPI struct {
|
|
getInterface armnetwork.Interface
|
|
getErr error
|
|
}
|
|
|
|
func (a *stubNetworkInterfacesAPI) GetVirtualMachineScaleSetNetworkInterface(context.Context, string,
|
|
string, string, string, *armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceOptions,
|
|
) (armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceResponse, error) {
|
|
return armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceResponse{
|
|
Interface: a.getInterface,
|
|
}, a.getErr
|
|
}
|
|
|
|
func (a *stubNetworkInterfacesAPI) Get(context.Context, string, string, *armnetwork.InterfacesClientGetOptions,
|
|
) (armnetwork.InterfacesClientGetResponse, error) {
|
|
return armnetwork.InterfacesClientGetResponse{
|
|
Interface: a.getInterface,
|
|
}, a.getErr
|
|
}
|
|
|
|
type stubVirtualMachineScaleSetsClientListPager struct {
|
|
list []armcompute.VirtualMachineScaleSet
|
|
fetchErr error
|
|
more bool
|
|
}
|
|
|
|
func (p *stubVirtualMachineScaleSetsClientListPager) moreFunc() func(armcompute.VirtualMachineScaleSetsClientListResponse) bool {
|
|
return func(armcompute.VirtualMachineScaleSetsClientListResponse) bool {
|
|
return p.more
|
|
}
|
|
}
|
|
|
|
func (p *stubVirtualMachineScaleSetsClientListPager) fetcherFunc() func(context.Context, *armcompute.VirtualMachineScaleSetsClientListResponse,
|
|
) (armcompute.VirtualMachineScaleSetsClientListResponse, error) {
|
|
return func(context.Context, *armcompute.VirtualMachineScaleSetsClientListResponse) (armcompute.VirtualMachineScaleSetsClientListResponse, error) {
|
|
page := make([]*armcompute.VirtualMachineScaleSet, len(p.list))
|
|
for i := range p.list {
|
|
page[i] = &p.list[i]
|
|
}
|
|
return armcompute.VirtualMachineScaleSetsClientListResponse{
|
|
VirtualMachineScaleSetListResult: armcompute.VirtualMachineScaleSetListResult{
|
|
Value: page,
|
|
},
|
|
}, p.fetchErr
|
|
}
|
|
}
|
|
|
|
type stubScaleSetsAPI struct {
|
|
pager *stubVirtualMachineScaleSetsClientListPager
|
|
}
|
|
|
|
func (a *stubScaleSetsAPI) NewListPager(string, *armcompute.VirtualMachineScaleSetsClientListOptions,
|
|
) *runtime.Pager[armcompute.VirtualMachineScaleSetsClientListResponse] {
|
|
return runtime.NewPager(runtime.PagingHandler[armcompute.VirtualMachineScaleSetsClientListResponse]{
|
|
More: a.pager.moreFunc(),
|
|
Fetcher: a.pager.fetcherFunc(),
|
|
})
|
|
}
|
|
|
|
type stubSecurityGroupsClientListPager struct {
|
|
list []armnetwork.SecurityGroup
|
|
fetchErr error
|
|
more bool
|
|
}
|
|
|
|
func (p *stubSecurityGroupsClientListPager) moreFunc() func(armnetwork.SecurityGroupsClientListResponse) bool {
|
|
return func(armnetwork.SecurityGroupsClientListResponse) bool {
|
|
return p.more
|
|
}
|
|
}
|
|
|
|
func (p *stubSecurityGroupsClientListPager) fetcherFunc() func(context.Context, *armnetwork.SecurityGroupsClientListResponse,
|
|
) (armnetwork.SecurityGroupsClientListResponse, error) {
|
|
return func(context.Context, *armnetwork.SecurityGroupsClientListResponse) (armnetwork.SecurityGroupsClientListResponse, error) {
|
|
page := make([]*armnetwork.SecurityGroup, len(p.list))
|
|
for i := range p.list {
|
|
page[i] = &p.list[i]
|
|
}
|
|
return armnetwork.SecurityGroupsClientListResponse{
|
|
SecurityGroupListResult: armnetwork.SecurityGroupListResult{
|
|
Value: page,
|
|
},
|
|
}, p.fetchErr
|
|
}
|
|
}
|
|
|
|
type stubSecurityGroupsAPI struct {
|
|
pager *stubSecurityGroupsClientListPager
|
|
}
|
|
|
|
func (a *stubSecurityGroupsAPI) NewListPager(string, *armnetwork.SecurityGroupsClientListOptions,
|
|
) *runtime.Pager[armnetwork.SecurityGroupsClientListResponse] {
|
|
return runtime.NewPager(runtime.PagingHandler[armnetwork.SecurityGroupsClientListResponse]{
|
|
More: a.pager.moreFunc(),
|
|
Fetcher: a.pager.fetcherFunc(),
|
|
})
|
|
}
|
|
|
|
type stubVirtualNetworksClientListPager struct {
|
|
list []armnetwork.VirtualNetwork
|
|
fetchErr error
|
|
more bool
|
|
}
|
|
|
|
func (p *stubVirtualNetworksClientListPager) moreFunc() func(armnetwork.VirtualNetworksClientListResponse) bool {
|
|
return func(armnetwork.VirtualNetworksClientListResponse) bool {
|
|
return p.more
|
|
}
|
|
}
|
|
|
|
func (p *stubVirtualNetworksClientListPager) fetcherFunc() func(context.Context, *armnetwork.VirtualNetworksClientListResponse,
|
|
) (armnetwork.VirtualNetworksClientListResponse, error) {
|
|
return func(context.Context, *armnetwork.VirtualNetworksClientListResponse) (armnetwork.VirtualNetworksClientListResponse, error) {
|
|
page := make([]*armnetwork.VirtualNetwork, len(p.list))
|
|
for i := range p.list {
|
|
page[i] = &p.list[i]
|
|
}
|
|
return armnetwork.VirtualNetworksClientListResponse{
|
|
VirtualNetworkListResult: armnetwork.VirtualNetworkListResult{
|
|
Value: page,
|
|
},
|
|
}, p.fetchErr
|
|
}
|
|
}
|
|
|
|
type stubVirtualNetworksAPI struct {
|
|
pager *stubVirtualNetworksClientListPager
|
|
}
|
|
|
|
func (a *stubVirtualNetworksAPI) NewListPager(string, *armnetwork.VirtualNetworksClientListOptions,
|
|
) *runtime.Pager[armnetwork.VirtualNetworksClientListResponse] {
|
|
return runtime.NewPager(runtime.PagingHandler[armnetwork.VirtualNetworksClientListResponse]{
|
|
More: a.pager.moreFunc(),
|
|
Fetcher: a.pager.fetcherFunc(),
|
|
})
|
|
}
|
|
|
|
type stubLoadBalancersClientListPager struct {
|
|
list []armnetwork.LoadBalancer
|
|
fetchErr error
|
|
more bool
|
|
}
|
|
|
|
func (p *stubLoadBalancersClientListPager) moreFunc() func(armnetwork.LoadBalancersClientListResponse) bool {
|
|
return func(armnetwork.LoadBalancersClientListResponse) bool {
|
|
return p.more
|
|
}
|
|
}
|
|
|
|
func (p *stubLoadBalancersClientListPager) fetcherFunc() func(context.Context, *armnetwork.LoadBalancersClientListResponse,
|
|
) (armnetwork.LoadBalancersClientListResponse, error) {
|
|
return func(context.Context, *armnetwork.LoadBalancersClientListResponse) (armnetwork.LoadBalancersClientListResponse, error) {
|
|
page := make([]*armnetwork.LoadBalancer, len(p.list))
|
|
for i := range p.list {
|
|
page[i] = &p.list[i]
|
|
}
|
|
return armnetwork.LoadBalancersClientListResponse{
|
|
LoadBalancerListResult: armnetwork.LoadBalancerListResult{
|
|
Value: page,
|
|
},
|
|
}, p.fetchErr
|
|
}
|
|
}
|
|
|
|
type stubLoadBalancersAPI struct {
|
|
pager *stubLoadBalancersClientListPager
|
|
}
|
|
|
|
func (a *stubLoadBalancersAPI) NewListPager(_ string, _ *armnetwork.LoadBalancersClientListOptions,
|
|
) *runtime.Pager[armnetwork.LoadBalancersClientListResponse] {
|
|
return runtime.NewPager(runtime.PagingHandler[armnetwork.LoadBalancersClientListResponse]{
|
|
More: a.pager.moreFunc(),
|
|
Fetcher: a.pager.fetcherFunc(),
|
|
})
|
|
}
|
|
|
|
type stubPublicIPAddressesAPI struct {
|
|
getResponse armnetwork.PublicIPAddressesClientGetResponse
|
|
getVirtualMachineScaleSetPublicIPAddressResponse armnetwork.PublicIPAddressesClientGetVirtualMachineScaleSetPublicIPAddressResponse
|
|
getErr error
|
|
}
|
|
|
|
func (a *stubPublicIPAddressesAPI) Get(context.Context, string, string, *armnetwork.PublicIPAddressesClientGetOptions,
|
|
) (armnetwork.PublicIPAddressesClientGetResponse, error) {
|
|
return a.getResponse, a.getErr
|
|
}
|
|
|
|
func (a *stubPublicIPAddressesAPI) GetVirtualMachineScaleSetPublicIPAddress(context.Context, string, string,
|
|
string, string, string, string, *armnetwork.PublicIPAddressesClientGetVirtualMachineScaleSetPublicIPAddressOptions,
|
|
) (armnetwork.PublicIPAddressesClientGetVirtualMachineScaleSetPublicIPAddressResponse, error) {
|
|
return a.getVirtualMachineScaleSetPublicIPAddressResponse, a.getErr
|
|
}
|