dfilppi | 9981f55 | 2017-08-07 20:10:53 +0000 | [diff] [blame^] | 1 | ######### |
| 2 | # Copyright (c) 2014 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 | import copy |
| 17 | import re |
| 18 | |
| 19 | from cloudify import ctx |
| 20 | from cloudify.exceptions import NonRecoverableError |
| 21 | |
| 22 | from openstack_plugin_common import ( |
| 23 | get_resource_id, |
| 24 | use_external_resource, |
| 25 | delete_resource_and_runtime_properties, |
| 26 | validate_resource, |
| 27 | validate_ip_or_range_syntax, |
| 28 | OPENSTACK_ID_PROPERTY, |
| 29 | OPENSTACK_TYPE_PROPERTY, |
| 30 | OPENSTACK_NAME_PROPERTY, |
| 31 | COMMON_RUNTIME_PROPERTIES_KEYS |
| 32 | ) |
| 33 | |
| 34 | SECURITY_GROUP_OPENSTACK_TYPE = 'security_group' |
| 35 | |
| 36 | # Runtime properties |
| 37 | RUNTIME_PROPERTIES_KEYS = COMMON_RUNTIME_PROPERTIES_KEYS |
| 38 | |
| 39 | NODE_NAME_RE = re.compile('^(.*)_.*$') # Anything before last underscore |
| 40 | |
| 41 | |
| 42 | def build_sg_data(args=None): |
| 43 | security_group = { |
| 44 | 'description': None, |
| 45 | 'name': get_resource_id(ctx, SECURITY_GROUP_OPENSTACK_TYPE), |
| 46 | } |
| 47 | |
| 48 | args = args or {} |
| 49 | security_group.update(ctx.node.properties['security_group'], **args) |
| 50 | |
| 51 | return security_group |
| 52 | |
| 53 | |
| 54 | def process_rules(client, sgr_default_values, cidr_field_name, |
| 55 | remote_group_field_name, min_port_field_name, |
| 56 | max_port_field_name): |
| 57 | rules_to_apply = ctx.node.properties['rules'] |
| 58 | security_group_rules = [] |
| 59 | for rule in rules_to_apply: |
| 60 | security_group_rules.append( |
| 61 | _process_rule(rule, client, sgr_default_values, cidr_field_name, |
| 62 | remote_group_field_name, min_port_field_name, |
| 63 | max_port_field_name)) |
| 64 | |
| 65 | return security_group_rules |
| 66 | |
| 67 | |
| 68 | def use_external_sg(client): |
| 69 | return use_external_resource(ctx, client, |
| 70 | SECURITY_GROUP_OPENSTACK_TYPE) |
| 71 | |
| 72 | |
| 73 | def set_sg_runtime_properties(sg, client): |
| 74 | ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] =\ |
| 75 | client.get_id_from_resource(sg) |
| 76 | ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] =\ |
| 77 | SECURITY_GROUP_OPENSTACK_TYPE |
| 78 | ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = \ |
| 79 | client.get_name_from_resource(sg) |
| 80 | |
| 81 | |
| 82 | def delete_sg(client, **kwargs): |
| 83 | delete_resource_and_runtime_properties(ctx, client, |
| 84 | RUNTIME_PROPERTIES_KEYS) |
| 85 | |
| 86 | |
| 87 | def sg_creation_validation(client, cidr_field_name, **kwargs): |
| 88 | validate_resource(ctx, client, SECURITY_GROUP_OPENSTACK_TYPE) |
| 89 | |
| 90 | ctx.logger.debug('validating CIDR for rules with a {0} field'.format( |
| 91 | cidr_field_name)) |
| 92 | for rule in ctx.node.properties['rules']: |
| 93 | if cidr_field_name in rule: |
| 94 | validate_ip_or_range_syntax(ctx, rule[cidr_field_name]) |
| 95 | |
| 96 | |
| 97 | def _process_rule(rule, client, sgr_default_values, cidr_field_name, |
| 98 | remote_group_field_name, min_port_field_name, |
| 99 | max_port_field_name): |
| 100 | ctx.logger.debug( |
| 101 | "Security group rule before transformations: {0}".format(rule)) |
| 102 | |
| 103 | sgr = copy.deepcopy(sgr_default_values) |
| 104 | if 'port' in rule: |
| 105 | rule[min_port_field_name] = rule['port'] |
| 106 | rule[max_port_field_name] = rule['port'] |
| 107 | del rule['port'] |
| 108 | sgr.update(rule) |
| 109 | |
| 110 | if (remote_group_field_name in sgr) and sgr[remote_group_field_name]: |
| 111 | sgr[cidr_field_name] = None |
| 112 | elif ('remote_group_node' in sgr) and sgr['remote_group_node']: |
| 113 | _, remote_group_node = _capabilities_of_node_named( |
| 114 | sgr['remote_group_node']) |
| 115 | sgr[remote_group_field_name] = remote_group_node[OPENSTACK_ID_PROPERTY] |
| 116 | del sgr['remote_group_node'] |
| 117 | sgr[cidr_field_name] = None |
| 118 | elif ('remote_group_name' in sgr) and sgr['remote_group_name']: |
| 119 | sgr[remote_group_field_name] = \ |
| 120 | client.get_id_from_resource( |
| 121 | client.cosmo_get_named( |
| 122 | SECURITY_GROUP_OPENSTACK_TYPE, sgr['remote_group_name'])) |
| 123 | del sgr['remote_group_name'] |
| 124 | sgr[cidr_field_name] = None |
| 125 | |
| 126 | ctx.logger.debug( |
| 127 | "Security group rule after transformations: {0}".format(sgr)) |
| 128 | return sgr |
| 129 | |
| 130 | |
| 131 | def _capabilities_of_node_named(node_name): |
| 132 | result = None |
| 133 | caps = ctx.capabilities.get_all() |
| 134 | for node_id in caps: |
| 135 | match = NODE_NAME_RE.match(node_id) |
| 136 | if match: |
| 137 | candidate_node_name = match.group(1) |
| 138 | if candidate_node_name == node_name: |
| 139 | if result: |
| 140 | raise NonRecoverableError( |
| 141 | "More than one node named '{0}' " |
| 142 | "in capabilities".format(node_name)) |
| 143 | result = (node_id, caps[node_id]) |
| 144 | if not result: |
| 145 | raise NonRecoverableError( |
| 146 | "Could not find node named '{0}' " |
| 147 | "in capabilities".format(node_name)) |
| 148 | return result |