def test_get_gateway(self): """ check get gateway """ # good case fake_client = self.generate_client() fake_ctx = self.generate_node_context() with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertEqual( network_plugin.get_gateway( fake_client, 'test name' ), fake_client._vdc_gateway ) fake_client.get_gateway.assert_called_with( 'vdc_name', 'test name' ) # bad case fake_client = self.generate_client() fake_ctx = self.generate_node_context() fake_client.get_gateway = mock.MagicMock(return_value=None) with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): network_plugin.get_gateway( fake_client, 'test name' )
def prepare_server_operation(vca_client, operation): """ generate nat rules by current list of rules in node """ try: gateway = get_gateway( vca_client, ctx.target.node.properties['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) private_ip = get_vm_ip(vca_client, ctx, gateway) has_snat = False for rule in ctx.target.node.properties['rules']: rule_type = rule['type'] if has_snat and _is_snat(rule_type): ctx.logger.info("Rules list must contains only one SNAT rule.") continue protocol = rule.get('protocol', "any") original_port = rule.get('original_port', "any") translated_port = rule.get('translated_port', "any") nat_network_operation( vca_client, gateway, operation, rule_type, public_ip, private_ip, original_port, translated_port, protocol) if _is_snat(rule_type): has_snat = True except KeyError as e: raise cfy_exc.NonRecoverableError("Parameter not found: {0}".format(e)) return _save_configuration(gateway, vca_client, operation, public_ip)
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 prepare_server_operation(vca_client, operation): """ generate nat rules by current list of rules in node """ try: gateway = get_gateway( vca_client, ctx.target.node.properties['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) private_ip = get_vm_ip(vca_client, ctx, gateway) has_snat = False for rule in ctx.target.node.properties['rules']: rule_type = rule['type'] if has_snat and _is_snat(rule_type): ctx.logger.info("Rules list must contains only one SNAT rule.") continue protocol = rule.get('protocol', "any") original_port = rule.get('original_port', "any") translated_port = rule.get('translated_port', "any") nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, private_ip, original_port, translated_port, protocol) if _is_snat(rule_type): has_snat = True except KeyError as e: raise cfy_exc.NonRecoverableError("Parameter not found: {0}".format(e)) return _save_configuration(gateway, vca_client, operation, public_ip)
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 prepare_network_operation(vca_client, operation): try: gateway = get_gateway(vca_client, ctx.target.node.properties['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) private_ip = _create_ip_range(vca_client, gateway) for rule in ctx.target.node.properties['rules']: rule_type = rule['type'] nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, private_ip, "any", "any", "any") except KeyError as e: raise cfy_exc.NonRecoverableError("Parameter not found: {0}".format(e)) _save_configuration(gateway, vca_client, operation, public_ip)
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 _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 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 prepare_server_operation(vca_client, operation): try: gateway = get_gateway(vca_client, ctx.target.node.properties['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) private_ip = get_vm_ip(vca_client, ctx, gateway) for rule in ctx.target.node.properties['rules']: rule_type = rule['type'] protocol = rule.get('protocol', "any") original_port = rule.get('original_port', "any") translated_port = rule.get('translated_port', "any") nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, private_ip, original_port, translated_port, protocol) except KeyError as e: raise cfy_exc.NonRecoverableError("Parameter not found: {0}".format(e)) _save_configuration(gateway, vca_client, operation, public_ip)
def prepare_network_operation(vca_client, operation): """ create nat rules by rules from network node """ try: gateway = get_gateway( vca_client, ctx.target.node.properties['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) private_ip = _create_ip_range(vca_client, gateway) for rule in ctx.target.node.properties['rules']: rule_type = rule['type'] nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, private_ip, "any", "any", "any") except KeyError as e: raise cfy_exc.NonRecoverableError("Parameter not found: {0}".format(e)) _save_configuration(gateway, vca_client, operation, public_ip)
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): 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 prepare_server_operation(vca_client, operation): """ generate nat rules by current list of rules in node """ try: gateway = get_gateway( vca_client, ctx.target.node.properties['nat']['edge_gateway']) public_ip = _obtain_public_ip(vca_client, ctx, gateway, operation) private_ip = get_vm_ip(vca_client, ctx, gateway) for rule in ctx.target.node.properties['rules']: rule_type = rule['type'] protocol = rule.get('protocol', "any") original_port = rule.get('original_port', "any") translated_port = rule.get('translated_port', "any") nat_network_operation(vca_client, gateway, operation, rule_type, public_ip, private_ip, original_port, translated_port, protocol) except KeyError as e: raise cfy_exc.NonRecoverableError("Parameter not found: {0}".format(e)) _save_configuration(gateway, vca_client, operation, public_ip)
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 _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 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 create(vca_client, **kwargs): """ create new vcloud air network, e.g.: { 'use_external_resource': False, 'resource_id': 'secret_network', 'network': { 'dhcp': { 'dhcp_range': "10.1.1.128-10.1.1.255" }, 'static_range': "10.1.1.2-10.1.1.127", 'gateway_ip': "10.1.1.1", 'edge_gateway': 'gateway', 'name': 'secret_network', "netmask": '255.255.255.0', "dns": ["8.8.8.8", "4.4.4.4"] } } """ vdc_name = get_vcloud_config()['vdc'] if ctx.node.properties['use_external_resource']: network_name = ctx.node.properties['resource_id'] if not is_network_exists(vca_client, network_name): raise cfy_exc.NonRecoverableError( "Can't find external resource: {0}".format(network_name)) ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] = network_name ctx.logger.info( "External resource {0} has been used".format(network_name)) return network_name = get_network_name(ctx.node.properties) if not ctx.instance.runtime_properties.get(SKIP_CREATE_NETWORK): net_prop = ctx.node.properties["network"] if network_name in _get_network_list(vca_client, get_vcloud_config()['vdc']): raise cfy_exc.NonRecoverableError( "Network {0} already exists, but parameter " "'use_external_resource' is 'false' or absent" .format(network_name)) ip = _split_adresses(net_prop['static_range']) gateway_name = net_prop['edge_gateway'] get_gateway(vca_client, gateway_name) start_address = ip.start end_address = ip.end gateway_ip = net_prop["gateway_ip"] netmask = net_prop["netmask"] dns1 = "" dns2 = "" dns_list = net_prop.get("dns") if dns_list: dns1 = dns_list[0] if len(dns_list) > 1: dns2 = dns_list[1] dns_suffix = net_prop.get("dns_suffix") ctx.logger.info("Create network {0}." .format(network_name)) success, result = vca_client.create_vdc_network( vdc_name, network_name, gateway_name, start_address, end_address, gateway_ip, netmask, dns1, dns2, dns_suffix) if success: wait_for_task(vca_client, result) ctx.logger.info("Network {0} has been successfully created." .format(network_name)) else: raise cfy_exc.NonRecoverableError( "Could not create network {0}: {1}". format(network_name, result)) ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] = network_name if not _dhcp_operation(vca_client, network_name, ADD_POOL): ctx.instance.runtime_properties[SKIP_CREATE_NETWORK] = True return set_retry(ctx)