Strip leading zeros from "funny" Service IPs

According to [1] we're supposed to support "funny" Service IPs, which
means IPs with leading zeros. Unlike unix in general we should not parse
them as octal values, but rather treat them like without leading zeros.
This commit makes sure that we strip the zeros from both ClusterIP and
LoadBalancerIP before we put them into KuryrLoadBalancer struct. This
means that later on Octavia and Neutron will get values that they
support and will proceed with LB or FIP creation normally.

[1] https://github.com/kubernetes/kubernetes/blob/v1.24.1/test/e2e/network/funny_ips.go

Change-Id: I0aa8d7326dbf40459f73037ae54d2afc01ea9bb6
Closes-Bug: 1978112
This commit is contained in:
Michał Dulko 2022-06-09 13:47:26 +02:00
parent 846f158724
commit ce6fb744b5
2 changed files with 24 additions and 11 deletions

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import netaddr
from kuryr.lib._i18n import _
from oslo_log import log as logging
@ -105,7 +107,7 @@ class ServiceHandler(k8s_base.ResourceEventHandler):
def _get_service_ip(self, service):
if self._is_supported_type(service):
return service['spec'].get('clusterIP')
return self._strip_funny_ip(service['spec'].get('clusterIP'))
return None
def _should_ignore(self, service):
@ -261,7 +263,7 @@ class ServiceHandler(k8s_base.ResourceEventHandler):
spec['provider'] = self._lb_provider
if spec_lb_ip is not None:
spec['lb_ip'] = spec_lb_ip
spec['lb_ip'] = self._strip_funny_ip(spec_lb_ip)
timeout_cli, timeout_mem = self._get_data_timeout_annotation(service)
spec['timeout_client_data'] = timeout_cli
spec['timeout_member_data'] = timeout_mem
@ -311,6 +313,9 @@ class ServiceHandler(k8s_base.ResourceEventHandler):
return False
def _strip_funny_ip(self, ip):
return str(netaddr.IPAddress(ip, flags=netaddr.core.ZEROFILL))
class EndpointsHandler(k8s_base.ResourceEventHandler):
"""EndpointsHandler handles K8s Endpoints events.

View File

@ -26,6 +26,9 @@ from kuryr_kubernetes.tests import base as test_base
_SUPPORTED_LISTENER_PROT = ('HTTP', 'HTTPS', 'TCP')
@mock.patch('kuryr_kubernetes.controller.drivers.base.LBaaSDriver.'
'get_instance', mock.Mock())
@mock.patch('kuryr_kubernetes.clients.get_kubernetes_client', mock.Mock())
class TestServiceHandler(test_base.TestCase):
@mock.patch('kuryr_kubernetes.clients.get_kubernetes_client')
def test_on_present(self, get_k8s_client):
@ -171,18 +174,23 @@ class TestServiceHandler(test_base.TestCase):
def test_get_service_ip(self):
svc_body = {'spec': {'type': 'ClusterIP',
'clusterIP': mock.sentinel.cluster_ip}}
m_handler = mock.Mock(spec=h_lbaas.ServiceHandler)
ret = h_lbaas.ServiceHandler._get_service_ip(m_handler, svc_body)
self.assertEqual(mock.sentinel.cluster_ip, ret)
'clusterIP': '192.168.0.11'}}
handler = h_lbaas.ServiceHandler()
ret = handler._get_service_ip(svc_body)
self.assertEqual('192.168.0.11', ret)
svc_body = {'spec': {'type': 'LoadBalancer',
'clusterIP': mock.sentinel.cluster_ip}}
m_handler = mock.Mock(spec=h_lbaas.ServiceHandler)
'clusterIP': '192.168.0.11'}}
ret = handler._get_service_ip(svc_body)
self.assertEqual('192.168.0.11', ret)
ret = h_lbaas.ServiceHandler._get_service_ip(m_handler, svc_body)
self.assertEqual(mock.sentinel.cluster_ip, ret)
def test_get_service_ip_funny(self):
svc_body = {'spec': {'type': 'ClusterIP',
'clusterIP': '172.30.0.011'}}
handler = h_lbaas.ServiceHandler()
ret = handler._get_service_ip(svc_body)
self.assertEqual('172.30.0.11', ret)
def test_is_supported_type_clusterip(self):
m_handler = mock.Mock(spec=h_lbaas.ServiceHandler)