Skip to content

Fix has_ip_address and has_ip_network functions #1448

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

Merged
merged 1 commit into from
Mar 5, 2025
Merged
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
109 changes: 56 additions & 53 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ environment.
* [`grep`](#grep): This function searches through an array and returns any elements that match
the provided regular expression.
* [`has_interface_with`](#has_interface_with): DEPRECATED. Use the namespaced function [`stdlib::has_interface_with`](#stdlibhas_interface_with) instead.
* [`has_interface_with`](#has_interface_with): Returns boolean based on kind and value.
* [`has_ip_address`](#has_ip_address): Returns true if the client has the requested IP address on some interface.
* [`has_ip_network`](#has_ip_network): Returns true if the client has an IP address within the requested network.
* [`has_ip_address`](#has_ip_address): DEPRECATED. Use the namespaced function [`stdlib::has_ip_address`](#stdlibhas_ip_address) instead.
* [`has_ip_network`](#has_ip_network): DEPRECATED. Use the namespaced function [`stdlib::has_ip_network`](#stdlibhas_ip_network) instead.
* [`intersection`](#intersection): This function returns an array of the intersection of two.
* [`is_a`](#is_a): Boolean check to determine whether a variable is of a given data type.
This is equivalent to the `=~` type checks.
Expand Down Expand Up @@ -126,6 +125,8 @@ optional seed for repeatable randomness.
* [`stdlib::fqdn_rotate`](#stdlib--fqdn_rotate): Rotates an array or string a random number of times, combining the `fqdn` fact and an optional seed for repeatable randomness.
* [`stdlib::has_function`](#stdlib--has_function): Returns whether the Puppet runtime has access to a given function.
* [`stdlib::has_interface_with`](#stdlib--has_interface_with): Returns boolean based on network interfaces present and their attribute values.
* [`stdlib::has_ip_address`](#stdlib--has_ip_address): Returns true if the client has the requested IPv4 address on some interface.
* [`stdlib::has_ip_network`](#stdlib--has_ip_network): Returns true if the client has the requested IPv4 network on some interface.
* [`stdlib::ip_in_range`](#stdlib--ip_in_range): Returns true if the ipaddress is within the given CIDRs
* [`stdlib::merge`](#stdlib--merge): Merges two or more hashes together or hashes resulting from iteration, and returns
the resulting hash.
Expand Down Expand Up @@ -2052,75 +2053,41 @@ Data type: `Any`



### <a name="has_interface_with"></a>`has_interface_with`

Type: Ruby 3.x API

Valid kinds are `macaddress`, `netmask`, `ipaddress` and `network`.

#### Examples

##### **Usage**

```puppet
has_interface_with("macaddress", "x:x:x:x:x:x") # Returns `false`
has_interface_with("ipaddress", "127.0.0.1") # Returns `true`
```

##### If no "kind" is given, then the presence of the interface is checked:

```puppet
has_interface_with("lo") # Returns `true`
```
### <a name="has_ip_address"></a>`has_ip_address`

#### `has_interface_with()`
Type: Ruby 4.x API

Valid kinds are `macaddress`, `netmask`, `ipaddress` and `network`.
DEPRECATED. Use the namespaced function [`stdlib::has_ip_address`](#stdlibhas_ip_address) instead.

Returns: `Any` boolean values `true` or `false`
#### `has_ip_address(Any *$args)`

##### Examples
The has_ip_address function.

###### **Usage**

```puppet
has_interface_with("macaddress", "x:x:x:x:x:x") # Returns `false`
has_interface_with("ipaddress", "127.0.0.1") # Returns `true`
```
Returns: `Any`

###### If no "kind" is given, then the presence of the interface is checked:
##### `*args`

```puppet
has_interface_with("lo") # Returns `true`
```
Data type: `Any`

### <a name="has_ip_address"></a>`has_ip_address`

Type: Ruby 3.x API

This function iterates through the 'interfaces' fact and checks the
'ipaddress_IFACE' facts, performing a simple string comparison.
### <a name="has_ip_network"></a>`has_ip_network`

#### `has_ip_address()`
Type: Ruby 4.x API

This function iterates through the 'interfaces' fact and checks the
'ipaddress_IFACE' facts, performing a simple string comparison.
DEPRECATED. Use the namespaced function [`stdlib::has_ip_network`](#stdlibhas_ip_network) instead.

Returns: `Boolean` `true` or `false`
#### `has_ip_network(Any *$args)`

### <a name="has_ip_network"></a>`has_ip_network`
The has_ip_network function.

Type: Ruby 3.x API
Returns: `Any`

This function iterates through the 'interfaces' fact and checks the
'network_IFACE' facts, performing a simple string comparision.
##### `*args`

#### `has_ip_network()`
Data type: `Any`

This function iterates through the 'interfaces' fact and checks the
'network_IFACE' facts, performing a simple string comparision.

Returns: `Any` Boolean value, `true` if the client has an IP address within the requested network.

### <a name="intersection"></a>`intersection`

Expand Down Expand Up @@ -3575,6 +3542,42 @@ Data type: `String[1]`

The value of the attribute

### <a name="stdlib--has_ip_address"></a>`stdlib::has_ip_address`

Type: Puppet Language

Returns true if the client has the requested IPv4 address on some interface.

#### `stdlib::has_ip_address(Stdlib::IP::Address::V4::Nosubnet $ip_address)`

The stdlib::has_ip_address function.

Returns: `Boolean` Returns `true` if the requested IP address exists on any interface.

##### `ip_address`

Data type: `Stdlib::IP::Address::V4::Nosubnet`

The IPv4 address you want to check the existence of

### <a name="stdlib--has_ip_network"></a>`stdlib::has_ip_network`

Type: Puppet Language

Returns true if the client has the requested IPv4 network on some interface.

#### `stdlib::has_ip_network(Stdlib::IP::Address::V4::Nosubnet $ip_network)`

The stdlib::has_ip_network function.

Returns: `Boolean` Returns `true` if the requested IP network exists on any interface.

##### `ip_network`

Data type: `Stdlib::IP::Address::V4::Nosubnet`

The IPv4 network you want to check the existence of

### <a name="stdlib--ip_in_range"></a>`stdlib::ip_in_range`

Type: Ruby 4.x API
Expand Down
10 changes: 10 additions & 0 deletions functions/has_ip_address.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# @summary Returns true if the client has the requested IPv4 address on some interface.
#
# @param ip_address
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we also support ipv6?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If someone wants to add that, they could open a PR for it. I did have a quick think about it, and I guess with IPv6 you'd want to do something a bit more sophisticated than just matching the string though as there are several ways to write the same address.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah right, that would require updating stdlib::has_interface_with() to work with IpAddr objects

# The IPv4 address you want to check the existence of
# @return [Boolean] Returns `true` if the requested IP address exists on any interface.
function stdlib::has_ip_address(
Stdlib::IP::Address::V4::Nosubnet $ip_address,
) >> Boolean {
stdlib::has_interface_with('ipaddress', $ip_address)
}
10 changes: 10 additions & 0 deletions functions/has_ip_network.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# @summary Returns true if the client has the requested IPv4 network on some interface.
#
# @param ip_network
# The IPv4 network you want to check the existence of
# @return [Boolean] Returns `true` if the requested IP network exists on any interface.
function stdlib::has_ip_network(
Stdlib::IP::Address::V4::Nosubnet $ip_network,
) >> Boolean {
stdlib::has_interface_with('network', $ip_network)
}
14 changes: 14 additions & 0 deletions lib/puppet/functions/has_ip_address.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims`

# @summary DEPRECATED. Use the namespaced function [`stdlib::has_ip_address`](#stdlibhas_ip_address) instead.
Puppet::Functions.create_function(:has_ip_address) do
dispatch :deprecation_gen do
repeated_param 'Any', :args
end
def deprecation_gen(*args)
call_function('deprecation', 'has_ip_address', 'This function is deprecated, please use stdlib::has_ip_address instead.', false)
call_function('stdlib::has_ip_address', *args)
end
end
14 changes: 14 additions & 0 deletions lib/puppet/functions/has_ip_network.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims`

# @summary DEPRECATED. Use the namespaced function [`stdlib::has_ip_network`](#stdlibhas_ip_network) instead.
Puppet::Functions.create_function(:has_ip_network) do
dispatch :deprecation_gen do
repeated_param 'Any', :args
end
def deprecation_gen(*args)
call_function('deprecation', 'has_ip_network', 'This function is deprecated, please use stdlib::has_ip_network instead.', false)
call_function('stdlib::has_ip_network', *args)
end
end
68 changes: 0 additions & 68 deletions lib/puppet/parser/functions/has_interface_with.rb

This file was deleted.

27 changes: 0 additions & 27 deletions lib/puppet/parser/functions/has_ip_address.rb

This file was deleted.

27 changes: 0 additions & 27 deletions lib/puppet/parser/functions/has_ip_network.rb

This file was deleted.

21 changes: 14 additions & 7 deletions spec/functions/has_ip_address_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,29 @@

describe 'has_ip_address' do
it { is_expected.not_to be_nil }
it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) }
it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) }
it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{'stdlib::has_ip_address' expects 1 argument, got none}) }
it { is_expected.to run.with_params('one', 'two').and_raise_error(ArgumentError, %r{'stdlib::has_ip_address' expects 1 argument, got 2}) }

context 'when on Linux Systems' do
let(:facts) do
{
interfaces: 'eth0,lo',
ipaddress: '10.0.0.1',
ipaddress_lo: '127.0.0.1',
ipaddress_eth0: '10.0.0.1'
networking: {
'interfaces' => {
'eth0' => {
'ip' => '10.0.0.1',
},
'lo' => {
'ip' => '127.0.0.1',
},
},
'ip' => '10.0.0.1',
},
}
end

it { is_expected.to run.with_params('127.0.0.1').and_return(true) }
it { is_expected.to run.with_params('10.0.0.1').and_return(true) }
it { is_expected.to run.with_params('8.8.8.8').and_return(false) }
it { is_expected.to run.with_params('invalid').and_return(false) }
it { is_expected.to run.with_params('invalid').and_raise_error(ArgumentError, %r{parameter 'ip_address' expects a match}) }
end
end
Loading
Loading