Jump to: navigation, search

Difference between revisions of "Neutron/sharing-model-for-external-networks"

(Created page with "External = True independent from Shared Impossible to assume external => shared = Sharing model for external networks = == Current logic == Currently the concept of 'extern...")
 
m (Approaches)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
External = True independent from Shared
+
= Current logic =
 
 
Impossible to assume external => shared
 
= Sharing model for external networks =
 
 
 
== Current logic ==
 
  
 
Currently the concept of 'external' network is somewhat similar to the concept of a 'shared' network.
 
Currently the concept of 'external' network is somewhat similar to the concept of a 'shared' network.
However, while every tenant can operate on a shared network, performing operations such as creating port, the set of operations a tenant can perform on a shared network is more limited, as it's currently restrained to setting external gateways on routers and creating floating IPs.
+
However, while every tenant can operate on a shared network, performing operations such as creating port, the set of operations a tenant can perform on an external network is more limited, as it's currently restrained to setting external gateways on routers and creating floating IPs.
  
 
Nevertheless, the concept of 'external' implies some forms of sharing, and this has some bearing on the topologies that can be achieved.
 
Nevertheless, the concept of 'external' implies some forms of sharing, and this has some bearing on the topologies that can be achieved.
 
For instance it is not possible at the moment have an external network which is reserved to a specific tenant. That external network will always show up in queries performed by other tenants too.
 
For instance it is not possible at the moment have an external network which is reserved to a specific tenant. That external network will always show up in queries performed by other tenants too.
  
== Goal ==
+
= Goal =
  
 
The goal of this blueprint is to find a solution for limiting the visibility scope of an external network while preserving backward compatibility.
 
The goal of this blueprint is to find a solution for limiting the visibility scope of an external network while preserving backward compatibility.
 
If a reasonable solution which preserves backward compatibility can't be found this blueprint should be deferred to the next release.
 
If a reasonable solution which preserves backward compatibility can't be found this blueprint should be deferred to the next release.
  
 +
= Approaches =
 
== Decoupling 'shared' from 'external': this won't work ==
 
== Decoupling 'shared' from 'external': this won't work ==
  
 
Apparently the easiest solution is to decouple the concept of 'external' from the concept of sharing.
 
Apparently the easiest solution is to decouple the concept of 'external' from the concept of sharing.
 
External will qualify the network in topological terms, whereas 'shared' will qualify it in terms of access.
 
External will qualify the network in topological terms, whereas 'shared' will qualify it in terms of access.
In this way,  
+
In this way, the external network as we know it today would be 'external and shared', whereas a network which is simply external would be visible only to the tenant who owns it, as any other network.
POST shared=True
+
 
1) shared = True, external=False
+
This is 'kind of' backward compatible. Indeed a data migration can be used to set shared=True for each network where external=True, but the responses will be different since the 'shared' attribute would change from False to True for existing external networks.
 +
 
 +
Moreover, in order to preserve backward compatibility, setting a network as external should keep having the same behaviour as now.
 +
This will mean that the network has to be 'shared' and 'external' at the same time.
 +
If a user want a 'private' external network, he/she will have to submit a request with shared=False, external=True (and this is a bit awkward).
 +
Similarly when unsetting the 'external' attribute, the network will go back to the 'private' state.
 +
 
 +
The real problem comes however when considering the following sequence of operations:
 +
# POST /networks with shared=True  --> shared = True, external=False
 +
# PUT /networks with external=True --> shared=True, external=False
 +
# PUT /networks external=False --> shared=False, external=False
 +
 
 +
The resulting state of the network at step 3 differs from step 1, and this is unaccepable.
 +
 
 +
Also, there will be complications related to policy verifications in this case. [discuss further]
 +
 
 +
== Public 'external' networks have no tenant ==
 +
 
 +
Set tenant_id=None for external networks which should be shared.
 +
Implications due to resources without tenant_id will cause get_networks to not return this network, and this will require some non-trivial changes into Neutron's db layer.
 +
Resources without owners might be troublesome also from an authZ perspective.
  
PUT external=True
+
It is not adviced to follow this approach.
2) shared=True, external=TRue
 
  
PUT external=False
+
== Extra attribute ==
3) shared=False, external=False
 
  
3 != 1 and this is wrong
+
Basically the logic is: if an admin creates an external network, it will be shared, unless he/she explicitly creates it for another tenant, in which case it will be private for that tenant.
 +
