######### # 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