Skip to content

Validate Whereabouts IPAM CIDRs in NAD admission webhook#120

Open
sanjaytripathi97 wants to merge 2 commits into
openshift:mainfrom
sanjaytripathi97:validate-whereabouts-ipam
Open

Validate Whereabouts IPAM CIDRs in NAD admission webhook#120
sanjaytripathi97 wants to merge 2 commits into
openshift:mainfrom
sanjaytripathi97:validate-whereabouts-ipam

Conversation

@sanjaytripathi97

@sanjaytripathi97 sanjaytripathi97 commented Jun 9, 2026

Copy link
Copy Markdown

Summary

The Multus admission controller accepts NetworkAttachmentDefinitions (NADs) with invalid Whereabouts IPAM values because validation only checks JSON syntax and basic CNI config shape. Invalid values such as abc.169.1.0/24 and a.b.c.d/23 are currently allowed at admission time.

This PR adds Whereabouts-specific IPAM validation during NAD admission and rejects configs containing invalid CIDR/IP values in:

  • ipam.range
  • ipam.exclude
  • ipam.gateway
  • ipam.range_start / ipam.range_end
  • ipam.ipRanges[].range / ipam.ipRanges[].exclude

Validation is scoped to ipam.type: whereabouts only. Other IPAM plugins are unchanged.

Problem

Invalid NAD example that is currently accepted:

apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: checking-nad
  namespace: checking-nad
spec:
  config: |-
    {
      "cniVersion": "0.3.1",
      "name": "whereabouts_sba",
      "type": "macvlan",
      "mode": "bridge",
      "ipam": {
        "type": "whereabouts",
        "range": "abc.169.1.0/24",
        "exclude": ["a.b.c.d/23"]
      }
    }

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added IPAM (IP address management) validation for network attachment definitions to prevent invalid configurations from being deployed. The validation checks IP address ranges, exclude lists, and gateway settings.

* **Improvements**
  * Enhanced webhook validation now catches and rejects network attachment definitions with malformed IPAM configurations during the admission control process, improving cluster stability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Sanjay Tripathi added 2 commits June 9, 2026 20:46
Reject NetworkAttachmentDefinitions whose whereabouts ipam range, exclude,
gateway, or ipRanges entries contain invalid CIDR or IP values during admission.
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Walkthrough

This PR adds Whereabouts IPAM validation to the webhook admission controller. It implements validators for Whereabouts IP address management configurations, integrates validation into the NetworkAttachmentDefinition admission flow, and provides comprehensive unit and integration test coverage.

Changes

Whereabouts IPAM Validation Implementation

