Skip to content

Commit

Permalink
add tenancy checks for ip address and prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
MaIT-HgA authored and Hoanganh.Mai committed Sep 30, 2024
2 parents ecbbec2 + 110cbb7 commit ce930f7
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 48 deletions.
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ body:
id: config
attributes:
label: Netbox operator configuration (command line flags or environment variables)
value: |
# paste your configuration here
description: Please copy and paste your configuration here.
render: Shell

- type: textarea
id: logs
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/build-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,18 @@ jobs:
with:
images: ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
tags: |
# for commits on the main branch only, we will generate the tag named `latest`
# (for commits on the main branch only) generate a tag named `latest`
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
# the tag named sha-[short sha value] will be generated in all cases
# (for all commits) generate a tag named sha-[short sha value]
type=sha,enable=true
# (for tagged commits only) generate tags identical to the git tag version, with and without the leading v
type=semver,pattern={{raw}},enable=${{startsWith(github.ref, 'refs/tags/v')}}
type=semver,pattern={{version}},enable=${{startsWith(github.ref, 'refs/tags/v')}}
- name: Build and push
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: ${{ github.ref == format('refs/heads/{0}', 'main') }}
# we push only if the pipeline is run against the commits on main branch or a tag
push: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ require (
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.20.3 // indirect
github.com/prometheus/client_golang v1.20.4 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.59.1 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
Expand All @@ -82,7 +82,7 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.mongodb.org/mongo-driver v1.16.1 // indirect
go.mongodb.org/mongo-driver v1.17.0 // indirect
go.opentelemetry.io/otel v1.30.0 // indirect
go.opentelemetry.io/otel/metric v1.30.0 // indirect
go.opentelemetry.io/otel/trace v1.30.0 // indirect
Expand All @@ -96,7 +96,7 @@ require (
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.24.0 // indirect
golang.org/x/tools v0.25.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0=
Expand Down Expand Up @@ -156,8 +156,8 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.mongodb.org/mongo-driver v1.16.1 h1:rIVLL3q0IHM39dvE+z2ulZLp9ENZKThVfuvN/IiN4l8=
go.mongodb.org/mongo-driver v1.16.1/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
go.mongodb.org/mongo-driver v1.17.0 h1:Hp4q2MCjvY19ViwimTs00wHi7G4yzxh4/2+nTx8r40k=
go.mongodb.org/mongo-driver v1.17.0/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4=
go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
Expand Down Expand Up @@ -212,8 +212,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
39 changes: 22 additions & 17 deletions internal/controller/ipaddress_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,6 @@ func (r *IpAddressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
return ctrl.Result{}, nil
}

// if PreserveIpInNetbox flag is false then register finalizer if not yet registered
if !o.Spec.PreserveInNetbox && !controllerutil.ContainsFinalizer(o, IpAddressFinalizerName) {
debugLogger.Info("adding the finalizer")
controllerutil.AddFinalizer(o, IpAddressFinalizerName)
if err := r.Update(ctx, o); err != nil {
return ctrl.Result{}, err
}
}

// 1. try to lock lease of parent prefix if IpAddress status condition is not true
// and IpAddress is owned by an IpAddressClaim
or := o.ObjectMeta.OwnerReferences
Expand Down Expand Up @@ -170,6 +161,19 @@ func (r *IpAddressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
"after reservation of ip in netbox failed: %w", updateStatusErr, err)
}

// 3. unlock lease of parent prefix
if ll != nil {
ll.Unlock()
}

// 4. update status fields
o.Status.IpAddressId = netboxIpAddressModel.ID
o.Status.IpAddressUrl = config.GetBaseUrl() + "/ipam/ip-addresses/" + strconv.FormatInt(netboxIpAddressModel.ID, 10)
err = r.Client.Status().Update(ctx, o)
if err != nil {
return ctrl.Result{}, err
}

// update lastIpAddressMetadata annotation
if annotations == nil {
annotations = make(map[string]string)
Expand Down Expand Up @@ -202,16 +206,17 @@ func (r *IpAddressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
r.Recorder.Event(o, corev1.EventTypeWarning, "IpDescriptionTruncated", "ip address was created with truncated description")
}

debugLogger.Info(fmt.Sprintf("reserved ip address in netbox, ip: %s", o.Spec.IpAddress))

// 3. unlock lease of parent prefix
if ll != nil {
ll.Unlock()
// if PreserveIpInNetbox flag is false then register finalizer if not yet registered
if !o.Spec.PreserveInNetbox && !controllerutil.ContainsFinalizer(o, IpAddressFinalizerName) {
debugLogger.Info("adding the finalizer")
controllerutil.AddFinalizer(o, IpAddressFinalizerName)
if err := r.Update(ctx, o); err != nil {
return ctrl.Result{}, err
}
}

// 4. update status conditions
o.Status.IpAddressId = netboxIpAddressModel.ID
o.Status.IpAddressUrl = config.GetBaseUrl() + "/ipam/ip-addresses/" + strconv.FormatInt(netboxIpAddressModel.ID, 10)
debugLogger.Info(fmt.Sprintf("reserved ip address in netbox, ip: %s", o.Spec.IpAddress))

err = r.SetConditionAndCreateEvent(ctx, o, netboxv1.ConditionIpaddressReadyTrue, corev1.EventTypeNormal, "")
if err != nil {
return ctrl.Result{}, err
Expand Down
39 changes: 22 additions & 17 deletions internal/controller/prefix_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,6 @@ func (r *PrefixReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, nil
}

// register finalizer if not yet registered
if !prefix.Spec.PreserveInNetbox && !controllerutil.ContainsFinalizer(prefix, PrefixFinalizerName) {
debugLogger.Info("adding the finalizer")
controllerutil.AddFinalizer(prefix, PrefixFinalizerName)
if err := r.Update(ctx, prefix); err != nil {
return ctrl.Result{}, err
}
}

/*
1. try to lock the lease of the parent prefix if all of the following conditions are met
- the prefix is owned by at least 1 prefixClaim
Expand Down Expand Up @@ -168,6 +159,19 @@ func (r *PrefixReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, fmt.Errorf("failed at update prefix status: %w, "+"after reservation of prefix in netbox failed: %w", updateStatusErr, err)
}

/* 3. unlock lease of parent prefix */
if ll != nil {
ll.Unlock()
}

/* 4. update status fields */
prefix.Status.PrefixId = netboxPrefixModel.ID
prefix.Status.PrefixUrl = config.GetBaseUrl() + "/ipam/prefixes/" + strconv.FormatInt(netboxPrefixModel.ID, 10)
err = r.Client.Status().Update(ctx, prefix)
if err != nil {
return ctrl.Result{}, err
}

// update lastPrefixMetadata annotation
if annotations == nil {
annotations = make(map[string]string)
Expand Down Expand Up @@ -197,16 +201,17 @@ func (r *PrefixReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
r.Recorder.Event(prefix, corev1.EventTypeWarning, "PrefixDescriptionTruncated", "prefix was created with truncated description")
}

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

/* 3. unlock lease of parent prefix */
if ll != nil {
ll.Unlock()
// register finalizer if not yet registered
if !prefix.Spec.PreserveInNetbox && !controllerutil.ContainsFinalizer(prefix, PrefixFinalizerName) {
debugLogger.Info("adding the finalizer")
controllerutil.AddFinalizer(prefix, PrefixFinalizerName)
if err := r.Update(ctx, prefix); err != nil {
return ctrl.Result{}, err
}
}

/* 4. update status conditions */
prefix.Status.PrefixId = netboxPrefixModel.ID
prefix.Status.PrefixUrl = config.GetBaseUrl() + "/ipam/prefixes/" + strconv.FormatInt(netboxPrefixModel.ID, 10)
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
1 change: 1 addition & 0 deletions pkg/netbox/api/ip_address_claim.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func (r *NetboxClient) RestoreExistingIpByHash(customFieldName string, hash stri

// GetAvailableIpAddressByClaim searches an available IpAddress in Netbox matching IpAddressClaim requirements
func (r *NetboxClient) GetAvailableIpAddressByClaim(ipAddressClaim *models.IPAddressClaim) (*models.IPAddress, error) {
// Note: the check passes for empty tenant and not for non-existing tenants
_, err := r.GetTenantDetails(ipAddressClaim.Metadata.Tenant)
if err != nil {
return nil, err
Expand Down
1 change: 1 addition & 0 deletions pkg/netbox/api/prefix_claim.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func isRequestingTheEntireParentPrefix(prefixClaim *models.PrefixClaim) (bool, e

// GetAvailablePrefixByClaim searches an available Prefix in Netbox matching PrefixClaim requirements
func (r *NetboxClient) GetAvailablePrefixByClaim(prefixClaim *models.PrefixClaim) (*models.Prefix, error) {
// Note: the check passes for empty tenant and not for non-existing tenants
_, err := r.GetTenantDetails(prefixClaim.Metadata.Tenant)
if err != nil {
return nil, err
Expand Down

0 comments on commit ce930f7

Please sign in to comment.