kuryr-kubernetes/kuryr_kubernetes/controller/drivers/lb_public_ip.py
Maysa Macedo 46723c5751 Skip FIP creation if no external subnet config is set
When creating a Service of LoadBalancer type, a external_svc_net
config must be set, otherwise the Floating IP for the respective
LoadBalancer won't get created and an exception will be raised of
missing config. This commit logs and skip the FIP creation when
the needed config is not set.

Change-Id: I155d11f7080d2d4dbeca6de85b2f284aaacd7d8d
2020-09-02 13:54:26 +00:00

114 lines
4.4 KiB
Python

# Copyright (c) 2017 RedHat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from kuryr_kubernetes import config
from kuryr_kubernetes.controller.drivers import base
from kuryr_kubernetes.controller.drivers import public_ip
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
class FloatingIpServicePubIPDriver(base.ServicePubIpDriver):
"""Manages floating ip for neutron lbaas.
Service loadbalancerIP support the following :
1. No loadbalancer IP - k8s service.spec.type != 'LoadBalancer'
2. Floating IP allocated from pool -
k8s service.spec.type = 'LoadBalancer' and
service.spec.loadBalancerIP NOT defined
3. Floating IP specified by the user -
k8s service.spec.type = 'LoadBalancer' and
service.spec.loadBalancerIP is defined.
"""
def __init__(self):
super(FloatingIpServicePubIPDriver, self).__init__()
self._drv_pub_ip = public_ip.FipPubIpDriver()
def acquire_service_pub_ip_info(self, spec_type, spec_lb_ip, project_id,
port_id_to_be_associated=None):
if spec_type != 'LoadBalancer':
return None
# get public network/subnet ids from kuryr.conf
public_network_id = config.CONF.neutron_defaults.external_svc_net
public_subnet_id = config.CONF.neutron_defaults.external_svc_subnet
if not public_network_id:
LOG.warning('Skipping Floating IP allocation on port: %s. '
'Missing value for external_svc_net config.',
port_id_to_be_associated)
return None
if spec_lb_ip:
user_specified_ip = spec_lb_ip.format()
res_id = self._drv_pub_ip.is_ip_available(user_specified_ip,
port_id_to_be_associated)
if res_id:
service_pub_ip_info = {
'ip_id': res_id,
'ip_addr': str(user_specified_ip),
'alloc_method': 'user'
}
return service_pub_ip_info
else:
# user specified IP is not valid
LOG.error("IP=%s is not available", user_specified_ip)
return None
else:
LOG.debug("Trying to allocate public ip from pool")
try:
res_id, alloc_ip_addr = (self._drv_pub_ip.allocate_ip(
public_network_id, project_id, pub_subnet_id=public_subnet_id,
description='kuryr_lb',
port_id_to_be_associated=port_id_to_be_associated))
except Exception:
LOG.exception("Failed to allocate public IP - net_id:%s",
public_network_id)
return None
service_pub_ip_info = {
'ip_id': res_id,
'ip_addr': alloc_ip_addr,
'alloc_method': 'pool'
}
return service_pub_ip_info
def release_pub_ip(self, service_pub_ip_info):
if not service_pub_ip_info:
return True
if service_pub_ip_info['alloc_method'] == 'pool':
retcode = self._drv_pub_ip.free_ip(service_pub_ip_info['ip_id'])
if not retcode:
LOG.error("Failed to delete public_ip_id =%s !",
service_pub_ip_info['ip_id'])
return False
return True
def associate_pub_ip(self, service_pub_ip_info, vip_port_id):
if (not service_pub_ip_info or
not vip_port_id or
not service_pub_ip_info['ip_id']):
return
self._drv_pub_ip.associate(
service_pub_ip_info['ip_id'], vip_port_id)
def disassociate_pub_ip(self, service_pub_ip_info):
if not service_pub_ip_info or not service_pub_ip_info['ip_id']:
return
self._drv_pub_ip.disassociate(service_pub_ip_info['ip_id'])