Ensure SSH access and LB backend pool for Master Node replacement (#2516)

This commit is contained in:
Sudharsan Reddy M H 2023-02-07 06:10:39 +05:30 коммит произвёл GitHub
Родитель a3c9e536a3
Коммит 78acd1eed3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 358 добавлений и 189 удалений

Просмотреть файл

@ -21,8 +21,6 @@ func (m *manager) fixSSH(ctx context.Context) error {
infraID = "aro"
}
resourceGroup := stringutils.LastTokenByte(m.doc.OpenShiftCluster.Properties.ClusterProfile.ResourceGroupID, '/')
var lbName string
switch m.doc.OpenShiftCluster.Properties.ArchitectureVersion {
case api.ArchitectureVersionV1:
@ -33,21 +31,39 @@ func (m *manager) fixSSH(ctx context.Context) error {
return fmt.Errorf("unknown architecture version %d", m.doc.OpenShiftCluster.Properties.ArchitectureVersion)
}
lb, err := m.loadBalancers.Get(ctx, resourceGroup, lbName, "")
resourceGroup := stringutils.LastTokenByte(m.doc.OpenShiftCluster.Properties.ClusterProfile.ResourceGroupID, '/')
lb, err := m.checkAndUpdateLB(ctx, resourceGroup, lbName)
if err != nil {
m.log.Warnf("Failed checking and Updating Load Balancer with error: %s", err)
return err
}
changed := updateLB(&lb)
err = m.checkandUpdateNIC(ctx, resourceGroup, infraID, lb)
if err != nil {
m.log.Warnf("Failed checking and Updating Network Interface with error: %s", err)
return err
}
return nil
}
if changed {
m.log.Printf("updating %s", lbName)
err = m.loadBalancers.CreateOrUpdateAndWait(ctx, resourceGroup, lbName, lb)
if err != nil {
return err
}
func (m *manager) checkAndUpdateLB(ctx context.Context, resourceGroup string, lbName string) (lb mgmtnetwork.LoadBalancer, err error) {
lb, err = m.loadBalancers.Get(ctx, resourceGroup, lbName, "")
if err != nil {
return lb, err
}
if m.updateLB(ctx, &lb, lbName) {
m.log.Printf("updating Load Balancer %s", lbName)
err = m.loadBalancers.CreateOrUpdateAndWait(ctx, resourceGroup, lbName, lb)
if err != nil {
return lb, err
}
}
return lb, nil
}
func (m *manager) checkandUpdateNIC(ctx context.Context, resourceGroup string, infraID string, lb mgmtnetwork.LoadBalancer) (err error) {
for i := 0; i < 3; i++ {
// NIC names might be different if customer re-created master nodes
// see https://bugzilla.redhat.com/show_bug.cgi?id=1882490 for more details
@ -56,52 +72,97 @@ func (m *manager) fixSSH(ctx context.Context) error {
nicNameInstaller := fmt.Sprintf("%s-master%d-nic", infraID, i)
nicNameMachineAPI := fmt.Sprintf("%s-master-%d-nic", infraID, i)
var iErr, err error
var nic mgmtnetwork.Interface
nicName := nicNameInstaller
fallbackNIC := false
nic, err = m.interfaces.Get(ctx, resourceGroup, nicName, "")
if err != nil {
iErr = err // preserve original error
m.log.Warnf("Fetching details for NIC %s has failed with err %s", nicName, err)
fallbackNIC = true
} else if nic.InterfacePropertiesFormat != nil && nic.InterfacePropertiesFormat.VirtualMachine == nil {
err = m.removeBackendPoolsFromNIC(ctx, resourceGroup, nicName, &nic)
if err != nil {
m.log.Warnf("Removing BackendPools from NIC %s has failed with err %s", nicName, err)
return err
}
m.log.Warnf("Installer provisioned NIC %s has no VM attached", nicName)
fallbackNIC = true
}
if fallbackNIC {
nicName = nicNameMachineAPI
m.log.Warnf("fallback to check MachineAPI Nic name format for %s", nicName)
m.log.Warnf("Fallback to check MachineAPI Nic name format for %s", nicName)
nic, err = m.interfaces.Get(ctx, resourceGroup, nicName, "")
if err != nil {
m.log.Warnf("fallback failed with err %s", err)
return iErr
m.log.Warnf("Fallback failed with err %s", err)
return err
}
}
changed = updateNIC(&nic, &lb, i)
if changed {
m.log.Printf("updating %s", nicName)
if m.updateNIC(ctx, &nic, nicName, &lb, i, infraID) {
m.log.Printf("updating Network Interface %s", nicName)
err = m.interfaces.CreateOrUpdateAndWait(ctx, resourceGroup, nicName, nic)
if err != nil {
return err
}
}
}
return nil
}
func updateNIC(nic *mgmtnetwork.Interface, lb *mgmtnetwork.LoadBalancer, i int) bool {
id := fmt.Sprintf("%s/backendAddressPools/ssh-%d", *lb.ID, i)
func (m *manager) removeBackendPoolsFromNIC(ctx context.Context, resourceGroup, nicName string, nic *mgmtnetwork.Interface) error {
if nic.InterfacePropertiesFormat.IPConfigurations == nil || len(*nic.InterfacePropertiesFormat.IPConfigurations) == 0 {
return fmt.Errorf("unable to remove Backend Address Pools from NIC as there are no IP configurations for %s in resource group %s", nicName, resourceGroup)
}
ipc := (*nic.InterfacePropertiesFormat.IPConfigurations)[0]
if ipc.LoadBalancerBackendAddressPools != nil {
m.log.Printf("Removing Load balancer Backend Address Pools from NIC %s with no VMs attached", nicName)
*(*nic.IPConfigurations)[0].LoadBalancerBackendAddressPools = []mgmtnetwork.BackendAddressPool{}
return m.interfaces.CreateOrUpdateAndWait(ctx, resourceGroup, nicName, *nic)
}
return nil
}
func (m *manager) updateNIC(ctx context.Context, nic *mgmtnetwork.Interface, nicName string, lb *mgmtnetwork.LoadBalancer, i int, infraID string) bool {
if nic.InterfacePropertiesFormat.IPConfigurations == nil || len(*nic.InterfacePropertiesFormat.IPConfigurations) == 0 {
m.log.Warnf("unable to update NIC as there are no IP configurations for %s", nicName)
return false
}
sshID := fmt.Sprintf("%s/backendAddressPools/ssh-%d", *lb.ID, i)
ilbID := fmt.Sprintf("%s/backendAddressPools/%s", *lb.ID, infraID)
updateSSHPool := true
updateILBPool := true
for _, p := range *(*nic.IPConfigurations)[0].LoadBalancerBackendAddressPools {
if strings.EqualFold(*p.ID, id) {
return false
if strings.EqualFold(*p.ID, sshID) {
updateSSHPool = false
}
if strings.EqualFold(*p.ID, ilbID) {
updateILBPool = false
}
}
*(*nic.IPConfigurations)[0].LoadBalancerBackendAddressPools = append(*(*nic.IPConfigurations)[0].LoadBalancerBackendAddressPools, mgmtnetwork.BackendAddressPool{
ID: &id,
})
if updateSSHPool {
m.log.Printf("Adding NIC %s to Internal Load Balancer SSH Backend Address Pool %s", nicName, sshID)
*(*nic.IPConfigurations)[0].LoadBalancerBackendAddressPools = append(*(*nic.IPConfigurations)[0].LoadBalancerBackendAddressPools, mgmtnetwork.BackendAddressPool{
ID: &sshID,
})
}
return true
if updateILBPool {
m.log.Printf("Adding NIC %s to Internal Load Balancer API Address Pool %s", nicName, ilbID)
*(*nic.IPConfigurations)[0].LoadBalancerBackendAddressPools = append(*(*nic.IPConfigurations)[0].LoadBalancerBackendAddressPools, mgmtnetwork.BackendAddressPool{
ID: &ilbID,
})
}
return updateSSHPool || updateILBPool
}
func updateLB(lb *mgmtnetwork.LoadBalancer) (changed bool) {
func (m *manager) updateLB(ctx context.Context, lb *mgmtnetwork.LoadBalancer, lbName string) (changed bool) {
backendAddressPools:
for i := 0; i < 3; i++ {
name := fmt.Sprintf("ssh-%d", i)
@ -112,6 +173,7 @@ backendAddressPools:
}
changed = true
m.log.Printf("Adding SSH Backend Address Pool %s to Internal Load Balancer %s", name, lbName)
*lb.BackendAddressPools = append(*lb.BackendAddressPools, mgmtnetwork.BackendAddressPool{
Name: &name,
})
@ -127,6 +189,7 @@ loadBalancingRules:
}
changed = true
m.log.Printf("Adding SSH Load Balancing Rule for %s to Internal Load Balancer %s", name, lbName)
*lb.LoadBalancingRules = append(*lb.LoadBalancingRules, mgmtnetwork.LoadBalancingRule{
LoadBalancingRulePropertiesFormat: &mgmtnetwork.LoadBalancingRulePropertiesFormat{
FrontendIPConfiguration: &mgmtnetwork.SubResource{
@ -156,6 +219,7 @@ loadBalancingRules:
}
changed = true
m.log.Printf("Adding ssh Health Probe to Internal Load Balancer %s", lbName)
*lb.Probes = append(*lb.Probes, mgmtnetwork.Probe{
ProbePropertiesFormat: &mgmtnetwork.ProbePropertiesFormat{
Protocol: mgmtnetwork.ProbeProtocolTCP,

Просмотреть файл

@ -17,156 +17,191 @@ import (
mock_network "github.com/Azure/ARO-RP/pkg/util/mocks/azureclient/mgmt/network"
)
var (
resourceGroup = "rg"
infraID = "infra"
ipc = "internal-lb-ip-v4"
)
func lbBefore(lbID string) *mgmtnetwork.LoadBalancer {
return &mgmtnetwork.LoadBalancer{
ID: to.StringPtr(lbID),
LoadBalancerPropertiesFormat: &mgmtnetwork.LoadBalancerPropertiesFormat{
FrontendIPConfigurations: &[]mgmtnetwork.FrontendIPConfiguration{
{
ID: to.StringPtr(lbID + "/frontendIPConfigurations/" + ipc),
},
},
BackendAddressPools: &[]mgmtnetwork.BackendAddressPool{},
LoadBalancingRules: &[]mgmtnetwork.LoadBalancingRule{},
Probes: &[]mgmtnetwork.Probe{},
},
}
}
func lbAfter(lbID string) *mgmtnetwork.LoadBalancer {
return &mgmtnetwork.LoadBalancer{
ID: to.StringPtr(lbID),
LoadBalancerPropertiesFormat: &mgmtnetwork.LoadBalancerPropertiesFormat{
FrontendIPConfigurations: &[]mgmtnetwork.FrontendIPConfiguration{
{
ID: to.StringPtr(lbID + "/frontendIPConfigurations/" + ipc),
},
},
BackendAddressPools: &[]mgmtnetwork.BackendAddressPool{
{
Name: to.StringPtr("ssh-0"),
},
{
Name: to.StringPtr("ssh-1"),
},
{
Name: to.StringPtr("ssh-2"),
},
},
LoadBalancingRules: &[]mgmtnetwork.LoadBalancingRule{
{
LoadBalancingRulePropertiesFormat: &mgmtnetwork.LoadBalancingRulePropertiesFormat{
FrontendIPConfiguration: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/frontendIPConfigurations/" + ipc),
},
BackendAddressPool: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/backendAddressPools/ssh-0"),
},
Probe: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/probes/ssh"),
},
Protocol: mgmtnetwork.TransportProtocolTCP,
LoadDistribution: mgmtnetwork.LoadDistributionDefault,
FrontendPort: to.Int32Ptr(2200),
BackendPort: to.Int32Ptr(22),
IdleTimeoutInMinutes: to.Int32Ptr(30),
DisableOutboundSnat: to.BoolPtr(true),
},
Name: to.StringPtr("ssh-0"),
},
{
LoadBalancingRulePropertiesFormat: &mgmtnetwork.LoadBalancingRulePropertiesFormat{
FrontendIPConfiguration: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/frontendIPConfigurations/" + ipc),
},
BackendAddressPool: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/backendAddressPools/ssh-1"),
},
Probe: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/probes/ssh"),
},
Protocol: mgmtnetwork.TransportProtocolTCP,
LoadDistribution: mgmtnetwork.LoadDistributionDefault,
FrontendPort: to.Int32Ptr(2201),
BackendPort: to.Int32Ptr(22),
IdleTimeoutInMinutes: to.Int32Ptr(30),
DisableOutboundSnat: to.BoolPtr(true),
},
Name: to.StringPtr("ssh-1"),
},
{
LoadBalancingRulePropertiesFormat: &mgmtnetwork.LoadBalancingRulePropertiesFormat{
FrontendIPConfiguration: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/frontendIPConfigurations/" + ipc),
},
BackendAddressPool: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/backendAddressPools/ssh-2"),
},
Probe: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/probes/ssh"),
},
Protocol: mgmtnetwork.TransportProtocolTCP,
LoadDistribution: mgmtnetwork.LoadDistributionDefault,
FrontendPort: to.Int32Ptr(2202),
BackendPort: to.Int32Ptr(22),
IdleTimeoutInMinutes: to.Int32Ptr(30),
DisableOutboundSnat: to.BoolPtr(true),
},
Name: to.StringPtr("ssh-2"),
},
},
Probes: &[]mgmtnetwork.Probe{
{
ProbePropertiesFormat: &mgmtnetwork.ProbePropertiesFormat{
Protocol: mgmtnetwork.ProbeProtocolTCP,
Port: to.Int32Ptr(22),
IntervalInSeconds: to.Int32Ptr(5),
NumberOfProbes: to.Int32Ptr(2),
},
Name: to.StringPtr("ssh"),
},
},
},
}
}
func ifBefore(lbID string, i int) *mgmtnetwork.Interface {
return &mgmtnetwork.Interface{
InterfacePropertiesFormat: &mgmtnetwork.InterfacePropertiesFormat{
VirtualMachine: &mgmtnetwork.SubResource{
ID: to.StringPtr(fmt.Sprintf("master-%d", i)),
},
IPConfigurations: &[]mgmtnetwork.InterfaceIPConfiguration{
{
InterfaceIPConfigurationPropertiesFormat: &mgmtnetwork.InterfaceIPConfigurationPropertiesFormat{
LoadBalancerBackendAddressPools: &[]mgmtnetwork.BackendAddressPool{},
},
},
},
},
}
}
func ifNoVmBefore(lbID string, i int) *mgmtnetwork.Interface {
return &mgmtnetwork.Interface{
InterfacePropertiesFormat: &mgmtnetwork.InterfacePropertiesFormat{
VirtualMachine: nil,
IPConfigurations: &[]mgmtnetwork.InterfaceIPConfiguration{
{
InterfaceIPConfigurationPropertiesFormat: &mgmtnetwork.InterfaceIPConfigurationPropertiesFormat{
LoadBalancerBackendAddressPools: &[]mgmtnetwork.BackendAddressPool{
{
ID: to.StringPtr(fmt.Sprintf(lbID+"/backendAddressPools/ssh-%d", i)),
},
},
},
},
},
},
}
}
func ifNoVmAfter(nic *mgmtnetwork.Interface) *mgmtnetwork.Interface {
emptyAddressPool := make([]mgmtnetwork.BackendAddressPool, 0)
(*nic.InterfacePropertiesFormat.IPConfigurations)[0].InterfaceIPConfigurationPropertiesFormat.LoadBalancerBackendAddressPools = &emptyAddressPool
return nic
}
func ifAfter(lbID string, i int) *mgmtnetwork.Interface {
return &mgmtnetwork.Interface{
InterfacePropertiesFormat: &mgmtnetwork.InterfacePropertiesFormat{
VirtualMachine: &mgmtnetwork.SubResource{
ID: to.StringPtr(fmt.Sprintf("master-%d", i)),
},
IPConfigurations: &[]mgmtnetwork.InterfaceIPConfiguration{
{
InterfaceIPConfigurationPropertiesFormat: &mgmtnetwork.InterfaceIPConfigurationPropertiesFormat{
LoadBalancerBackendAddressPools: &[]mgmtnetwork.BackendAddressPool{
{
ID: to.StringPtr(fmt.Sprintf(lbID+"/backendAddressPools/ssh-%d", i)),
},
{
ID: to.StringPtr(fmt.Sprintf(lbID+"/backendAddressPools/%s", infraID)),
},
},
},
},
},
},
}
}
func TestFixSSH(t *testing.T) {
resourceGroup := "rg"
infraID := "infra"
ipc := "internal-lb-ip-v4"
lbBefore := func(lbID string) *mgmtnetwork.LoadBalancer {
return &mgmtnetwork.LoadBalancer{
ID: to.StringPtr(lbID),
LoadBalancerPropertiesFormat: &mgmtnetwork.LoadBalancerPropertiesFormat{
FrontendIPConfigurations: &[]mgmtnetwork.FrontendIPConfiguration{
{
ID: to.StringPtr(lbID + "/frontendIPConfigurations/" + ipc),
},
},
BackendAddressPools: &[]mgmtnetwork.BackendAddressPool{},
LoadBalancingRules: &[]mgmtnetwork.LoadBalancingRule{},
Probes: &[]mgmtnetwork.Probe{},
},
}
}
lbAfter := func(lbID string) *mgmtnetwork.LoadBalancer {
return &mgmtnetwork.LoadBalancer{
ID: to.StringPtr(lbID),
LoadBalancerPropertiesFormat: &mgmtnetwork.LoadBalancerPropertiesFormat{
FrontendIPConfigurations: &[]mgmtnetwork.FrontendIPConfiguration{
{
ID: to.StringPtr(lbID + "/frontendIPConfigurations/" + ipc),
},
},
BackendAddressPools: &[]mgmtnetwork.BackendAddressPool{
{
Name: to.StringPtr("ssh-0"),
},
{
Name: to.StringPtr("ssh-1"),
},
{
Name: to.StringPtr("ssh-2"),
},
},
LoadBalancingRules: &[]mgmtnetwork.LoadBalancingRule{
{
LoadBalancingRulePropertiesFormat: &mgmtnetwork.LoadBalancingRulePropertiesFormat{
FrontendIPConfiguration: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/frontendIPConfigurations/" + ipc),
},
BackendAddressPool: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/backendAddressPools/ssh-0"),
},
Probe: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/probes/ssh"),
},
Protocol: mgmtnetwork.TransportProtocolTCP,
LoadDistribution: mgmtnetwork.LoadDistributionDefault,
FrontendPort: to.Int32Ptr(2200),
BackendPort: to.Int32Ptr(22),
IdleTimeoutInMinutes: to.Int32Ptr(30),
DisableOutboundSnat: to.BoolPtr(true),
},
Name: to.StringPtr("ssh-0"),
},
{
LoadBalancingRulePropertiesFormat: &mgmtnetwork.LoadBalancingRulePropertiesFormat{
FrontendIPConfiguration: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/frontendIPConfigurations/" + ipc),
},
BackendAddressPool: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/backendAddressPools/ssh-1"),
},
Probe: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/probes/ssh"),
},
Protocol: mgmtnetwork.TransportProtocolTCP,
LoadDistribution: mgmtnetwork.LoadDistributionDefault,
FrontendPort: to.Int32Ptr(2201),
BackendPort: to.Int32Ptr(22),
IdleTimeoutInMinutes: to.Int32Ptr(30),
DisableOutboundSnat: to.BoolPtr(true),
},
Name: to.StringPtr("ssh-1"),
},
{
LoadBalancingRulePropertiesFormat: &mgmtnetwork.LoadBalancingRulePropertiesFormat{
FrontendIPConfiguration: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/frontendIPConfigurations/" + ipc),
},
BackendAddressPool: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/backendAddressPools/ssh-2"),
},
Probe: &mgmtnetwork.SubResource{
ID: to.StringPtr(lbID + "/probes/ssh"),
},
Protocol: mgmtnetwork.TransportProtocolTCP,
LoadDistribution: mgmtnetwork.LoadDistributionDefault,
FrontendPort: to.Int32Ptr(2202),
BackendPort: to.Int32Ptr(22),
IdleTimeoutInMinutes: to.Int32Ptr(30),
DisableOutboundSnat: to.BoolPtr(true),
},
Name: to.StringPtr("ssh-2"),
},
},
Probes: &[]mgmtnetwork.Probe{
{
ProbePropertiesFormat: &mgmtnetwork.ProbePropertiesFormat{
Protocol: mgmtnetwork.ProbeProtocolTCP,
Port: to.Int32Ptr(22),
IntervalInSeconds: to.Int32Ptr(5),
NumberOfProbes: to.Int32Ptr(2),
},
Name: to.StringPtr("ssh"),
},
},
},
}
}
ifBefore := func(lbID string, i int) *mgmtnetwork.Interface {
return &mgmtnetwork.Interface{
InterfacePropertiesFormat: &mgmtnetwork.InterfacePropertiesFormat{
IPConfigurations: &[]mgmtnetwork.InterfaceIPConfiguration{
{
InterfaceIPConfigurationPropertiesFormat: &mgmtnetwork.InterfaceIPConfigurationPropertiesFormat{
LoadBalancerBackendAddressPools: &[]mgmtnetwork.BackendAddressPool{},
},
},
},
},
}
}
ifAfter := func(lbID string, i int) *mgmtnetwork.Interface {
return &mgmtnetwork.Interface{
InterfacePropertiesFormat: &mgmtnetwork.InterfacePropertiesFormat{
IPConfigurations: &[]mgmtnetwork.InterfaceIPConfiguration{
{
InterfaceIPConfigurationPropertiesFormat: &mgmtnetwork.InterfaceIPConfigurationPropertiesFormat{
LoadBalancerBackendAddressPools: &[]mgmtnetwork.BackendAddressPool{
{
ID: to.StringPtr(fmt.Sprintf(lbID+"/backendAddressPools/ssh-%d", i)),
},
},
},
},
},
},
}
}
for _, tt := range []struct {
name string
architectureVersion api.ArchitectureVersion
@ -175,8 +210,12 @@ func TestFixSSH(t *testing.T) {
loadbalancer func(string) *mgmtnetwork.LoadBalancer
iface func(string, int) *mgmtnetwork.Interface
iNameF string
ifaceNoVmAttached bool // create the NIC without a master VM attached, to simulate a master node replacement
lbErrorExpected bool
writeExpected bool // do we expect write to happen as part of this test
fallbackExpected bool // do we expect fallback nic.Get as part of this test
nicErrorExpected bool
wantError string
}{
{
name: "updates v1 resources correctly",
@ -225,6 +264,46 @@ func TestFixSSH(t *testing.T) {
writeExpected: true,
fallbackExpected: true,
},
{
name: "updates v2 resources correctly with masters recreated and no VM attached to the installer NIC",
architectureVersion: api.ArchitectureVersionV2,
lb: infraID + "-internal",
lbID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/" + resourceGroup + "/providers/Microsoft.Network/loadBalancers/" + infraID + "-internal",
loadbalancer: lbBefore,
iface: ifNoVmBefore,
iNameF: "%s-master-%d-nic",
ifaceNoVmAttached: true,
writeExpected: true,
fallbackExpected: true,
},
{
name: "FixSSH function returns an error while Fetching LB",
architectureVersion: api.ArchitectureVersionV2,
lb: infraID + "-internal",
lbID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/" + resourceGroup + "/providers/Microsoft.Network/loadBalancers/" + infraID + "-internal",
loadbalancer: lbBefore,
iface: ifNoVmBefore,
iNameF: "%s-master%d-nic",
writeExpected: false,
fallbackExpected: false,
lbErrorExpected: true,
nicErrorExpected: false,
wantError: "Loadbalancer not found",
},
{
name: "FixSSH function returns an error while Fetching NIC",
architectureVersion: api.ArchitectureVersionV2,
lb: infraID + "-internal",
lbID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/" + resourceGroup + "/providers/Microsoft.Network/loadBalancers/" + infraID + "-internal",
loadbalancer: lbBefore,
iface: ifNoVmBefore,
iNameF: "%s-master-%d-nic",
writeExpected: true,
fallbackExpected: false,
lbErrorExpected: false,
nicErrorExpected: true,
wantError: "Interface not found",
},
} {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
@ -233,19 +312,44 @@ func TestFixSSH(t *testing.T) {
interfaces := mock_network.NewMockInterfacesClient(ctrl)
loadBalancers := mock_network.NewMockLoadBalancersClient(ctrl)
// check
loadBalancers.EXPECT().Get(gomock.Any(), resourceGroup, tt.lb, "").Return(*tt.loadbalancer(tt.lbID), nil)
for i := 0; i < 3; i++ {
if tt.fallbackExpected { // bit of hack to check fallback.
interfaces.EXPECT().Get(gomock.Any(), resourceGroup, fmt.Sprintf("%s-master%d-nic", infraID, i), "").Return(mgmtnetwork.Interface{}, fmt.Errorf("nic not found"))
if tt.lbErrorExpected {
loadBalancers.EXPECT().Get(gomock.Any(), resourceGroup, tt.lb, "").Return(mgmtnetwork.LoadBalancer{}, fmt.Errorf("Loadbalancer not found"))
} else {
loadBalancers.EXPECT().Get(gomock.Any(), resourceGroup, tt.lb, "").Return(*tt.loadbalancer(tt.lbID), nil)
if tt.writeExpected {
loadBalancers.EXPECT().CreateOrUpdateAndWait(gomock.Any(), resourceGroup, tt.lb, *lbAfter(tt.lbID))
}
interfaces.EXPECT().Get(gomock.Any(), resourceGroup, fmt.Sprintf(tt.iNameF, infraID, i), "").Return(*tt.iface(tt.lbID, i), nil)
}
if tt.writeExpected {
loadBalancers.EXPECT().CreateOrUpdateAndWait(gomock.Any(), resourceGroup, tt.lb, *lbAfter(tt.lbID))
for i := 0; i < 3; i++ {
interfaces.EXPECT().CreateOrUpdateAndWait(gomock.Any(), resourceGroup, fmt.Sprintf(tt.iNameF, infraID, i), *ifAfter(tt.lbID, i))
for i := 0; i < 3; i++ {
vmNicBefore := tt.iface(tt.lbID, i)
if tt.fallbackExpected { // bit of hack to check fallback.
if tt.ifaceNoVmAttached {
vmNicBefore = ifNoVmBefore(tt.lbID, i)
interfaces.EXPECT().Get(gomock.Any(), resourceGroup, fmt.Sprintf("%s-master%d-nic", infraID, i), "").Return(*vmNicBefore, nil)
} else {
interfaces.EXPECT().Get(gomock.Any(), resourceGroup, fmt.Sprintf("%s-master%d-nic", infraID, i), "").Return(mgmtnetwork.Interface{}, fmt.Errorf("nic not found"))
}
}
if tt.nicErrorExpected {
interfaces.EXPECT().Get(gomock.Any(), resourceGroup, fmt.Sprintf("%s-master%d-nic", infraID, i), "").Return(mgmtnetwork.Interface{}, fmt.Errorf("Interface not found"))
interfaces.EXPECT().Get(gomock.Any(), resourceGroup, fmt.Sprintf(tt.iNameF, infraID, i), "").Return(mgmtnetwork.Interface{}, fmt.Errorf("Interface not found"))
break
} else if tt.lbErrorExpected {
interfaces.EXPECT().Get(gomock.Any(), resourceGroup, fmt.Sprintf(tt.iNameF, infraID, i), "").Times(0)
} else {
interfaces.EXPECT().Get(gomock.Any(), resourceGroup, fmt.Sprintf(tt.iNameF, infraID, i), "").Return(*vmNicBefore, nil)
}
if tt.writeExpected {
if tt.ifaceNoVmAttached {
interfaces.EXPECT().CreateOrUpdateAndWait(gomock.Any(), resourceGroup, fmt.Sprintf("%s-master%d-nic", infraID, i), *vmNicBefore)
interfaces.EXPECT().CreateOrUpdateAndWait(gomock.Any(), resourceGroup, fmt.Sprintf(tt.iNameF, infraID, i), *ifNoVmAfter(vmNicBefore))
} else {
interfaces.EXPECT().CreateOrUpdateAndWait(gomock.Any(), resourceGroup, fmt.Sprintf(tt.iNameF, infraID, i), *vmNicBefore)
}
}
}
@ -267,7 +371,8 @@ func TestFixSSH(t *testing.T) {
}
err := m.fixSSH(context.Background())
if err != nil {
if err != nil && err.Error() != tt.wantError ||
err == nil && tt.wantError != "" {
t.Error(err)
}
})