def _dhcp_operation(vca_client, network_name, operation): """ update dhcp setting for network """ dhcp_settings = ctx.node.properties["network"].get("dhcp") if dhcp_settings is None: return gateway_name = ctx.node.properties["network"]["edge_gateway"] gateway = vca_client.get_gateway(get_vcloud_config()["vdc"], gateway_name) if not gateway: raise cfy_exc.NonRecoverableError("Gateway {0} not found!".format(gateway_name)) if operation == ADD_POOL: ip = _split_adresses(dhcp_settings["dhcp_range"]) low_ip_address = check_ip(ip.start) hight_ip_address = check_ip(ip.end) default_lease = dhcp_settings.get("default_lease") max_lease = dhcp_settings.get("max_lease") gateway.add_dhcp_pool(network_name, low_ip_address, hight_ip_address, default_lease, max_lease) ctx.logger.info("DHCP rule successful created for network {0}".format(network_name)) if operation == DELETE_POOL: gateway.delete_dhcp_pool(network_name) ctx.logger.info("DHCP rule successful deleted for network {0}".format(network_name)) if not save_gateway_configuration(gateway, vca_client): return ctx.operation.retry(message="Waiting for gateway.", retry_after=10)
def _dhcp_operation(vca_client, network_name, operation): """ update dhcp setting for network """ dhcp_settings = ctx.node.properties['network'].get('dhcp') if dhcp_settings is None: return True gateway_name = ctx.node.properties["network"]['edge_gateway'] gateway = get_gateway(vca_client, gateway_name) if gateway.is_busy(): return False if operation == ADD_POOL: ip = _split_adresses(dhcp_settings['dhcp_range']) low_ip_address = check_ip(ip.start) hight_ip_address = check_ip(ip.end) default_lease = dhcp_settings.get('default_lease') max_lease = dhcp_settings.get('max_lease') gateway.add_dhcp_pool(network_name, low_ip_address, hight_ip_address, default_lease, max_lease) if save_gateway_configuration(gateway, vca_client): ctx.logger.info("DHCP rule successful created for network {0}" .format(network_name)) return True if operation == DELETE_POOL: gateway.delete_dhcp_pool(network_name) if save_gateway_configuration(gateway, vca_client): ctx.logger.info("DHCP rule successful deleted for network {0}" .format(network_name)) return True return False
def _dhcp_operation(vca_client, network_name, operation): """ update dhcp setting for network """ dhcp_settings = ctx.node.properties['network'].get('dhcp') if dhcp_settings is None: return gateway_name = ctx.node.properties["network"]['edge_gateway'] gateway = vca_client.get_gateway(get_vcloud_config()['vdc'], gateway_name) if not gateway: raise cfy_exc.NonRecoverableError( "Gateway {0} not found!".format(gateway_name)) if operation == ADD_POOL: ip = _split_adresses(dhcp_settings['dhcp_range']) low_ip_address = check_ip(ip.start) hight_ip_address = check_ip(ip.end) default_lease = dhcp_settings.get('default_lease') max_lease = dhcp_settings.get('max_lease') gateway.add_dhcp_pool(network_name, low_ip_address, hight_ip_address, default_lease, max_lease) ctx.logger.info("DHCP rule successful created for network {0}".format( network_name)) if operation == DELETE_POOL: gateway.delete_dhcp_pool(network_name) ctx.logger.info("DHCP rule successful deleted for network {0}".format( network_name)) if not save_gateway_configuration(gateway, vca_client): return ctx.operation.retry(message='Waiting for gateway.', retry_after=10)
def creation_validation(vca_client, **kwargs): port = get_mandatory(ctx.node.properties, 'port') ip_allocation_mode = port.get('ip_allocation_mode') if ip_allocation_mode: if ip_allocation_mode.lower() not in ['manual', 'dhcp', 'pool']: raise cfy_exc.NonRecoverableError( "Unknown allocation mode {0}".format(ip_allocation_mode)) ip_address = port.get('ip_address') if ip_address: check_ip(ip_address)
def test_check_ip(self): """ check ip code """ # wrong type with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.check_ip({'wrong': None}) # wrong value with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.check_ip("1.1.1.400") # good case self.assertEqual(network_plugin.check_ip("1.1.1.40"), "1.1.1.40")
def creation_validation(vca_client, **kwargs): floatingip = get_mandatory(ctx.node.properties, 'floatingip') edge_gateway = get_mandatory(floatingip, 'edge_gateway') gateway = get_gateway(vca_client, edge_gateway) service_type = get_vcloud_config().get('service_type') public_ip = floatingip.get(PUBLIC_IP) if public_ip: check_ip(public_ip) CheckAssignedExternalIp(public_ip, gateway) else: if is_subscription(service_type): getFreeIP(gateway)
def creation_validation(vca_client, **kwargs): """ validate firewall rules for node """ getaway = get_gateway( vca_client, _get_gateway_name(ctx.node.properties) ) if not getaway.is_fw_enabled(): raise cfy_exc.NonRecoverableError( "Gateway firewall is disabled. Please, enable firewall.") rules = get_mandatory(ctx.node.properties, 'rules') for rule in rules: description = rule.get("description") if description and not isinstance(description, basestring): raise cfy_exc.NonRecoverableError( "Parameter 'description' must be string.") source = rule.get("source") if source: if not isinstance(source, basestring): raise cfy_exc.NonRecoverableError( "Parameter 'source' must be valid IP address string.") if not _is_literal_ip(source): check_ip(source) utils.check_port(rule.get('source_port')) destination = rule.get('destination') if destination: if not isinstance(destination, basestring): raise cfy_exc.NonRecoverableError( "Parameter 'destination' must be valid IP address string.") if not _is_literal_ip(destination): check_ip(destination) utils.check_port(rule.get('destination_port')) utils.check_protocol(rule.get('protocol')) action = get_mandatory(rule, "action") if (not isinstance(action, basestring) or action.lower() not in ACTIONS): raise cfy_exc.NonRecoverableError( "Action must be on of{0}.".format(ACTIONS)) log = rule.get('log_traffic') if log and not isinstance(log, bool): raise cfy_exc.NonRecoverableError( "Parameter 'log_traffic' must be boolean.")
def creation_validation(vca_client, **kwargs): """ validate port settings, ip_allocation_mode must be in 'manual', 'dhcp', 'pool', and valid ip_address if set """ port = get_mandatory(ctx.node.properties, 'port') ip_allocation_mode = port.get('ip_allocation_mode') if ip_allocation_mode: if ip_allocation_mode.lower() not in ['manual', 'dhcp', 'pool']: raise cfy_exc.NonRecoverableError( "Unknown allocation mode {0}".format(ip_allocation_mode)) ip_address = port.get('ip_address') if ip_address: check_ip(ip_address)
def _split_adresses(address_range): """ split network addresses from 1.1.1.1-2.2.2.2 representation to separate (start,end) tuple """ adresses = [ip.strip() for ip in address_range.split("-")] IPRange = collections.namedtuple("IPRange", "start end") try: start = check_ip(adresses[0]) end = check_ip(adresses[1]) if not is_valid_ip_range(start, end): raise cfy_exc.NonRecoverableError("Start address {0} is greater than end address: {1}".format(start, end)) return IPRange(start=start, end=end) except IndexError: raise cfy_exc.NonRecoverableError("Can't parse IP range:{0}".format(address_range))
def test_check_ip(self): """ check ip code """ # wrong type with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.check_ip({'wrong': None}) # wrong value with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.check_ip("1.1.1.400") # good case self.assertEqual( network_plugin.check_ip("1.1.1.40"), "1.1.1.40" )
def creation_validation(vca_client, **kwargs): """ validate firewall rules for node """ getaway = get_gateway(vca_client, _get_gateway_name(ctx.node.properties)) if not getaway.is_fw_enabled(): raise cfy_exc.NonRecoverableError( "Gateway firewall is disabled. Please, enable firewall.") rules = get_mandatory(ctx.node.properties, 'rules') for rule in rules: description = rule.get("description") if description and not isinstance(description, basestring): raise cfy_exc.NonRecoverableError( "Parameter 'description' must be string.") source = rule.get("source") if source: if not isinstance(source, basestring): raise cfy_exc.NonRecoverableError( "Parameter 'source' must be valid IP address string.") if not _is_literal_ip(source): check_ip(source) utils.check_port(rule.get('source_port')) destination = rule.get('destination') if destination: if not isinstance(destination, basestring): raise cfy_exc.NonRecoverableError( "Parameter 'destination' must be valid IP address string.") if not _is_literal_ip(destination): check_ip(destination) utils.check_port(rule.get('destination_port')) utils.check_protocol(rule.get('protocol')) action = get_mandatory(rule, "action") if (not isinstance(action, basestring) or action.lower() not in ACTIONS): raise cfy_exc.NonRecoverableError( "Action must be on of{0}.".format(ACTIONS)) log = rule.get('log_traffic') if log and not isinstance(log, bool): raise cfy_exc.NonRecoverableError( "Parameter 'log_traffic' must be boolean.")
def _split_adresses(address_range): """ split network addresses from 1.1.1.1-2.2.2.2 representation to separate (start,end) tuple """ adresses = [ip.strip() for ip in address_range.split('-')] IPRange = collections.namedtuple('IPRange', 'start end') try: start = check_ip(adresses[0]) end = check_ip(adresses[1]) if not is_valid_ip_range(start, end): raise cfy_exc.NonRecoverableError( "Start address {0} is greater than end address: {1}".format( start, end)) return IPRange(start=start, end=end) except IndexError: raise cfy_exc.NonRecoverableError( "Can't parse IP range:{0}".format(address_range))
def creation_validation(vca_client, **kwargs): nat = get_mandatory(ctx.node.properties, 'nat') rules = get_mandatory(ctx.node.properties, 'rules') gateway = get_gateway(vca_client, get_mandatory(nat, 'edge_gateway')) service_type = get_vcloud_config().get('service_type') public_ip = nat.get(PUBLIC_IP) if public_ip: check_ip(public_ip) CheckAssignedExternalIp(public_ip, gateway) else: if isSubscription(service_type): getFreeIP(gateway) check_protocol(rules.get('protocol', "any")) original_port = rules.get('original_port') if original_port and not isinstance(original_port, int): raise cfy_exc.NonRecoverableError("Parameter 'original_port' must be integer") translated_port = rules.get('translated_port') if translated_port and not isinstance(translated_port, int): raise cfy_exc.NonRecoverableError("Parameter 'translated_port' must be integer")
def creation_validation(vca_client, **kwargs): nat = get_mandatory(ctx.node.properties, 'nat') rules = get_mandatory(ctx.node.properties, 'rules') gateway = get_gateway(vca_client, get_mandatory(nat, 'edge_gateway')) service_type = get_vcloud_config().get('service_type') public_ip = nat.get(PUBLIC_IP) if public_ip: check_ip(public_ip) CheckAssignedExternalIp(public_ip, gateway) else: if isSubscription(service_type): getFreeIP(gateway) check_protocol(rules.get('protocol', "any")) original_port = rules.get('original_port') if original_port and not isinstance(original_port, int): raise cfy_exc.NonRecoverableError( "Parameter 'original_port' must be integer") translated_port = rules.get('translated_port') if translated_port and not isinstance(translated_port, int): raise cfy_exc.NonRecoverableError( "Parameter 'translated_port' must be integer")
def creation_validation(vca_client, **kwargs): """ validate node context, fields from floatingip dict: * edge_gateway - mandatory, * public_ip - prefered ip for node, can be empty fields from vcloud_config: * service_type - ondemand, subscription also check availability of public ip if set or exist some free ip in subscription case """ floatingip = get_mandatory(ctx.node.properties, 'floatingip') edge_gateway = get_mandatory(floatingip, 'edge_gateway') gateway = get_gateway(vca_client, edge_gateway) service_type = get_vcloud_config().get('service_type') public_ip = floatingip.get(PUBLIC_IP) if public_ip: check_ip(public_ip) CheckAssignedExternalIp(public_ip, gateway) else: if is_subscription(service_type): getFreeIP(gateway)
def _rule_operation(operation, vca_client): """ create/delete firewall rules in gateway for current node """ gateway = get_gateway( vca_client, _get_gateway_name(ctx.target.node.properties)) if gateway.is_busy(): return False for rule in ctx.target.node.properties['rules']: description = rule.get('description', "Rule added by pyvcloud").strip() source_ip = rule.get("source", "external") if not _is_literal_ip(source_ip): check_ip(source_ip) elif _is_host_ip(source_ip): source_ip = get_vm_ip(vca_client, ctx, gateway) source_port = str(rule.get("source_port", "any")) dest_ip = rule.get("destination", "external") if not _is_literal_ip(dest_ip): check_ip(dest_ip) elif _is_host_ip(dest_ip): dest_ip = get_vm_ip(vca_client, ctx, gateway) dest_port = str(rule.get('destination_port', 'any')) protocol = rule.get('protocol', 'any').capitalize() action = rule.get("action", "allow") log = rule.get('log_traffic', False) if operation == CREATE_RULE: gateway.add_fw_rule( True, description, action, protocol, dest_port, dest_ip, source_port, source_ip, log) ctx.logger.info( "Firewall rule has been created: {0}".format(description)) elif operation == DELETE_RULE: gateway.delete_fw_rule(protocol, dest_port, dest_ip, source_port, source_ip) ctx.logger.info( "Firewall rule has been deleted: {0}".format(description)) return save_gateway_configuration(gateway, vca_client)
def _floatingip_operation(operation, vca_client, ctx): """ create/release floating ip by nat rules for this ip with relation to internal ip for current node, save selected public_ip in runtime properties """ service_type = get_vcloud_config().get('service_type') gateway = get_gateway( vca_client, ctx.target.node.properties['floatingip']['edge_gateway']) internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None public_ip = (ctx.target.instance.runtime_properties.get(PUBLIC_IP) or ctx.target.node.properties['floatingip'].get(PUBLIC_IP)) if operation == CREATE: CheckAssignedInternalIp(internal_ip, gateway) if public_ip: CheckAssignedExternalIp(public_ip, gateway) else: public_ip = get_public_ip(vca_client, gateway, service_type, ctx) nat_operation = _add_nat_rule elif operation == DELETE: if not public_ip: ctx.logger.info("Can't get external IP".format(public_ip)) return nat_operation = _del_nat_rule else: raise cfy_exc.NonRecoverableError( "Unknown operation {0}".format(operation) ) external_ip = check_ip(public_ip) nat_operation(gateway, "SNAT", internal_ip, external_ip) nat_operation(gateway, "DNAT", external_ip, internal_ip) if not save_gateway_configuration(gateway, vca_client): return ctx.operation.retry(message='Waiting for gateway.', retry_after=10) if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip else: if is_ondemand(service_type): if not ctx.target.node.properties['floatingip'].get(PUBLIC_IP): del_ondemand_public_ip( vca_client, gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) del ctx.target.instance.runtime_properties[PUBLIC_IP]
def _rule_operation(operation, vca_client): """ create/delete firewall rules in gateway for current node """ gateway = get_gateway(vca_client, _get_gateway_name(ctx.target.node.properties)) if gateway.is_busy(): return False for rule in ctx.target.node.properties['rules']: description = rule.get('description', "Rule added by pyvcloud").strip() source_ip = rule.get("source", "external") if not _is_literal_ip(source_ip): check_ip(source_ip) elif _is_host_ip(source_ip): source_ip = get_vm_ip(vca_client, ctx, gateway) source_port = str(rule.get("source_port", "any")) dest_ip = rule.get("destination", "external") if not _is_literal_ip(dest_ip): check_ip(dest_ip) elif _is_host_ip(dest_ip): dest_ip = get_vm_ip(vca_client, ctx, gateway) dest_port = str(rule.get('destination_port', 'any')) protocol = rule.get('protocol', 'any').capitalize() action = rule.get("action", "allow") log = rule.get('log_traffic', False) if operation == CREATE_RULE: gateway.add_fw_rule(True, description, action, protocol, dest_port, dest_ip, source_port, source_ip, log) ctx.logger.info( "Firewall rule has been created: {0}".format(description)) elif operation == DELETE_RULE: gateway.delete_fw_rule(protocol, dest_port, dest_ip, source_port, source_ip) ctx.logger.info( "Firewall rule has been deleted: {0}".format(description)) return save_gateway_configuration(gateway, vca_client)
def _floatingip_operation(operation, vca_client, ctx): """ create/release floating ip by nat rules for this ip with relation to internal ip for current node, save selected public_ip in runtime properties """ service_type = get_vcloud_config().get('service_type') gateway = get_gateway( vca_client, ctx.target.node.properties['floatingip']['edge_gateway']) if gateway.is_busy(): return False internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None public_ip = (ctx.target.instance.runtime_properties.get(PUBLIC_IP) or ctx.target.node.properties['floatingip'].get(PUBLIC_IP)) if operation == CREATE: CheckAssignedInternalIp(internal_ip, gateway) if public_ip: CheckAssignedExternalIp(public_ip, gateway) else: public_ip = get_public_ip(vca_client, gateway, service_type, ctx) nat_operation = _add_nat_rule elif operation == DELETE: if not public_ip: ctx.logger.info("Can't get external IP".format(public_ip)) return nat_operation = _del_nat_rule else: raise cfy_exc.NonRecoverableError( "Unknown operation {0}".format(operation)) external_ip = check_ip(public_ip) nat_operation(gateway, "SNAT", internal_ip, external_ip) nat_operation(gateway, "DNAT", external_ip, internal_ip) success = save_gateway_configuration(gateway, vca_client) if not success: return False if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip else: if is_ondemand(service_type): if not ctx.target.node.properties['floatingip'].get(PUBLIC_IP): del_ondemand_public_ip( vca_client, gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) del ctx.target.instance.runtime_properties[PUBLIC_IP] return True
def creation_validation(vca_client, **kwargs): """ validate nat rules in node properties """ nat = get_mandatory(ctx.node.properties, 'nat') gateway = get_gateway(vca_client, get_mandatory(nat, 'edge_gateway')) service_type = get_vcloud_config().get('service_type') public_ip = nat.get(PUBLIC_IP) if public_ip: check_ip(public_ip) else: if is_subscription(service_type): getFreeIP(gateway) for rule in get_mandatory(ctx.node.properties, 'rules'): if rule['type'] == "DNAT": utils.check_protocol(rule.get('protocol')) original_port = rule.get('original_port') if original_port and not isinstance(original_port, int): raise cfy_exc.NonRecoverableError( "Parameter 'original_port' must be integer") translated_port = rule.get('translated_port') if translated_port and not isinstance(translated_port, int): raise cfy_exc.NonRecoverableError( "Parameter 'translated_port' must be integer")
def _rule_operation(operation, vca_client): gateway = get_gateway( vca_client, _get_gateway_name(ctx.target.node.properties)) for rule in ctx.target.node.properties['rules']: description = rule.get('description', "Rule added by pyvcloud").strip() source_ip = rule.get("source", "external").capitalize() if source_ip not in ADDRESS_LITERALS: check_ip(source_ip) elif source_ip == ADDRESS_LITERALS[-1]: source_ip = get_vm_ip(vca_client, ctx, gateway) source_port = str(rule.get("source_port", "any")).capitalize() dest_ip = rule.get("destination", "external").capitalize() if dest_ip not in ADDRESS_LITERALS: check_ip(dest_ip) elif dest_ip == ADDRESS_LITERALS[-1]: dest_ip = get_vm_ip(vca_client, ctx, gateway) dest_port = str(rule.get('destination_port', 'any')).capitalize() protocol = rule.get('protocol', 'any').capitalize() action = rule.get("action", "allow") log = rule.get('log_traffic', False) if operation == CREATE_RULE: gateway.add_fw_rule( True, description, action, protocol, dest_port, dest_ip, source_port, source_ip, log) ctx.logger.info( "Firewall rule has been created: {0}".format(description)) elif operation == DELETE_RULE: gateway.delete_fw_rule(protocol, dest_port, dest_ip.lower(), source_port, source_ip.lower()) ctx.logger.info( "Firewall rule has been deleted: {0}".format(description)) if not save_gateway_configuration(gateway, vca_client): return ctx.operation.retry(message='Waiting for gateway.', retry_after=10)
def creation_validation(vca_client, **kwargs): """ check network description from node description """ network_name = get_network_name(ctx.node.properties) ctx.logger.info( "Validation cloudify.vcloud.nodes.Network node: {0}".format( network_name)) if is_network_exists(vca_client, network_name): if ctx.node.properties.get('use_external_resource'): # TODO: check: default gateway must exists return else: raise cfy_exc.NonRecoverableError( "Network already exsists: {0}".format(network_name)) net_prop = get_mandatory(ctx.node.properties, "network") gateway_name = get_mandatory(net_prop, 'edge_gateway') if not vca_client.get_gateway(get_vcloud_config()['vdc'], gateway_name): raise cfy_exc.NonRecoverableError( "Gateway {0} not found".format(gateway_name)) static_ip = _split_adresses(get_mandatory(net_prop, 'static_range')) check_ip(static_ip.start) check_ip(static_ip.end) dns_list = net_prop.get("dns") if dns_list: for ip in dns_list: check_ip(ip) gateway_ip = check_ip(get_mandatory(net_prop, "gateway_ip")) netmask = check_ip(get_mandatory(net_prop, "netmask")) ips = [gateway_ip, static_ip.start, static_ip.end] dhcp = net_prop.get("dhcp") if dhcp: dhcp_range = get_mandatory(net_prop["dhcp"], "dhcp_range") dhcp_ip = _split_adresses(dhcp_range) if not is_separate_ranges(static_ip, dhcp_ip): raise cfy_exc.NonRecoverableError( "Static_range and dhcp_range is overlapped.") ips.extend([dhcp_ip.start, dhcp_ip.end]) if not is_ips_in_same_subnet(ips, netmask): raise cfy_exc.NonRecoverableError("IP addresses in different subnets.")
def creation_validation(vca_client, **kwargs): """ check network description from node description """ network_name = get_network_name(ctx.node.properties) ctx.logger.info("Validation cloudify.vcloud.nodes.Network node: {0}" .format(network_name)) if is_network_exists(vca_client, network_name): if ctx.node.properties.get('use_external_resource'): # TODO: check: default gateway must exists return else: raise cfy_exc.NonRecoverableError( "Network already exsists: {0}".format(network_name)) net_prop = get_mandatory(ctx.node.properties, "network") gateway_name = get_mandatory(net_prop, 'edge_gateway') if not vca_client.get_gateway(get_vcloud_config()['vdc'], gateway_name): raise cfy_exc.NonRecoverableError( "Gateway {0} not found".format(gateway_name)) static_ip = _split_adresses(get_mandatory(net_prop, 'static_range')) check_ip(static_ip.start) check_ip(static_ip.end) dns_list = net_prop.get("dns") if dns_list: for ip in dns_list: check_ip(ip) gateway_ip = check_ip(get_mandatory(net_prop, "gateway_ip")) netmask = check_ip(get_mandatory(net_prop, "netmask")) ips = [gateway_ip, static_ip.start, static_ip.end] dhcp = net_prop.get("dhcp") if dhcp: dhcp_range = get_mandatory(net_prop["dhcp"], "dhcp_range") dhcp_ip = _split_adresses(dhcp_range) if not is_separate_ranges(static_ip, dhcp_ip): raise cfy_exc.NonRecoverableError( "Static_range and dhcp_range is overlapped.") ips.extend([dhcp_ip.start, dhcp_ip.end]) if not is_ips_in_same_subnet(ips, netmask): raise cfy_exc.NonRecoverableError( "IP addresses in different subnets.")