base.py 10.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
#    Copyright 2014 Rackspace
#
#    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.

import abc

import six

from octavia.common import exceptions


class NetworkException(exceptions.OctaviaException):
    pass


class PlugVIPException(NetworkException):
    pass


class UnplugVIPException(NetworkException):
    pass


class AllocateVIPException(NetworkException):
    pass


class DeallocateVIPException(NetworkException):
    pass


class PlugNetworkException(NetworkException):
    pass


class UnplugNetworkException(NetworkException):
    pass


class VIPInUseException(NetworkException):
    pass


class PortNotFound(NetworkException):
    pass


class NetworkNotFound(NetworkException):
    pass


62 63 64 65
class SubnetNotFound(NetworkException):
    pass


66 67 68 69 70 71 72 73
class AmphoraNotFound(NetworkException):
    pass


class PluggedVIPNotFound(NetworkException):
    pass


74 75 76 77
class TimeoutException(NetworkException):
    pass


78 79 80 81
class QosPolicyNotFound(NetworkException):
    pass


82 83 84 85 86 87 88 89 90
@six.add_metaclass(abc.ABCMeta)
class AbstractNetworkDriver(object):
    """This class defines the methods for a fully functional network driver.

    Implementations of this interface can expect a rollback to occur if any of
    the non-nullipotent methods raise an exception.
    """

    @abc.abstractmethod
91
    def allocate_vip(self, load_balancer):
92 93 94 95 96
        """Allocates a virtual ip.

        Reserves it for later use as the frontend connection of a load
        balancer.

97
        :param load_balancer: octavia.common.data_models.LoadBalancer instance
98
        :return: octavia.common.data_models.VIP
99
        :raises: AllocateVIPException, PortNotFound, SubnetNotFound
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
        """
        pass

    @abc.abstractmethod
    def deallocate_vip(self, vip):
        """Removes any resources that reserved this virtual ip.

        :param vip: octavia.common.data_models.VIP instance
        :return: None
        :raises: DeallocateVIPException, VIPInUseException,
                 VIPConfiigurationNotFound
        """
        pass

    @abc.abstractmethod
    def plug_vip(self, load_balancer, vip):
        """Plugs a virtual ip as the frontend connection of a load balancer.

        Sets up the routing of traffic from the vip to the load balancer
        and its amphorae.

        :param load_balancer: octavia.common.data_models.LoadBalancer instance
        :param vip: octavia.common.data_models.VIP instance
123 124 125
        :return: dict consisting of amphora_id as key and bind_ip as value.
                 bind_ip is the ip that the amphora should listen on to
                 receive traffic to load balance.
126
        :raises: PlugVIPException, PortNotFound
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
        """
        pass

    @abc.abstractmethod
    def unplug_vip(self, load_balancer, vip):
        """Unplugs a virtual ip as the frontend connection of a load balancer.

        Removes the routing of traffic from the vip to the load balancer
        and its amphorae.

        :param load_balancer: octavia.common.data_models.LoadBalancer instance
        :param vip: octavia.common.data_models.VIP instance
        :return: octavia.common.data_models.VIP instance
        :raises: UnplugVIPException, PluggedVIPNotFound
        """
        pass

    @abc.abstractmethod
145
    def plug_network(self, compute_id, network_id, ip_address=None):
146 147
        """Connects an existing amphora to an existing network.

148
        :param compute_id: id of an amphora in the compute service
149 150 151 152 153 154 155
        :param network_id: id of a network
        :param ip_address: ip address to attempt to be assigned to interface
        :return: octavia.network.data_models.Interface instance
        :raises: PlugNetworkException, AmphoraNotFound, NetworkNotFound
        """

    @abc.abstractmethod
156
    def unplug_network(self, compute_id, network_id, ip_address=None):
157 158
        """Disconnects an existing amphora from an existing network.

159 160 161
        If ip_address is not specificed, all the interfaces plugged on
        network_id should be unplugged.

162
        :param compute_id: id of an amphora in the compute service
163
        :param network_id: id of a network
164
        :param ip_address: specific ip_address to unplug
165
        :return: None
166 167
        :raises: UnplugNetworkException, AmphoraNotFound, NetworkNotFound,
                 NetworkException
168 169 170 171
        """
        pass

    @abc.abstractmethod
172
    def get_plugged_networks(self, compute_id):
173 174
        """Retrieves the current plugged networking configuration.

175
        :param compute_id: id of an amphora in the compute service
176
        :return: [octavia.network.data_models.Instance]
177 178
        """

179
    def update_vip(self, load_balancer, for_delete):
180 181 182 183 184 185 186 187
        """Hook for the driver to update the VIP information.

        This method will be called upon the change of a load_balancer
        configuration. It is an optional method to be implemented by drivers.
        It allows the driver to update any VIP information based on the
        state of the passed in load_balancer.

        :param load_balancer: octavia.common.data_models.LoadBalancer instance
188 189
        :param for_delete: Boolean indicating if this update is for a delete
        :raises: MissingVIPSecurityGroup
190 191 192
        :return: None
        """
        pass
193 194

    @abc.abstractmethod
