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

Update RandIpAddress() so it can use any prefix as input #305

Merged
merged 4 commits into from
Mar 25, 2024

Conversation

chrismarget
Copy link
Contributor

The RandIpAddress() function has some confusing issues.

  • The comment The prefix length must be less than 31 isn't correct. It will accept an IPv4 prefix with a 32-bit mask length, and IPv6 prefix bit masks must be at least 65 bits long. While I have doubts about the utility of "give me a random value from within the range of exactly one host", that functionality is validated by the tests.
  • It won't, however, accept "0.0.0.0/0" (the shortest possible IPv4 prefix: "give me any address in the whole Internet"), but there doesn't seem to be any reason for this constraint.
  • It also won't accept IPv6 prefixes shorter than /65 because of of how the random host portion is generated (only 63 bits available). Being unable to generate an IP within a /64 (standard subnet, let alone a reasonable sized block like the documentation prefix) is what led me to dig into this function.

This PR eliminates the confusing comment and lifts the unnecessary constraints for both protocols so that random addresses can be generated from IPv4 prefixes 0.0.0.0/0 through 255.255.255.255/32, IPv6 prefixes ::/0 through ff:ff:ff:ff:ff:ff:ff:ff/128, and anywhere in between.

@chrismarget chrismarget requested a review from a team as a code owner March 11, 2024 03:09
@hashicorp-cla
Copy link

hashicorp-cla commented Mar 11, 2024

CLA assistant check
All committers have signed the CLA.

@austinvalle austinvalle added the bug Something isn't working label Mar 15, 2024
Copy link
Member

@austinvalle austinvalle left a comment

Choose a reason for hiding this comment

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

Overall I think these changes look good, I have one minor note and there are a couple small lint errors pointed out in the PR.

Also would you mind adding a changelog for this fix?

randAddrInt.Add(randAddrInt, big.NewInt(randInt))

randAddr, ok := netip.AddrFromSlice(randAddrInt.Bytes())
result, _ := netip.AddrFromSlice(resultBytes)
Copy link
Member

Choose a reason for hiding this comment

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

nit: I know it's not possible at this point, given the logic above, but I feel like we should keep the original logic of checking the ok return from netip.AddrFromSlice and returning an error with the byte data:

result, ok := netip.AddrFromSlice(resultBytes)
if !ok {
    return "", fmt.Errorf("unexpected error creating random address from bytes: %#v", resultBytes)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey @austinvalle,

I think I took care of your punch list.

Additionally, see the inline comment about the addition of Masked() (a change you didn't request, but seems like a better way to handle slightly-broken input).

Thanks!

@austinvalle austinvalle added this to the v1.8.0 milestone Mar 15, 2024
if prefix.Addr().Is4() && prefixSizeExponent > 31 {
return "", fmt.Errorf("CIDR range is too large: %d", prefixSizeExponent)
// base address as byte slice
prefixBytes, err := prefix.Masked().Addr().MarshalBinary()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added Masked() here to ensure that a user asking for a random address within "192.168.1.77/24" isn't masking out random bits with that "77". They'll get any address within 192.168.1.0-255 this way.

Copy link
Member

Choose a reason for hiding this comment

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

Ah! That makes sense. I can't really think of a scenario where you'd want to lose that portion of the range, and honestly at that point, the cost of implementing your own random IP function is low 😄

Copy link
Member

@austinvalle austinvalle left a comment

Choose a reason for hiding this comment

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

Thanks for making those changes. Everything new looks good to me 🚀

I have a slight addition to the changelog which I'll resolve and merge. Thanks for the contribution @chrismarget ! This will go out in the upcoming v1.8.0 of the testing module 👍🏻

.changes/unreleased/ENHANCEMENTS-20240315-185051.yaml Outdated Show resolved Hide resolved
if prefix.Addr().Is4() && prefixSizeExponent > 31 {
return "", fmt.Errorf("CIDR range is too large: %d", prefixSizeExponent)
// base address as byte slice
prefixBytes, err := prefix.Masked().Addr().MarshalBinary()
Copy link
Member

Choose a reason for hiding this comment

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

Ah! That makes sense. I can't really think of a scenario where you'd want to lose that portion of the range, and honestly at that point, the cost of implementing your own random IP function is low 😄

@austinvalle austinvalle merged commit 0847ba8 into hashicorp:main Mar 25, 2024
4 checks passed
Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants