8000 kubectl-ceph-rook: Monitor endpoint parsing fails with IPv6 addresses · Issue #367 · rook/kubectl-rook-ceph · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

kubectl-ceph-rook: Monitor endpoint parsing fails with IPv6 addresses #367

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

Open
aagogolev opened this issue Apr 17, 2025 · 0 comments
Open

Comments

@aagogolev
Copy link
aagogolev commented Apr 17, 2025

Problem Description

The kubectl-ceph-rook plugin fails to correctly parse IPv6 monitor endpoints, causing commands like mons restore-quorum to fail when working with Ceph clusters configured with IPv6 addresses.

Current Behavior

When running kubectl rook-ceph mons restore-quorum with IPv6 monitor addresses, the command fails with an error:

Info: mon=a, endpoints=[2a02:5501:31:c0a::3]:6789
Info: mon=b, endpoints=[2a02:5501:31:c0a::4]:6789
...
Info: Restoring mon quorum to mon b [2a02
...
parse error setting 'public_addr' to '[2a02'
too many arguments: [--setuser-match-path=/var/lib/ceph/mon/ceph-b/store.db]
Error: failed to run command. failed to run command. command terminated with exit code 1
%!(EXTRA string=failed to extract monmap)

The issue occurs in the getMonDetails() function, which uses a simple string split by the first colon to extract the IP address and port from monitor endpoints:

goodMonPublicIp, goodMonPort, ok = strings.Cut(monEndpoint, ":")

This approach works for IPv4 addresses (e.g., 192.168.1.1:6789), but fails for IPv6 addresses (e.g., [2a02:5501:31:c0a::3]:6789) because IPv6 addresses themselves contain colons.

Expected Behavior

The getMonDetails() function should correctly parse both IPv4 and IPv6 monitor endpoints, extracting the proper IP address and port in both cases.

Proposed Solution

The getMonDetails() function needs to be enhanced to handle IPv6 addresses. A possible solution is to check if the endpoint contains more than one colon (indicating a possible IPv6 address) and use the last colon as the separator between the IP address and port for IPv6 addresses:

func getMonDetails(goodMon string, monEndpoints []string) ([]string, string, string, error) {
	var goodMonPublicIp, goodMonPort string
	var badMons []string

	for _, m := range monEndpoints {
		monName, monEndpoint, ok := strings.Cut(m, "=")
		if !ok {
			return []string{}, "", "", fmt.Errorf("failed to fetch mon endpoint")
		} else if monName == goodMon {
			host, port, err := net.SplitHostPort(monEndpoint)
			if err != nil {
				return []string{}, "", "", fmt.Errorf("failed to split host and port from endpoint %s: %v", monEndpoint, err)
			}

			if ip := net.ParseIP(host); ip == nil {
				return []string{}, "", "", fmt.Errorf("invalid IP address in endpoint: %s", host)
			}

			goodMonPublicIp = host
			goodMonPort = port
		} else {
			badMons = append(badMons, monName)
		}
		logging.Info("mon=%s, endpoints=%s\n", monName, monEndpoint)
	}

	return badMons, goodMonPublicIp, goodMonPort, nil
}

This approach would correctly handle both IPv4 and IPv6 addresses without breaking existing functionality.

Fix Implementation

I've submitted a pull request that implements the proposed solution:

PR #366: kubectl-ceph-rook: Fix IPv6 address handling in monitor endpoint parsing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant
0