This could be achieved with a data model API not exposed through the API.
 +
Implicitly set db field for privatising the network if it's external and the tenant_id selected != from context.tenant_id.
  
Also, checking on get whether tenant_id of the network is admin or not is terribly expensive even if we perform this check only on external networks.
+
If there is a good reason for allowing programmatic control over sharing for external networks, this attribute (which we could call private) might be exposed through the API too.
The check will require a round trip to Keystone.
+
In this case we would be introducing a concept of private network. By default each network is private. A network can't be private and shared at the same time. A network however can be private and external at the same time.
  
EXTERNAL, BUT SPECIFIC TO TENANT
+
== RBAC control for networks ==
get_networks won't return it
 
  
1) EXTRA FLAG, not exposed via API. Might work but it's ugly - unless we find a good reason for it and we expose it through the API (---private?)
+
There is an [https://review.openstack.org/#/c/132661/ abandoned blueprint] from Kilo proposing role based access control for networks.
1.A) implicitly set db column for privatise the network if it's external and the tenant_id selected != from context.tenant_id (still has weaknesses)
 
1.B) Introduce a concept of private network. By default each network is private. A network can't be private and shared at the same time. A network however can be private and external at the same time.
 
2) TENANT_ID=None for external networks which should be shared as well. Implications due to resources without tenant_id. Resource without owners might be troublesome.
 
3) there is no option 3 so far
 

Latest revision as of 13:55, 6 February 2015

Current logic

Currently the concept of 'external' network is somewhat similar to the concept of a 'shared' network. However, while every tenant can operate on a shared network, performing operations such as creating port, the set of operations a tenant can perform on an external network is more limited, as it's currently restrained to setting external gateways on routers and creating floating IPs.

Nevertheless, the concept of 'external' implies some forms of sharing, and this has some bearing on the topologies that can be achieved. For instance it is not possible at the moment have an external network which is reserved to a specific tenant. That external network will always show up in queries performed by other tenants too.

Goal

The goal of this blueprint is to find a solution for limiting the visibility scope of an external network while preserving backward compatibility. If a reasonable solution which preserves backward compatibility can't be found this blueprint should be deferred to the next release.

Approaches

Decoupling 'shared' from 'external': this won't work

Apparently the easiest solution is to decouple the concept of 'external' from the concept of sharing. External will qualify the network in topological terms, whereas 'shared' will qualify it in terms of access. In this way, the external network as we know it today would be 'external and shared', whereas a network which is simply external would be visible only to the tenant who owns it, as any other network.

This is 'kind of' backward compatible. Indeed a data migration can be used to set shared=True for each network where external=True, but the responses will be different since the 'shared' attribute would change from False to True for existing external networks.

Moreover, in order to preserve backward compatibility, setting a network as external should keep having the same behaviour as now. This will mean that the network has to be 'shared' and 'external' at the same time. If a user want a 'private' external network, he/she will have to submit a request with shared=False, external=True (and this is a bit awkward). Similarly when unsetting the 'external' attribute, the network will go back to the 'private' state.

The real problem comes however when considering the following sequence of operations:

  1. POST /networks with shared=True --> shared = True, external=False
  2. PUT /networks with external=True --> shared=True, external=False
  3. PUT /networks external=False --> shared=False, external=False

The resulting state of the network at step 3 differs from step 1, and this is unaccepable.

Also, there will be complications related to policy verifications in this case. [discuss further]

Public 'external' networks have no tenant

Set tenant_id=None for external networks which should be shared. Implications due to resources without tenant_id will cause get_networks to not return this network, and this will require some non-trivial changes into Neutron's db layer. Resources without owners might be troublesome also from an authZ perspective.

It is not adviced to follow this approach.

Extra attribute

Basically the logic is: if an admin creates an external network, it will be shared, unless he/she explicitly creates it for another tenant, in which case it will be private for that tenant. This could be achieved with a data model API not exposed through the API. Implicitly set db field for privatising the network if it's external and the tenant_id selected != from context.tenant_id.

If there is a good reason for allowing programmatic control over sharing for external networks, this attribute (which we could call private) might be exposed through the API too. In this case we would be introducing a concept of private network. By default each network is private. A network can't be private and shared at the same time. A network however can be private and external at the same time.

RBAC control for networks

There is an abandoned blueprint from Kilo proposing role based access control for networks.