Skip to content

Commit 88c6dac

Browse files
Krzysztof BijakowskiGhaleb
authored andcommitted
RBAC policy support added
1 parent 862c46b commit 88c6dac

5 files changed

Lines changed: 903 additions & 1 deletion

File tree

blueprints/network_rbac.yaml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
tosca_definitions_version: cloudify_dsl_1_3
2+
3+
description: >
4+
Create an Example Openstack Network with RBAC policy
5+
6+
imports:
7+
- http://www.getcloudify.org/spec/cloudify/4.2/types.yaml
8+
- http://www.getcloudify.org/spec/openstack-plugin/2.9.9/plugin.yaml
9+
10+
inputs:
11+
keystone_username:
12+
default: { get_secret: keystone_username }
13+
14+
keystone_password:
15+
default: { get_secret: keystone_password }
16+
17+
keystone_tenant_name:
18+
default: { get_secret: keystone_tenant_name }
19+
20+
keystone_url:
21+
default: { get_secret: keystone_url }
22+
23+
region:
24+
default: { get_secret: region }
25+
26+
subnet_cidr:
27+
type: string
28+
default: '192.168.1.0/24'
29+
30+
admin_project_id:
31+
type: string
32+
33+
rbac_policy_tenant_name:
34+
type: string
35+
36+
dsl_definitions:
37+
openstack_config: &openstack_admin_config
38+
username: { get_input: keystone_username }
39+
password: { get_input: keystone_password }
40+
tenant_name: { get_input: keystone_tenant_name }
41+
auth_url: { get_input: keystone_url }
42+
region: { get_input: region }
43+
insecure: true
44+
custom_configuration:
45+
keystone_client:
46+
interface: public
47+
48+
openstack_config: &openstack_tenant_config
49+
username: { get_input: keystone_username }
50+
password: { get_input: keystone_password }
51+
tenant_name: { get_input: rbac_policy_tenant_name }
52+
auth_url: { get_input: keystone_url }
53+
region: { get_input: region }
54+
insecure: true
55+
custom_configuration:
56+
keystone_client:
57+
interface: public
58+
59+
node_templates:
60+
network_rbac_policy:
61+
type: cloudify.openstack.nodes.RBACPolicy
62+
properties:
63+
rbac_policy:
64+
target_tenant: { get_input: admin_project_id }
65+
action: access_as_shared
66+
openstack_config: *openstack_admin_config
67+
relationships:
68+
- type: cloudify.openstack.rbac_policy_applied_to
69+
target: network
70+
71+
network:
72+
type: cloudify.openstack.nodes.Network
73+
properties:
74+
openstack_config: *openstack_tenant_config
75+
76+
subnet:
77+
type: cloudify.openstack.nodes.Subnet
78+
properties:
79+
openstack_config: *openstack_tenant_config
80+
interfaces:
81+
cloudify.interfaces.lifecycle:
82+
create:
83+
inputs:
84+
args:
85+
ip_version: 4
86+
cidr: { get_input: subnet_cidr }
87+
relationships:
88+
- type: cloudify.relationships.contained_in
89+
target: network
90+
91+
outputs:
92+
network:
93+
value: { get_attribute: [ network, external_id ] }
94+
subnet:
95+
value: { get_attribute: [ subnet, external_id ] }
96+
network_rbac_policy:
97+
value: { get_attribute: [ network_rbac_policy, external_id ] }
98+

