Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add integer and boolean data types for the custom fields #121

Closed
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
35 changes: 29 additions & 6 deletions api/v1/prefixclaim_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,20 @@ import (
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

// PrefixClaimSpec defines the desired state of PrefixClaim
// TODO: The reason for using a workaround please see https://github.com/netbox-community/netbox-operator/pull/90#issuecomment-2402112475
// +kubebuilder:validation:XValidation:rule="(!has(self.parentPrefix) && has(self.parentPrefixSelector)) || (has(self.parentPrefix) && !has(self.parentPrefixSelector))"
type PrefixClaimSpec struct {

// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file

//+kubebuilder:validation:Required
//+kubebuilder:validation:Format=cidr
//+kubebuilder:validation:XValidation:rule="self == oldSelf",message="Field 'parentPrefix' is immutable"
ParentPrefix string `json:"parentPrefix"`
ParentPrefix string `json:"parentPrefix,omitempty"`

// TODO(henrybear327): validate the key and value are all of type string
//+kubebuilder:validation:XValidation:rule="self == oldSelf",message="Field 'parentPrefixSelector' is immutable"
ParentPrefixSelector map[string]string `json:"parentPrefixSelector,omitempty"`

//+kubebuilder:validation:Required
//+kubebuilder:validation:Pattern=`^\/[0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]$`
Expand All @@ -56,16 +62,19 @@ type PrefixClaimSpec struct {
type PrefixClaimStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Prefix status: container, active, reserved , deprecated
Prefix string `json:"prefix,omitempty"`
PrefixName string `json:"prefixName,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
// Prefix status: container, active, reserved, deprecated

ParentPrefix string `json:"parentPrefix,omitempty"` // Due to the fact that we can use ParentPrefixSelector to assign parent prefixes, we use this field to store exactly which parent prefix we are using for prefix allocation
Prefix string `json:"prefix,omitempty"`
PrefixName string `json:"prefixName,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Prefix",type=string,JSONPath=`.status.prefix`
// +kubebuilder:printcolumn:name="PrefixAssigned",type=string,JSONPath=`.status.conditions[?(@.type=="PrefixAssigned")].status`
// +kubebuilder:printcolumn:name="ParentPrefix",type=string,JSONPath=`.status.parentPrefix`
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:resource:shortName=pxc
Expand Down Expand Up @@ -118,3 +127,17 @@ var ConditionPrefixAssignedFalse = metav1.Condition{
Reason: "PrefixCRNotCreated",
Message: "Failed to fetch new Prefix from NetBox",
}

var ConditionParentPrefixComputedTrue = metav1.Condition{
Type: "ParentPrefixComputed",
Status: "True",
Reason: "ParentPrefixComputed",
Message: "The parent prefix was computed successfully",
}

var ConditionParentPrefixComputedFalse = metav1.Condition{
Type: "ParentPrefixComputed",
Status: "False",
Reason: "ParentPrefixNotComputed",
Message: "The parent prefix was not able to be computed",
}
7 changes: 7 additions & 0 deletions api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 20 additions & 6 deletions config/crd/bases/netbox.dev_prefixclaims.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ spec:
- jsonPath: .status.conditions[?(@.type=="PrefixAssigned")].status
name: PrefixAssigned
type: string
- jsonPath: .status.parentPrefix
name: ParentPrefix
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Ready
type: string
Expand Down Expand Up @@ -52,7 +55,9 @@ spec:
metadata:
type: object
spec:
description: PrefixClaimSpec defines the desired state of PrefixClaim
description: |-
PrefixClaimSpec defines the desired state of PrefixClaim
TODO: The reason for using a workaround please see https://github.com/netbox-community/netbox-operator/pull/90#issuecomment-2402112475
properties:
comments:
type: string
Expand All @@ -68,6 +73,15 @@ spec:
x-kubernetes-validations:
- message: Field 'parentPrefix' is immutable
rule: self == oldSelf
parentPrefixSelector:
additionalProperties:
type: string
description: 'TODO(henrybear327): validate the key and value are all
of type string'
type: object
x-kubernetes-validations:
- message: Field 'parentPrefixSelector' is immutable
rule: self == oldSelf
prefixLength:
pattern: ^\/[0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]$
type: string
Expand All @@ -84,9 +98,11 @@ spec:
- message: Field 'tenant' is immutable
rule: self == oldSelf
required:
- parentPrefix
- prefixLength
type: object
x-kubernetes-validations:
- rule: (!has(self.parentPrefix) && has(self.parentPrefixSelector)) ||
(has(self.parentPrefix) && !has(self.parentPrefixSelector))
status:
description: PrefixClaimStatus defines the observed state of PrefixClaim
properties:
Expand Down Expand Up @@ -159,11 +175,9 @@ spec:
- type
type: object
type: array
parentPrefix:
type: string
prefix:
description: |-
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
Important: Run "make" to regenerate code after modifying this file
Prefix status: container, active, reserved , deprecated
type: string
prefixName:
type: string
Expand Down
1 change: 1 addition & 0 deletions config/samples/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ resources:
- netbox_v1_ipaddressclaim.yaml
- netbox_v1_prefix.yaml
- netbox_v1_prefixclaim.yaml
- netbox_v1_prefixclaim_customfields.yaml
#+kubebuilder:scaffold:manifestskustomizesamples
19 changes: 19 additions & 0 deletions config/samples/netbox_v1_prefixclaim_customfields.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: netbox.dev/v1
kind: PrefixClaim
metadata:
labels:
app.kubernetes.io/name: netbox-operator
app.kubernetes.io/managed-by: kustomize
name: prefixclaim-customfields-sample
spec:
tenant: "Dunder-Mifflin, Inc."
site: "DataCenter"
description: "some description"
comments: "your comments"
preserveInNetbox: true
prefixLength: "/31"
parentPrefixSelector: # notice that the keys and values are case-sensitive
environment: "Production"
poolName: "Pool 1"
# environment: "production"
# poolName: "pool 3"
28 changes: 28 additions & 0 deletions config/samples/netbox_v1_prefixclaim_customfields_bool_int.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: netbox.dev/v1
kind: PrefixClaim
metadata:
labels:
app.kubernetes.io/name: netbox-operator
app.kubernetes.io/managed-by: kustomize
name: prefixclaim-customfields-sample-4
spec:
tenant: "Dunder-Mifflin, Inc."
site: "DataCenter"
description: "some description"
comments: "your comments"
preserveInNetbox: true
prefixLength: "/31"
parentPrefixSelector: # notice that the keys and values are case-sensitive
# should return a prefix in 3.0.0.0/24
environment: "Production"
poolName: "Pool 1"
# same condition as above, should return a prefix in 3.0.0.0/24
# cfDataTypeBool: "true"
# cfDataTypeInteger: "1"

# should return a prefix in 3.0.2.0/24
# environment: "Development"
# poolName: "Pool 1"
# same condition as above, should return a prefix in 3.0.0.0/24
# cfDataTypeBool: "false"
# cfDataTypeInteger: "2"
5 changes: 2 additions & 3 deletions internal/controller/ipaddress_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,8 @@ func (r *IpAddressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
// create lock
locked := ll.TryLock(lockCtx)
if !locked {
logger.Info(fmt.Sprintf("failed to lock parent prefix %s", ipAddressClaim.Spec.ParentPrefix))
r.Recorder.Eventf(o, corev1.EventTypeWarning, "FailedToLockParentPrefix", "failed to lock parent prefix %s",
ipAddressClaim.Spec.ParentPrefix)
errorMsg := fmt.Sprintf("failed to lock parent prefix %s", ipAddressClaim.Spec.ParentPrefix)
r.Recorder.Eventf(o, corev1.EventTypeWarning, "FailedToLockParentPrefix", errorMsg)
return ctrl.Result{
RequeueAfter: 2 * time.Second,
}, nil
Expand Down
8 changes: 3 additions & 5 deletions internal/controller/ipaddressclaim_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"time"

netboxv1 "github.com/netbox-community/netbox-operator/api/v1"
"github.com/netbox-community/netbox-operator/pkg/config"
"github.com/netbox-community/netbox-operator/pkg/netbox/api"
"github.com/netbox-community/netbox-operator/pkg/netbox/models"
"github.com/swisscom/leaselocker"
Expand Down Expand Up @@ -111,9 +110,8 @@ func (r *IpAddressClaimReconciler) Reconcile(ctx context.Context, req ctrl.Reque
locked := ll.TryLock(lockCtx)
if !locked {
// lock for parent prefix was not available, rescheduling
logger.Info(fmt.Sprintf("failed to lock parent prefix %s", o.Spec.ParentPrefix))
r.Recorder.Eventf(o, corev1.EventTypeWarning, "FailedToLockParentPrefix", "failed to lock parent prefix %s",
o.Spec.ParentPrefix)
errorMsg := fmt.Sprintf("failed to lock parent prefix %s", o.Spec.ParentPrefix)
r.Recorder.Eventf(o, corev1.EventTypeWarning, "FailedToLockParentPrefix", errorMsg)
return ctrl.Result{
RequeueAfter: 2 * time.Second,
}, nil
Expand All @@ -122,7 +120,7 @@ func (r *IpAddressClaimReconciler) Reconcile(ctx context.Context, req ctrl.Reque

// 4. try to reclaim ip address
h := generateIpAddressRestorationHash(o)
ipAddressModel, err := r.NetboxClient.RestoreExistingIpByHash(config.GetOperatorConfig().NetboxRestorationHashFieldName, h)
ipAddressModel, err := r.NetboxClient.RestoreExistingIpByHash(h)
if err != nil {
if setConditionErr := r.SetConditionAndCreateEvent(ctx, o, netboxv1.ConditionIpAssignedFalse, corev1.EventTypeWarning, err.Error()); setConditionErr != nil {
return ctrl.Result{}, fmt.Errorf("error updating status: %w, looking up ip by hash failed: %w", setConditionErr, err)
Expand Down
20 changes: 14 additions & 6 deletions internal/controller/prefix_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,19 @@ func (r *PrefixReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, err
}

if prefixClaim.Status.ParentPrefix == "" {
// the parent prefix is not computed
if err := r.SetConditionAndCreateEvent(ctx, prefix, netboxv1.ConditionPrefixReadyFalse, corev1.EventTypeWarning, "the parent prefix is not computed"); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{
Requeue: true,
}, nil
}

// get the name of the parent prefix
leaseLockerNSN := types.NamespacedName{
Name: convertCIDRToLeaseLockName(prefixClaim.Spec.ParentPrefix),
Name: convertCIDRToLeaseLockName(prefixClaim.Status.ParentPrefix),
Namespace: r.OperatorNamespace,
}
ll, err = leaselocker.NewLeaseLocker(r.RestConfig, leaseLockerNSN, req.NamespacedName.String())
Expand All @@ -147,14 +157,13 @@ func (r *PrefixReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr

// create lock
if locked := ll.TryLock(lockCtx); !locked {
logger.Info(fmt.Sprintf("failed to lock parent prefix %s", prefixClaim.Spec.ParentPrefix))
r.Recorder.Eventf(prefix, corev1.EventTypeWarning, "FailedToLockParentPrefix", "failed to lock parent prefix %s",
prefixClaim.Spec.ParentPrefix)
errorMsg := fmt.Sprintf("failed to lock parent prefix %s", prefixClaim.Status.ParentPrefix)
r.Recorder.Eventf(prefix, corev1.EventTypeWarning, "FailedToLockParentPrefix", errorMsg)
return ctrl.Result{
RequeueAfter: 2 * time.Second,
}, nil
}
debugLogger.Info("successfully locked parent prefix %s", prefixClaim.Spec.ParentPrefix)
debugLogger.Info("successfully locked parent prefix %s", prefixClaim.Status.ParentPrefix)
}

/* 2. reserve or update Prefix in netbox */
Expand Down Expand Up @@ -218,7 +227,6 @@ func (r *PrefixReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
}

debugLogger.Info(fmt.Sprintf("reserved prefix in netbox, prefix: %s", prefix.Spec.Prefix))

if err = r.SetConditionAndCreateEvent(ctx, prefix, netboxv1.ConditionPrefixReadyTrue, corev1.EventTypeNormal, ""); err != nil {
return ctrl.Result{}, err
}
Expand Down
Loading