Skip to content

Commit dde853b

Browse files
authored
Verify prefix length before restoring PrefixClaim from NetBox (netbox-community#373)
If there is a mismatch of .spec.prefixLength and the prefix length of the Prefix in NetBox that would be restored, NetBox Operator will now longer restore it.
1 parent 0dcf9a3 commit dde853b

File tree

5 files changed

+103
-9
lines changed

5 files changed

+103
-9
lines changed

internal/controller/prefixclaim_controller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func (r *PrefixClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request)
104104
// since the parent prefix is not part of the restoration hash computation
105105
// we can quickly check to see if the prefix with the restoration hash is matched in NetBox
106106
h := generatePrefixRestorationHash(o)
107-
canBeRestored, err := r.NetboxClient.RestoreExistingPrefixByHash(h)
107+
canBeRestored, err := r.NetboxClient.RestoreExistingPrefixByHash(h, o.Spec.PrefixLength)
108108
if err != nil {
109109
if errReport := r.EventStatusRecorder.Report(ctx, o, netboxv1.ConditionParentPrefixSelectedFalse, corev1.EventTypeWarning, fmt.Errorf("failed to look up prefix by hash: %w", err)); errReport != nil {
110110
return ctrl.Result{}, errReport
@@ -239,7 +239,7 @@ func (r *PrefixClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request)
239239

240240
// 5. try to reclaim Prefix using restorationHash
241241
h := generatePrefixRestorationHash(o)
242-
prefixModel, err := r.NetboxClient.RestoreExistingPrefixByHash(h)
242+
prefixModel, err := r.NetboxClient.RestoreExistingPrefixByHash(h, o.Spec.PrefixLength)
243243
if err != nil {
244244
if errReport := r.EventStatusRecorder.Report(ctx, o, netboxv1.ConditionPrefixAssignedFalse, corev1.EventTypeWarning, err); errReport != nil {
245245
return ctrl.Result{}, errReport

pkg/netbox/api/prefix_claim.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ var (
3636
ErrNoPrefixMatchsSizeCriteria = errors.New("no available prefix matches size criteria")
3737
)
3838

39-
func (r *NetboxClient) RestoreExistingPrefixByHash(hash string) (*models.Prefix, error) {
39+
func (r *NetboxClient) RestoreExistingPrefixByHash(hash string, requestedPrefixLength string) (*models.Prefix, error) {
4040
customPrefixSearch := newQueryFilterOperation(nil, []CustomFieldEntry{
4141
{
4242
key: config.GetOperatorConfig().NetboxRestorationHashFieldName,
@@ -53,17 +53,29 @@ func (r *NetboxClient) RestoreExistingPrefixByHash(hash string) (*models.Prefix,
5353
return nil, nil
5454
}
5555

56+
// Filter for exact prefix length
57+
prefixesWithExactPrefixLength := make([]*models.Prefix, 0)
58+
for _, prefix := range list.Payload.Results {
59+
if strings.Contains(*prefix.Prefix, requestedPrefixLength) {
60+
prefixesWithExactPrefixLength = append(prefixesWithExactPrefixLength, &models.Prefix{
61+
Prefix: *prefix.Prefix,
62+
})
63+
}
64+
}
65+
5666
// We should not have more than 1 result...
57-
if len(list.Payload.Results) != 1 {
58-
return nil, fmt.Errorf("incorrect number of restoration results, number of results: %v", len(list.Payload.Results))
67+
if len(prefixesWithExactPrefixLength) > 1 {
68+
return nil, fmt.Errorf("too many restoration results found in NetBox for hash %s and prefix length %s, number of results: %v", hash, requestedPrefixLength, len(prefixesWithExactPrefixLength))
69+
} else if len(prefixesWithExactPrefixLength) == 0 {
70+
return nil, fmt.Errorf("no prefix found in NetBox with restoration hash %s and prefix length %s", hash, requestedPrefixLength)
5971
}
60-
res := list.Payload.Results[0]
61-
if res.Prefix == nil {
62-
return nil, errors.New("prefix in netbox is nil")
72+
res := prefixesWithExactPrefixLength[0]
73+
if res.Prefix == "" {
74+
return nil, errors.New("prefix in netbox is empty")
6375
}
6476

6577
return &models.Prefix{
66-
Prefix: *res.Prefix,
78+
Prefix: res.Prefix,
6779
}, nil
6880
}
6981

tests/e2e/Prefix/IPv4/prefixclaim-ipv4-parentprefix-restore/chainsaw-test.yaml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,57 @@ spec:
129129
tenant: MY_TENANT
130130
customFields:
131131
netboxOperatorRestorationHash: 00b8772de73cdac083b0732d5bb85ab4f0caa16c
132+
- name: Apply Prerequisite Prefix for CR 3
133+
try:
134+
- apply:
135+
file: netbox_v1_prefix_3-wrong-length.yaml
136+
- assert:
137+
resource:
138+
apiVersion: netbox.dev/v1
139+
kind: Prefix
140+
metadata:
141+
name: prefixclaim-ipv4-parentprefix-restore-3-prefix-with-wrong-length
142+
spec:
143+
comments: your comments
144+
customFields:
145+
netboxOperatorRestorationHash: 1309280893365bfd94710d148379a6f501a46afe
146+
description: some description
147+
prefix: 2.0.3.224/27
148+
site: MY_SITE
149+
tenant: MY_TENANT
150+
status:
151+
(conditions[?type == 'Ready']):
152+
- status: 'True'
153+
- name: Apply CR 3
154+
try:
155+
- apply:
156+
file: netbox_v1_prefixclaim_3.yaml
157+
- name: Check CR 3 spec and status, verify mismatched length doesn't assign wrong prefix
158+
try:
159+
- assert:
160+
resource:
161+
apiVersion: netbox.dev/v1
162+
kind: PrefixClaim
163+
metadata:
164+
labels:
165+
app.kubernetes.io/name: netbox-operator
166+
app.kubernetes.io/managed-by: kustomize
167+
name: prefixclaim-ipv4-parentprefix-restore-3
168+
spec:
169+
tenant: "MY_TENANT"
170+
site: "MY_SITE"
171+
description: "some description"
172+
comments: "your comments"
173+
preserveInNetbox: false
174+
parentPrefix: "2.0.3.0/24"
175+
prefixLength: "/28"
176+
status:
177+
(conditions[?type == 'PrefixAssigned']):
178+
- reason: PrefixCRNotCreated
179+
message: 'Failed to assign prefix, prefix CR creation skipped: no prefix found in NetBox with restoration hash 1309280893365bfd94710d148379a6f501a46afe and prefix length /28'
180+
status: 'False'
181+
(conditions[?type == 'Ready']):
182+
- status: 'False'
132183
- name: Set preserveInNetbox to false
133184
description: Set preserveInNetbox to false to clean up the NetBox test instance
134185
try:
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: netbox.dev/v1
2+
kind: Prefix
3+
metadata:
4+
labels:
5+
app.kubernetes.io/name: netbox-operator
6+
app.kubernetes.io/managed-by: kustomize
7+
name: prefixclaim-ipv4-parentprefix-restore-3-prefix-with-wrong-length
8+
spec:
9+
comments: your comments
10+
customFields:
11+
netboxOperatorRestorationHash: 1309280893365bfd94710d148379a6f501a46afe
12+
description: some description
13+
preserveInNetbox: false
14+
site: MY_SITE
15+
tenant: MY_TENANT
16+
prefix: "2.0.3.224/27" # this is the prefix that we expect to mismatch during restore
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: netbox.dev/v1
2+
kind: PrefixClaim
3+
metadata:
4+
labels:
5+
app.kubernetes.io/name: netbox-operator
6+
app.kubernetes.io/managed-by: kustomize
7+
name: prefixclaim-ipv4-parentprefix-restore-3
8+
spec:
9+
tenant: "MY_TENANT"
10+
site: "MY_SITE"
11+
description: "some description"
12+
comments: "your comments"
13+
preserveInNetbox: false
14+
parentPrefix: "2.0.3.0/24"
15+
prefixLength: "/28"

0 commit comments

Comments
 (0)