Tests pass again, and we're properly cleaning up after ourselves
This commit is contained in:
parent
dca69104a4
commit
949fa7f2d7
100
DESIGN
100
DESIGN
@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
## Why
|
## Why
|
||||||
|
|
||||||
<p>We don't have centralized networking services. Quantum is incapable of talking to melange, melange <em>could</em> talk to Quantum,
|
We don't have centralized networking services. Quantum is incapable of talking to melange, melange <em>could</em> talk to Quantum,
|
||||||
but then we're bothering with HTTPS handshaking for no reason. Alternatively, we need to retain the network manager as a traffic
|
but then we're bothering with HTTPS handshaking for no reason. Alternatively, we need to retain the network manager as a traffic
|
||||||
arbiter. Given the upstream push to eliminate the network managers and move entirely to quantum, we needed to consider alternative
|
arbiter. Given the upstream push to eliminate the network managers and move entirely to quantum, we needed to consider alternative
|
||||||
solutions. Given that we'd like to avoid making melange a glorified network manager, we originally decided we want to write a
|
solutions. Given that we'd like to avoid making melange a glorified network manager, we originally decided we want to write a
|
||||||
Quantum-lite, named Newtonian, as our first pass. However, resistance from the company pushed us to try and write a solution that
|
Quantum-lite, named Newtonian, as our first pass. However, resistance from the company pushed us to try and write a solution that
|
||||||
fits within the goals of the community itself. Hence, Quark was born.</p>
|
fits within the goals of the community itself. Hence, Quark was born.
|
||||||
|
|
||||||
## History
|
## History
|
||||||
|
|
||||||
<p>Nova provided a network manager type of Flat, which allows us to easily give out real-world public IPv4 and v6 addresses without any oversight
|
Nova provided a network manager type of Flat, which allows us to easily give out real-world public IPv4 and v6 addresses without any oversight
|
||||||
from Nova itself. Meanwhile, Quantum appears, and implements L2 logical networking. However, it leaves Nova as the IPAM solution for the cloud.
|
from Nova itself. Meanwhile, Quantum appears, and implements L2 logical networking. However, it leaves Nova as the IPAM solution for the cloud.
|
||||||
Rackspace begins development of a solution called Melange, intended to abstract IPAM and provide it at a different tier in the Openstack stack.
|
Rackspace begins development of a solution called Melange, intended to abstract IPAM and provide it at a different tier in the Openstack stack.
|
||||||
Melange is a functional, performant solution for providing IP addressing and MAC addressing to instances created by Nova. However, Quantum, running
|
Melange is a functional, performant solution for providing IP addressing and MAC addressing to instances created by Nova. However, Quantum, running
|
||||||
@ -21,38 +21,13 @@ The caveat is the implementation of each is left up to the developer of each plu
|
|||||||
This creates a problem for Rackspace, who 1) doesn't want to be tied to a given Quantum backend and 2) doesn't want to be stuck with a potentially gimped
|
This creates a problem for Rackspace, who 1) doesn't want to be tied to a given Quantum backend and 2) doesn't want to be stuck with a potentially gimped
|
||||||
IPAM solution. As such, work on Newtonian begins. After much debate with the community and internal Rackspace folks, it's finally decided that Newtonian
|
IPAM solution. As such, work on Newtonian begins. After much debate with the community and internal Rackspace folks, it's finally decided that Newtonian
|
||||||
represents a fork, which is a Bad Thing™. Given that, we decide that the next bset solution is to provide a Quantum plugin that implements the Rackspace
|
represents a fork, which is a Bad Thing™. Given that, we decide that the next bset solution is to provide a Quantum plugin that implements the Rackspace
|
||||||
preferred backend with the intent of providing Quantum wide IPAM, Mac Addressing, and networking abstractions, with less dependence on a given backend.</p>
|
preferred backend with the intent of providing Quantum wide IPAM, Mac Addressing, and networking abstractions, with less dependence on a given backend.
|
||||||
|
|
||||||
## User Stories and Epics
|
|
||||||
|
|
||||||
* As a product manager, I need IPAM management in a service deployable at a region level
|
|
||||||
* As a product manager, I need Mac Address management in a central service that can be deployed at the region level
|
|
||||||
* As an openstack community member, I need to provide a networking solution that can be used by the community
|
|
||||||
* As an ops engineer, I need Nova to make less calls to Quantum to prevent kicking it over.
|
|
||||||
* I need to be able to create a network with all of it's subnets in a single call
|
|
||||||
* As an ops engineer, I need Quantum to make less call to the Networking Backend to mitigate timeouts and throttling
|
|
||||||
* As a Rackspace developer, I want less code to maintain that is a diff from upstream Openstack.
|
|
||||||
* As a Rackspace developer, I want an extension in Quantum that allows me to bulk create all networking for an instance in a single call.
|
|
||||||
* As a Rackspace developer, I want a Quantum abstraction that depends less heavily on the networking backend
|
|
||||||
* As a product manager, I need MAC Address ranges to be available to all tenants of Quantum/Quark
|
|
||||||
* As a Quantum user, I need a consistent API
|
|
||||||
* As a Quantum user, I need a consistently performing API
|
|
||||||
* As Rackspace, I need less build failures due to networking setup timeouts talking to the Quantum backend
|
|
||||||
* As Rackspace, I want faster instance build times, which are dependent on a responsive Quantum
|
|
||||||
* As a customer, I want faster build times
|
|
||||||
* As Rackspace, I don't want to be locked into any Vendor
|
|
||||||
* As the network team manager, I need benchmarks to show the improvement of Quark over vanilla Quantum
|
|
||||||
* As the network team manager, I need measurable improvements in Quark on a regular basis
|
|
||||||
* As a Rackspace developer, I need a design document with the extended API for Quark to present to the community
|
|
||||||
* As a user, I need a way to create routes for my networks
|
|
||||||
* As a user, I need a way to request additional IP addresses from my networks.
|
|
||||||
* As a user, I need a way to share IP addresses across my ports
|
|
||||||
|
|
||||||
## Nice to Haves
|
## Nice to Haves
|
||||||
|
|
||||||
* As a product manager, I want less dependency on Quantum.
|
* As a product manager, I want less dependency on Quantum.
|
||||||
* I want my builds to have more parallel functioning pieces, which means I want my networking request to be fulfilled at the same time as other operations
|
* I want my builds to have more parallel functioning pieces, which means I want my networking request to be fulfilled at the same time as other operations
|
||||||
* As Rackspace, I may need MDI to keep selling</p>
|
* As Rackspace, I may need MDI to keep selling
|
||||||
|
|
||||||
## Priorities first to last
|
## Priorities first to last
|
||||||
|
|
||||||
@ -86,47 +61,84 @@ preferred backend with the intent of providing Quantum wide IPAM, Mac Addressing
|
|||||||
|
|
||||||
### Switching to QV2 will DoS Backend with current implementation
|
### Switching to QV2 will DoS Backend with current implementation
|
||||||
|
|
||||||
<p>DoS'd due to GETs when Nova is trying to retrieve instance network info in the periodic tasks. We currently get around it by providing this data
|
DoS'd due to GETs when Nova is trying to retrieve instance network info in the periodic tasks. We currently get around it by providing this data
|
||||||
in melange. We're doing the same thing in the Quark Model by storing all relevant bits in the database. This database creates a single authoritative
|
in melange. We're doing the same thing in the Quark Model by storing all relevant bits in the database. This database creates a single authoritative
|
||||||
source of all network state</p>
|
source of all network state
|
||||||
|
|
||||||
<p>DoSing due to POSTs when creating networks. One possible solution is to implement a manner of asynchronously creating networking information via Request
|
DoSing due to POSTs when creating networks. One possible solution is to implement a manner of asynchronously creating networking information via Request
|
||||||
IDs or other similar constructs.</p>
|
IDs or other similar constructs.
|
||||||
|
|
||||||
### Current Quantum solution is non-performant
|
### Current Quantum solution is non-performant
|
||||||
|
|
||||||
<p>Current REST implementation forces you to make piecemeal requests. You need to look up networks to find your subnets. Then look up each port by subnet. Beyond that,
|
Current REST implementation forces you to make piecemeal requests. You need to look up networks to find your subnets. Then look up each port by subnet. Beyond that,
|
||||||
individual operations can explode into an unknown number of backend operations. We feel that the safer solution is to assume that the backend will behave badly,
|
individual operations can explode into an unknown number of backend operations. We feel that the safer solution is to assume that the backend will behave badly,
|
||||||
and limit the number of calls we need to make to it.</p>
|
and limit the number of calls we need to make to it.
|
||||||
|
|
||||||
### Network Manager needs to go away
|
### Network Manager needs to go away
|
||||||
|
|
||||||
<p>This is a unilateral community decision. We need to shift out dependence on the quantumv2 manager up to the quantum network API and down into Quark/Quantum</p>
|
This is a unilateral community decision. We need to shift out dependence on the quantumv2 manager up to the quantum network API and down into Quark/Quantum
|
||||||
|
|
||||||
### Too many REST calls in current quantum client
|
### Too many REST calls in current quantum client
|
||||||
|
|
||||||
<p>This is by design. Reworking the above non-performant problem also necessitates reworking the CLI to make less calls</p>
|
This is by design. Reworking the above non-performant problem also necessitates reworking the CLI to make less calls
|
||||||
|
|
||||||
### Current IMPL does not support bulk operations on nested resources
|
### Current IMPL does not support bulk operations on nested resources
|
||||||
|
|
||||||
<p>Original V2 API for quantum provided this construct, which was then removed. We can solve this by removing the check to perform the bulk</p>
|
Original V2 API for quantum provided this construct, which was then removed. We can solve this by removing the check to perform the bulk
|
||||||
|
|
||||||
### Quantum <-> Backend delay causing building
|
### Quantum <-> Backend delay causing building
|
||||||
|
|
||||||
<p>By eliminating some of the superfluous calls to the backend, we hope to reduce the length of the timeouts required to remain robust</p>
|
By eliminating some of the superfluous calls to the backend, we hope to reduce the length of the timeouts required to remain robust
|
||||||
|
|
||||||
### Unknown performance hit with increased requests to the Network Backend
|
### Unknown performance hit with increased requests to the Network Backend
|
||||||
|
|
||||||
<p>Since we don't know what the backend is going to do with a given operation, as above, eliminating the calls as above helps us zero in on the problem</p>
|
Since we don't know what the backend is going to do with a given operation, as above, eliminating the calls as above helps us zero in on the problem
|
||||||
|
|
||||||
### Backend request times are non-determinstic
|
### Backend request times are non-determinstic
|
||||||
|
|
||||||
<p>We can't solve this, we can only rely on it less</p>
|
We can't solve this, we can only rely on it less
|
||||||
|
|
||||||
### Vendor lock-in is bad
|
### Vendor lock-in is bad
|
||||||
|
|
||||||
<p>Denormalizing Quantum constructs into a database helps use mitigate for this problem</p>
|
Denormalizing Quantum constructs into a database helps use mitigate for this problem
|
||||||
|
|
||||||
### A unified network model
|
### A unified network model
|
||||||
|
|
||||||
<p>We feel that we may spend too much time converting from one structure of the networking information to another. The schema for Quark more closely models what Nova is expecting</p>
|
We feel that we may spend too much time converting from one structure of the networking information to another. The schema for Quark more closely models what Nova is expecting
|
||||||
|
|
||||||
|
## User Stories and Epics
|
||||||
|
|
||||||
|
#### As a product manager, I need IPAM in a service deployable at a region level
|
||||||
|
|
||||||
|
We need to provide APIs for adding and removing IP addresses to arbitrary devices. Instances are folded under this.
|
||||||
|
|
||||||
|
#### As a product manager, I need Mac Address management in a central service that can be deployed at the region level
|
||||||
|
|
||||||
|
We need to provide APIs for adding and removing MAC addresses to arbitrary devices. Instances are folded under this.
|
||||||
|
|
||||||
|
#### As an openstack community member, I need to provide a networking solution that can be used by the community
|
||||||
|
|
||||||
|
Implement Quark as Yet Another Quantum plugin (YAQ)™ with bundled extensions. The intent is to trickle ideas up
|
||||||
|
|
||||||
|
#### As an ops engineer, I need Nova to make less calls to Quantum to prevent kicking it over.
|
||||||
|
|
||||||
|
Implementation of a database layer that let's us eliminate alot of the calls the existing plugins are making to the networking backend
|
||||||
|
|
||||||
|
#### I need to be able to create a network with all of it's subnets in a single call
|
||||||
|
#### As an ops engineer, I need Quantum to make less call to the Networking Backend to mitigate timeouts and throttling
|
||||||
|
#### As a Rackspace developer, I want less code to maintain that is a diff from upstream Openstack.
|
||||||
|
#### As a Rackspace developer, I want an extension in Quantum that allows me to bulk create all networking for an instance in a single call.
|
||||||
|
#### As a Rackspace developer, I want a Quantum abstraction that depends less heavily on the networking backend
|
||||||
|
#### As a product manager, I need MAC Address ranges to be available to all tenants of Quantum/Quark
|
||||||
|
#### As a Quantum user, I need a consistent API
|
||||||
|
#### As a Quantum user, I need a consistently performing API
|
||||||
|
#### As Rackspace, I need less build failures due to networking setup timeouts talking to the Quantum backend
|
||||||
|
#### As Rackspace, I want faster instance build times, which are dependent on a responsive Quantum
|
||||||
|
#### As a customer, I want faster build times
|
||||||
|
#### As Rackspace, I don't want to be locked into any Vendor
|
||||||
|
#### As the network team manager, I need benchmarks to show the improvement of Quark over vanilla Quantum
|
||||||
|
#### As the network team manager, I need measurable improvements in Quark on a regular basis
|
||||||
|
#### As a Rackspace developer, I need a design document with the extended API for Quark to present to the community
|
||||||
|
#### As a user, I need a way to create routes for my networks
|
||||||
|
#### As a user, I need a way to request additional IP addresses from my networks.
|
||||||
|
#### As a user, I need a way to share IP addresses across my ports
|
||||||
|
@ -132,6 +132,7 @@ class IPAddress(BASEV2, HasId, HasTenant):
|
|||||||
sa.ForeignKey("quark_networks.id",
|
sa.ForeignKey("quark_networks.id",
|
||||||
ondelete="CASCADE"))
|
ondelete="CASCADE"))
|
||||||
|
|
||||||
|
port_id = sa.Column(sa.String(36))
|
||||||
version = sa.Column(sa.Integer())
|
version = sa.Column(sa.Integer())
|
||||||
|
|
||||||
# Need a constant to facilitate the indexed search for new IPs
|
# Need a constant to facilitate the indexed search for new IPs
|
||||||
@ -222,7 +223,6 @@ class Port(BASEV2, HasId, HasTenant):
|
|||||||
backend_key = sa.Column(sa.String(36), nullable=False)
|
backend_key = sa.Column(sa.String(36), nullable=False)
|
||||||
mac_address = sa.Column(sa.BigInteger())
|
mac_address = sa.Column(sa.BigInteger())
|
||||||
device_id = sa.Column(sa.String(255), nullable=False)
|
device_id = sa.Column(sa.String(255), nullable=False)
|
||||||
ip_addresses = orm.relationship(IPAddress, backref=orm.backref("ports"))
|
|
||||||
|
|
||||||
|
|
||||||
class MacAddress(BASEV2, HasTenant):
|
class MacAddress(BASEV2, HasTenant):
|
||||||
|
@ -527,6 +527,9 @@ class Plugin(quantum_plugin_base_v2.QuantumPluginBaseV2):
|
|||||||
assoc = models.PortIPAddressAssociation()
|
assoc = models.PortIPAddressAssociation()
|
||||||
assoc["port"] = new_port
|
assoc["port"] = new_port
|
||||||
assoc["ip_address"] = addr
|
assoc["ip_address"] = addr
|
||||||
|
|
||||||
|
#TODO: remove this after the join table works
|
||||||
|
addr["port_id"] = port_id
|
||||||
session.add(addr)
|
session.add(addr)
|
||||||
session.add(assoc)
|
session.add(assoc)
|
||||||
session.add(new_port)
|
session.add(new_port)
|
||||||
@ -656,7 +659,6 @@ class Plugin(quantum_plugin_base_v2.QuantumPluginBaseV2):
|
|||||||
LOG.info("delete_port %s for tenant %s" %
|
LOG.info("delete_port %s for tenant %s" %
|
||||||
(id, context.tenant_id))
|
(id, context.tenant_id))
|
||||||
session = context.session
|
session = context.session
|
||||||
with session.begin():
|
|
||||||
port = session.query(models.Port).\
|
port = session.query(models.Port).\
|
||||||
filter(models.Port.id == id).\
|
filter(models.Port.id == id).\
|
||||||
filter(models.Port.tenant_id == context.tenant_id).\
|
filter(models.Port.tenant_id == context.tenant_id).\
|
||||||
@ -664,13 +666,20 @@ class Plugin(quantum_plugin_base_v2.QuantumPluginBaseV2):
|
|||||||
if not port:
|
if not port:
|
||||||
raise exceptions.NetworkNotFound(net_id=id)
|
raise exceptions.NetworkNotFound(net_id=id)
|
||||||
|
|
||||||
|
assocs = session.query(models.PortIPAddressAssociation).\
|
||||||
|
filter(models.PortIPAddressAssociation.port_id == id).\
|
||||||
|
all()
|
||||||
|
|
||||||
backend_key = port["backend_key"]
|
backend_key = port["backend_key"]
|
||||||
mac_address = netaddr.EUI(port["mac_address"]).value
|
mac_address = netaddr.EUI(port["mac_address"]).value
|
||||||
self.ipam_driver.deallocate_mac_address(session,
|
self.ipam_driver.deallocate_mac_address(session,
|
||||||
mac_address,)
|
mac_address,)
|
||||||
self.ipam_driver.deallocate_ip_address(
|
self.ipam_driver.deallocate_ip_address(
|
||||||
session, id, ipam_reuse_after=self.ipam_reuse_after)
|
session, id, ipam_reuse_after=self.ipam_reuse_after)
|
||||||
|
for assoc in assocs:
|
||||||
|
session.delete(assoc)
|
||||||
session.delete(port)
|
session.delete(port)
|
||||||
|
session.flush()
|
||||||
self.net_driver.delete_port(context, backend_key)
|
self.net_driver.delete_port(context, backend_key)
|
||||||
|
|
||||||
def get_mac_address_ranges(self, context):
|
def get_mac_address_ranges(self, context):
|
||||||
|
Loading…
Reference in New Issue
Block a user