[pve-devel] applied: [PATCH manager v2] ceph: create mon: fix & improve check if IP is in public net

Wolfgang Bumiller w.bumiller at proxmox.com
Tue Nov 28 16:52:33 CET 2017


applied

On Tue, Nov 28, 2017 at 04:32:44PM +0100, Thomas Lamprecht wrote:
> If a CIDR gets passed to Net::IP it is expected to not be from the
> middle of  an subnet, i.e., 192.168.1.12/24 is *not* OK but
> 192.168.1.0/24 would be OK.
> 
> As the Network/interfaces files also accepts CIDR notation for the
> 'address' param (now also for IPv4) this let to problems in our node
> monitor IP detection code, which used the interface file and Net::IP to
> find any address from the ceph public network.
> 
> So change to our newer helper PVE::Network::get_local_ip_from_cidr to
> get all configured and ready (=up) IPs from this network.
> 
> Also handle the case where multiple networks where returned, add a
> parameter to allow specifying one of those and ask the user to do so.
> 
> If no public network is configured and no mon-address parameter was
> passed, we fall back to the remote node IP of the node, as was done
> previously. We expect that the user only overwrites the mon-address
> if he knows what he do and omit checks here.
> ---
> 
> changes v1 -> v2:
> * the regex in grep had an unquoted variable, instead of quoting just
>   use 'eq' in grep, makes it even more clear what we do
> * don't use post-fix if on return but only on dies, make code a bit more
>   readable
> 
>  PVE/API2/Ceph.pm | 52 +++++++++++++++++++++++++++++++---------------------
>  1 file changed, 31 insertions(+), 21 deletions(-)
> 
> diff --git a/PVE/API2/Ceph.pm b/PVE/API2/Ceph.pm
> index 0fd8e388..be193a46 100644
> --- a/PVE/API2/Ceph.pm
> +++ b/PVE/API2/Ceph.pm
> @@ -918,24 +918,32 @@ __PACKAGE__->register_method ({
>  	return undef;
>      }});
>  
> -my $find_node_ip = sub {
> -    my ($cidr) = @_;
> +my $find_mon_ip = sub {
> +    my ($pubnet, $node, $overwrite_ip) = @_;
>  
> -    my $net = Net::IP->new($cidr) || die Net::IP::Error() . "\n";
> -    my $id = $net->version == 6 ? 'address6' : 'address';
> -
> -    my $config = PVE::INotify::read_file('interfaces');
> -    my $ifaces = $config->{ifaces};
> -
> -    foreach my $iface (keys %$ifaces) {
> -	my $d = $ifaces->{$iface};
> -	next if !$d->{$id};
> -	my $a = Net::IP->new($d->{$id});
> -	next if !$a;
> -	return $d->{$id} if $net->overlaps($a);
> +    if (!$pubnet) {
> +	return $overwrite_ip // PVE::Cluster::remote_node_ip($node);
>      }
>  
> -    die "unable to find local address within network '$cidr'\n";
> +    my $allowed_ips = PVE::Network::get_local_ip_from_cidr($pubnet);
> +    die "No IP configured and up from ceph public network '$pubnet'\n"
> +	if scalar(@$allowed_ips) < 1;
> +
> +    if (!$overwrite_ip) {
> +	if (scalar(@$allowed_ips) == 1) {
> +	    return $allowed_ips->[0];
> +	}
> +	die "Multiple IPs for ceph public network '$pubnet' detected on $node:\n".
> +	    join("\n", @$allowed_ips) ."\nuse 'mon-address' to specify one of them.\n";
> +    } else {
> +	if (grep { $_ eq $overwrite_ip } @$allowed_ips) {
> +	    return $overwrite_ip;
> +	}
> +	die "Monitor IP '$overwrite_ip' not in ceph public network '$pubnet'\n"
> +	    if !PVE::Network::is_ip_in_cidr($overwrite_ip, $pubnet);
> +
> +	die "Specified monitor IP '$overwrite_ip' not configured or up on $node!\n";
> +    }
>  };
>  
>  my $create_mgr = sub {
> @@ -1016,6 +1024,12 @@ __PACKAGE__->register_method ({
>  		default => 0,
>  		description => "When set, only a monitor will be created.",
>  	    },
> +	    'mon-address' => {
> +		description => 'Overwrites autodetected monitor IP address. ' .
> +		               'Must be in the public network of ceph.',
> +		type => 'string', format => 'ip',
> +		optional => 1,
> +	    },
>  	},
>      },
>      returns => { type => 'string' },
> @@ -1057,12 +1071,8 @@ __PACKAGE__->register_method ({
>  	my $monid = $param->{id} // $param->{node};
>  
>  	my $monsection = "mon.$monid";
> -	my $ip;
> -	if (my $pubnet = $cfg->{global}->{'public network'}) {
> -	    $ip = &$find_node_ip($pubnet);
> -	} else {
> -	    $ip = PVE::Cluster::remote_node_ip($param->{node});
> -	}
> +	my $pubnet = $cfg->{global}->{'public network'};
> +	my $ip = $find_mon_ip->($pubnet, $param->{node}, $param->{'mon-address'});
>  
>  	my $monaddr = Net::IP::ip_is_ipv6($ip) ? "[$ip]:6789" : "$ip:6789";
>  	my $monname = $param->{node};
> -- 
> 2.11.0




More information about the pve-devel mailing list