Represent External Connectivity in GBP

Today, the GBP model only represents east-west traffic policies.
This new API and reference implementation
allows north-south traffic in a GBP enabled cloud

blueprint external-connectivity

Change-Id: Ie70612396b2515e378bc8c6983d03a4e518173f7
This commit is contained in:
Ivar Lazzaro 2014-11-21 18:23:01 -08:00
parent 4c6f215d88
commit 6c391e5723
1 changed files with 366 additions and 0 deletions

View File

@ -0,0 +1,366 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
==========================================
GBP External Connectivity
==========================================
Launchpad blueprint:
https://blueprints.launchpad.net/group-based-policy/+spec/external-connectivity
Today, the GBP model only represents east-west traffic policies.
This blueprint introduces new API to allow north-south traffic in
a GBP enabled cloud
Problem description
===================
The existing API doesn't provide any way to represent external access
(i.e. north-south traffic) in a GBP enabled cloud.
In order to obtain such capabilities, today the user has to go to
Neutron and define the right topology by creating external networks
and attaching the proper router interfaces to them.
Furthermore, the above workaround assumes that a Neutron mapping is
in place, which is not true for all the GBP drivers.
Proposed change
===============
This proposal presents new API objects in order to model the external
connectivity policy. Although the objective is always to capture
the user's intent, it has to be noted that this particular case usually
requires a lot of manual configuration by the admin *outside* the cloud
boundaries (e.g. configuring external router), which means that the
usual automation provided by GBP has to be paired with meaningful tools
which allow detailed configuration when needed.
The following new terminology is introduced:
**Nat Policy** A pool of IP addresses (range/cidr) that will be used
by the drivers to implement NAT capabilities when needed. How
and whether the Nat Policy will be used by the reference implementation
is out of scope of this blueprint.
**External Segment** A cidr and representing the L3 policy interface
to a given portion of the external world. The L3 Policy needs to provide
which address it has to expose on a given external access segment.
**External Route** A combination of a cidr and a next hop
representing a portion of the external world reachable by the L3_Policy
via a given next hop
**External Policy** A collection of ESs that provides and
consumes PRSs in order to define the data path filtering for the
north-south traffic.
Notes on the Neutron resource mapping changes:
- The external segment will be mapped to a Neutron subnet;
- The network in which the ES's subnet resides must be external;
- To avoid to overload the model, in this iteration the external
subnet must always be explicit;
- Restriction: Only one External Policy per tenant is allowed
(side effect of https://bugs.launchpad.net/group-based-policy/+bug/1398156)
- Restriction: Only one ES per EP is allowed;
- Restriction: Only one ES per L3P is allowed;
- When no nexthop is specified in a ER, the subnet GW IP will be used;
- When no address is specified by the L3P when a ES is added, one will be
assigned automatically if available;
- Restriction: In this cycle, any NAT policy operation is completely ignored.
Example CLI:
Coming Soon
Alternatives
------------
Today there's no GBP alternative for external connectivity.
Data model impact
-----------------
New model is introduced in order to represent the external
connectivity::
+----------+
| External |
| Policy |
+----+-----+
|m
|
|n
+----+-------+ +---------+
| Ext. |1 m| NAT |
| Segment +----------+ Policy |
+----+-------+ +---------+
|
| +---------+
|1 n| Ext. |
+------------------+ Route |
| +---------+
|
| +------------+
|1 n | L3P Address|
+------------------+ Allocation |
+------------+
All objects (excluded ER and L3PAA) have the following common attributes:
* id - standard object uuid
* name - optional name
* description - optional annotation
* shared - whether the object is shared or not
External Segment
* ip_version - [4, 6]
* cidr - string on the form <subnet>/<prefix_length> which describes
the external segment subnet
* l3_policies - a list of l3_policies UUIDs
* port_address_translation - boolean, specifies whether PAT needs to be performed
using the addresses allocated for the L3P
NAT Policy
* ip_version - [4,6]
* ip_pool - string, IPSubnet with mask used to pull addresses from
for NAT purposes
* external_segments - UUID list of the ESs using this NAT policy
External Route
* cidr - string, IPSubnet with mask used to represent a portion of the
external world
* netx_hop - string, ip address describing where the traffic should be sent
in order to reach cidr
* external_segment_id - UUID of the ES through which this ER is
consumable
External Policy
* external_segments - a list of external access segments UUIDs
* provided_policy_rules_set - a list of provided policy rules set UUIDs
* consumed_policy_rules_set - a list of consumed policy rules set UUIDs
L3P Address Allocation
* external_segment_id - ES UUID
* l3_policy_id - L3P UUI
* allocated_address - IP address belonging to the ES subnet
The following tables will be modified:
L3 Policy
* (add column) external_segments - list of ES UUIDs
REST API impact
---------------
Code snippet describing the new model::
EXTERNAL_POLICIES: {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True, 'primary_key': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': None},
'default': '', 'is_visible': True},
'description': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': None},
'is_visible': True, 'default': ''},
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'external_segments': {
'allow_post': True, 'allow_put': True, 'default': None,
'validate': {'type:uuid_list': None},
'convert_to': attr.convert_none_to_empty_list, 'is_visible': True},
'provided_policy_rule_sets': {'allow_post': True, 'allow_put': True,
'validate': {'type:dict_or_none': None},
'convert_to':
attr.convert_none_to_empty_dict,
'default': None, 'is_visible': True},
'consumed_policy_rule_sets': {'allow_post': True, 'allow_put': True,
'validate': {'type:dict_or_none': None},
'convert_to':
attr.convert_none_to_empty_dict,
'default': None, 'is_visible': True},
attr.SHARED: {'allow_post': True, 'allow_put': True,
'default': False, 'convert_to': attr.convert_to_boolean,
'is_visible': True, 'required_by_policy': True,
'enforce_policy': True},
},
EXTERNAL_SEGMENTS: {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True, 'primary_key': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': None},
'default': '', 'is_visible': True},
'description': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': None},
'is_visible': True, 'default': ''},
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'ip_version': {'allow_post': True, 'allow_put': False,
'convert_to': attr.convert_to_int,
'validate': {'type:values': [4, 6]},
'default': attr.ATTR_NOT_SPECIFIED, 'is_visible': True},
'cidr': {'allow_post': True, 'allow_put': False,
'validate': {'type:subnet': None},
'default': attr.ATTR_NOT_SPECIFIED, 'is_visible': True},
'external_policies': {
'allow_post': False, 'allow_put': False, 'default': None,
'validate': {'type:uuid_list': None},
'convert_to': attr.convert_none_to_empty_list, 'is_visible': True},
'external_routes': {
'allow_post': True, 'allow_put': True,
'default': attr.ATTR_NOT_SPECIFIED,
'validate': {'type:gbproutes': None},
'is_visible': True},
'l3_policies': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid_list': None},
'convert_to': attr.convert_none_to_empty_list,
'default': None, 'is_visible': True},
'port_address_translation': {
'allow_post': True, 'allow_put': True,
'default': False, 'convert_to': attr.convert_to_boolean,
'is_visible': True, 'required_by_policy': True,
'enforce_policy': True},
attr.SHARED: {'allow_post': True, 'allow_put': True,
'default': False, 'convert_to': attr.convert_to_boolean,
'is_visible': True, 'required_by_policy': True,
'enforce_policy': True},
},
NAT_POOLS: {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True, 'primary_key': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': None},
'default': '', 'is_visible': True},
'description': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': None},
'is_visible': True, 'default': ''},
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True, 'is_visible': True},
'ip_version': {'allow_post': True, 'allow_put': False,
'convert_to': attr.convert_to_int,
'validate': {'type:values': [4, 6]},
'default': 4, 'is_visible': True},
'ip_pool': {'allow_post': True, 'allow_put': False,
'validate': {'type:subnet': None},
'is_visible': True},
'external_segment_id': {'allow_post': True, 'allow_put': True,
'validate': {'type:uuid_or_none': None},
'is_visible': True, 'required': True},
attr.SHARED: {'allow_post': True, 'allow_put': True,
'default': False, 'convert_to': attr.convert_to_boolean,
'is_visible': True, 'required_by_policy': True,
'enforce_policy': True},
}
The following have been modified (only new attributes shown)::
L3_POLICIES: {
'external_segments': {
'allow_post': True, 'allow_put': True,
'validate': {'type:external_dict': None},
'convert_to': attr.convert_none_to_empty_dict,
'default': attr.ATTR_NOT_SPECIFIED, 'is_visible': True},
},
More information about the attribute types follows:
**type:hostroutes**
A dictionary in the form {"destination": <cidr>, "nexthop": <ip_address>}
**type:external_dict**
A dictionary in the form {<es_uuid>: [<my_es_ip>, ...]}. It represents
which ES the L3P is connected through, and which addresses it uses on it.
Security impact
---------------
Policy Targets within the cloud can be reach and can reach the outside world.
The security implications depend on the way the PRS are composed
by the cloud admin.
In order to talk to the external world, a given Policy Target Group
needs to satisfy the followings:
- The L3P it belongs to must have at least one external access segment and one IP allocated;
- The External Segment must have at least one route;
- the External Segment must have an External Policy;
- The PTG must provide/consume a PRS provided/consumed by the said EP;
- The traffic has to satisfy the filtering rules defined in the PRS;
Notifications impact
--------------------
This blueprint has no impact on notifications.
Other end user impact
---------------------
The python client and the UI have to expose the new model
to the end user.
Performance Impact
------------------
None
Other deployer impact
---------------------
None
Developer impact
----------------
None
Implementation
==============
Assignee(s)
-----------
Primary assignee:
Ivar Lazzaro (mmaleckk)
Other contributors:
None
Work Items
----------
- Database and API;
- Plugin;
- Neutron mapping driver;
- Implicit driver.
Dependencies
============
None
Testing
=======
New unit tests will be added for the external connectivity extension
itself, and existing unit tests for the mapping will be updated
when needed.
Documentation Impact
====================
Eventual GBP documentation will need to address configuration
of external access policy
References
==========
None