46723c5751
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
114 lines
4.4 KiB
Python
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'])
|