Layer / File(s) Summary
Whereabouts IPAM validation functions
pkg/webhook/ipam_validation.go
Core validation logic with validateIPAMConfigs entry point parsing JSON and routing to plugin validators; validatePluginIPAM extracts IPAM sections and delegates Whereabouts validation; validateWhereaboutsIPAM validates optional range, string IP fields (range_start, range_end, gateway), exclude lists, and ipRanges array entries; helper functions validate Whereabouts range syntax (supporting startIP-CIDR or plain CIDR), IP strings via netutils.ParseIPSloppy, and exclude list entries.
Webhook NAD validation integration
pkg/webhook/webhook.go, pkg/webhook/webhook_test.go
validateNetworkAttachmentDefinition now calls validateIPAMConfigs after CNI validation and rejects if IPAM validation fails; two new test cases added for invalid (range with exclude) and valid (range, exclude, and gateway) Whereabouts IPAM configurations.
Comprehensive IPAM validation test coverage
pkg/webhook/ipam_validation_test.go
Test helpers marshal Whereabouts IPAM configs and construct NADs; unit tests for validateWhereaboutsRange cover invalid formats (CIDR/host routes, hyphen ranges, invalid prefixes, out-of-range octets); unit tests for validateIPAMConfigs cover invalid and valid Whereabouts payloads; integration tests verify non-Whereabouts IPAM skipping, plugin-nested validation, end-to-end NAD validation with original bug repro and additional cases, invalid range rejection, and helper formatting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
Stable And Deterministic Test Names ❌ Error Five Entry() test names use test data (abcd, abc.def.ghi.jkl/24, a.b.c.d/23, 192.168.1.256/24, not-an-ip/24) as test identifiers instead of descriptive text. Replace Entry() test names with descriptive labels, e.g., Entry("with plain text", "abcd") instead of Entry("abcd", "abcd").
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ⚠️ Warning All 15+ assertions in ipam_validation_test.go use generic patterns without meaningful failure messages, violating requirement #4. They should include context strings like "expected no error". Add failure messages to all assertions. For example: change Expect(err).NotTo(HaveOccurred()) to Expect(err).NotTo(HaveOccurred(), "expected no error for valid configuration")
✅ Passed checks (12 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding Whereabouts IPAM CIDR validation to the NAD admission webhook, which is the core objective of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Microshift Test Compatibility ✅ Passed Tests use only standard Kubernetes APIs (admissionv1, metav1, and k8s.cni.cncf.io NetworkAttachmentDefinition) available on MicroShift, with no OpenShift-specific APIs.
Single Node Openshift (Sno) Test Compatibility ✅ Passed Ginkgo unit tests (not e2e tests) validating IPAM JSON parsing and CIDR format in isolation; no multi-node or cluster topology assumptions made.
Topology-Aware Scheduling Compatibility ✅ Passed This PR only adds IPAM validation logic to the webhook. No deployment manifests, operators, or scheduling constraints are introduced.
Ote Binary Stdout Contract ✅ Passed PR adds validation functions and tests without any process-level stdout writes; all logging is within HTTP handlers (using glog to stderr) and test functions (within Ginkgo test blocks).
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Tests are unit tests (not e2e) validating webhook IPAM parsing in isolation. No cluster/network dependencies, no external connectivity, and IPv6-compatible validation logic.
No-Weak-Crypto ✅ Passed PR contains no cryptographic operations: adds IPAM validation for IP/CIDR formats only, using standard Go libraries and k8s.io/utils/net without any crypto algorithms or comparisons.
Container-Privileges ✅ Passed PR only adds Go validation code and tests. No container privilege settings found in changed files or deployment manifests.
No-Sensitive-Data-In-Logs ✅ Passed Error messages include user-provided CIDR/IP addresses logged via glog.Info(), but these are network configuration values, not sensitive data (passwords, tokens, keys, PII, session IDs).
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci Bot requested review from bpickard22 and s1061123 June 9, 2026 15:35
@openshift-ci

openshift-ci Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: sanjaytripathi97
Once this PR has been reviewed and has the lgtm label, please assign dougbtv for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Jun 9, 2026
@openshift-ci

openshift-ci Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Hi @sanjaytripathi97. Thanks for your PR.

I'm waiting for a openshift member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/webhook/ipam_validation.go`:
- Around line 55-77: The validators currently treat type mismatches as absent
and silently accept malformed Whereabouts IPAM fields; update the validation in
the ipam validation path to explicitly reject wrong JSON types instead of
returning nil. For each key referenced (range -> validateWhereaboutsRange,
range_start/range_end/gateway -> validateWhereaboutsStringIP, exclude ->
validateWhereaboutsExcludeList, and ipRanges -> the ipRangesRaw handling) detect
if the key exists but is the wrong type and return a descriptive error (e.g.,
"field X must be a string" or "field ipRanges must be an array") rather than
treating it as missing; keep calling the existing helper functions when types
are correct and only short-circuit to an error on type mismatches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6745bcfc-b3f9-4061-9f68-68ef6df1df0f

📥 Commits

Reviewing files that changed from the base of the PR and between 12d99f3 and deaf644.

📒 Files selected for processing (4)
  • pkg/webhook/ipam_validation.go
  • pkg/webhook/ipam_validation_test.go
  • pkg/webhook/webhook.go
  • pkg/webhook/webhook_test.go

Comment on lines +55 to +77
if rangeStr, ok := ipam["range"].(string); ok && rangeStr != "" {
if err := validateWhereaboutsRange(rangeStr); err != nil {
return fmt.Errorf("invalid whereabouts ipam range: %w", err)
}
}

if err := validateWhereaboutsStringIP(ipam, "range_start"); err != nil {
return err
}
if err := validateWhereaboutsStringIP(ipam, "range_end"); err != nil {
return err
}
if err := validateWhereaboutsStringIP(ipam, "gateway"); err != nil {
return err
}

if err := validateWhereaboutsExcludeList(ipam["exclude"]); err != nil {
return err
}

ipRangesRaw, ok := ipam["ipRanges"].([]interface{})
if !ok {
return nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject wrong JSON types for Whereabouts IPAM fields instead of silently skipping

Several validators treat type mismatch as “not present” and return nil (e.g., exclude, ipRanges, gateway/range_start/range_end, range). This lets malformed Whereabouts IPAM objects pass admission when fields exist but are non-string/non-array.

Suggested fix
 func validateWhereaboutsIPAM(ipam map[string]interface{}) error {
-	if rangeStr, ok := ipam["range"].(string); ok && rangeStr != "" {
-		if err := validateWhereaboutsRange(rangeStr); err != nil {
-			return fmt.Errorf("invalid whereabouts ipam range: %w", err)
-		}
-	}
+	if raw, exists := ipam["range"]; exists {
+		rangeStr, ok := raw.(string)
+		if !ok {
+			return fmt.Errorf("invalid whereabouts ipam range: must be a string")
+		}
+		if rangeStr != "" {
+			if err := validateWhereaboutsRange(rangeStr); err != nil {
+				return fmt.Errorf("invalid whereabouts ipam range: %w", err)
+			}
+		}
+	}
@@
-	ipRangesRaw, ok := ipam["ipRanges"].([]interface{})
-	if !ok {
-		return nil
-	}
+	rawIPRanges, exists := ipam["ipRanges"]
+	if !exists {
+		return nil
+	}
+	ipRangesRaw, ok := rawIPRanges.([]interface{})
+	if !ok {
+		return fmt.Errorf("invalid whereabouts ipam ipRanges: must be an array")
+	}
@@
 func validateWhereaboutsExcludeList(excludeRaw interface{}) error {
-	excludeList, ok := excludeRaw.([]interface{})
-	if !ok || len(excludeList) == 0 {
+	if excludeRaw == nil {
+		return nil
+	}
+	excludeList, ok := excludeRaw.([]interface{})
+	if !ok {
+		return fmt.Errorf("invalid exclude list: must be an array")
+	}
+	if len(excludeList) == 0 {
 		return nil
 	}
@@
 func validateWhereaboutsStringIP(ipam map[string]interface{}, field string) error {
-	value, ok := ipam[field].(string)
-	if !ok || value == "" {
+	raw, exists := ipam[field]
+	if !exists {
+		return nil
+	}
+	value, ok := raw.(string)
+	if !ok {
+		return fmt.Errorf("invalid whereabouts ipam %s: must be a string", field)
+	}
+	if value == "" {
 		return nil
 	}

Also applies to: 101-123

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/webhook/ipam_validation.go` around lines 55 - 77, The validators
currently treat type mismatches as absent and silently accept malformed
Whereabouts IPAM fields; update the validation in the ipam validation path to
explicitly reject wrong JSON types instead of returning nil. For each key
referenced (range -> validateWhereaboutsRange, range_start/range_end/gateway ->
validateWhereaboutsStringIP, exclude -> validateWhereaboutsExcludeList, and
ipRanges -> the ipRangesRaw handling) detect if the key exists but is the wrong
type and return a descriptive error (e.g., "field X must be a string" or "field
ipRanges must be an array") rather than treating it as missing; keep calling the
existing helper functions when types are correct and only short-circuit to an
error on type mismatches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant