diff --git a/.github/env b/.github/env new file mode 100644 index 00000000..b84dad01 --- /dev/null +++ b/.github/env @@ -0,0 +1,3 @@ +golang-version=1.23 +kind-version=v0.25.0 +kind-image=kindest/node:v1.31.2 diff --git a/.github/workflows/e2e-tests.yaml b/.github/workflows/e2e-tests.yaml new file mode 100644 index 00000000..280d1ee2 --- /dev/null +++ b/.github/workflows/e2e-tests.yaml @@ -0,0 +1,77 @@ +# Modified from https://github.com/prometheus-operator/prometheus-operator/blob/main/.github/workflows/e2e-feature-gated.yaml +name: e2e-tests +on: + push: + branches: + - main + tags: + - v* + pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +env: + NETBOX_HOST: demo.netbox.dev + AUTH_TOKEN: 0123456789abcdef0123456789abcdef01234567 + POD_NAMESPACE: default + HTTPS_ENABLE: true + NETBOX_RESTORATION_HASH_FIELD_NAME: netboxOperatorRestorationHash +jobs: + e2e-tests: + name: E2E tests for netbox operator + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version: 1.23.4 + - name: Install Chainsaw + uses: kyverno/action-install-chainsaw@f2b47b97dc889c12702113753d713f01ec268de5 #v0.2.12 + - name: Check Chainsaw installation + run: chainsaw version + - name: Import environment variables from file + run: | + cat ".github/env" >> "$GITHUB_ENV" + echo "E2E_DIAGNOSTIC_DIRECTORY=$(mktemp -d)" >> "$GITHUB_ENV" + - name: Start kind cluster + uses: helm/kind-action@0025e74a8c7512023d06dc019c617aa3cf561fde # v1.10.0 + with: + version: ${{ env.kind-version }} + node_image: ${{ env.kind-image }} + wait: 300s + config: ./tests/e2e/kind-config.yaml + cluster_name: e2e + - name: Wait for cluster to finish bootstraping + run: | + echo "Waiting for all nodes to be ready..." + kubectl wait --for=condition=Ready nodes --all --timeout=120s + kubectl get nodes + echo "Waiting for all pods to be ready..." + kubectl wait --for=condition=Ready pods --all --all-namespaces --timeout=300s + kubectl get pods -A + echo "Cluster information" + kubectl cluster-info + - name: Setup kind cluster with required software such as NetBox + run: | + make create-kind + - name: Deploy NetBox operator to the kind cluster + run: | + make deploy-kind + - name: Run tests + env: + E2E_DIAGNOSTIC_DIRECTORY: ${{ env.E2E_DIAGNOSTIC_DIRECTORY }} + run: | + # # Very straight forward way of implementing a test and checking the result + # kubectl apply -f config/samples/netbox_v1_prefixclaim.yaml + # kubectl get prefixclaim,prefix,ipaddressclaim,ipaddress,iprange,iprangeclaim + # kubectl wait --for=condition=ready --timeout=30s prefixclaim.netbox.dev/prefixclaim-sample + + # Use Chainsaw + make test-e2e + - name: Upload diagnostics artifact + if: ${{ failure() }} + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + with: + name: cluster-state + path: ${{ env.E2E_DIAGNOSTIC_DIRECTORY }} + retention-days: 15 diff --git a/.gitignore b/.gitignore index 6eabc0a3..ea12f279 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ Dockerfile.cross # Test binary, built with `go test -c` *.test +database.sql # Output of the go coverage tool, specifically when used with LiteIDE *.out diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bc2cc647..0c7fdc22 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,14 +26,13 @@ To optionally access the NetBox UI: - Port-forward NetBox: `kubectl port-forward deploy/netbox 8080:8080 -n default` - Open in your favorite browser and log in with the username `admin` and password `admin`, you will be able to access the local NetBox instance running in the kind cluster. - Open a new terminal window and export the following environment variables: - - ```bash - export NETBOX_HOST="localhost:8080" - export AUTH_TOKEN="0123456789abcdef0123456789abcdef01234567" - export POD_NAMESPACE="default" - export HTTPS_ENABLE="false" - export NETBOX_RESTORATION_HASH_FIELD_NAME="netboxOperatorRestorationHash" - ``` + ```bash + export NETBOX_HOST="localhost:8080" + export AUTH_TOKEN="0123456789abcdef0123456789abcdef01234567" + export POD_NAMESPACE="default" + export HTTPS_ENABLE="false" + export NETBOX_RESTORATION_HASH_FIELD_NAME="netboxOperatorRestorationHash" + ``` - Run the NetBox Operator locally `make install && make run` @@ -46,14 +45,13 @@ Note: This requires a running NetBox instance that you can use (e.g. and create a token "0123456789abcdef0123456789abcdef01234567" with default settings - Open and create a custom field called "netboxOperatorRestorationHash" for Object types "IPAM > IP Address" and "IPAM > Prefix" - Open a new terminal window and export the following environment variables: - - ```bash - export NETBOX_HOST="demo.netbox.dev" - export AUTH_TOKEN="0123456789abcdef0123456789abcdef01234567" - export POD_NAMESPACE="default" - export HTTPS_ENABLE="true" - export NETBOX_RESTORATION_HASH_FIELD_NAME="netboxOperatorRestorationHash" - ``` + ```bash + export NETBOX_HOST="demo.netbox.dev" + export AUTH_TOKEN="0123456789abcdef0123456789abcdef01234567" + export POD_NAMESPACE="default" + export HTTPS_ENABLE="true" + export NETBOX_RESTORATION_HASH_FIELD_NAME="netboxOperatorRestorationHash" + ``` - Run the NetBox Operator locally `make install && make run` @@ -130,3 +128,9 @@ make undeploy Run `make help` for more information on all potential `make` targets More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) + +## Running e2e tests locally + +Please read the [README in the e2e test directory] for more information! + +[README in the e2e test directory]: ./tests/e2e/README.md diff --git a/Makefile b/Makefile index cf20441f..2c32f85e 100644 --- a/Makefile +++ b/Makefile @@ -226,3 +226,7 @@ $(ENVTEST): $(LOCALBIN) generate_mocks: # TODO: auto install go install go.uber.org/mock/mockgen@latest mkdir -p ${GEN_DIR} mockgen -destination ${GEN_DIR}/${NETBOX_MOCKS_OUTPUT_FILE} -source=${INTERFACE_DEFITIONS_DIR} + +.PHONY: test-e2e +test-e2e: # notice that if we apply several CRs at the same time, the IP/Prefix/etc. allocated to the CR might differ each time due to the timing of execution for reservation on the NetBox side + chainsaw test --namespace e2e diff --git a/README.md b/README.md index f039d545..76df1d87 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,6 @@ Please read [ParentPrefixSelector guide] for more information! [ParentPrefixSelector guide]: ./ParentPrefixSelectorGuide.md - # Project Distribution Following are the steps to build the installer and distribute this project to users. diff --git a/kind/load-data-job/local-demo-data.sql b/kind/load-data-job/local-demo-data.sql index b9900e96..f2cf3853 100644 --- a/kind/load-data-job/local-demo-data.sql +++ b/kind/load-data-job/local-demo-data.sql @@ -63,6 +63,14 @@ VALUES ('2024-06-14 09:57:11.709344+00', '2024-06-14 09:57:11.709359+00', '{"cus INSERT INTO public.ipam_prefix (created, last_updated, custom_field_data, prefix, status, is_pool, description, role_id, site_id, tenant_id, vlan_id, vrf_id, _children, _depth, mark_utilized, comments) VALUES ('2024-06-14 10:01:10.094083+00', '2024-06-14 10:01:10.094095+00', '{}', '2.0.0.0/16', 'active', false, '', NULL, NULL, 100, NULL, NULL, 0, 0, false, ''); +-- 2.1.0.0/24 +INSERT INTO public.ipam_prefix (created, last_updated, custom_field_data, prefix, status, is_pool, description, role_id, site_id, tenant_id, vlan_id, vrf_id, _children, _depth, mark_utilized, comments) +VALUES ('2024-06-14 10:01:10.094083+00', '2024-06-14 10:01:10.094095+00', '{}', '2.1.0.0/24', 'active', false, '', NULL, NULL, 100, NULL, NULL, 0, 0, false, ''); + +-- 2.2.0.0/24 +INSERT INTO public.ipam_prefix (created, last_updated, custom_field_data, prefix, status, is_pool, description, role_id, site_id, tenant_id, vlan_id, vrf_id, _children, _depth, mark_utilized, comments) +VALUES ('2024-06-14 10:01:10.094083+00', '2024-06-14 10:01:10.094095+00', '{}', '2.2.0.0/24', 'active', false, '', NULL, NULL, 100, NULL, NULL, 0, 0, false, ''); + -- 3.0.0.0/24 - 3.0.8.0/24 (watch out for the upper/lower-case) -- Pool 1, Production (IPv4) INSERT INTO public.ipam_prefix (created, last_updated, custom_field_data, prefix, status, is_pool, description, role_id, site_id, tenant_id, vlan_id, vrf_id, _children, _depth, mark_utilized, comments) diff --git a/kind/local-env.sh b/kind/local-env.sh index 3cc87056..c56640d9 100755 --- a/kind/local-env.sh +++ b/kind/local-env.sh @@ -51,4 +51,3 @@ helm upgrade --install --namespace="${NAMESPACE}" netbox \ https://github.com/netbox-community/netbox-chart/releases/download/netbox-5.0.0-beta.34/netbox-5.0.0-beta.34.tgz kubectl rollout status --namespace="${NAMESPACE}" deployment netbox - diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/chainsaw-test.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/chainsaw-test.yaml new file mode 100644 index 00000000..f015148e --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/chainsaw-test.yaml @@ -0,0 +1,95 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: prefixclaim-ipv4-apply-exhausted +spec: + steps: + - name: Install CR 1 + description: Apply prefix claim CR 1 + try: + - apply: + file: netbox_v1_prefixclaim_1.yaml + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-apply-prefixexhausted-1 + spec: + comments: your comments + description: some description + parentPrefix: 2.1.0.0/24 + prefixLength: /25 + preserveInNetbox: false + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 2.1.0.0/24 + prefix: 2.1.0.0/25 + prefixName: prefixclaim-ipv4-apply-prefixexhausted-1 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-apply-prefixexhausted-1 + spec: + comments: your comments + description: some description + prefix: 2.1.0.0/25 + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + - name: Install CR 2 + description: Apply prefix claim CR 2 + try: + - apply: + file: netbox_v1_prefixclaim_2.yaml + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-apply-prefixexhausted-2 + spec: + comments: your comments + description: some description + parentPrefix: 2.1.0.0/24 + prefixLength: /25 + preserveInNetbox: false + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 2.1.0.0/24 + prefix: 2.1.0.128/25 + prefixName: prefixclaim-ipv4-apply-prefixexhausted-2 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-apply-prefixexhausted-2 + spec: + comments: your comments + description: some description + prefix: 2.1.0.128/25 + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + - name: Install CR 3 + description: Apply prefix claim CR 3 + try: + - apply: + file: netbox_v1_prefixclaim_3.yaml + - assert: + resource: + apiVersion: v1 + count: 1 + kind: Event + type: Warning + reason: PrefixCRNotCreated + source: + component: prefix-claim-controller + message: Failed to fetch new Prefix from NetBox. parent prefix exhausted, will restart the parent prefix selection process + involvedObject: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + name: prefixclaim-ipv4-apply-prefixexhausted-3 diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/netbox_v1_prefixclaim_1.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/netbox_v1_prefixclaim_1.yaml new file mode 100644 index 00000000..3df56390 --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/netbox_v1_prefixclaim_1.yaml @@ -0,0 +1,15 @@ +apiVersion: netbox.dev/v1 +kind: PrefixClaim +metadata: + labels: + app.kubernetes.io/name: netbox-operator + app.kubernetes.io/managed-by: kustomize + name: prefixclaim-ipv4-apply-prefixexhausted-1 +spec: + tenant: "Dunder-Mifflin, Inc." + site: "DM-Akron" + description: "some description" + comments: "your comments" + preserveInNetbox: false + parentPrefix: "2.1.0.0/24" + prefixLength: "/25" diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/netbox_v1_prefixclaim_2.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/netbox_v1_prefixclaim_2.yaml new file mode 100644 index 00000000..6d845454 --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/netbox_v1_prefixclaim_2.yaml @@ -0,0 +1,15 @@ +apiVersion: netbox.dev/v1 +kind: PrefixClaim +metadata: + labels: + app.kubernetes.io/name: netbox-operator + app.kubernetes.io/managed-by: kustomize + name: prefixclaim-ipv4-apply-prefixexhausted-2 +spec: + tenant: "Dunder-Mifflin, Inc." + site: "DM-Akron" + description: "some description" + comments: "your comments" + preserveInNetbox: false + parentPrefix: "2.1.0.0/24" + prefixLength: "/25" diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/netbox_v1_prefixclaim_3.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/netbox_v1_prefixclaim_3.yaml new file mode 100644 index 00000000..25e28979 --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted/netbox_v1_prefixclaim_3.yaml @@ -0,0 +1,15 @@ +apiVersion: netbox.dev/v1 +kind: PrefixClaim +metadata: + labels: + app.kubernetes.io/name: netbox-operator + app.kubernetes.io/managed-by: kustomize + name: prefixclaim-ipv4-apply-prefixexhausted-3 +spec: + tenant: "Dunder-Mifflin, Inc." + site: "DM-Akron" + description: "some description" + comments: "your comments" + preserveInNetbox: false + parentPrefix: "2.1.0.0/24" + prefixLength: "/25" diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithIPv4ParentPrefixSelectorWhenAppliedThenSucceed/chainsaw-test.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithIPv4ParentPrefixSelectorWhenAppliedThenSucceed/chainsaw-test.yaml new file mode 100644 index 00000000..d74dcc4d --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithIPv4ParentPrefixSelectorWhenAppliedThenSucceed/chainsaw-test.yaml @@ -0,0 +1,47 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: prefixclaim-ipv4-parentprefixselector-apply-succeed +spec: + steps: + - name: Apply prefix claim CR and go through each field and check for equality + try: + - apply: + file: netbox_v1_prefixclaim.yaml + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-parentprefixselector-sample + spec: + comments: your comments + description: some description + parentPrefixSelector: + environment: Production + family: IPv4 + poolName: Pool 1 + site: DM-Buffalo + tenant: MY_TENANT + prefixLength: /31 + preserveInNetbox: true + site: DM-Akron + tenant: MY_TENANT + status: + parentPrefix: 3.0.1.0/24 + prefix: 3.0.1.0/31 + prefixName: prefixclaim-ipv4-parentprefixselector-sample + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-parentprefixselector-sample + spec: + comments: your comments + description: some description + prefix: 3.0.1.0/31 + preserveInNetbox: true + tenant: MY_TENANT + customFields: + netboxOperatorRestorationHash: b0d7d37281d2f2735ff188bdfa4eda469e55b684 diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithIPv4ParentPrefixSelectorWhenAppliedThenSucceed/netbox_v1_prefixclaim.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithIPv4ParentPrefixSelectorWhenAppliedThenSucceed/netbox_v1_prefixclaim.yaml new file mode 100644 index 00000000..ce896811 --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithIPv4ParentPrefixSelectorWhenAppliedThenSucceed/netbox_v1_prefixclaim.yaml @@ -0,0 +1,22 @@ +apiVersion: netbox.dev/v1 +kind: PrefixClaim +metadata: + labels: + app.kubernetes.io/name: netbox-operator + app.kubernetes.io/managed-by: kustomize + name: prefixclaim-ipv4-parentprefixselector-sample +spec: + tenant: "MY_TENANT" # Use the `name` value instead of the `slug` value + site: "DM-Akron" # Use the `name` value instead of the `slug` value + description: "some description" + comments: "your comments" + preserveInNetbox: true + prefixLength: "/31" + parentPrefixSelector: # The keys and values are case-sensitive + tenant: "MY_TENANT" # Use the `name` value instead of the `slug` value + site: "DM-Buffalo" # Use the `name` value instead of the `slug` value + family: "IPv4" # Can only be either IPv4 or IPv6" + + # custom fields of your interest + environment: "Production" + poolName: "Pool 1" diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedDeletedAppliedThenRestorationSucceed/chainsaw-test.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedDeletedAppliedThenRestorationSucceed/chainsaw-test.yaml new file mode 100644 index 00000000..202f1130 --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedDeletedAppliedThenRestorationSucceed/chainsaw-test.yaml @@ -0,0 +1,159 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: prefixclaim-ipv4-restoration-succeed +spec: + steps: + - name: Apply prefix claim CR 1 for the first time and go through each field and check for equality + try: + - apply: + file: netbox_v1_prefixclaim_1.yaml + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-apply-delete-apply-restored-1 + spec: + comments: your comments + description: some description + parentPrefix: 2.0.0.0/16 + prefixLength: /28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 2.0.0.0/16 + prefix: 2.0.0.0/28 + prefixName: prefixclaim-ipv4-apply-delete-apply-restored-1 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-apply-delete-apply-restored-1 + spec: + comments: your comments + description: some description + prefix: 2.0.0.0/28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + customFields: + netboxOperatorRestorationHash: 8beafa710a38be8c61ce9c9e85bd734801ae2464 + - name: Apply prefix claim CR 2 for the first time and go through each field and check for equality + try: + - apply: + file: netbox_v1_prefixclaim_2.yaml + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-apply-delete-apply-restored-2 + spec: + comments: your comments + description: some description + parentPrefix: 2.0.0.0/16 + prefixLength: /28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 2.0.0.0/16 + prefix: 2.0.0.16/28 + prefixName: prefixclaim-ipv4-apply-delete-apply-restored-2 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-apply-delete-apply-restored-2 + spec: + comments: your comments + description: some description + prefix: 2.0.0.16/28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + customFields: + netboxOperatorRestorationHash: ac35098e1a755678ced699b581c5615acbb0ed94 + - name: Delete the applied CR 1 + description: delete prefix claim CR 1 (we only delete CR1, so if the restoration failed to claim, it will take the next available prefix which will be wrong) + try: + - delete: + ref: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + name: prefixclaim-ipv4-apply-delete-apply-restored-1 + - name: Apply prefix claim CR 1 for the second time and check after deletion and reapply of CR 1 + description: + try: + - apply: + file: netbox_v1_prefixclaim_1.yaml + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-apply-delete-apply-restored-1 + spec: + comments: your comments + description: some description + parentPrefix: 2.0.0.0/16 + prefixLength: /28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 2.0.0.0/16 + prefix: 2.0.0.0/28 + prefixName: prefixclaim-ipv4-apply-delete-apply-restored-1 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-apply-delete-apply-restored-1 + spec: + comments: your comments + description: some description + prefix: 2.0.0.0/28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + customFields: + netboxOperatorRestorationHash: 8beafa710a38be8c61ce9c9e85bd734801ae2464 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-apply-delete-apply-restored-2 + spec: + comments: your comments + description: some description + parentPrefix: 2.0.0.0/16 + prefixLength: /28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 2.0.0.0/16 + prefix: 2.0.0.16/28 + prefixName: prefixclaim-ipv4-apply-delete-apply-restored-2 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-apply-delete-apply-restored-2 + spec: + comments: your comments + description: some description + prefix: 2.0.0.16/28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + customFields: + netboxOperatorRestorationHash: ac35098e1a755678ced699b581c5615acbb0ed94 diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_1.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_1.yaml new file mode 100644 index 00000000..935ab0ec --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_1.yaml @@ -0,0 +1,15 @@ +apiVersion: netbox.dev/v1 +kind: PrefixClaim +metadata: + labels: + app.kubernetes.io/name: netbox-operator + app.kubernetes.io/managed-by: kustomize + name: prefixclaim-ipv4-apply-delete-apply-restored-1 +spec: + tenant: "Dunder-Mifflin, Inc." + site: "DM-Akron" + description: "some description" + comments: "your comments" + preserveInNetbox: true + parentPrefix: "2.0.0.0/16" + prefixLength: "/28" diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_2.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_2.yaml new file mode 100644 index 00000000..a7a498cd --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_2.yaml @@ -0,0 +1,15 @@ +apiVersion: netbox.dev/v1 +kind: PrefixClaim +metadata: + labels: + app.kubernetes.io/name: netbox-operator + app.kubernetes.io/managed-by: kustomize + name: prefixclaim-ipv4-apply-delete-apply-restored-2 +spec: + tenant: "Dunder-Mifflin, Inc." + site: "DM-Akron" + description: "some description" + comments: "your comments" + preserveInNetbox: true + parentPrefix: "2.0.0.0/16" + prefixLength: "/28" diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedThenSucceed/chainsaw-test.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedThenSucceed/chainsaw-test.yaml new file mode 100644 index 00000000..a4e32d64 --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedThenSucceed/chainsaw-test.yaml @@ -0,0 +1,43 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: prefixclaim-ipv4-apply-succeed +spec: + steps: + - name: Apply prefix claim CR and go through each field and check for equality + try: + - apply: + file: netbox_v1_prefixclaim.yaml + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-apply + spec: + comments: your comments + description: some description + parentPrefix: 2.2.0.0/24 + prefixLength: /28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 2.2.0.0/24 + prefix: 2.2.0.0/28 + prefixName: prefixclaim-ipv4-apply + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-apply + spec: + comments: your comments + description: some description + prefix: 2.2.0.0/28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + customFields: + netboxOperatorRestorationHash: 7a4827d80057860f6e6ab58c317323d1a82431cf diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedThenSucceed/netbox_v1_prefixclaim.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedThenSucceed/netbox_v1_prefixclaim.yaml new file mode 100644 index 00000000..6de1c704 --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenAppliedThenSucceed/netbox_v1_prefixclaim.yaml @@ -0,0 +1,15 @@ +apiVersion: netbox.dev/v1 +kind: PrefixClaim +metadata: + labels: + app.kubernetes.io/name: netbox-operator + app.kubernetes.io/managed-by: kustomize + name: prefixclaim-ipv4-apply +spec: + tenant: "Dunder-Mifflin, Inc." + site: "DM-Akron" + description: "some description" + comments: "your comments" + preserveInNetbox: true + parentPrefix: "2.2.0.0/24" + prefixLength: "/28" diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenParentPrefixSelectorAppliedDeletedAppliedThenRestorationSucceed/chainsaw-test.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenParentPrefixSelectorAppliedDeletedAppliedThenRestorationSucceed/chainsaw-test.yaml new file mode 100644 index 00000000..fbeeeb35 --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenParentPrefixSelectorAppliedDeletedAppliedThenRestorationSucceed/chainsaw-test.yaml @@ -0,0 +1,179 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: prefixclaim-ipv4-parentprefixselector-restoration-succeed +spec: + steps: + - name: Apply prefix claim CR 1 for the first time and go through each field and check for equality + try: + - apply: + file: netbox_v1_prefixclaim_1.yaml + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-1 + spec: + comments: your comments + description: some description + parentPrefixSelector: + environment: Production + family: IPv4 + poolName: Pool 2 + site: DM-Buffalo + tenant: MY_TENANT + prefixLength: /28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 3.0.4.0/24 + prefix: 3.0.4.0/28 + prefixName: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-1 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-1 + spec: + comments: your comments + description: some description + prefix: 3.0.4.0/28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + customFields: + netboxOperatorRestorationHash: f1265230d10c00215cd515759cd44f9622da833f + - name: Apply prefix claim CR 2 for the first time and go through each field and check for equality + try: + - apply: + file: netbox_v1_prefixclaim_2.yaml + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-2 + spec: + comments: your comments + description: some description + parentPrefixSelector: + environment: Production + family: IPv4 + poolName: Pool 2 + site: DM-Buffalo + tenant: MY_TENANT + prefixLength: /28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 3.0.1.0/24 + prefix: 3.0.1.0/28 + prefixName: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-2 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-2 + spec: + comments: your comments + description: some description + prefix: 3.0.1.0/28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + customFields: + netboxOperatorRestorationHash: 98e9822f1444f135a7794bc382a3cdd4162fe941 + - name: Delete the applied CR 1 + description: delete prefix claim CR 1 (we only delete CR1, so if the restoration failed to claim, it will take the next available prefix which will be wrong) + try: + - delete: + ref: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-1 + - name: Apply prefix claim CR 1 for the second time and check after deletion and reapply of CR 1 + description: + try: + - apply: + file: netbox_v1_prefixclaim_1.yaml + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-1 + spec: + comments: your comments + description: some description + parentPrefixSelector: + environment: Production + family: IPv4 + poolName: Pool 2 + site: DM-Buffalo + tenant: MY_TENANT + prefixLength: /28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: Prefix restored from hash, cannot infer the parent prefix + prefix: 3.0.4.0/28 + prefixName: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-1 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-1 + spec: + comments: your comments + description: some description + prefix: 3.0.4.0/28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + customFields: + netboxOperatorRestorationHash: f1265230d10c00215cd515759cd44f9622da833f + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-2 + spec: + comments: your comments + description: some description + parentPrefixSelector: + environment: Production + family: IPv4 + poolName: Pool 2 + site: DM-Buffalo + tenant: MY_TENANT + prefixLength: /28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 3.0.1.0/24 + prefix: 3.0.1.0/28 + prefixName: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-2 + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-2 + spec: + comments: your comments + description: some description + prefix: 3.0.1.0/28 + preserveInNetbox: true + site: DM-Akron + tenant: Dunder-Mifflin, Inc. + customFields: + netboxOperatorRestorationHash: 98e9822f1444f135a7794bc382a3cdd4162fe941 diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenParentPrefixSelectorAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_1.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenParentPrefixSelectorAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_1.yaml new file mode 100644 index 00000000..b7facc5b --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenParentPrefixSelectorAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_1.yaml @@ -0,0 +1,22 @@ +apiVersion: netbox.dev/v1 +kind: PrefixClaim +metadata: + labels: + app.kubernetes.io/name: netbox-operator + app.kubernetes.io/managed-by: kustomize + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-1 +spec: + tenant: "Dunder-Mifflin, Inc." + site: "DM-Akron" + description: "some description" + comments: "your comments" + preserveInNetbox: true + prefixLength: "/28" + parentPrefixSelector: # The keys and values are case-sensitive + tenant: "MY_TENANT" # Use the `name` value instead of the `slug` value + site: "DM-Buffalo" # Use the `name` value instead of the `slug` value + family: "IPv4" # Can only be either IPv4 or IPv6" + + # custom fields of your interest + environment: "Production" + poolName: "Pool 2" diff --git a/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenParentPrefixSelectorAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_2.yaml b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenParentPrefixSelectorAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_2.yaml new file mode 100644 index 00000000..d33972f5 --- /dev/null +++ b/tests/e2e/Prefix/IPv4/GivenPrefixClaimWithPreserveWhenParentPrefixSelectorAppliedDeletedAppliedThenRestorationSucceed/netbox_v1_prefixclaim_2.yaml @@ -0,0 +1,22 @@ +apiVersion: netbox.dev/v1 +kind: PrefixClaim +metadata: + labels: + app.kubernetes.io/name: netbox-operator + app.kubernetes.io/managed-by: kustomize + name: prefixclaim-ipv4-parentprefixselector-apply-delete-apply-restored-2 +spec: + tenant: "Dunder-Mifflin, Inc." + site: "DM-Akron" + description: "some description" + comments: "your comments" + preserveInNetbox: true + prefixLength: "/28" + parentPrefixSelector: # The keys and values are case-sensitive + tenant: "MY_TENANT" # Use the `name` value instead of the `slug` value + site: "DM-Buffalo" # Use the `name` value instead of the `slug` value + family: "IPv4" # Can only be either IPv4 or IPv6" + + # custom fields of your interest + environment: "Production" + poolName: "Pool 1" diff --git a/tests/e2e/Prefix/IPv6/GivenPrefixClaimWithIPv6ParentPrefixSelectorWhenAppliedThenSucceed/chainsaw-test.yaml b/tests/e2e/Prefix/IPv6/GivenPrefixClaimWithIPv6ParentPrefixSelectorWhenAppliedThenSucceed/chainsaw-test.yaml new file mode 100644 index 00000000..eec6901c --- /dev/null +++ b/tests/e2e/Prefix/IPv6/GivenPrefixClaimWithIPv6ParentPrefixSelectorWhenAppliedThenSucceed/chainsaw-test.yaml @@ -0,0 +1,49 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: prefixclaim-ipv6-parentprefixselector-apply-succeed +spec: + steps: + - name: Setup + description: Apply prefix claim CR + try: + - apply: + file: netbox_v1_prefixclaim.yaml + - name: Check + description: Go through each field and check for equality + try: + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: PrefixClaim + metadata: + name: prefixclaim-ipv6-parentprefixselector-apply-succeed + spec: + comments: your comments + description: some description + parentPrefixSelector: + environment: production + family: IPv6 + poolName: pool 4 + tenant: Dunder-Mifflin, Inc. + prefixLength: /124 + preserveInNetbox: true + tenant: Dunder-Mifflin, Inc. + status: + parentPrefix: 2::/64 + prefix: 2::/124 + prefixName: prefixclaim-ipv6-parentprefixselector-apply-succeed + - assert: + resource: + apiVersion: netbox.dev/v1 + kind: Prefix + metadata: + name: prefixclaim-ipv6-parentprefixselector-apply-succeed + spec: + comments: your comments + description: some description + prefix: 2::/124 + preserveInNetbox: true + tenant: Dunder-Mifflin, Inc. + customFields: + netboxOperatorRestorationHash: a7fbe45766da6a472a3b3d4d7f7070622feb555d diff --git a/tests/e2e/Prefix/IPv6/GivenPrefixClaimWithIPv6ParentPrefixSelectorWhenAppliedThenSucceed/netbox_v1_prefixclaim.yaml b/tests/e2e/Prefix/IPv6/GivenPrefixClaimWithIPv6ParentPrefixSelectorWhenAppliedThenSucceed/netbox_v1_prefixclaim.yaml new file mode 100644 index 00000000..fea0526d --- /dev/null +++ b/tests/e2e/Prefix/IPv6/GivenPrefixClaimWithIPv6ParentPrefixSelectorWhenAppliedThenSucceed/netbox_v1_prefixclaim.yaml @@ -0,0 +1,20 @@ +apiVersion: netbox.dev/v1 +kind: PrefixClaim +metadata: + labels: + app.kubernetes.io/name: netbox-operator + app.kubernetes.io/managed-by: kustomize + name: prefixclaim-ipv6-parentprefixselector-apply-succeed +spec: + tenant: "Dunder-Mifflin, Inc." # Use the `name` value instead of the `slug` value + description: "some description" + comments: "your comments" + preserveInNetbox: true + prefixLength: "/124" + parentPrefixSelector: # The keys and values are case-sensitive + # if the entry for tenant or site is missing, it will *not* inherit from the tenant and site from the Spec + tenant: "Dunder-Mifflin, Inc." # Use the `name` value instead of the `slug` value + family: "IPv6" # Can only be either IPv4 or IPv6" + + environment: "production" + poolName: "pool 4" diff --git a/tests/e2e/README.md b/tests/e2e/README.md new file mode 100644 index 00000000..6a8ac803 --- /dev/null +++ b/tests/e2e/README.md @@ -0,0 +1,26 @@ +# e2e tests + +# How to run the test locally? + +- [Install](https://kyverno.github.io/chainsaw/latest/quick-start/install/) `chainsaw`: `go install github.com/kyverno/chainsaw@latest` +- Execute `make test-e2e` + +# How to add a new test locally? + +- Create a clean cluster `kind delete cluster --name kind && make create-kind deploy-kind && kubectl port-forward deploy/netbox 8080:8080 -n default` +- During development, we would need to have a clean NetBox instance between runs, which we can do with the following commands as soon as we create a new cluster + - Backup: `kubectl exec pod/netbox-db-0 -- bash -c "pg_dump --clean -U postgres netbox" > database.sql` +- The simplest test case is `tests/e2e/GivenPrefixClaimWithPreserveWhenAppliedThenSucceed` + - We always need a `chainsaw-test.yaml` +- Perform a clean run by resetting the database first, then execute the test + - Reset database `cat database.sql | kubectl exec -i pod/netbox-db-0 -- psql -U postgres -d netbox` + - Make sure that in the `e2e` namespace, no leftover CRs are there + - Execute the entire e2e test `make test-e2e` + - Or just perform a specific run, e.g. `chainsaw test --test-dir tests/e2e/Prefix/IPv4/GivenPrefixClaimWhenAppliedThenFailedPrefixExhausted` + +# Some debugging tips + +- `kubectl get prefixclaim,prefix,ipaddressclaim,ipaddress,iprange,iprangeclaim -A` +- For monitoring failures, we can use event (which is a native k8s object) + - e.g. `kubectl events --for prefixclaim.netbox.dev/prefixclaim-apply-prefixexhausted-3 -o yaml` +- I am not entirely sure why is resetting the database not clean enough, maybe the redis is doing some caching that I am not aware of diff --git a/tests/e2e/kind-config.yaml b/tests/e2e/kind-config.yaml new file mode 100644 index 00000000..42c6a320 --- /dev/null +++ b/tests/e2e/kind-config.yaml @@ -0,0 +1,9 @@ +# See https://kind.sigs.k8s.io/docs/user/configuration/ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +name: kind + +nodes: +- role: control-plane +- role: worker +- role: worker