195 196
    def get_network(self, network_id):
        """Retrieves network from network id.
197 198 199 200 201

        :param network_id: id of an network to retrieve
        :return: octavia.network.data_models.Network
        :raises: NetworkException, NetworkNotFound
        """
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
        pass

    @abc.abstractmethod
    def get_subnet(self, subnet_id):
        """Retrieves subnet from subnet id.

        :param subnet_id: id of a subnet to retrieve
        :return: octavia.network.data_models.Subnet
        :raises: NetworkException, SubnetNotFound
        """
        pass

    @abc.abstractmethod
    def get_port(self, port_id):
        """Retrieves port from port id.

        :param port_id: id of a port to retrieve
        :return: octavia.network.data_models.Port
        :raises: NetworkException, PortNotFound
        """
        pass
223

224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
    @abc.abstractmethod
    def get_network_by_name(self, network_name):
        """Retrieves network from network name.

        :param network_name: name of a network to retrieve
        :return: octavia.network.data_models.Network
        :raises: NetworkException, NetworkNotFound
        """
        pass

    @abc.abstractmethod
    def get_subnet_by_name(self, subnet_name):
        """Retrieves subnet from subnet name.

        :param subnet_name: name of a subnet to retrieve
        :return: octavia.network.data_models.Subnet
        :raises: NetworkException, SubnetNotFound
        """
        pass

    @abc.abstractmethod
    def get_port_by_name(self, port_name):
        """Retrieves port from port name.

        :param port_name: name of a port to retrieve
        :return: octavia.network.data_models.Port
        :raises: NetworkException, PortNotFound
        """
        pass

    @abc.abstractmethod
    def get_port_by_net_id_device_id(self, network_id, device_id):
        """Retrieves port from network id and device id.

        :param network_id: id of a network to filter by
        :param device_id: id of a network device to filter by
        :return: octavia.network.data_models.Port
        :raises: NetworkException, PortNotFound
        """
        pass

265 266 267 268 269 270 271 272 273
    @abc.abstractmethod
    def failover_preparation(self, amphora):
        """Prepare an amphora for failover.

        :param amphora: amphora object to failover
        :return: None
        :raises: PortNotFound
        """
        pass
274 275

    @abc.abstractmethod
276
    def plug_port(self, amphora, port):
277 278
        """Plug a neutron port in to a compute instance

279
        :param amphora: amphora object to plug the port into
280 281 282 283 284
        :param port: port to plug into the compute instance
        :return: None
        :raises: PlugNetworkException, AmphoraNotFound, NetworkNotFound
        """
        pass
285 286

    @abc.abstractmethod
Michael Johnson's avatar
Michael Johnson committed
287
    def get_network_configs(self, load_balancer, amphora=None):
288 289 290 291 292 293 294 295 296 297
        """Retrieve network configurations

        This method assumes that a dictionary of AmphoraNetworkConfigs keyed
        off of the related amphora id are returned.
        The configs contain data pertaining to each amphora that is later
        used for finalization of the entire load balancer configuration.
        The data provided to these configs is left up to the driver, this
        means the driver is responsible for providing data that is appropriate
        for the amphora network configurations.

298
        Example return: {<amphora.id>: <AmphoraNetworkConfig>}
299 300

        :param load_balancer: The load_balancer configuration
Michael Johnson's avatar
Michael Johnson committed
301
        :param amphora: Optional amphora to only query.
302
        :return: dict of octavia.network.data_models.AmphoraNetworkConfig
303
                 keyed off of the amphora id the config is associated with.
304 305 306
        :raises: NotFound, NetworkNotFound, SubnetNotFound, PortNotFound
        """
        pass
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321

    @abc.abstractmethod
    def wait_for_port_detach(self, amphora):
        """Waits for the amphora ports device_id to be unset.

        This method waits for the ports on an amphora device_id
        parameter to be '' or None which signifies that nova has
        finished detaching the port from the instance.

        :param amphora: Amphora to wait for ports to detach.
        :returns: None
        :raises TimeoutException: Port did not detach in interval.
        :raises PortNotFound: Port was not found by neutron.
        """
        pass
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351

    @abc.abstractmethod
    def update_vip_sg(self, load_balancer, vip):
        """Updates the security group for a VIP

        :param load_balancer: Load Balancer to rpepare the VIP for
        :param vip: The VIP to plug
        """
        pass

    @abc.abstractmethod
    def plug_aap_port(self, load_balancer, vip, amphora, subnet):
        """Plugs the AAP port to the amp

        :param load_balancer: Load Balancer to prepare the VIP for
        :param vip: The VIP to plug
        :param amphora: The amphora to plug the VIP into
        :param subnet: The subnet to plug the aap into
        """
        pass

    @abc.abstractmethod
    def unplug_aap_port(self, vip, amphora, subnet):
        """Unplugs the AAP port to the amp

        :param vip: The VIP to plug
        :param amphora: The amphora to plug the VIP into
        :param subnet: The subnet to plug the aap into
        """
        pass
352 353 354 355 356 357 358

    @abc.abstractmethod
    def qos_enabled(self):
        """Whether QoS is enabled

        :return: Boolean
        """