neutron_plugin/rbac_policy.py

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
#########
2+
# Copyright (c) 2018 GigaSpaces Technologies Ltd. All rights reserved
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# * See the License for the specific language governing permissions and
14+
# * limitations under the License.
15+
16+
from cloudify import ctx
17+
from cloudify.decorators import operation
18+
from cloudify.exceptions import NonRecoverableError
19+
20+
from openstack_plugin_common import (
21+
with_neutron_client,
22+
use_external_resource,
23+
create_object_dict,
24+
add_list_to_runtime_properties,
25+
set_neutron_runtime_properties,
26+
get_relationships_by_relationship_type,
27+
delete_resource_and_runtime_properties,
28+
COMMON_RUNTIME_PROPERTIES_KEYS,
29+
OPENSTACK_ID_PROPERTY,
30+
OPENSTACK_TYPE_PROPERTY
31+
)
32+
33+
RBAC_POLICY_OPENSTACK_TYPE = 'rbac_policy'
34+
RBAC_POLICY_APPLIED_FOR_RELATIONSHIP_TYPE = \
35+
'cloudify.openstack.rbac_policy_applied_to'
36+
37+
38+
def find_resource_to_apply_rbac_policy(ctx):
39+
found_relationships = get_relationships_by_relationship_type(
40+
ctx,
41+
RBAC_POLICY_APPLIED_FOR_RELATIONSHIP_TYPE
42+
)
43+
44+
if len(found_relationships) == 0:
45+
ctx.logger.info(
46+
'Resource for which RBAC policy may be applied '
47+
'not found using {} relationship'
48+
.format(RBAC_POLICY_APPLIED_FOR_RELATIONSHIP_TYPE)
49+
)
50+
51+
return {}
52+
53+
if len(found_relationships) > 1:
54+
raise NonRecoverableError(
55+
'Multiple ({0}) resources for which RBAC policy may be applied '
56+
'found using relationship {1}'
57+
.format(
58+
len(found_relationships),
59+
RBAC_POLICY_APPLIED_FOR_RELATIONSHIP_TYPE
60+
)
61+
)
62+
63+
found_resource = found_relationships[0].target.instance
64+
ctx.logger.info(
65+
'{0} resource for which RBAC policy may be applied '
66+
'found using {1} relationship)'
67+
.format(found_resource, RBAC_POLICY_APPLIED_FOR_RELATIONSHIP_TYPE)
68+
)
69+
70+
id = found_resource.runtime_properties.get(OPENSTACK_ID_PROPERTY, None)
71+
type = found_resource.runtime_properties.get(
72+
OPENSTACK_TYPE_PROPERTY,
73+
None
74+
)
75+
76+
if not id or not type:
77+
ctx.logger.warn(
78+
'Found using relationship resource has not defined either '
79+
'"id" or "type" runtime_property. Skipping.'
80+
)
81+
82+
return {}
83+
84+
return {
85+
'object_type': type,
86+
'object_id': id
87+
}
88+
89+
90+
def validate_found_resource(input_dict, found_resource):
91+
if found_resource:
92+
for key in found_resource.keys():
93+
if key in input_dict and input_dict.get(key):
94+
raise NonRecoverableError(
95+
'Multiple definitions of resource for which '
96+
'RBAC policy should be applied. '
97+
'You specified it both using properties / operation '
98+
'inputs and relationship.'
99+
)
100+
101+
102+
def create_rbac_policy_object_dict(ctx, args):
103+
found_resource = find_resource_to_apply_rbac_policy(ctx)
104+
validate_found_resource(
105+
ctx.node.properties.get(RBAC_POLICY_OPENSTACK_TYPE, {}),
106+
found_resource
107+
)
108+
109+
validate_found_resource(
110+
args.get(RBAC_POLICY_OPENSTACK_TYPE, {}),
111+
found_resource
112+
)
113+
114+
rbac_policy = create_object_dict(
115+
ctx,
116+
RBAC_POLICY_OPENSTACK_TYPE,
117+
args,
118+
found_resource
119+
)
120+
121+
return rbac_policy
122+
123+
124+
@operation
125+
@with_neutron_client
126+
def create(neutron_client, args, **kwargs):
127+
if use_external_resource(ctx, neutron_client, RBAC_POLICY_OPENSTACK_TYPE):
128+
return
129+
130+
rbac_policy_raw = create_rbac_policy_object_dict(ctx, args)
131+
ctx.logger.info('rbac_policy: {0}'.format(rbac_policy_raw))
132+
133+
rbac_policy = rbac_policy_raw.copy()
134+
rbac_policy.pop('name', None) # rbac_policy doesn't accept name parameter
135+
136+
rp = neutron_client.create_rbac_policy({
137+
RBAC_POLICY_OPENSTACK_TYPE: rbac_policy
138+
})[RBAC_POLICY_OPENSTACK_TYPE]
139+
rp['name'] = None
140+
141+
set_neutron_runtime_properties(ctx, rp, RBAC_POLICY_OPENSTACK_TYPE)
142+
143+
144+
@operation
145+
@with_neutron_client
146+
def delete(neutron_client, **kwargs):
147+
delete_resource_and_runtime_properties(
148+
ctx,
149+
neutron_client,
150+
COMMON_RUNTIME_PROPERTIES_KEYS
151+
)
152+
153+
154+
@operation
155+
@with_neutron_client
156+
def list_rbac_policies(neutron_client, args, **kwargs):
157+
rbac_policies = neutron_client.list_rbac_policies(**args)
158+
add_list_to_runtime_properties(
159+
ctx,
160+
RBAC_POLICY_OPENSTACK_TYPE,
161+
rbac_policies.get('rbac_policies', [])
162+
)
163+
164+
165+
@operation
166+
@with_neutron_client
167+
def find_and_delete(neutron_client, args, **kwargs):
168+
reference_rbac_policy = create_rbac_policy_object_dict(ctx, args)
169+
reference_rbac_policy.pop('name', None)
170+
rbac_policies_list = neutron_client.list_rbac_policies() \
171+
.get('rbac_policies', [])
172+
173+
for rbac_policy in rbac_policies_list:
174+
if all(
175+
item in rbac_policy.items()
176+
for item
177+
in reference_rbac_policy.items()
178+
):
179+
id = rbac_policy['id']
180+
ctx.logger.info(
181+
'Found RBAC policy with ID: {0} - deleting ...'.format(id)
182+
)
183+
184+
neutron_client.cosmo_delete_resource(
185+
RBAC_POLICY_OPENSTACK_TYPE,
186+
id
187+
)
188+
189+
return
190+
191+
ctx.logger.warn('No suitable RBAC policy found')

0 commit comments

Comments
 (0)