| ######### |
| # Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # * See the License for the specific language governing permissions and |
| # * limitations under the License. |
| |
| import copy |
| import re |
| |
| from cloudify import ctx |
| from cloudify.exceptions import NonRecoverableError |
| |
| from openstack_plugin_common import ( |
| get_resource_id, |
| use_external_resource, |
| delete_resource_and_runtime_properties, |
| validate_resource, |
| validate_ip_or_range_syntax, |
| OPENSTACK_ID_PROPERTY, |
| OPENSTACK_TYPE_PROPERTY, |
| OPENSTACK_NAME_PROPERTY, |
| COMMON_RUNTIME_PROPERTIES_KEYS |
| ) |
| |
| SECURITY_GROUP_OPENSTACK_TYPE = 'security_group' |
| |
| # Runtime properties |
| RUNTIME_PROPERTIES_KEYS = COMMON_RUNTIME_PROPERTIES_KEYS |
| |
| NODE_NAME_RE = re.compile('^(.*)_.*$') # Anything before last underscore |
| |
| |
| def build_sg_data(args=None): |
| security_group = { |
| 'description': None, |
| 'name': get_resource_id(ctx, SECURITY_GROUP_OPENSTACK_TYPE), |
| } |
| |
| args = args or {} |
| security_group.update(ctx.node.properties['security_group'], **args) |
| |
| return security_group |
| |
| |
| def process_rules(client, sgr_default_values, cidr_field_name, |
| remote_group_field_name, min_port_field_name, |
| max_port_field_name): |
| rules_to_apply = ctx.node.properties['rules'] |
| security_group_rules = [] |
| for rule in rules_to_apply: |
| security_group_rules.append( |
| _process_rule(rule, client, sgr_default_values, cidr_field_name, |
| remote_group_field_name, min_port_field_name, |
| max_port_field_name)) |
| |
| return security_group_rules |
| |
| |
| def use_external_sg(client): |
| return use_external_resource(ctx, client, |
| SECURITY_GROUP_OPENSTACK_TYPE) |
| |
| |
| def set_sg_runtime_properties(sg, client): |
| ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] =\ |
| client.get_id_from_resource(sg) |
| ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] =\ |
| SECURITY_GROUP_OPENSTACK_TYPE |
| ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = \ |
| client.get_name_from_resource(sg) |
| |
| |
| def delete_sg(client, **kwargs): |
| delete_resource_and_runtime_properties(ctx, client, |
| RUNTIME_PROPERTIES_KEYS) |
| |
| |
| def sg_creation_validation(client, cidr_field_name, **kwargs): |
| validate_resource(ctx, client, SECURITY_GROUP_OPENSTACK_TYPE) |
| |
| ctx.logger.debug('validating CIDR for rules with a {0} field'.format( |
| cidr_field_name)) |
| for rule in ctx.node.properties['rules']: |
| if cidr_field_name in rule: |
| validate_ip_or_range_syntax(ctx, rule[cidr_field_name]) |
| |
| |
| def _process_rule(rule, client, sgr_default_values, cidr_field_name, |
| remote_group_field_name, min_port_field_name, |
| max_port_field_name): |
| ctx.logger.debug( |
| "Security group rule before transformations: {0}".format(rule)) |
| |
| sgr = copy.deepcopy(sgr_default_values) |
| if 'port' in rule: |
| rule[min_port_field_name] = rule['port'] |
| rule[max_port_field_name] = rule['port'] |
| del rule['port'] |
| sgr.update(rule) |
| |
| if (remote_group_field_name in sgr) and sgr[remote_group_field_name]: |
| sgr[cidr_field_name] = None |
| elif ('remote_group_node' in sgr) and sgr['remote_group_node']: |
| _, remote_group_node = _capabilities_of_node_named( |
| sgr['remote_group_node']) |
| sgr[remote_group_field_name] = remote_group_node[OPENSTACK_ID_PROPERTY] |
| del sgr['remote_group_node'] |
| sgr[cidr_field_name] = None |
| elif ('remote_group_name' in sgr) and sgr['remote_group_name']: |
| sgr[remote_group_field_name] = \ |
| client.get_id_from_resource( |
| client.cosmo_get_named( |
| SECURITY_GROUP_OPENSTACK_TYPE, sgr['remote_group_name'])) |
| del sgr['remote_group_name'] |
| sgr[cidr_field_name] = None |
| |
| ctx.logger.debug( |
| "Security group rule after transformations: {0}".format(sgr)) |
| return sgr |
| |
| |
| def _capabilities_of_node_named(node_name): |
| result = None |
| caps = ctx.capabilities.get_all() |
| for node_id in caps: |
| match = NODE_NAME_RE.match(node_id) |
| if match: |
| candidate_node_name = match.group(1) |
| if candidate_node_name == node_name: |
| if result: |
| raise NonRecoverableError( |
| "More than one node named '{0}' " |
| "in capabilities".format(node_name)) |
| result = (node_id, caps[node_id]) |
| if not result: |
| raise NonRecoverableError( |
| "Could not find node named '{0}' " |
| "in capabilities".format(node_name)) |
| return result |