Network RBAC rule management implemented.
Change-Id: Ia7f06b5e5c3fa7cef56173758d268c58e7f274f1
Related-Prod: SSMCP-149
diff --git a/README.rst b/README.rst
index 2ef3f49..ca02600 100644
--- a/README.rst
+++ b/README.rst
@@ -1291,7 +1291,7 @@
Neutron Client
--------------
-Neutron networks:
+Neutron networks and RBAC:
.. code-block:: yaml
@@ -1300,6 +1300,18 @@
enabled: true
server:
identity:
+ rbac:
+ network:
+ rule1:
+ absent: True
+ target_tenant: admin
+ action: access_as_shared
+ network: public
+ rule2:
+ absent: False
+ target_tenant: service
+ action: access_as_external
+ network: public
endpoint_type: internalURL
network:
inet1:
diff --git a/_modules/neutronv2/__init__.py b/_modules/neutronv2/__init__.py
index 74b6fb1..c6ebe0f 100644
--- a/_modules/neutronv2/__init__.py
+++ b/_modules/neutronv2/__init__.py
@@ -14,6 +14,7 @@
from neutronv2 import routers
from neutronv2 import ports
from neutronv2 import common
+from neutronv2 import rbac
network_get_details = networks.network_get_details
@@ -69,6 +70,10 @@
port_get_details = ports.port_get_details
+rbac_policies_list = lists.rbac_policies_list
+rbac_policies_create = rbac.rbac_policies_create
+rbac_policies_delete = rbac.rbac_policies_delete
+
wait_for_network_services = agents.wait_for_network_services
wait_for_api_ready = common.wait_for_api_ready
@@ -88,6 +93,7 @@
'router_list', 'router_create', 'router_delete', 'router_get_details',
'router_interface_add', 'router_interface_remove', 'router_update',
'port_create', 'port_delete', 'port_update', 'port_list', 'port_get_details',
+ 'rbac_policies_create' 'rbac_policies_delete', 'rbac_policies_list',
)
diff --git a/_modules/neutronv2/lists.py b/_modules/neutronv2/lists.py
index eea4a7a..13958ee 100644
--- a/_modules/neutronv2/lists.py
+++ b/_modules/neutronv2/lists.py
@@ -39,4 +39,10 @@
@send('get')
def port_list(**kwargs):
url = '/ports?{}'.format(urlencode(kwargs))
- return url, {}
\ No newline at end of file
+ return url, {}
+
+
+@send('get')
+def rbac_policies_list(**kwargs):
+ url = '/rbac-policies?{}'.format(urlencode(kwargs))
+ return url, {}
diff --git a/_modules/neutronv2/rbac.py b/_modules/neutronv2/rbac.py
new file mode 100644
index 0000000..021d535
--- /dev/null
+++ b/_modules/neutronv2/rbac.py
@@ -0,0 +1,27 @@
+from neutronv2.common import send
+from neutronv2.arg_converter import get_by_name_or_uuid_multiple
+
+try:
+ from urllib.parse import urlencode
+except ImportError:
+ from urllib import urlencode
+
+
+@send('delete')
+def rbac_policies_delete(id):
+ url = '/rbac-policies/{}'.format(id)
+ return url, {}
+
+
+@get_by_name_or_uuid_multiple([('network', 'object_id')])
+@send('post')
+def rbac_policies_create(object_id,**kwargs):
+
+ url = '/rbac-policies'
+ kwargs.update({'object_type': 'network'})
+ kwargs.update({'object_id': object_id})
+ json = {
+ 'rbac_policy': kwargs,
+ }
+
+ return url, {'json': json}
diff --git a/_states/neutronv2.py b/_states/neutronv2.py
index 81c8fa4..7bfa7fb 100644
--- a/_states/neutronv2.py
+++ b/_states/neutronv2.py
@@ -271,6 +271,58 @@
cloud_name, **kwargs)
+def rbac_get_rule_id(cloud_name, **kwargs):
+ existing_rules = _neutronv2_call('rbac_policies_list',
+ cloud_name=cloud_name)
+
+ match_condition_fields = ['action',
+ 'target_tenant',
+ 'object_id',
+ ]
+
+ for rule in existing_rules['rbac_policies']:
+ match = True
+ for field in match_condition_fields:
+ if rule[field] != kwargs[field]:
+ match = False
+ break
+ if match: return rule['id']
+
+
+def rbac_present(name, cloud_name, **kwargs):
+ resource = 'rbac_policies'
+ # Resolve network name to UID if needed
+ kwargs['object_id'] = __salt__['neutronv2.network_get_details'] \
+ (network_id=kwargs['object_id'],cloud_name=cloud_name)['network']['id']
+
+ if rbac_get_rule_id(cloud_name, **kwargs):
+ return _succeeded('no_changes', name, resource)
+
+ r = _neutronv2_call('{}_create'.format(resource),
+ cloud_name=cloud_name,
+ **kwargs)
+ if r:
+ return _succeeded('create', name, resource, changes=r)
+ else:
+ return _failed('create', name, kwargs)
+
+def rbac_absent(name, cloud_name, **kwargs):
+ resource = 'rbac_policies'
+ # Resolve network name to UID if needed
+ kwargs['object_id'] = __salt__['neutronv2.network_get_details'] \
+ (network_id=kwargs['object_id'],cloud_name=cloud_name)['network']['id']
+
+ rule_id = rbac_get_rule_id(cloud_name, **kwargs)
+
+ if rule_id:
+ r = _neutronv2_call('{}_delete'.format(resource),
+ cloud_name=cloud_name,
+ id=rule_id)
+ return _succeeded('delete', name, resource, changes=r)
+
+ return _succeeded('no_changes', name, resource)
+
+
def _succeeded(op, name, resource, changes=None):
msg_map = {
'create': '{0} {1} created',
diff --git a/neutron/client/resources/v2.sls b/neutron/client/resources/v2.sls
index 3bd57b9..43db50e 100644
--- a/neutron/client/resources/v2.sls
+++ b/neutron/client/resources/v2.sls
@@ -118,5 +118,33 @@
{%- endfor %}
{%- endif %}
+ {%- if identity.rbac is defined %}
+ {%- for rule_name, rule in identity.rbac.network.iteritems() %}
+
+ {%- if rule.absent is defined and rule.absent %}
+neutron_openstack_rbac_network_{{ rule_name }}:
+ neutronv2.rbac_absent:
+ - name: {{ rule_name }}
+ - cloud_name: {{ identity_name }}
+ - target_tenant: {{ rule.target_tenant }}
+ - action: {{ rule.action }}
+ - object_id: {{ rule.network }}
+
+ {%- else %}
+neutron_openstack_rbac_network_{{ rule_name }}:
+ neutronv2.rbac_present:
+ - name: {{ rule_name }}
+ - cloud_name: {{ identity_name }}
+ - target_tenant: {{ rule.target_tenant }}
+ - action: {{ rule.action }}
+ - object_id: {{ rule.network }}
+
+
+ {%- endif %}
+
+ {%- endfor %}
+ {%- endif %}
+
+
{%- endfor %}
{%- endif %}