Skip to content

Commit ecbbec2

Browse files
author
Hoanganh.Mai
committed
add check for tenant existence
1 parent 0508ece commit ecbbec2

12 files changed

+235
-31
lines changed

internal/controller/expected_netboxmock_calls_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ func mockTenancyTenancyTenantsList(tenancyMock *mock_interfaces.MockTenancyInter
234234
}
235235

236236
// -----------------------------
237-
// Restet Mock Functions
237+
// Reset Mock Functions
238238
// -----------------------------
239239

240240
func resetMockFunctions(ipamMockA *mock_interfaces.MockIpamInterface, ipamMockB *mock_interfaces.MockIpamInterface, tenancyMock *mock_interfaces.MockTenancyInterface) {

internal/controller/ipaddress_controller.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func (r *IpAddressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
7878
// if being deleted
7979
if !o.ObjectMeta.DeletionTimestamp.IsZero() {
8080
if controllerutil.ContainsFinalizer(o, IpAddressFinalizerName) {
81-
if !o.Spec.PreserveInNetbox {
81+
if o.Status.IpAddressId != 0 {
8282
err := r.NetboxClient.DeleteIpAddress(o.Status.IpAddressId)
8383
if err != nil {
8484
return ctrl.Result{}, err
@@ -101,6 +101,15 @@ func (r *IpAddressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
101101
return ctrl.Result{}, nil
102102
}
103103

104+
// if PreserveIpInNetbox flag is false then register finalizer if not yet registered
105+
if !o.Spec.PreserveInNetbox && !controllerutil.ContainsFinalizer(o, IpAddressFinalizerName) {
106+
debugLogger.Info("adding the finalizer")
107+
controllerutil.AddFinalizer(o, IpAddressFinalizerName)
108+
if err := r.Update(ctx, o); err != nil {
109+
return ctrl.Result{}, err
110+
}
111+
}
112+
104113
// 1. try to lock lease of parent prefix if IpAddress status condition is not true
105114
// and IpAddress is owned by an IpAddressClaim
106115
or := o.ObjectMeta.OwnerReferences
@@ -193,15 +202,6 @@ func (r *IpAddressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
193202
r.Recorder.Event(o, corev1.EventTypeWarning, "IpDescriptionTruncated", "ip address was created with truncated description")
194203
}
195204

196-
// if PreserveIpInNetbox flag is false then register finalizer if not yet registered
197-
if !o.Spec.PreserveInNetbox && !controllerutil.ContainsFinalizer(o, IpAddressFinalizerName) {
198-
debugLogger.Info("adding the finalizer")
199-
controllerutil.AddFinalizer(o, IpAddressFinalizerName)
200-
if err := r.Update(ctx, o); err != nil {
201-
return ctrl.Result{}, err
202-
}
203-
}
204-
205205
debugLogger.Info(fmt.Sprintf("reserved ip address in netbox, ip: %s", o.Spec.IpAddress))
206206

207207
// 3. unlock lease of parent prefix

internal/controller/ipaddressclaim_controller.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,14 @@ func (r *IpAddressClaimReconciler) Reconcile(ctx context.Context, req ctrl.Reque
137137
},
138138
})
139139
if err != nil {
140-
return ctrl.Result{}, err
140+
setConditionErr := r.SetConditionAndCreateEvent(ctx, o, netboxv1.ConditionIpAssignedFalse, corev1.EventTypeWarning, err.Error())
141+
if setConditionErr != nil {
142+
return ctrl.Result{}, fmt.Errorf("error updating status: %w, when getting an available IP address failed: %w", setConditionErr, err)
143+
}
144+
145+
return ctrl.Result{Requeue: true}, nil
141146
}
142-
debugLogger.Info(fmt.Sprintf("ip address is not reserved in netbox, assignined new ip address: %s", ipAddressModel.IpAddress))
147+
debugLogger.Info(fmt.Sprintf("ip address is not reserved in netbox, assigned new ip address: %s", ipAddressModel.IpAddress))
143148
} else {
144149
// 5.b reassign reserved ip address from netbox
145150
// do nothing, ip address restored

internal/controller/prefix_controller.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func (r *PrefixReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
7979
// if being deleted
8080
if !prefix.ObjectMeta.DeletionTimestamp.IsZero() {
8181
if controllerutil.ContainsFinalizer(prefix, PrefixFinalizerName) {
82-
if !prefix.Spec.PreserveInNetbox {
82+
if prefix.Status.PrefixId != 0 {
8383
if err := r.NetboxClient.DeletePrefix(prefix.Status.PrefixId); err != nil {
8484
return ctrl.Result{}, err
8585
}
@@ -99,6 +99,15 @@ func (r *PrefixReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
9999
return ctrl.Result{}, nil
100100
}
101101

102+
// register finalizer if not yet registered
103+
if !prefix.Spec.PreserveInNetbox && !controllerutil.ContainsFinalizer(prefix, PrefixFinalizerName) {
104+
debugLogger.Info("adding the finalizer")
105+
controllerutil.AddFinalizer(prefix, PrefixFinalizerName)
106+
if err := r.Update(ctx, prefix); err != nil {
107+
return ctrl.Result{}, err
108+
}
109+
}
110+
102111
/*
103112
1. try to lock the lease of the parent prefix if all of the following conditions are met
104113
- the prefix is owned by at least 1 prefixClaim
@@ -188,15 +197,6 @@ func (r *PrefixReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
188197
r.Recorder.Event(prefix, corev1.EventTypeWarning, "PrefixDescriptionTruncated", "prefix was created with truncated description")
189198
}
190199

191-
// register finalizer if not yet registered
192-
if !prefix.Spec.PreserveInNetbox && !controllerutil.ContainsFinalizer(prefix, PrefixFinalizerName) {
193-
debugLogger.Info("adding the finalizer")
194-
controllerutil.AddFinalizer(prefix, PrefixFinalizerName)
195-
if err := r.Update(ctx, prefix); err != nil {
196-
return ctrl.Result{}, err
197-
}
198-
}
199-
200200
debugLogger.Info(fmt.Sprintf("reserved prefix in netbox, prefix: %s", prefix.Spec.Prefix))
201201

202202
/* 3. unlock lease of parent prefix */

internal/controller/prefixclaim_controller.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,12 @@ func (r *PrefixClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request)
135135
},
136136
})
137137
if err != nil {
138-
return ctrl.Result{}, err
138+
setConditionErr := r.SetConditionAndCreateEvent(ctx, prefixClaim, netboxv1.ConditionPrefixAssignedFalse, corev1.EventTypeWarning, err.Error())
139+
if setConditionErr != nil {
140+
return ctrl.Result{}, fmt.Errorf("error updating status: %w, when getting an available Prefix failed: %w", setConditionErr, err)
141+
}
142+
143+
return ctrl.Result{Requeue: true}, nil
139144
}
140145
debugLogger.Info(fmt.Sprintf("prefix is not reserved in netbox, assignined new prefix: %s", prefixModel.Prefix))
141146
} else {

pkg/netbox/api/ip_address_claim.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323

2424
"github.com/netbox-community/go-netbox/v3/netbox/client/ipam"
2525
"github.com/netbox-community/netbox-operator/pkg/netbox/models"
26+
"github.com/netbox-community/netbox-operator/pkg/netbox/utils"
2627
)
2728

2829
const (
@@ -57,6 +58,10 @@ func (r *NetboxClient) RestoreExistingIpByHash(customFieldName string, hash stri
5758

5859
// GetAvailableIpAddressByClaim searches an available IpAddress in Netbox matching IpAddressClaim requirements
5960
func (r *NetboxClient) GetAvailableIpAddressByClaim(ipAddressClaim *models.IPAddressClaim) (*models.IPAddress, error) {
61+
_, err := r.GetTenantDetails(ipAddressClaim.Metadata.Tenant)
62+
if err != nil {
63+
return nil, err
64+
}
6065

6166
responseParentPrefix, err := r.GetPrefix(&models.Prefix{
6267
Prefix: ipAddressClaim.ParentPrefix,
@@ -66,7 +71,7 @@ func (r *NetboxClient) GetAvailableIpAddressByClaim(ipAddressClaim *models.IPAdd
6671
return nil, err
6772
}
6873
if len(responseParentPrefix.Payload.Results) == 0 {
69-
return nil, errors.New("parent prefix not found")
74+
return nil, utils.NetboxNotFoundError("parent prefix")
7075
}
7176

7277
parentPrefixId := responseParentPrefix.Payload.Results[0].ID

pkg/netbox/api/ip_address_claim_test.go

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package api
1818

1919
import (
20+
"errors"
2021
"testing"
2122

2223
"github.com/netbox-community/go-netbox/v3/netbox/client/ipam"
@@ -166,8 +167,10 @@ func TestIPAddressClaim(t *testing.T) {
166167
},
167168
})
168169

170+
expectedErrMsg := "failed to fetch parent prefix: not found"
171+
169172
// assert error
170-
AssertError(t, err, "parent prefix not found")
173+
AssertError(t, err, expectedErrMsg)
171174
// assert nil output
172175
assert.Nil(t, actual)
173176
})
@@ -231,3 +234,78 @@ func TestIPAddressClaim(t *testing.T) {
231234
assert.Equal(t, ipAddressRestore, actual.IpAddress)
232235
})
233236
}
237+
238+
func TestIPAddressClaim_GetNoAvailableIPAddressWithTenancyChecks(t *testing.T) {
239+
ctrl := gomock.NewController(t)
240+
defer ctrl.Finish()
241+
242+
mockTenancy := mock_interfaces.NewMockTenancyInterface(ctrl)
243+
244+
parentPrefix := "10.112.140.0/24"
245+
t.Run("No IP address asigned with an error when getting the tenant list", func(t *testing.T) {
246+
247+
tenantName := "Tenant1"
248+
249+
inputTenant := tenancy.NewTenancyTenantsListParams().WithName(&tenantName)
250+
251+
// expected error
252+
expectedErrorMsg := "cannot get the list" // testcase-defined error
253+
254+
mockTenancy.EXPECT().TenancyTenantsList(inputTenant, nil).Return(nil, errors.New(expectedErrorMsg)).AnyTimes()
255+
256+
// init client
257+
client := &NetboxClient{
258+
Tenancy: mockTenancy,
259+
}
260+
261+
actual, err := client.GetAvailableIpAddressByClaim(&models.IPAddressClaim{
262+
ParentPrefix: parentPrefix,
263+
Metadata: &models.NetboxMetadata{
264+
Tenant: tenantName,
265+
},
266+
})
267+
268+
// assert error
269+
assert.Containsf(t, err.Error(), expectedErrorMsg, "Error should contain: %v, got: %v", expectedErrorMsg, err.Error())
270+
// assert nil output
271+
assert.Equal(t, actual, (*models.IPAddress)(nil))
272+
})
273+
274+
t.Run("No IP address asigned with non-existing tenant", func(t *testing.T) {
275+
276+
// non existing tenant
277+
nonExistingTenant := "non-existing-tenant"
278+
279+
inputTenant := tenancy.NewTenancyTenantsListParams().WithName(&nonExistingTenant)
280+
281+
// empty tenant list
282+
emptyTenantList := &tenancy.TenancyTenantsListOK{
283+
Payload: &tenancy.TenancyTenantsListOKBody{
284+
Results: []*netboxModels.Tenant{},
285+
},
286+
}
287+
288+
// expected error
289+
expectedErrorMsg := "failed to fetch tenant: not found"
290+
291+
// mock empty list call
292+
mockTenancy.EXPECT().TenancyTenantsList(inputTenant, nil).Return(emptyTenantList, nil).AnyTimes()
293+
294+
// init client
295+
client := &NetboxClient{
296+
Tenancy: mockTenancy,
297+
}
298+
299+
actual, err := client.GetAvailableIpAddressByClaim(&models.IPAddressClaim{
300+
ParentPrefix: parentPrefix,
301+
Metadata: &models.NetboxMetadata{
302+
Tenant: nonExistingTenant,
303+
},
304+
})
305+
306+
// assert error
307+
assert.EqualErrorf(t, err, expectedErrorMsg, "Error should be: %v, got: %v", expectedErrorMsg, err)
308+
// assert nil output
309+
assert.Equal(t, actual, (*models.IPAddress)(nil))
310+
})
311+
}

pkg/netbox/api/prefix_claim.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ func isRequestingTheEntireParentPrefix(prefixClaim *models.PrefixClaim) (bool, e
6767

6868
// GetAvailablePrefixByClaim searches an available Prefix in Netbox matching PrefixClaim requirements
6969
func (r *NetboxClient) GetAvailablePrefixByClaim(prefixClaim *models.PrefixClaim) (*models.Prefix, error) {
70+
_, err := r.GetTenantDetails(prefixClaim.Metadata.Tenant)
71+
if err != nil {
72+
return nil, err
73+
}
74+
7075
responseParentPrefix, err := r.GetPrefix(&models.Prefix{
7176
Prefix: prefixClaim.ParentPrefix,
7277
Metadata: prefixClaim.Metadata,

0 commit comments

Comments
 (0)