Merge pull request #16812 from rook/mergify/bp/release-1.19/pr-16792
external: fix endpoint slice type for ipv6 clusters (backport #16792)
This commit is contained in:
4 files changed
+125
-7
No files matched your search
@@ -871,13 +871,18 @@ func createExternalMetricsEndpoints(namespace string, monitoringSpec cephv1.Moni
|
||||
addresses[i] = endpoint.IP
|
||||
}
|
||||
|
||||
addressType, err := k8sutil.GetIpAddressType(addresses)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get the addressType")
|
||||
}
|
||||
|
||||
endpoints := &discoveryv1.EndpointSlice{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: ExternalMgrAppName,
|
||||
Namespace: namespace,
|
||||
Labels: labels,
|
||||
},
|
||||
AddressType: discoveryv1.AddressTypeIPv4,
|
||||
AddressType: addressType,
|
||||
Endpoints: []discoveryv1.Endpoint{
|
||||
{
|
||||
Addresses: addresses,
|
||||
@@ -895,7 +900,7 @@ func createExternalMetricsEndpoints(namespace string, monitoringSpec cephv1.Moni
|
||||
},
|
||||
}
|
||||
|
||||
err := ownerInfo.SetControllerReference(endpoints)
|
||||
err = ownerInfo.SetControllerReference(endpoints)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to set owner reference to metric endpoints %q", endpoints.Name)
|
||||
}
|
||||
|
||||
@@ -735,7 +735,7 @@ func (c *clusterConfig) generateService(cephObjectStore *cephv1.CephObjectStore)
|
||||
return svc
|
||||
}
|
||||
|
||||
func (c *clusterConfig) generateEndpoint(cephObjectStore *cephv1.CephObjectStore) *discoveryv1.EndpointSlice {
|
||||
func (c *clusterConfig) generateEndpoint(cephObjectStore *cephv1.CephObjectStore) (*discoveryv1.EndpointSlice, error) {
|
||||
labels := getLabels(cephObjectStore.Name, cephObjectStore.Namespace, true)
|
||||
|
||||
// Convert to string addresses
|
||||
@@ -744,13 +744,18 @@ func (c *clusterConfig) generateEndpoint(cephObjectStore *cephv1.CephObjectStore
|
||||
k8sEndpointAddrs = append(k8sEndpointAddrs, rookEndpoint.IP)
|
||||
}
|
||||
|
||||
addressType, err := k8sutil.GetIpAddressType(k8sEndpointAddrs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get the addressType")
|
||||
}
|
||||
|
||||
endpoints := &discoveryv1.EndpointSlice{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: instanceName(cephObjectStore.Name),
|
||||
Namespace: cephObjectStore.Namespace,
|
||||
Labels: labels,
|
||||
},
|
||||
AddressType: discoveryv1.AddressTypeIPv4,
|
||||
AddressType: addressType,
|
||||
Endpoints: []discoveryv1.Endpoint{
|
||||
{
|
||||
Addresses: k8sEndpointAddrs,
|
||||
@@ -765,16 +770,19 @@ func (c *clusterConfig) generateEndpoint(cephObjectStore *cephv1.CephObjectStore
|
||||
addPortToEndpoint(endpoints, "http", cephObjectStore.Spec.Gateway.Port)
|
||||
addPortToEndpoint(endpoints, "https", cephObjectStore.Spec.Gateway.SecurePort)
|
||||
|
||||
return endpoints
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
func (c *clusterConfig) reconcileExternalEndpoint(cephObjectStore *cephv1.CephObjectStore) error {
|
||||
nsName := controller.NsName(c.store.Namespace, c.store.Name)
|
||||
log.NamedInfo(nsName, logger, "reconciling external object store service")
|
||||
|
||||
endpoint := c.generateEndpoint(cephObjectStore)
|
||||
endpoint, err := c.generateEndpoint(cephObjectStore)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to generate the endpoint %q", endpoint.Name)
|
||||
}
|
||||
// Set owner ref to the parent object
|
||||
err := c.ownerInfo.SetControllerReference(endpoint)
|
||||
err = c.ownerInfo.SetControllerReference(endpoint)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to set owner reference to ceph object store endpoint %q", endpoint.Name)
|
||||
}
|
||||
|
||||
@@ -18,11 +18,13 @@ package k8sutil
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
|
||||
"github.com/pkg/errors"
|
||||
cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
|
||||
discoveryv1 "k8s.io/api/discovery/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
@@ -110,3 +112,39 @@ func ParseLinuxIpAddrOutput(rawOutput string) ([]LinuxIpAddrResult, error) {
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func GetIpAddressType(addresses []string) (discoveryv1.AddressType, error) {
|
||||
var addressType discoveryv1.AddressType
|
||||
|
||||
if len(addresses) == 0 {
|
||||
return addressType, errors.New("failed to get the address type for ip address, address list is empty type")
|
||||
}
|
||||
ip, err := netip.ParseAddr(addresses[0])
|
||||
if err != nil {
|
||||
return addressType, errors.Wrapf(err, "failed to get the address type for ip address %q", addresses[0])
|
||||
}
|
||||
addressType = discoveryv1.AddressTypeIPv4
|
||||
if ip.Is6() {
|
||||
addressType = discoveryv1.AddressTypeIPv6
|
||||
}
|
||||
|
||||
// validate all addresses are of the same type
|
||||
for _, addr := range addresses[1:] {
|
||||
ip, err := netip.ParseAddr(addr)
|
||||
if err != nil {
|
||||
return addressType, errors.Wrapf(err, "failed to get the address type for ip address %q", addr)
|
||||
}
|
||||
|
||||
if ip.Is6() {
|
||||
if addressType != discoveryv1.AddressTypeIPv6 {
|
||||
return addressType, errors.Errorf("all ip address are not of same type %v", addresses)
|
||||
}
|
||||
} else {
|
||||
if addressType != discoveryv1.AddressTypeIPv4 {
|
||||
return addressType, errors.Errorf("all ip address are not of same type %v", addresses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return addressType, nil
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
discoveryv1 "k8s.io/api/discovery/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
@@ -307,3 +308,69 @@ func removeLastChar(in string) string {
|
||||
len := len(chars)
|
||||
return string(chars[0 : len-1])
|
||||
}
|
||||
|
||||
// test for GetIpAddressType
|
||||
func TestGetIpAddressType(t *testing.T) {
|
||||
// test cases
|
||||
tests := []struct {
|
||||
name string
|
||||
addresses []string
|
||||
wantType discoveryv1.AddressType
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "single IPv4 address",
|
||||
addresses: []string{"192.168.1.1"},
|
||||
wantType: discoveryv1.AddressTypeIPv4,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "IPv4 address",
|
||||
addresses: []string{"192.168.1.1", "192.146.1.1"},
|
||||
wantType: discoveryv1.AddressTypeIPv4,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "single IPv6 address",
|
||||
addresses: []string{"2001:0db8:85a3:0000:0000:8a2e:0370:7334"},
|
||||
wantType: discoveryv1.AddressTypeIPv6,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "IPv6 address",
|
||||
addresses: []string{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "fe80::1ff:fe23:4567:890a"},
|
||||
wantType: discoveryv1.AddressTypeIPv6,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Mixed addresses",
|
||||
addresses: []string{"192.168.1.1", "192.146.1.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "fe80::1ff:fe23:4567:890a"},
|
||||
wantType: "",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Empty address list",
|
||||
addresses: []string{},
|
||||
wantType: "",
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotType, err := GetIpAddressType(tt.addresses)
|
||||
if err != nil {
|
||||
if !tt.wantErr {
|
||||
t.Errorf("GetIpAddressType() unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if tt.wantErr {
|
||||
t.Errorf("GetIpAddressType() expected error but got none")
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.wantType, gotType)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user