diff --git a/docs/airlock_gateway_rest_api_lib/airlock_gateway_rest_api_lib.html b/docs/airlock_gateway_rest_api_lib/airlock_gateway_rest_api_lib.html index fa4c575..fb93e0b 100644 --- a/docs/airlock_gateway_rest_api_lib/airlock_gateway_rest_api_lib.html +++ b/docs/airlock_gateway_rest_api_lib/airlock_gateway_rest_api_lib.html @@ -834,611 +834,616 @@

516 ''' 517 path = f'/configuration/mappings?filter=name=={name}' 518 res = get(gw_session, path, exp_code=200) - 519 return res.json().get('data') - 520 - 521 - 522def get_all_mapping_names(gw_session: GatewaySession) -> list: - 523 ''' - 524 Returns a sorted list of all mapping names on the Airlock Host. - 525 ''' - 526 mappings = get_all_mappings(gw_session) - 527 mapping_names = [] - 528 for mapping in mappings: - 529 mapping_name = mapping["attributes"]["name"] - 530 mapping_names.append(mapping_name) - 531 return sorted(mapping_names) - 532 - 533 - 534def import_mappings_from_xml(gw_session, mappings_xmls: list): - 535 ''' - 536 Adds all mappings specified in the list of dictionary objects - 537 representing XML files stored in `mappings_xmls` on the - 538 Airlock Host. If a mapping with the same name already exists, - 539 it will be overwritten. - 540 ''' - 541 for mapping_xml in mappings_xmls: - 542 mapping_zip = BytesIO() - 543 with ZipFile(mapping_zip, mode="w") as zip_file: - 544 zip_file.writestr("alec_table.xml", mapping_xml) - 545 - 546 mapping_zip.seek(0) - 547 - 548 req_raw(gw_session, "put", "/configuration/mappings/import", - 549 "application/zip", mapping_zip.read(), 200) + 519 + 520 candidate_list = res.json().get('data') + 521 if len(candidate_list) == 1: + 522 return candidate_list[0] + 523 else: + 524 return {} + 525 + 526 + 527def get_all_mapping_names(gw_session: GatewaySession) -> list: + 528 ''' + 529 Returns a sorted list of all mapping names on the Airlock Host. + 530 ''' + 531 mappings = get_all_mappings(gw_session) + 532 mapping_names = [] + 533 for mapping in mappings: + 534 mapping_name = mapping["attributes"]["name"] + 535 mapping_names.append(mapping_name) + 536 return sorted(mapping_names) + 537 + 538 + 539def import_mappings_from_xml(gw_session, mappings_xmls: list): + 540 ''' + 541 Adds all mappings specified in the list of dictionary objects + 542 representing XML files stored in `mappings_xmls` on the + 543 Airlock Host. If a mapping with the same name already exists, + 544 it will be overwritten. + 545 ''' + 546 for mapping_xml in mappings_xmls: + 547 mapping_zip = BytesIO() + 548 with ZipFile(mapping_zip, mode="w") as zip_file: + 549 zip_file.writestr("alec_table.xml", mapping_xml) 550 - 551 - 552def export_mappings(gw_session: GatewaySession, - 553 mapping_ids: list = None) -> list: - 554 ''' - 555 Returns a list of the XML files describing the mappings with IDs - 556 contained in the `mapping_ids` list.\n - 557 `mapping_ids` must be a list of strings. If it is omitted, all mappings - 558 are returned. \n - 559 If one or more of the mappings IDs is not found, it is ignored. - 560 ''' - 561 if mapping_ids is None: - 562 mapping_ids = [data["id"] for data in get_all_mappings(gw_session)] - 563 - 564 mapping_xmls = [] - 565 for mapping_id in mapping_ids: - 566 gw_session.add_headers({"Accept": "application/zip"}) - 567 path = f'/configuration/mappings/{mapping_id}/export' - 568 res = get(gw_session, path, exp_code=[200, 404]) - 569 if res.status_code == 200: - 570 with ZipFile(BytesIO(res.content)) as zip_file: - 571 with zip_file.open("alec_table.xml", "r") as mapping_xml: - 572 mapping_xmls.append(mapping_xml.read()) - 573 else: - 574 logging.info("Mapping with ID %s was not found on Airlock Host", - 575 mapping_id) - 576 - 577 gw_session.add_headers({"Accept": "application/json"}) - 578 return mapping_xmls - 579 - 580 - 581def delete_mapping_by_id(gw_session: GatewaySession, mapping_id: str) -> bool: - 582 ''' - 583 Deletes the Mapping with the selected ID.\n - 584 Returns True if deletion was successful and False if no mapping with ID - 585 `mapping_id` was found.. - 586 ''' - 587 path = f"/configuration/mappings/{mapping_id}" - 588 res = delete(gw_session, path, exp_code=[204, 404]) - 589 return res.status_code == 204 - 590 - 591 - 592def get_templates(gw_session: GatewaySession) -> dict: - 593 ''' - 594 Returns a dictionary object mapping every mapping template name to its ID. - 595 ''' - 596 res = get(gw_session, '/configuration/templates/mappings', 200) - 597 data = res.json()['data'] - 598 return {x['attributes']['name']: x['id'] for x in data} - 599 - 600 - 601def update_mapping(gw_session: GatewaySession, mapping_id: str, - 602 attributes: dict) -> bool: - 603 ''' - 604 Updates the mapping with ID `mapping_id` with the given `attributes`, - 605 for example name or entry path.\n - 606 Returns True if update was successful and False if no mapping with ID - 607 `mapping_id` was found. - 608 ''' - 609 data = { - 610 "data": { - 611 "type": 'mapping', - 612 "attributes": attributes - 613 } - 614 } - 615 path = f'/configuration/mappings/{mapping_id}' - 616 res = patch(gw_session, path, data, [200, 404]) - 617 return res.status_code == 200 - 618 - 619 - 620def add_mapping(gw_session: GatewaySession, name: str, - 621 template: str = 'New_Mapping', entry_path: str = '/') -> str: - 622 ''' - 623 Adds a new mapping to the Airlock host, with the specified - 624 `name` and `entry_path`.\n Optionally, a template can - 625 be used for the new mapping.\n - 626 Returns the mapping ID of the new mapping. - 627 ''' - 628 templates = get_templates(gw_session) - 629 data = { - 630 "data": { - 631 "type": "create-mapping-from-template", - 632 "attributes": { - 633 "id": templates[template] - 634 } - 635 } - 636 } - 637 path = '/configuration/mappings/create-from-template' - 638 res = post(gw_session, path, data, 201) - 639 mapping_id = res.json()['data']['id'] - 640 attributes = { - 641 "name": name, - 642 "entryPath": {"value": entry_path} - 643 } - 644 update_mapping(gw_session, mapping_id, attributes) - 645 return mapping_id - 646 - 647 - 648def set_source_mapping(gw_session: GatewaySession, mapping_id: str, - 649 src_mapping_id: str) -> bool: - 650 ''' - 651 Sets the source mapping of mapping with ID `mapping_id` - 652 to the mapping with ID `src_mapping_id`. \n - 653 Returns True if the operation was successful and False if - 654 no mapping with ID `mapping_id` was found. - 655 ''' - 656 data = { - 657 "data": { - 658 "type": 'mapping', - 659 "id": src_mapping_id - 660 } - 661 } - 662 path = f'/configuration/mappings/{mapping_id}/relationships/template' - 663 res = patch(gw_session, path, data, [204, 404]) - 664 if res.status_code == 404: - 665 return False - 666 - 667 lock_cfg = { - 668 "enabled": True, - 669 "labels": True, - 670 "entryPath": {"settings": True} - 671 } - 672 - 673 return update_mapping(gw_session, mapping_id, {"locking": lock_cfg}) - 674 - 675 - 676def pull_from_source_mapping(gw_session: GatewaySession, - 677 mapping_id: str) -> bool: - 678 ''' - 679 Performs a pull from the source mapping on the mapping with - 680 ID `mapping_id`.\n - 681 Returns True if the pull was succesfull and False if no mapping with ID - 682 `mapping_id` was found. - 683 ''' - 684 path = f'/configuration/mappings/{mapping_id}/pull-from-source-mapping' - 685 res = post(gw_session, path, exp_code=[200, 404]) - 686 return res.status_code == 200 - 687 - 688 - 689def gen_backend_host(protocol: str, name: str, port: int) -> dict: - 690 ''' - 691 Returns a dictionary object representing a new Backend Host. - 692 ''' - 693 host_data = { - 694 "protocol": protocol, - 695 "hostName": name, - 696 "port": port - 697 } - 698 return host_data - 699 - 700 - 701def add_backend_group(gw_session: GatewaySession, beg_name: str, - 702 be_hosts: list) -> str: - 703 ''' - 704 Adds a new Backend Group with the name `beg_name` and the hosts - 705 contained in `be_hosts` to the Airlock Host.\n - 706 Returns the ID of the newly added Backend Group. - 707 ''' - 708 beg_data = { - 709 "data": { - 710 "type": "back-end-group", - 711 "attributes": { - 712 "name": beg_name, - 713 "backendHosts": be_hosts - 714 } - 715 } - 716 } - 717 res = post(gw_session, "/configuration/back-end-groups", beg_data, 201) - 718 return res.json()['data']['id'] - 719 - 720 - 721def get_backend_groups(gw_session: GatewaySession) -> list: - 722 ''' - 723 Returns a list containing all backend groups on the Airlock Host. - 724 ''' - 725 res = get(gw_session, '/configuration/back-end-groups', exp_code=200) - 726 return res.json().get('data') - 727 - 728 - 729def get_backend_group_by_id(gw_session: GatewaySession, beg_id: str) -> dict: - 730 ''' - 731 Returns a dictionary object describing the backend group with ID - 732 `beg_id`, or None if no such group was found. - 733 ''' - 734 path = f'/configuration/back-end-groups/{beg_id}' - 735 res = get(gw_session, path, exp_code=[200, 404]) - 736 if res.status_code == 200: - 737 return res.json().get('data') - 738 return None - 739 - 740 - 741def update_backend_group_by_id(gw_session: GatewaySession, beg_id: str, - 742 attributes: dict) -> bool: - 743 ''' - 744 Updates the Backend Group with ID `beg_id` with the given attributes, - 745 for example hostname or port. \n - 746 Returns True if the update was succesfull and False if no Backend Group - 747 with ID `beg_id` was found. - 748 ''' - 749 beg_data = { - 750 "data": { - 751 "type": "back-end-group", - 752 "id": beg_id, - 753 "attributes": attributes - 754 } - 755 } - 756 path = f"/configuration/back-end-groups/{beg_id}" - 757 res = patch(gw_session, path, beg_data, [200, 404]) - 758 return res.status_code == 200 - 759 - 760 - 761def delete_backend_group_by_id(gw_session: GatewaySession, - 762 beg_id: str) -> bool: - 763 ''' - 764 Deletes the Backend Group with ID `beg_id` from the Airlock Host.\n - 765 Returns True if deletion was successful and False if no Backend - 766 Group with ID `beg_id` was found. - 767 ''' - 768 path = f"/configuration/back-end-groups/{beg_id}" - 769 res = delete(gw_session, path, exp_code=[204, 404]) - 770 return res.status_code == 204 - 771 - 772 - 773def connect_virtual_host_to_map(gw_session: GatewaySession, vh_id: str, - 774 mapping_id: str) -> bool: - 775 ''' - 776 Connects Virtual Host with id `vh_id` to the Mapping with ID - 777 `mapping_id`.\n Returns True if the operation was successful - 778 and False if one of the provided IDs was not found. - 779 ''' - 780 data = { - 781 "data": [{ - 782 "type": 'mapping', - 783 "id": mapping_id - 784 }] - 785 } - 786 path = f'/configuration/virtual-hosts/{vh_id}/relationships/mappings' - 787 res = patch(gw_session, path, data, [204, 404]) - 788 return res.status_code == 204 - 789 - 790 - 791def connect_map_to_beg(gw_session: GatewaySession, mapping_id: str, - 792 beg_ids: list) -> bool: - 793 ''' - 794 Connects Mapping with ID `mapping_id` to the Backend Groups - 795 with IDs in `beg_ids`.\n - 796 Returns True if the operation was successful and False if one of - 797 the provided IDs was not found. - 798 ''' - 799 data = { - 800 "data": [] - 801 } - 802 for beg_id in beg_ids: - 803 group = { - 804 "type": 'back-end-group', - 805 "id": beg_id - 806 } - 807 data['data'].append(group) - 808 map_id = mapping_id - 809 path = f'/configuration/mappings/{map_id}/relationships/back-end-groups' - 810 res = patch(gw_session, path, data, [204, 404]) - 811 return res.status_code == 204 - 812 - 813 - 814def disconnect_virtual_host_to_map(gw_session: GatewaySession, vh_id: str, - 815 mapping_id: str) -> bool: - 816 ''' - 817 Disconnects Virtual Host with id `vh_id` to the Mapping with - 818 ID `mapping_id`.\n Returns True if the operation was successful - 819 and False if one of the provided IDs was not found. - 820 ''' - 821 data = { - 822 "data": [{ - 823 "type": 'mapping', - 824 "id": mapping_id - 825 }] - 826 } - 827 path = f'/configuration/virtual-hosts/{vh_id}/relationships/mappings' - 828 res = delete(gw_session, path, data, [204, 404]) - 829 return res.status_code == 204 - 830 - 831 - 832def disconnect_map_to_beg(gw_session: GatewaySession, mapping_id: str, - 833 beg_ids: list) -> bool: - 834 ''' - 835 Disconnects Mapping with ID `mapping_id` from the Backend Groups - 836 with IDs in `beg_ids`.\n Returns True if the operation was successful - 837 and False if one of the provided IDs was not found. - 838 ''' - 839 data = { - 840 "data": [] - 841 } - 842 for beg_id in beg_ids: - 843 group = { - 844 "type": 'back-end-group', - 845 "id": beg_id - 846 } - 847 data['data'].append(group) - 848 map_id = mapping_id - 849 path = f'/configuration/mappings/{map_id}/relationships/back-end-groups' - 850 res = delete(gw_session, path, data, [204, 404]) - 851 return res.status_code == 204 - 852 - 853 - 854def get_mapping_deny_rule_group(gw_session: GatewaySession, mapping_id: str, - 855 denyrule_group_shortname: str) -> dict: - 856 ''' - 857 Returns a dictionary object describing the deny rule group in the - 858 specified Mapping, or None if the mapping or shortname specified were not - 859 found. - 860 ''' - 861 path = f'/configuration/mappings/{mapping_id}/deny-rule-groups/{denyrule_group_shortname}' - 862 res = get(gw_session, path, exp_code=[200, 404]) - 863 return res.json().get('data') - 864 - 865 - 866def update_mapping_deny_rule_group(gw_session: GatewaySession, mapping_id: str, - 867 denyrule_group_shortname: str, - 868 attributes: dict) -> bool: - 869 ''' - 870 Updates the settings for a deny rule group within a specified mapping. - 871 Returns True if successful, and False if if the mapping or shortname - 872 specified were not found. - 873 ''' - 874 path = f'/configuration/mappings/{mapping_id}/deny-rule-groups/{denyrule_group_shortname}' - 875 data = { - 876 "data": { - 877 "type": "mapping-deny-rule-group", - 878 "attributes": attributes - 879 } - 880 } - 881 res = patch(gw_session, path, data, exp_code=[200, 404]) - 882 return res.status_code == 200 - 883 - 884 - 885def get_mapping_deny_rule(gw_session: GatewaySession, mapping_id: str, - 886 denyrule_shortname: str) -> dict: - 887 ''' - 888 Returns a dictionary object describing the deny rule in the specified - 889 Mapping, or None if the mapping or shortname specified were not found. - 890 ''' - 891 path = f'/configuration/mappings/{mapping_id}/deny-rules/{denyrule_shortname}' - 892 res = get(gw_session, path, exp_code=[200, 404]) - 893 return res.json().get("data") - 894 - 895 - 896def update_mapping_deny_rule(gw_session: GatewaySession, mapping_id: str, - 897 denyrule_shortname: str, attributes: dict) -> bool: - 898 ''' - 899 Updates the settings for a deny rule within a specified mapping. Returns - 900 True if successful, and False if if the mapping or shortname specified - 901 were not found. - 902 ''' - 903 path = f'/configuration/mappings/{mapping_id}/deny-rules/{denyrule_shortname}' - 904 data = { - 905 "data": { - 906 "type": "mapping-deny-rule", - 907 "attributes": attributes - 908 } - 909 } - 910 res = patch(gw_session, path, data, exp_code=[200, 404]) - 911 return res.status_code == 200 - 912 - 913 - 914def get_deny_rule_groups(gw_session: GatewaySession) -> dict: - 915 ''' - 916 Returns a list of all deny rule groups on the Airlock Host. - 917 ''' + 551 mapping_zip.seek(0) + 552 + 553 req_raw(gw_session, "put", "/configuration/mappings/import", + 554 "application/zip", mapping_zip.read(), 200) + 555 + 556 + 557def export_mappings(gw_session: GatewaySession, + 558 mapping_ids: list = None) -> list: + 559 ''' + 560 Returns a list of the XML files describing the mappings with IDs + 561 contained in the `mapping_ids` list.\n + 562 `mapping_ids` must be a list of strings. If it is omitted, all mappings + 563 are returned. \n + 564 If one or more of the mappings IDs is not found, it is ignored. + 565 ''' + 566 if mapping_ids is None: + 567 mapping_ids = [data["id"] for data in get_all_mappings(gw_session)] + 568 + 569 mapping_xmls = [] + 570 for mapping_id in mapping_ids: + 571 gw_session.add_headers({"Accept": "application/zip"}) + 572 path = f'/configuration/mappings/{mapping_id}/export' + 573 res = get(gw_session, path, exp_code=[200, 404]) + 574 if res.status_code == 200: + 575 with ZipFile(BytesIO(res.content)) as zip_file: + 576 with zip_file.open("alec_table.xml", "r") as mapping_xml: + 577 mapping_xmls.append(mapping_xml.read()) + 578 else: + 579 logging.info("Mapping with ID %s was not found on Airlock Host", + 580 mapping_id) + 581 + 582 gw_session.add_headers({"Accept": "application/json"}) + 583 return mapping_xmls + 584 + 585 + 586def delete_mapping_by_id(gw_session: GatewaySession, mapping_id: str) -> bool: + 587 ''' + 588 Deletes the Mapping with the selected ID.\n + 589 Returns True if deletion was successful and False if no mapping with ID + 590 `mapping_id` was found.. + 591 ''' + 592 path = f"/configuration/mappings/{mapping_id}" + 593 res = delete(gw_session, path, exp_code=[204, 404]) + 594 return res.status_code == 204 + 595 + 596 + 597def get_templates(gw_session: GatewaySession) -> dict: + 598 ''' + 599 Returns a dictionary object mapping every mapping template name to its ID. + 600 ''' + 601 res = get(gw_session, '/configuration/templates/mappings', 200) + 602 data = res.json()['data'] + 603 return {x['attributes']['name']: x['id'] for x in data} + 604 + 605 + 606def update_mapping(gw_session: GatewaySession, mapping_id: str, + 607 attributes: dict) -> bool: + 608 ''' + 609 Updates the mapping with ID `mapping_id` with the given `attributes`, + 610 for example name or entry path.\n + 611 Returns True if update was successful and False if no mapping with ID + 612 `mapping_id` was found. + 613 ''' + 614 data = { + 615 "data": { + 616 "type": 'mapping', + 617 "attributes": attributes + 618 } + 619 } + 620 path = f'/configuration/mappings/{mapping_id}' + 621 res = patch(gw_session, path, data, [200, 404]) + 622 return res.status_code == 200 + 623 + 624 + 625def add_mapping(gw_session: GatewaySession, name: str, + 626 template: str = 'New_Mapping', entry_path: str = '/') -> str: + 627 ''' + 628 Adds a new mapping to the Airlock host, with the specified + 629 `name` and `entry_path`.\n Optionally, a template can + 630 be used for the new mapping.\n + 631 Returns the mapping ID of the new mapping. + 632 ''' + 633 templates = get_templates(gw_session) + 634 data = { + 635 "data": { + 636 "type": "create-mapping-from-template", + 637 "attributes": { + 638 "id": templates[template] + 639 } + 640 } + 641 } + 642 path = '/configuration/mappings/create-from-template' + 643 res = post(gw_session, path, data, 201) + 644 mapping_id = res.json()['data']['id'] + 645 attributes = { + 646 "name": name, + 647 "entryPath": {"value": entry_path} + 648 } + 649 update_mapping(gw_session, mapping_id, attributes) + 650 return mapping_id + 651 + 652 + 653def set_source_mapping(gw_session: GatewaySession, mapping_id: str, + 654 src_mapping_id: str) -> bool: + 655 ''' + 656 Sets the source mapping of mapping with ID `mapping_id` + 657 to the mapping with ID `src_mapping_id`. \n + 658 Returns True if the operation was successful and False if + 659 no mapping with ID `mapping_id` was found. + 660 ''' + 661 data = { + 662 "data": { + 663 "type": 'mapping', + 664 "id": src_mapping_id + 665 } + 666 } + 667 path = f'/configuration/mappings/{mapping_id}/relationships/template' + 668 res = patch(gw_session, path, data, [204, 404]) + 669 if res.status_code == 404: + 670 return False + 671 + 672 lock_cfg = { + 673 "enabled": True, + 674 "labels": True, + 675 "entryPath": {"settings": True} + 676 } + 677 + 678 return update_mapping(gw_session, mapping_id, {"locking": lock_cfg}) + 679 + 680 + 681def pull_from_source_mapping(gw_session: GatewaySession, + 682 mapping_id: str) -> bool: + 683 ''' + 684 Performs a pull from the source mapping on the mapping with + 685 ID `mapping_id`.\n + 686 Returns True if the pull was succesfull and False if no mapping with ID + 687 `mapping_id` was found. + 688 ''' + 689 path = f'/configuration/mappings/{mapping_id}/pull-from-source-mapping' + 690 res = post(gw_session, path, exp_code=[200, 404]) + 691 return res.status_code == 200 + 692 + 693 + 694def gen_backend_host(protocol: str, name: str, port: int) -> dict: + 695 ''' + 696 Returns a dictionary object representing a new Backend Host. + 697 ''' + 698 host_data = { + 699 "protocol": protocol, + 700 "hostName": name, + 701 "port": port + 702 } + 703 return host_data + 704 + 705 + 706def add_backend_group(gw_session: GatewaySession, beg_name: str, + 707 be_hosts: list) -> str: + 708 ''' + 709 Adds a new Backend Group with the name `beg_name` and the hosts + 710 contained in `be_hosts` to the Airlock Host.\n + 711 Returns the ID of the newly added Backend Group. + 712 ''' + 713 beg_data = { + 714 "data": { + 715 "type": "back-end-group", + 716 "attributes": { + 717 "name": beg_name, + 718 "backendHosts": be_hosts + 719 } + 720 } + 721 } + 722 res = post(gw_session, "/configuration/back-end-groups", beg_data, 201) + 723 return res.json()['data']['id'] + 724 + 725 + 726def get_backend_groups(gw_session: GatewaySession) -> list: + 727 ''' + 728 Returns a list containing all backend groups on the Airlock Host. + 729 ''' + 730 res = get(gw_session, '/configuration/back-end-groups', exp_code=200) + 731 return res.json().get('data') + 732 + 733 + 734def get_backend_group_by_id(gw_session: GatewaySession, beg_id: str) -> dict: + 735 ''' + 736 Returns a dictionary object describing the backend group with ID + 737 `beg_id`, or None if no such group was found. + 738 ''' + 739 path = f'/configuration/back-end-groups/{beg_id}' + 740 res = get(gw_session, path, exp_code=[200, 404]) + 741 if res.status_code == 200: + 742 return res.json().get('data') + 743 return None + 744 + 745 + 746def update_backend_group_by_id(gw_session: GatewaySession, beg_id: str, + 747 attributes: dict) -> bool: + 748 ''' + 749 Updates the Backend Group with ID `beg_id` with the given attributes, + 750 for example hostname or port. \n + 751 Returns True if the update was succesfull and False if no Backend Group + 752 with ID `beg_id` was found. + 753 ''' + 754 beg_data = { + 755 "data": { + 756 "type": "back-end-group", + 757 "id": beg_id, + 758 "attributes": attributes + 759 } + 760 } + 761 path = f"/configuration/back-end-groups/{beg_id}" + 762 res = patch(gw_session, path, beg_data, [200, 404]) + 763 return res.status_code == 200 + 764 + 765 + 766def delete_backend_group_by_id(gw_session: GatewaySession, + 767 beg_id: str) -> bool: + 768 ''' + 769 Deletes the Backend Group with ID `beg_id` from the Airlock Host.\n + 770 Returns True if deletion was successful and False if no Backend + 771 Group with ID `beg_id` was found. + 772 ''' + 773 path = f"/configuration/back-end-groups/{beg_id}" + 774 res = delete(gw_session, path, exp_code=[204, 404]) + 775 return res.status_code == 204 + 776 + 777 + 778def connect_virtual_host_to_map(gw_session: GatewaySession, vh_id: str, + 779 mapping_id: str) -> bool: + 780 ''' + 781 Connects Virtual Host with id `vh_id` to the Mapping with ID + 782 `mapping_id`.\n Returns True if the operation was successful + 783 and False if one of the provided IDs was not found. + 784 ''' + 785 data = { + 786 "data": [{ + 787 "type": 'mapping', + 788 "id": mapping_id + 789 }] + 790 } + 791 path = f'/configuration/virtual-hosts/{vh_id}/relationships/mappings' + 792 res = patch(gw_session, path, data, [204, 404]) + 793 return res.status_code == 204 + 794 + 795 + 796def connect_map_to_beg(gw_session: GatewaySession, mapping_id: str, + 797 beg_ids: list) -> bool: + 798 ''' + 799 Connects Mapping with ID `mapping_id` to the Backend Groups + 800 with IDs in `beg_ids`.\n + 801 Returns True if the operation was successful and False if one of + 802 the provided IDs was not found. + 803 ''' + 804 data = { + 805 "data": [] + 806 } + 807 for beg_id in beg_ids: + 808 group = { + 809 "type": 'back-end-group', + 810 "id": beg_id + 811 } + 812 data['data'].append(group) + 813 map_id = mapping_id + 814 path = f'/configuration/mappings/{map_id}/relationships/back-end-groups' + 815 res = patch(gw_session, path, data, [204, 404]) + 816 return res.status_code == 204 + 817 + 818 + 819def disconnect_virtual_host_to_map(gw_session: GatewaySession, vh_id: str, + 820 mapping_id: str) -> bool: + 821 ''' + 822 Disconnects Virtual Host with id `vh_id` to the Mapping with + 823 ID `mapping_id`.\n Returns True if the operation was successful + 824 and False if one of the provided IDs was not found. + 825 ''' + 826 data = { + 827 "data": [{ + 828 "type": 'mapping', + 829 "id": mapping_id + 830 }] + 831 } + 832 path = f'/configuration/virtual-hosts/{vh_id}/relationships/mappings' + 833 res = delete(gw_session, path, data, [204, 404]) + 834 return res.status_code == 204 + 835 + 836 + 837def disconnect_map_to_beg(gw_session: GatewaySession, mapping_id: str, + 838 beg_ids: list) -> bool: + 839 ''' + 840 Disconnects Mapping with ID `mapping_id` from the Backend Groups + 841 with IDs in `beg_ids`.\n Returns True if the operation was successful + 842 and False if one of the provided IDs was not found. + 843 ''' + 844 data = { + 845 "data": [] + 846 } + 847 for beg_id in beg_ids: + 848 group = { + 849 "type": 'back-end-group', + 850 "id": beg_id + 851 } + 852 data['data'].append(group) + 853 map_id = mapping_id + 854 path = f'/configuration/mappings/{map_id}/relationships/back-end-groups' + 855 res = delete(gw_session, path, data, [204, 404]) + 856 return res.status_code == 204 + 857 + 858 + 859def get_mapping_deny_rule_group(gw_session: GatewaySession, mapping_id: str, + 860 denyrule_group_shortname: str) -> dict: + 861 ''' + 862 Returns a dictionary object describing the deny rule group in the + 863 specified Mapping, or None if the mapping or shortname specified were not + 864 found. + 865 ''' + 866 path = f'/configuration/mappings/{mapping_id}/deny-rule-groups/{denyrule_group_shortname}' + 867 res = get(gw_session, path, exp_code=[200, 404]) + 868 return res.json().get('data') + 869 + 870 + 871def update_mapping_deny_rule_group(gw_session: GatewaySession, mapping_id: str, + 872 denyrule_group_shortname: str, + 873 attributes: dict) -> bool: + 874 ''' + 875 Updates the settings for a deny rule group within a specified mapping. + 876 Returns True if successful, and False if if the mapping or shortname + 877 specified were not found. + 878 ''' + 879 path = f'/configuration/mappings/{mapping_id}/deny-rule-groups/{denyrule_group_shortname}' + 880 data = { + 881 "data": { + 882 "type": "mapping-deny-rule-group", + 883 "attributes": attributes + 884 } + 885 } + 886 res = patch(gw_session, path, data, exp_code=[200, 404]) + 887 return res.status_code == 200 + 888 + 889 + 890def get_mapping_deny_rule(gw_session: GatewaySession, mapping_id: str, + 891 denyrule_shortname: str) -> dict: + 892 ''' + 893 Returns a dictionary object describing the deny rule in the specified + 894 Mapping, or None if the mapping or shortname specified were not found. + 895 ''' + 896 path = f'/configuration/mappings/{mapping_id}/deny-rules/{denyrule_shortname}' + 897 res = get(gw_session, path, exp_code=[200, 404]) + 898 return res.json().get("data") + 899 + 900 + 901def update_mapping_deny_rule(gw_session: GatewaySession, mapping_id: str, + 902 denyrule_shortname: str, attributes: dict) -> bool: + 903 ''' + 904 Updates the settings for a deny rule within a specified mapping. Returns + 905 True if successful, and False if if the mapping or shortname specified + 906 were not found. + 907 ''' + 908 path = f'/configuration/mappings/{mapping_id}/deny-rules/{denyrule_shortname}' + 909 data = { + 910 "data": { + 911 "type": "mapping-deny-rule", + 912 "attributes": attributes + 913 } + 914 } + 915 res = patch(gw_session, path, data, exp_code=[200, 404]) + 916 return res.status_code == 200 + 917 918 - 919 path = '/configuration/deny-rule-groups' - 920 res = get(gw_session, path, exp_code=200) - 921 return res.json().get("data") - 922 + 919def get_deny_rule_groups(gw_session: GatewaySession) -> dict: + 920 ''' + 921 Returns a list of all deny rule groups on the Airlock Host. + 922 ''' 923 - 924def get_deny_rule_group(gw_session: GatewaySession, short_name: str) -> dict: - 925 ''' - 926 Returns a dictionary object describing the specified deny rule group, - 927 or None if it does not exist. - 928 ''' - 929 - 930 path = f'/configuration/deny-rule-groups/{short_name}' - 931 res = get(gw_session, path, exp_code=[200, 404]) - 932 return res.json().get("data") - 933 + 924 path = '/configuration/deny-rule-groups' + 925 res = get(gw_session, path, exp_code=200) + 926 return res.json().get("data") + 927 + 928 + 929def get_deny_rule_group(gw_session: GatewaySession, short_name: str) -> dict: + 930 ''' + 931 Returns a dictionary object describing the specified deny rule group, + 932 or None if it does not exist. + 933 ''' 934 - 935def get_deny_rules(gw_session: GatewaySession) -> list: - 936 ''' - 937 Returns a list of all deny-rules on the Airlock Host. - 938 ''' + 935 path = f'/configuration/deny-rule-groups/{short_name}' + 936 res = get(gw_session, path, exp_code=[200, 404]) + 937 return res.json().get("data") + 938 939 - 940 path = '/configuration/deny-rules' - 941 res = get(gw_session, path, exp_code=200) - 942 return res.json().get("data") - 943 + 940def get_deny_rules(gw_session: GatewaySession) -> list: + 941 ''' + 942 Returns a list of all deny-rules on the Airlock Host. + 943 ''' 944 - 945def get_deny_rule(gw_session: GatewaySession, short_name: str) -> dict: - 946 ''' - 947 Returns a dictionary object describing the specified deny-rule, or None - 948 if it does not exist. - 949 ''' - 950 path = f'/configuration/deny-rules/{short_name}' - 951 res = get(gw_session, path, exp_code=[200, 404]) - 952 return res.json().get("data") - 953 - 954 - 955def load_config(gw_session: GatewaySession, config_id: int, - 956 host_name: str = None) -> bool: - 957 ''' - 958 Loads the configuration with ID `config_id` on the Airlock Host.\n - 959 Returns True if the operation was successful and False if no configuration - 960 with ID `config_id` was found. - 961 ''' - 962 data = {"hostname": host_name or gw_session.host_name} - 963 path = f"/configuration/configurations/{config_id}/load" - 964 res = post(gw_session, path, data, [204, 404]) - 965 return res.status_code == 204 - 966 - 967 - 968def load_empty_config(gw_session: GatewaySession, host_name: str = None): - 969 ''' - 970 Loads the empty configuration on the Airlock Host. - 971 ''' - 972 data = {"hostname": host_name or gw_session.host_name} - 973 path = "/configuration/configurations/load-empty-config" - 974 post(gw_session, path, data, 204) - 975 - 976 - 977def load_active_config(gw_session: GatewaySession): - 978 ''' - 979 Loads the currently active configuration on the Airlock Host. - 980 ''' - 981 post(gw_session, '/configuration/configurations/load-active', None, 204) - 982 - 983 - 984def load_initial_config(gw_session: GatewaySession): - 985 ''' - 986 Loads the initial configuration on the Airlock Host. - 987 ''' - 988 res = get(gw_session, '/configuration/configurations', exp_code=200) - 989 data = res.json()['data'] - 990 init_cfg_id = [x['id'] for x in data - 991 if x['attributes']['configType'] == 'INITIAL'][0] - 992 path = f'/configuration/configurations/{init_cfg_id}/load' - 993 post(gw_session, path, None, 204) - 994 - 995 - 996def _get_hostname_from_config_zip(cfg_zip: str): - 997 ''' - 998 Returns the name of the Airlock Host from the config - 999 zip file located at `cfg_zip`. -1000 ''' -1001 host_name = None -1002 with zipfile.ZipFile(cfg_zip) as zip_file: -1003 with zip_file.open('alec_full.xml') as config_xml: -1004 doc = ET.parse(config_xml) -1005 host_names = [n.text for n in doc.findall("./Nodes/*/HostName")] -1006 if host_names: -1007 host_name = host_names[0] -1008 return host_name -1009 -1010 -1011def import_config(gw_session: GatewaySession, cfg_zip: str): -1012 ''' -1013 Imports the configuration zip file located at -1014 `cfg_zip` to the Airlock Host. -1015 ''' -1016 with open(cfg_zip, 'rb') as file: -1017 cfg_host_name = _get_hostname_from_config_zip(cfg_zip) -1018 load_empty_config(gw_session, cfg_host_name) -1019 path = "/configuration/configurations/import/" -1020 req_raw(gw_session, "PUT", path, "application/zip", file, 200) -1021 -1022 -1023def _export_current_config_data(gw_session: GatewaySession): -1024 ''' -1025 Returns a zip file that describes the currently active configuration -1026 on Airlock Host. -1027 ''' -1028 path = '/configuration/configurations/export' -1029 res = get(gw_session, path, exp_code=200) -1030 return res.content -1031 -1032 -1033def export_current_config_file(gw_session: GatewaySession, cfg_zip: str): -1034 ''' -1035 Exports the currently active configuration to a -1036 zip file located at `cfg_zip`. -1037 ''' -1038 data = _export_current_config_data(gw_session) -1039 with open(cfg_zip, 'wb') as file: -1040 file.write(data) -1041 -1042 -1043def get_error_page_settings(gw_session: GatewaySession) -> dict: -1044 ''' -1045 Returns a dictionary object describing the current error page settings. -1046 ''' -1047 path = '/configuration/error-pages' -1048 res = get(gw_session, path, exp_code=200) -1049 return res.json().get('data') -1050 -1051 -1052def set_error_page_settings(gw_session: GatewaySession, attributes: dict): -1053 ''' -1054 Updates the error page settings with the given attributes. -1055 ''' -1056 path = '/configuration/error-pages' -1057 data = { -1058 "data": { -1059 "type": "error-pages", -1060 "attributes": attributes -1061 } -1062 } -1063 patch(gw_session, path, data, exp_code=200) -1064 -1065 -1066def get_error_pages(gw_session: GatewaySession) -> Union[bytes, None]: -1067 ''' -1068 Returns a zip file containing the error pages -1069 ''' -1070 path = '/configuration/error-pages/content' -1071 res = get(gw_session, path, exp_code=[200, 404]) -1072 if res.status_code == 404: -1073 return None -1074 return res.content -1075 -1076 -1077def set_error_pages(gw_session: GatewaySession, error_page_zip: str): -1078 ''' -1079 Imports the error page zip-file located at `error_page_zip`. -1080 ''' -1081 with open(error_page_zip, 'rb') as file: -1082 path = "/configuration/error-pages/content" -1083 req_raw(gw_session, "PUT", path, "application/zip", file, 200) -1084 -1085 -1086def delete_error_pages(gw_session: GatewaySession): -1087 ''' -1088 Remove the custom error pages. -1089 ''' -1090 path = '/configuration/error-pages/content' -1091 delete(gw_session, path, exp_code=200) -1092 -1093 -1094def get_default_error_pages(gw_session: GatewaySession) -> bytes: -1095 ''' -1096 Returns a zip file containing the default error pages. -1097 ''' -1098 path = '/configuration/error-pages/content/default' -1099 res = get(gw_session, path, exp_code=200) -1100 return res.content -1101 -1102 -1103def get_expert_settings(gw_session: GatewaySession) -> dict: -1104 ''' -1105 Returns a dict containing the global expert settings for the Gateway as well as for Apache -1106 ''' -1107 path = '/configuration/expert-settings' -1108 res = get(gw_session, path, exp_code=200) -1109 return res.json().get('data') -1110 -1111 -1112def set_expert_settings(gw_session: GatewaySession, attributes: dict) -> None: -1113 ''' -1114 Updates the global expert settings with the given attributes. -1115 ''' -1116 path = '/configuration/expert-settings' -1117 data = { -1118 "data": { -1119 "type": 'expert-settings', -1120 "attributes": attributes -1121 } -1122 } -1123 patch(gw_session, path, data, exp_code=200) + 945 path = '/configuration/deny-rules' + 946 res = get(gw_session, path, exp_code=200) + 947 return res.json().get("data") + 948 + 949 + 950def get_deny_rule(gw_session: GatewaySession, short_name: str) -> dict: + 951 ''' + 952 Returns a dictionary object describing the specified deny-rule, or None + 953 if it does not exist. + 954 ''' + 955 path = f'/configuration/deny-rules/{short_name}' + 956 res = get(gw_session, path, exp_code=[200, 404]) + 957 return res.json().get("data") + 958 + 959 + 960def load_config(gw_session: GatewaySession, config_id: int, + 961 host_name: str = None) -> bool: + 962 ''' + 963 Loads the configuration with ID `config_id` on the Airlock Host.\n + 964 Returns True if the operation was successful and False if no configuration + 965 with ID `config_id` was found. + 966 ''' + 967 data = {"hostname": host_name or gw_session.host_name} + 968 path = f"/configuration/configurations/{config_id}/load" + 969 res = post(gw_session, path, data, [204, 404]) + 970 return res.status_code == 204 + 971 + 972 + 973def load_empty_config(gw_session: GatewaySession, host_name: str = None): + 974 ''' + 975 Loads the empty configuration on the Airlock Host. + 976 ''' + 977 data = {"hostname": host_name or gw_session.host_name} + 978 path = "/configuration/configurations/load-empty-config" + 979 post(gw_session, path, data, 204) + 980 + 981 + 982def load_active_config(gw_session: GatewaySession): + 983 ''' + 984 Loads the currently active configuration on the Airlock Host. + 985 ''' + 986 post(gw_session, '/configuration/configurations/load-active', None, 204) + 987 + 988 + 989def load_initial_config(gw_session: GatewaySession): + 990 ''' + 991 Loads the initial configuration on the Airlock Host. + 992 ''' + 993 res = get(gw_session, '/configuration/configurations', exp_code=200) + 994 data = res.json()['data'] + 995 init_cfg_id = [x['id'] for x in data + 996 if x['attributes']['configType'] == 'INITIAL'][0] + 997 path = f'/configuration/configurations/{init_cfg_id}/load' + 998 post(gw_session, path, None, 204) + 999 +1000 +1001def _get_hostname_from_config_zip(cfg_zip: str): +1002 ''' +1003 Returns the name of the Airlock Host from the config +1004 zip file located at `cfg_zip`. +1005 ''' +1006 host_name = None +1007 with zipfile.ZipFile(cfg_zip) as zip_file: +1008 with zip_file.open('alec_full.xml') as config_xml: +1009 doc = ET.parse(config_xml) +1010 host_names = [n.text for n in doc.findall("./Nodes/*/HostName")] +1011 if host_names: +1012 host_name = host_names[0] +1013 return host_name +1014 +1015 +1016def import_config(gw_session: GatewaySession, cfg_zip: str): +1017 ''' +1018 Imports the configuration zip file located at +1019 `cfg_zip` to the Airlock Host. +1020 ''' +1021 with open(cfg_zip, 'rb') as file: +1022 cfg_host_name = _get_hostname_from_config_zip(cfg_zip) +1023 load_empty_config(gw_session, cfg_host_name) +1024 path = "/configuration/configurations/import/" +1025 req_raw(gw_session, "PUT", path, "application/zip", file, 200) +1026 +1027 +1028def _export_current_config_data(gw_session: GatewaySession): +1029 ''' +1030 Returns a zip file that describes the currently active configuration +1031 on Airlock Host. +1032 ''' +1033 path = '/configuration/configurations/export' +1034 res = get(gw_session, path, exp_code=200) +1035 return res.content +1036 +1037 +1038def export_current_config_file(gw_session: GatewaySession, cfg_zip: str): +1039 ''' +1040 Exports the currently active configuration to a +1041 zip file located at `cfg_zip`. +1042 ''' +1043 data = _export_current_config_data(gw_session) +1044 with open(cfg_zip, 'wb') as file: +1045 file.write(data) +1046 +1047 +1048def get_error_page_settings(gw_session: GatewaySession) -> dict: +1049 ''' +1050 Returns a dictionary object describing the current error page settings. +1051 ''' +1052 path = '/configuration/error-pages' +1053 res = get(gw_session, path, exp_code=200) +1054 return res.json().get('data') +1055 +1056 +1057def set_error_page_settings(gw_session: GatewaySession, attributes: dict): +1058 ''' +1059 Updates the error page settings with the given attributes. +1060 ''' +1061 path = '/configuration/error-pages' +1062 data = { +1063 "data": { +1064 "type": "error-pages", +1065 "attributes": attributes +1066 } +1067 } +1068 patch(gw_session, path, data, exp_code=200) +1069 +1070 +1071def get_error_pages(gw_session: GatewaySession) -> Union[bytes, None]: +1072 ''' +1073 Returns a zip file containing the error pages +1074 ''' +1075 path = '/configuration/error-pages/content' +1076 res = get(gw_session, path, exp_code=[200, 404]) +1077 if res.status_code == 404: +1078 return None +1079 return res.content +1080 +1081 +1082def set_error_pages(gw_session: GatewaySession, error_page_zip: str): +1083 ''' +1084 Imports the error page zip-file located at `error_page_zip`. +1085 ''' +1086 with open(error_page_zip, 'rb') as file: +1087 path = "/configuration/error-pages/content" +1088 req_raw(gw_session, "PUT", path, "application/zip", file, 200) +1089 +1090 +1091def delete_error_pages(gw_session: GatewaySession): +1092 ''' +1093 Remove the custom error pages. +1094 ''' +1095 path = '/configuration/error-pages/content' +1096 delete(gw_session, path, exp_code=200) +1097 +1098 +1099def get_default_error_pages(gw_session: GatewaySession) -> bytes: +1100 ''' +1101 Returns a zip file containing the default error pages. +1102 ''' +1103 path = '/configuration/error-pages/content/default' +1104 res = get(gw_session, path, exp_code=200) +1105 return res.content +1106 +1107 +1108def get_expert_settings(gw_session: GatewaySession) -> dict: +1109 ''' +1110 Returns a dict containing the global expert settings for the Gateway as well as for Apache +1111 ''' +1112 path = '/configuration/expert-settings' +1113 res = get(gw_session, path, exp_code=200) +1114 return res.json().get('data') +1115 +1116 +1117def set_expert_settings(gw_session: GatewaySession, attributes: dict) -> None: +1118 ''' +1119 Updates the global expert settings with the given attributes. +1120 ''' +1121 path = '/configuration/expert-settings' +1122 data = { +1123 "data": { +1124 "type": 'expert-settings', +1125 "attributes": attributes +1126 } +1127 } +1128 patch(gw_session, path, data, exp_code=200) @@ -2660,7 +2665,12 @@

Inherited Members
517 ''' 518 path = f'/configuration/mappings?filter=name=={name}' 519 res = get(gw_session, path, exp_code=200) -520 return res.json().get('data') +520 +521 candidate_list = res.json().get('data') +522 if len(candidate_list) == 1: +523 return candidate_list[0] +524 else: +525 return {} @@ -2682,16 +2692,16 @@
Inherited Members
-
523def get_all_mapping_names(gw_session: GatewaySession) -> list:
-524    '''
-525    Returns a sorted list of all mapping names on the Airlock Host.
-526    '''
-527    mappings = get_all_mappings(gw_session)
-528    mapping_names = []
-529    for mapping in mappings:
-530        mapping_name = mapping["attributes"]["name"]
-531        mapping_names.append(mapping_name)
-532    return sorted(mapping_names)
+            
528def get_all_mapping_names(gw_session: GatewaySession) -> list:
+529    '''
+530    Returns a sorted list of all mapping names on the Airlock Host.
+531    '''
+532    mappings = get_all_mappings(gw_session)
+533    mapping_names = []
+534    for mapping in mappings:
+535        mapping_name = mapping["attributes"]["name"]
+536        mapping_names.append(mapping_name)
+537    return sorted(mapping_names)
 
@@ -2711,22 +2721,22 @@
Inherited Members
-
535def import_mappings_from_xml(gw_session, mappings_xmls: list):
-536    '''
-537    Adds all mappings specified in the list of dictionary objects
-538    representing XML files stored in  `mappings_xmls` on the
-539    Airlock Host. If a mapping with the same name already exists,
-540    it will be overwritten.
-541    '''
-542    for mapping_xml in mappings_xmls:
-543        mapping_zip = BytesIO()
-544        with ZipFile(mapping_zip, mode="w") as zip_file:
-545            zip_file.writestr("alec_table.xml", mapping_xml)
-546
-547        mapping_zip.seek(0)
-548
-549        req_raw(gw_session, "put", "/configuration/mappings/import",
-550                "application/zip", mapping_zip.read(), 200)
+            
540def import_mappings_from_xml(gw_session, mappings_xmls: list):
+541    '''
+542    Adds all mappings specified in the list of dictionary objects
+543    representing XML files stored in  `mappings_xmls` on the
+544    Airlock Host. If a mapping with the same name already exists,
+545    it will be overwritten.
+546    '''
+547    for mapping_xml in mappings_xmls:
+548        mapping_zip = BytesIO()
+549        with ZipFile(mapping_zip, mode="w") as zip_file:
+550            zip_file.writestr("alec_table.xml", mapping_xml)
+551
+552        mapping_zip.seek(0)
+553
+554        req_raw(gw_session, "put", "/configuration/mappings/import",
+555                "application/zip", mapping_zip.read(), 200)
 
@@ -2749,33 +2759,33 @@
Inherited Members
-
553def export_mappings(gw_session: GatewaySession,
-554                    mapping_ids: list = None) -> list:
-555    '''
-556    Returns a list of the XML files describing the mappings with IDs
-557    contained in the `mapping_ids` list.\n
-558    `mapping_ids` must be a list of strings. If it is omitted, all mappings
-559    are returned. \n
-560    If one or more of the mappings IDs is not found, it is ignored.
-561    '''
-562    if mapping_ids is None:
-563        mapping_ids = [data["id"] for data in get_all_mappings(gw_session)]
-564
-565    mapping_xmls = []
-566    for mapping_id in mapping_ids:
-567        gw_session.add_headers({"Accept": "application/zip"})
-568        path = f'/configuration/mappings/{mapping_id}/export'
-569        res = get(gw_session, path, exp_code=[200, 404])
-570        if res.status_code == 200:
-571            with ZipFile(BytesIO(res.content)) as zip_file:
-572                with zip_file.open("alec_table.xml", "r") as mapping_xml:
-573                    mapping_xmls.append(mapping_xml.read())
-574        else:
-575            logging.info("Mapping with ID %s was not found on Airlock Host",
-576                         mapping_id)
-577
-578    gw_session.add_headers({"Accept": "application/json"})
-579    return mapping_xmls
+            
558def export_mappings(gw_session: GatewaySession,
+559                    mapping_ids: list = None) -> list:
+560    '''
+561    Returns a list of the XML files describing the mappings with IDs
+562    contained in the `mapping_ids` list.\n
+563    `mapping_ids` must be a list of strings. If it is omitted, all mappings
+564    are returned. \n
+565    If one or more of the mappings IDs is not found, it is ignored.
+566    '''
+567    if mapping_ids is None:
+568        mapping_ids = [data["id"] for data in get_all_mappings(gw_session)]
+569
+570    mapping_xmls = []
+571    for mapping_id in mapping_ids:
+572        gw_session.add_headers({"Accept": "application/zip"})
+573        path = f'/configuration/mappings/{mapping_id}/export'
+574        res = get(gw_session, path, exp_code=[200, 404])
+575        if res.status_code == 200:
+576            with ZipFile(BytesIO(res.content)) as zip_file:
+577                with zip_file.open("alec_table.xml", "r") as mapping_xml:
+578                    mapping_xmls.append(mapping_xml.read())
+579        else:
+580            logging.info("Mapping with ID %s was not found on Airlock Host",
+581                         mapping_id)
+582
+583    gw_session.add_headers({"Accept": "application/json"})
+584    return mapping_xmls
 
@@ -2801,15 +2811,15 @@
Inherited Members
-
582def delete_mapping_by_id(gw_session: GatewaySession, mapping_id: str) -> bool:
-583    '''
-584    Deletes the Mapping with the selected ID.\n
-585    Returns True if deletion was successful and False if no mapping with ID
-586    `mapping_id` was found..
-587    '''
-588    path = f"/configuration/mappings/{mapping_id}"
-589    res = delete(gw_session, path, exp_code=[204, 404])
-590    return res.status_code == 204
+            
587def delete_mapping_by_id(gw_session: GatewaySession, mapping_id: str) -> bool:
+588    '''
+589    Deletes the Mapping with the selected ID.\n
+590    Returns True if deletion was successful and False if no mapping with ID
+591    `mapping_id` was found..
+592    '''
+593    path = f"/configuration/mappings/{mapping_id}"
+594    res = delete(gw_session, path, exp_code=[204, 404])
+595    return res.status_code == 204
 
@@ -2832,13 +2842,13 @@
Inherited Members
-
593def get_templates(gw_session: GatewaySession) -> dict:
-594    '''
-595    Returns a dictionary object mapping every mapping template name to its ID.
-596    '''
-597    res = get(gw_session, '/configuration/templates/mappings', 200)
-598    data = res.json()['data']
-599    return {x['attributes']['name']: x['id'] for x in data}
+            
598def get_templates(gw_session: GatewaySession) -> dict:
+599    '''
+600    Returns a dictionary object mapping every mapping template name to its ID.
+601    '''
+602    res = get(gw_session, '/configuration/templates/mappings', 200)
+603    data = res.json()['data']
+604    return {x['attributes']['name']: x['id'] for x in data}
 
@@ -2858,23 +2868,23 @@
Inherited Members
-
602def update_mapping(gw_session: GatewaySession, mapping_id: str,
-603                   attributes: dict) -> bool:
-604    '''
-605    Updates the mapping with ID `mapping_id` with the given `attributes`,
-606    for example name or entry path.\n
-607    Returns True if update was successful and False if no mapping with ID
-608    `mapping_id` was found.
-609    '''
-610    data = {
-611        "data": {
-612            "type": 'mapping',
-613            "attributes": attributes
-614        }
-615    }
-616    path = f'/configuration/mappings/{mapping_id}'
-617    res = patch(gw_session, path, data, [200, 404])
-618    return res.status_code == 200
+            
607def update_mapping(gw_session: GatewaySession, mapping_id: str,
+608                   attributes: dict) -> bool:
+609    '''
+610    Updates the mapping with ID `mapping_id` with the given `attributes`,
+611    for example name or entry path.\n
+612    Returns True if update was successful and False if no mapping with ID
+613    `mapping_id` was found.
+614    '''
+615    data = {
+616        "data": {
+617            "type": 'mapping',
+618            "attributes": attributes
+619        }
+620    }
+621    path = f'/configuration/mappings/{mapping_id}'
+622    res = patch(gw_session, path, data, [200, 404])
+623    return res.status_code == 200
 
@@ -2898,32 +2908,32 @@
Inherited Members
-
621def add_mapping(gw_session: GatewaySession, name: str,
-622                template: str = 'New_Mapping', entry_path: str = '/') -> str:
-623    '''
-624    Adds a new mapping to the Airlock host, with the specified
-625    `name` and `entry_path`.\n Optionally, a template can
-626    be used for the new mapping.\n
-627    Returns the mapping ID of the new mapping.
-628    '''
-629    templates = get_templates(gw_session)
-630    data = {
-631        "data": {
-632            "type": "create-mapping-from-template",
-633            "attributes": {
-634                "id": templates[template]
-635            }
-636        }
-637    }
-638    path = '/configuration/mappings/create-from-template'
-639    res = post(gw_session, path, data, 201)
-640    mapping_id = res.json()['data']['id']
-641    attributes = {
-642        "name": name,
-643        "entryPath": {"value": entry_path}
-644    }
-645    update_mapping(gw_session, mapping_id, attributes)
-646    return mapping_id
+            
626def add_mapping(gw_session: GatewaySession, name: str,
+627                template: str = 'New_Mapping', entry_path: str = '/') -> str:
+628    '''
+629    Adds a new mapping to the Airlock host, with the specified
+630    `name` and `entry_path`.\n Optionally, a template can
+631    be used for the new mapping.\n
+632    Returns the mapping ID of the new mapping.
+633    '''
+634    templates = get_templates(gw_session)
+635    data = {
+636        "data": {
+637            "type": "create-mapping-from-template",
+638            "attributes": {
+639                "id": templates[template]
+640            }
+641        }
+642    }
+643    path = '/configuration/mappings/create-from-template'
+644    res = post(gw_session, path, data, 201)
+645    mapping_id = res.json()['data']['id']
+646    attributes = {
+647        "name": name,
+648        "entryPath": {"value": entry_path}
+649    }
+650    update_mapping(gw_session, mapping_id, attributes)
+651    return mapping_id
 
@@ -2948,32 +2958,32 @@
Inherited Members
-
649def set_source_mapping(gw_session: GatewaySession, mapping_id: str,
-650                       src_mapping_id: str) -> bool:
-651    '''
-652    Sets the source mapping of mapping with ID `mapping_id`
-653    to the mapping with ID `src_mapping_id`. \n
-654    Returns True if the operation was successful and False if
-655    no mapping with ID `mapping_id` was found.
-656    '''
-657    data = {
-658        "data": {
-659            "type": 'mapping',
-660            "id": src_mapping_id
-661        }
-662    }
-663    path = f'/configuration/mappings/{mapping_id}/relationships/template'
-664    res = patch(gw_session, path, data, [204, 404])
-665    if res.status_code == 404:
-666        return False
-667
-668    lock_cfg = {
-669        "enabled": True,
-670        "labels": True,
-671        "entryPath": {"settings": True}
-672    }
-673
-674    return update_mapping(gw_session, mapping_id, {"locking": lock_cfg})
+            
654def set_source_mapping(gw_session: GatewaySession, mapping_id: str,
+655                       src_mapping_id: str) -> bool:
+656    '''
+657    Sets the source mapping of mapping with ID `mapping_id`
+658    to the mapping with ID `src_mapping_id`. \n
+659    Returns True if the operation was successful and False if
+660    no mapping with ID `mapping_id` was found.
+661    '''
+662    data = {
+663        "data": {
+664            "type": 'mapping',
+665            "id": src_mapping_id
+666        }
+667    }
+668    path = f'/configuration/mappings/{mapping_id}/relationships/template'
+669    res = patch(gw_session, path, data, [204, 404])
+670    if res.status_code == 404:
+671        return False
+672
+673    lock_cfg = {
+674        "enabled": True,
+675        "labels": True,
+676        "entryPath": {"settings": True}
+677    }
+678
+679    return update_mapping(gw_session, mapping_id, {"locking": lock_cfg})
 
@@ -2997,17 +3007,17 @@
Inherited Members
-
677def pull_from_source_mapping(gw_session: GatewaySession,
-678                             mapping_id: str) -> bool:
-679    '''
-680    Performs a pull from the source mapping on the mapping with
-681    ID `mapping_id`.\n
-682    Returns True if the pull was succesfull and False if no mapping with ID
-683    `mapping_id` was found.
-684    '''
-685    path = f'/configuration/mappings/{mapping_id}/pull-from-source-mapping'
-686    res = post(gw_session, path, exp_code=[200, 404])
-687    return res.status_code == 200
+            
682def pull_from_source_mapping(gw_session: GatewaySession,
+683                             mapping_id: str) -> bool:
+684    '''
+685    Performs a pull from the source mapping on the mapping with
+686    ID `mapping_id`.\n
+687    Returns True if the pull was succesfull and False if no mapping with ID
+688    `mapping_id` was found.
+689    '''
+690    path = f'/configuration/mappings/{mapping_id}/pull-from-source-mapping'
+691    res = post(gw_session, path, exp_code=[200, 404])
+692    return res.status_code == 200
 
@@ -3031,16 +3041,16 @@
Inherited Members
-
690def gen_backend_host(protocol: str, name: str, port: int) -> dict:
-691    '''
-692    Returns a dictionary object representing a new Backend Host.
-693    '''
-694    host_data = {
-695        "protocol": protocol,
-696        "hostName": name,
-697        "port": port
-698    }
-699    return host_data
+            
695def gen_backend_host(protocol: str, name: str, port: int) -> dict:
+696    '''
+697    Returns a dictionary object representing a new Backend Host.
+698    '''
+699    host_data = {
+700        "protocol": protocol,
+701        "hostName": name,
+702        "port": port
+703    }
+704    return host_data
 
@@ -3060,24 +3070,24 @@
Inherited Members
-
702def add_backend_group(gw_session: GatewaySession, beg_name: str,
-703                      be_hosts: list) -> str:
-704    '''
-705    Adds a new Backend Group with the name `beg_name` and the hosts
-706    contained in `be_hosts` to the Airlock Host.\n
-707    Returns the ID of the newly added Backend Group.
-708    '''
-709    beg_data = {
-710        "data": {
-711            "type": "back-end-group",
-712            "attributes": {
-713                "name": beg_name,
-714                "backendHosts": be_hosts
-715            }
-716        }
-717    }
-718    res = post(gw_session, "/configuration/back-end-groups", beg_data, 201)
-719    return res.json()['data']['id']
+            
707def add_backend_group(gw_session: GatewaySession, beg_name: str,
+708                      be_hosts: list) -> str:
+709    '''
+710    Adds a new Backend Group with the name `beg_name` and the hosts
+711    contained in `be_hosts` to the Airlock Host.\n
+712    Returns the ID of the newly added Backend Group.
+713    '''
+714    beg_data = {
+715        "data": {
+716            "type": "back-end-group",
+717            "attributes": {
+718                "name": beg_name,
+719                "backendHosts": be_hosts
+720            }
+721        }
+722    }
+723    res = post(gw_session, "/configuration/back-end-groups", beg_data, 201)
+724    return res.json()['data']['id']
 
@@ -3100,12 +3110,12 @@
Inherited Members
-
722def get_backend_groups(gw_session: GatewaySession) -> list:
-723    '''
-724    Returns a list containing all backend groups on the Airlock Host.
-725    '''
-726    res = get(gw_session, '/configuration/back-end-groups', exp_code=200)
-727    return res.json().get('data')
+            
727def get_backend_groups(gw_session: GatewaySession) -> list:
+728    '''
+729    Returns a list containing all backend groups on the Airlock Host.
+730    '''
+731    res = get(gw_session, '/configuration/back-end-groups', exp_code=200)
+732    return res.json().get('data')
 
@@ -3125,16 +3135,16 @@
Inherited Members
-
730def get_backend_group_by_id(gw_session: GatewaySession, beg_id: str) -> dict:
-731    '''
-732    Returns a dictionary object describing the backend group with ID
-733    `beg_id`, or None if no such group was found.
-734    '''
-735    path = f'/configuration/back-end-groups/{beg_id}'
-736    res = get(gw_session, path, exp_code=[200, 404])
-737    if res.status_code == 200:
-738        return res.json().get('data')
-739    return None
+            
735def get_backend_group_by_id(gw_session: GatewaySession, beg_id: str) -> dict:
+736    '''
+737    Returns a dictionary object describing the backend group with ID
+738    `beg_id`, or None if no such group was found.
+739    '''
+740    path = f'/configuration/back-end-groups/{beg_id}'
+741    res = get(gw_session, path, exp_code=[200, 404])
+742    if res.status_code == 200:
+743        return res.json().get('data')
+744    return None
 
@@ -3155,24 +3165,24 @@
Inherited Members
-
742def update_backend_group_by_id(gw_session: GatewaySession, beg_id: str,
-743                               attributes: dict) -> bool:
-744    '''
-745    Updates the Backend Group with ID `beg_id` with the given attributes,
-746    for example hostname or port. \n
-747    Returns True if the update was succesfull and False if no Backend Group
-748    with ID `beg_id` was found.
-749    '''
-750    beg_data = {
-751        "data": {
-752            "type": "back-end-group",
-753            "id": beg_id,
-754            "attributes": attributes
-755        }
-756    }
-757    path = f"/configuration/back-end-groups/{beg_id}"
-758    res = patch(gw_session, path, beg_data, [200, 404])
-759    return res.status_code == 200
+            
747def update_backend_group_by_id(gw_session: GatewaySession, beg_id: str,
+748                               attributes: dict) -> bool:
+749    '''
+750    Updates the Backend Group with ID `beg_id` with the given attributes,
+751    for example hostname or port. \n
+752    Returns True if the update was succesfull and False if no Backend Group
+753    with ID `beg_id` was found.
+754    '''
+755    beg_data = {
+756        "data": {
+757            "type": "back-end-group",
+758            "id": beg_id,
+759            "attributes": attributes
+760        }
+761    }
+762    path = f"/configuration/back-end-groups/{beg_id}"
+763    res = patch(gw_session, path, beg_data, [200, 404])
+764    return res.status_code == 200
 
@@ -3196,16 +3206,16 @@
Inherited Members
-
762def delete_backend_group_by_id(gw_session: GatewaySession,
-763                               beg_id: str) -> bool:
-764    '''
-765    Deletes the Backend Group with ID `beg_id` from the Airlock Host.\n
-766    Returns True if deletion was successful and False if no Backend
-767    Group with ID `beg_id` was found.
-768    '''
-769    path = f"/configuration/back-end-groups/{beg_id}"
-770    res = delete(gw_session, path, exp_code=[204, 404])
-771    return res.status_code == 204
+            
767def delete_backend_group_by_id(gw_session: GatewaySession,
+768                               beg_id: str) -> bool:
+769    '''
+770    Deletes the Backend Group with ID `beg_id` from the Airlock Host.\n
+771    Returns True if deletion was successful and False if no Backend
+772    Group with ID `beg_id` was found.
+773    '''
+774    path = f"/configuration/back-end-groups/{beg_id}"
+775    res = delete(gw_session, path, exp_code=[204, 404])
+776    return res.status_code == 204
 
@@ -3228,22 +3238,22 @@
Inherited Members
-
774def connect_virtual_host_to_map(gw_session: GatewaySession, vh_id: str,
-775                                mapping_id: str) -> bool:
-776    '''
-777    Connects Virtual Host with id `vh_id` to the Mapping with ID
-778    `mapping_id`.\n Returns True if the operation was successful
-779    and False if one of the provided IDs was not found.
-780    '''
-781    data = {
-782        "data": [{
-783            "type": 'mapping',
-784            "id": mapping_id
-785        }]
-786    }
-787    path = f'/configuration/virtual-hosts/{vh_id}/relationships/mappings'
-788    res = patch(gw_session, path, data, [204, 404])
-789    return res.status_code == 204
+            
779def connect_virtual_host_to_map(gw_session: GatewaySession, vh_id: str,
+780                                mapping_id: str) -> bool:
+781    '''
+782    Connects Virtual Host with id `vh_id` to the Mapping with ID
+783    `mapping_id`.\n Returns True if the operation was successful
+784    and False if one of the provided IDs was not found.
+785    '''
+786    data = {
+787        "data": [{
+788            "type": 'mapping',
+789            "id": mapping_id
+790        }]
+791    }
+792    path = f'/configuration/virtual-hosts/{vh_id}/relationships/mappings'
+793    res = patch(gw_session, path, data, [204, 404])
+794    return res.status_code == 204
 
@@ -3266,27 +3276,27 @@
Inherited Members
-
792def connect_map_to_beg(gw_session: GatewaySession, mapping_id: str,
-793                       beg_ids: list) -> bool:
-794    '''
-795    Connects Mapping with ID `mapping_id` to the Backend Groups
-796    with IDs in `beg_ids`.\n
-797    Returns True if the operation was successful and False if one of
-798    the provided IDs was not found.
-799    '''
-800    data = {
-801        "data": []
-802    }
-803    for beg_id in beg_ids:
-804        group = {
-805            "type": 'back-end-group',
-806            "id": beg_id
-807        }
-808        data['data'].append(group)
-809    map_id = mapping_id
-810    path = f'/configuration/mappings/{map_id}/relationships/back-end-groups'
-811    res = patch(gw_session, path, data, [204, 404])
-812    return res.status_code == 204
+            
797def connect_map_to_beg(gw_session: GatewaySession, mapping_id: str,
+798                       beg_ids: list) -> bool:
+799    '''
+800    Connects Mapping with ID `mapping_id` to the Backend Groups
+801    with IDs in `beg_ids`.\n
+802    Returns True if the operation was successful and False if one of
+803    the provided IDs was not found.
+804    '''
+805    data = {
+806        "data": []
+807    }
+808    for beg_id in beg_ids:
+809        group = {
+810            "type": 'back-end-group',
+811            "id": beg_id
+812        }
+813        data['data'].append(group)
+814    map_id = mapping_id
+815    path = f'/configuration/mappings/{map_id}/relationships/back-end-groups'
+816    res = patch(gw_session, path, data, [204, 404])
+817    return res.status_code == 204
 
@@ -3310,22 +3320,22 @@
Inherited Members
-
815def disconnect_virtual_host_to_map(gw_session: GatewaySession, vh_id: str,
-816                                   mapping_id: str) -> bool:
-817    '''
-818    Disconnects Virtual Host with id `vh_id` to the Mapping with
-819    ID `mapping_id`.\n Returns True if the operation was successful
-820    and False if one of the provided IDs was not found.
-821    '''
-822    data = {
-823        "data": [{
-824            "type": 'mapping',
-825            "id": mapping_id
-826        }]
-827    }
-828    path = f'/configuration/virtual-hosts/{vh_id}/relationships/mappings'
-829    res = delete(gw_session, path, data, [204, 404])
-830    return res.status_code == 204
+            
820def disconnect_virtual_host_to_map(gw_session: GatewaySession, vh_id: str,
+821                                   mapping_id: str) -> bool:
+822    '''
+823    Disconnects Virtual Host with id `vh_id` to the Mapping with
+824    ID `mapping_id`.\n Returns True if the operation was successful
+825    and False if one of the provided IDs was not found.
+826    '''
+827    data = {
+828        "data": [{
+829            "type": 'mapping',
+830            "id": mapping_id
+831        }]
+832    }
+833    path = f'/configuration/virtual-hosts/{vh_id}/relationships/mappings'
+834    res = delete(gw_session, path, data, [204, 404])
+835    return res.status_code == 204
 
@@ -3348,26 +3358,26 @@
Inherited Members
-
833def disconnect_map_to_beg(gw_session: GatewaySession, mapping_id: str,
-834                          beg_ids: list) -> bool:
-835    '''
-836    Disconnects Mapping with ID `mapping_id` from the Backend Groups
-837    with IDs in `beg_ids`.\n Returns True if the operation was successful
-838    and False if one of the provided IDs was not found.
-839    '''
-840    data = {
-841        "data": []
-842    }
-843    for beg_id in beg_ids:
-844        group = {
-845            "type": 'back-end-group',
-846            "id": beg_id
-847        }
-848        data['data'].append(group)
-849    map_id = mapping_id
-850    path = f'/configuration/mappings/{map_id}/relationships/back-end-groups'
-851    res = delete(gw_session, path, data, [204, 404])
-852    return res.status_code == 204
+            
838def disconnect_map_to_beg(gw_session: GatewaySession, mapping_id: str,
+839                          beg_ids: list) -> bool:
+840    '''
+841    Disconnects Mapping with ID `mapping_id` from the Backend Groups
+842    with IDs in `beg_ids`.\n Returns True if the operation was successful
+843    and False if one of the provided IDs was not found.
+844    '''
+845    data = {
+846        "data": []
+847    }
+848    for beg_id in beg_ids:
+849        group = {
+850            "type": 'back-end-group',
+851            "id": beg_id
+852        }
+853        data['data'].append(group)
+854    map_id = mapping_id
+855    path = f'/configuration/mappings/{map_id}/relationships/back-end-groups'
+856    res = delete(gw_session, path, data, [204, 404])
+857    return res.status_code == 204
 
@@ -3390,16 +3400,16 @@
Inherited Members
-
855def get_mapping_deny_rule_group(gw_session: GatewaySession, mapping_id: str,
-856                                denyrule_group_shortname: str) -> dict:
-857    '''
-858    Returns a dictionary object describing the deny rule group in the
-859    specified Mapping, or None if the mapping or shortname specified were not
-860    found.
-861    '''
-862    path = f'/configuration/mappings/{mapping_id}/deny-rule-groups/{denyrule_group_shortname}'
-863    res = get(gw_session, path, exp_code=[200, 404])
-864    return res.json().get('data')
+            
860def get_mapping_deny_rule_group(gw_session: GatewaySession, mapping_id: str,
+861                                denyrule_group_shortname: str) -> dict:
+862    '''
+863    Returns a dictionary object describing the deny rule group in the
+864    specified Mapping, or None if the mapping or shortname specified were not
+865    found.
+866    '''
+867    path = f'/configuration/mappings/{mapping_id}/deny-rule-groups/{denyrule_group_shortname}'
+868    res = get(gw_session, path, exp_code=[200, 404])
+869    return res.json().get('data')
 
@@ -3421,23 +3431,23 @@
Inherited Members
-
867def update_mapping_deny_rule_group(gw_session: GatewaySession, mapping_id: str,
-868                                   denyrule_group_shortname: str,
-869                                   attributes: dict) -> bool:
-870    '''
-871    Updates the settings for a deny rule group within a specified mapping.
-872    Returns True if successful, and False if if the mapping or shortname
-873    specified were not found.
-874    '''
-875    path = f'/configuration/mappings/{mapping_id}/deny-rule-groups/{denyrule_group_shortname}'
-876    data = {
-877        "data": {
-878            "type": "mapping-deny-rule-group",
-879            "attributes": attributes
-880        }
-881    }
-882    res = patch(gw_session, path, data, exp_code=[200, 404])
-883    return res.status_code == 200
+            
872def update_mapping_deny_rule_group(gw_session: GatewaySession, mapping_id: str,
+873                                   denyrule_group_shortname: str,
+874                                   attributes: dict) -> bool:
+875    '''
+876    Updates the settings for a deny rule group within a specified mapping.
+877    Returns True if successful, and False if if the mapping or shortname
+878    specified were not found.
+879    '''
+880    path = f'/configuration/mappings/{mapping_id}/deny-rule-groups/{denyrule_group_shortname}'
+881    data = {
+882        "data": {
+883            "type": "mapping-deny-rule-group",
+884            "attributes": attributes
+885        }
+886    }
+887    res = patch(gw_session, path, data, exp_code=[200, 404])
+888    return res.status_code == 200
 
@@ -3459,15 +3469,15 @@
Inherited Members
-
886def get_mapping_deny_rule(gw_session: GatewaySession, mapping_id: str,
-887                          denyrule_shortname: str) -> dict:
-888    '''
-889    Returns a dictionary object describing the deny rule in the specified
-890    Mapping, or None if the mapping or shortname specified were not found.
-891    '''
-892    path = f'/configuration/mappings/{mapping_id}/deny-rules/{denyrule_shortname}'
-893    res = get(gw_session, path, exp_code=[200, 404])
-894    return res.json().get("data")
+            
891def get_mapping_deny_rule(gw_session: GatewaySession, mapping_id: str,
+892                          denyrule_shortname: str) -> dict:
+893    '''
+894    Returns a dictionary object describing the deny rule in the specified
+895    Mapping, or None if the mapping or shortname specified were not found.
+896    '''
+897    path = f'/configuration/mappings/{mapping_id}/deny-rules/{denyrule_shortname}'
+898    res = get(gw_session, path, exp_code=[200, 404])
+899    return res.json().get("data")
 
@@ -3488,22 +3498,22 @@
Inherited Members
-
897def update_mapping_deny_rule(gw_session: GatewaySession, mapping_id: str,
-898                             denyrule_shortname: str, attributes: dict) -> bool:
-899    '''
-900    Updates the settings for a deny rule within a specified mapping. Returns
-901    True if successful, and False if if the mapping or shortname specified
-902    were not found.
-903    '''
-904    path = f'/configuration/mappings/{mapping_id}/deny-rules/{denyrule_shortname}'
-905    data = {
-906        "data": {
-907            "type": "mapping-deny-rule",
-908            "attributes": attributes
-909        }
-910    }
-911    res = patch(gw_session, path, data, exp_code=[200, 404])
-912    return res.status_code == 200
+            
902def update_mapping_deny_rule(gw_session: GatewaySession, mapping_id: str,
+903                             denyrule_shortname: str, attributes: dict) -> bool:
+904    '''
+905    Updates the settings for a deny rule within a specified mapping. Returns
+906    True if successful, and False if if the mapping or shortname specified
+907    were not found.
+908    '''
+909    path = f'/configuration/mappings/{mapping_id}/deny-rules/{denyrule_shortname}'
+910    data = {
+911        "data": {
+912            "type": "mapping-deny-rule",
+913            "attributes": attributes
+914        }
+915    }
+916    res = patch(gw_session, path, data, exp_code=[200, 404])
+917    return res.status_code == 200
 
@@ -3525,14 +3535,14 @@
Inherited Members
-
915def get_deny_rule_groups(gw_session: GatewaySession) -> dict:
-916    '''
-917    Returns a list of all deny rule groups on the Airlock Host.
-918    '''
-919
-920    path = '/configuration/deny-rule-groups'
-921    res = get(gw_session, path, exp_code=200)
-922    return res.json().get("data")
+            
920def get_deny_rule_groups(gw_session: GatewaySession) -> dict:
+921    '''
+922    Returns a list of all deny rule groups on the Airlock Host.
+923    '''
+924
+925    path = '/configuration/deny-rule-groups'
+926    res = get(gw_session, path, exp_code=200)
+927    return res.json().get("data")
 
@@ -3552,15 +3562,15 @@
Inherited Members
-
925def get_deny_rule_group(gw_session: GatewaySession, short_name: str) -> dict:
-926    '''
-927    Returns a dictionary object describing the specified deny rule group,
-928    or None if it does not exist.
-929    '''
-930
-931    path = f'/configuration/deny-rule-groups/{short_name}'
-932    res = get(gw_session, path, exp_code=[200, 404])
-933    return res.json().get("data")
+            
930def get_deny_rule_group(gw_session: GatewaySession, short_name: str) -> dict:
+931    '''
+932    Returns a dictionary object describing the specified deny rule group,
+933    or None if it does not exist.
+934    '''
+935
+936    path = f'/configuration/deny-rule-groups/{short_name}'
+937    res = get(gw_session, path, exp_code=[200, 404])
+938    return res.json().get("data")
 
@@ -3581,14 +3591,14 @@
Inherited Members
-
936def get_deny_rules(gw_session: GatewaySession) -> list:
-937    '''
-938    Returns a list of all deny-rules on the Airlock Host.
-939    '''
-940
-941    path = '/configuration/deny-rules'
-942    res = get(gw_session, path, exp_code=200)
-943    return res.json().get("data")
+            
941def get_deny_rules(gw_session: GatewaySession) -> list:
+942    '''
+943    Returns a list of all deny-rules on the Airlock Host.
+944    '''
+945
+946    path = '/configuration/deny-rules'
+947    res = get(gw_session, path, exp_code=200)
+948    return res.json().get("data")
 
@@ -3608,14 +3618,14 @@
Inherited Members
-
946def get_deny_rule(gw_session: GatewaySession, short_name: str) -> dict:
-947    '''
-948    Returns a dictionary object describing the specified deny-rule, or None
-949    if it does not exist.
-950    '''
-951    path = f'/configuration/deny-rules/{short_name}'
-952    res = get(gw_session, path, exp_code=[200, 404])
-953    return res.json().get("data")
+            
951def get_deny_rule(gw_session: GatewaySession, short_name: str) -> dict:
+952    '''
+953    Returns a dictionary object describing the specified deny-rule, or None
+954    if it does not exist.
+955    '''
+956    path = f'/configuration/deny-rules/{short_name}'
+957    res = get(gw_session, path, exp_code=[200, 404])
+958    return res.json().get("data")
 
@@ -3636,17 +3646,17 @@
Inherited Members
-
956def load_config(gw_session: GatewaySession, config_id: int,
-957                host_name: str = None) -> bool:
-958    '''
-959    Loads the configuration with ID `config_id` on the Airlock Host.\n
-960    Returns True if the operation was successful and False if no configuration
-961    with ID `config_id` was found.
-962    '''
-963    data = {"hostname": host_name or gw_session.host_name}
-964    path = f"/configuration/configurations/{config_id}/load"
-965    res = post(gw_session, path, data, [204, 404])
-966    return res.status_code == 204
+            
961def load_config(gw_session: GatewaySession, config_id: int,
+962                host_name: str = None) -> bool:
+963    '''
+964    Loads the configuration with ID `config_id` on the Airlock Host.\n
+965    Returns True if the operation was successful and False if no configuration
+966    with ID `config_id` was found.
+967    '''
+968    data = {"hostname": host_name or gw_session.host_name}
+969    path = f"/configuration/configurations/{config_id}/load"
+970    res = post(gw_session, path, data, [204, 404])
+971    return res.status_code == 204
 
@@ -3669,13 +3679,13 @@
Inherited Members
-
969def load_empty_config(gw_session: GatewaySession, host_name: str = None):
-970    '''
-971    Loads the empty configuration on the Airlock Host.
-972    '''
-973    data = {"hostname": host_name or gw_session.host_name}
-974    path = "/configuration/configurations/load-empty-config"
-975    post(gw_session, path, data, 204)
+            
974def load_empty_config(gw_session: GatewaySession, host_name: str = None):
+975    '''
+976    Loads the empty configuration on the Airlock Host.
+977    '''
+978    data = {"hostname": host_name or gw_session.host_name}
+979    path = "/configuration/configurations/load-empty-config"
+980    post(gw_session, path, data, 204)
 
@@ -3695,11 +3705,11 @@
Inherited Members
-
978def load_active_config(gw_session: GatewaySession):
-979    '''
-980    Loads the currently active configuration on the Airlock Host.
-981    '''
-982    post(gw_session, '/configuration/configurations/load-active', None, 204)
+            
983def load_active_config(gw_session: GatewaySession):
+984    '''
+985    Loads the currently active configuration on the Airlock Host.
+986    '''
+987    post(gw_session, '/configuration/configurations/load-active', None, 204)
 
@@ -3719,16 +3729,16 @@
Inherited Members
-
985def load_initial_config(gw_session: GatewaySession):
-986    '''
-987    Loads the initial configuration on the Airlock Host.
-988    '''
-989    res = get(gw_session, '/configuration/configurations', exp_code=200)
-990    data = res.json()['data']
-991    init_cfg_id = [x['id'] for x in data
-992                   if x['attributes']['configType'] == 'INITIAL'][0]
-993    path = f'/configuration/configurations/{init_cfg_id}/load'
-994    post(gw_session, path, None, 204)
+            
990def load_initial_config(gw_session: GatewaySession):
+991    '''
+992    Loads the initial configuration on the Airlock Host.
+993    '''
+994    res = get(gw_session, '/configuration/configurations', exp_code=200)
+995    data = res.json()['data']
+996    init_cfg_id = [x['id'] for x in data
+997                   if x['attributes']['configType'] == 'INITIAL'][0]
+998    path = f'/configuration/configurations/{init_cfg_id}/load'
+999    post(gw_session, path, None, 204)
 
@@ -3748,16 +3758,16 @@
Inherited Members
-
1012def import_config(gw_session: GatewaySession, cfg_zip: str):
-1013    '''
-1014    Imports the configuration zip file located at
-1015    `cfg_zip` to the Airlock Host.
-1016    '''
-1017    with open(cfg_zip, 'rb') as file:
-1018        cfg_host_name = _get_hostname_from_config_zip(cfg_zip)
-1019        load_empty_config(gw_session, cfg_host_name)
-1020        path = "/configuration/configurations/import/"
-1021        req_raw(gw_session, "PUT", path, "application/zip", file, 200)
+            
1017def import_config(gw_session: GatewaySession, cfg_zip: str):
+1018    '''
+1019    Imports the configuration zip file located at
+1020    `cfg_zip` to the Airlock Host.
+1021    '''
+1022    with open(cfg_zip, 'rb') as file:
+1023        cfg_host_name = _get_hostname_from_config_zip(cfg_zip)
+1024        load_empty_config(gw_session, cfg_host_name)
+1025        path = "/configuration/configurations/import/"
+1026        req_raw(gw_session, "PUT", path, "application/zip", file, 200)
 
@@ -3778,14 +3788,14 @@
Inherited Members
-
1034def export_current_config_file(gw_session: GatewaySession, cfg_zip: str):
-1035    '''
-1036    Exports the currently active configuration to a
-1037    zip file located at `cfg_zip`.
-1038    '''
-1039    data = _export_current_config_data(gw_session)
-1040    with open(cfg_zip, 'wb') as file:
-1041        file.write(data)
+            
1039def export_current_config_file(gw_session: GatewaySession, cfg_zip: str):
+1040    '''
+1041    Exports the currently active configuration to a
+1042    zip file located at `cfg_zip`.
+1043    '''
+1044    data = _export_current_config_data(gw_session)
+1045    with open(cfg_zip, 'wb') as file:
+1046        file.write(data)
 
@@ -3806,13 +3816,13 @@
Inherited Members
-
1044def get_error_page_settings(gw_session: GatewaySession) -> dict:
-1045    '''
-1046    Returns a dictionary object describing the current error page settings.
-1047    '''
-1048    path = '/configuration/error-pages'
-1049    res = get(gw_session, path, exp_code=200)
-1050    return res.json().get('data')
+            
1049def get_error_page_settings(gw_session: GatewaySession) -> dict:
+1050    '''
+1051    Returns a dictionary object describing the current error page settings.
+1052    '''
+1053    path = '/configuration/error-pages'
+1054    res = get(gw_session, path, exp_code=200)
+1055    return res.json().get('data')
 
@@ -3832,18 +3842,18 @@
Inherited Members
-
1053def set_error_page_settings(gw_session: GatewaySession, attributes: dict):
-1054    '''
-1055    Updates the error page settings with the given attributes.
-1056    '''
-1057    path = '/configuration/error-pages'
-1058    data = {
-1059        "data": {
-1060            "type": "error-pages",
-1061            "attributes": attributes
-1062        }
-1063    }
-1064    patch(gw_session, path, data, exp_code=200)
+            
1058def set_error_page_settings(gw_session: GatewaySession, attributes: dict):
+1059    '''
+1060    Updates the error page settings with the given attributes.
+1061    '''
+1062    path = '/configuration/error-pages'
+1063    data = {
+1064        "data": {
+1065            "type": "error-pages",
+1066            "attributes": attributes
+1067        }
+1068    }
+1069    patch(gw_session, path, data, exp_code=200)
 
@@ -3863,15 +3873,15 @@
Inherited Members
-
1067def get_error_pages(gw_session: GatewaySession) -> Union[bytes, None]:
-1068    '''
-1069    Returns a zip file containing the error pages
-1070    '''
-1071    path = '/configuration/error-pages/content'
-1072    res = get(gw_session, path, exp_code=[200, 404])
-1073    if res.status_code == 404:
-1074        return None
-1075    return res.content
+            
1072def get_error_pages(gw_session: GatewaySession) -> Union[bytes, None]:
+1073    '''
+1074    Returns a zip file containing the error pages
+1075    '''
+1076    path = '/configuration/error-pages/content'
+1077    res = get(gw_session, path, exp_code=[200, 404])
+1078    if res.status_code == 404:
+1079        return None
+1080    return res.content
 
@@ -3891,13 +3901,13 @@
Inherited Members
-
1078def set_error_pages(gw_session: GatewaySession, error_page_zip: str):
-1079    '''
-1080    Imports the error page zip-file located at `error_page_zip`.
-1081    '''
-1082    with open(error_page_zip, 'rb') as file:
-1083        path = "/configuration/error-pages/content"
-1084        req_raw(gw_session, "PUT", path, "application/zip", file, 200)
+            
1083def set_error_pages(gw_session: GatewaySession, error_page_zip: str):
+1084    '''
+1085    Imports the error page zip-file located at `error_page_zip`.
+1086    '''
+1087    with open(error_page_zip, 'rb') as file:
+1088        path = "/configuration/error-pages/content"
+1089        req_raw(gw_session, "PUT", path, "application/zip", file, 200)
 
@@ -3917,12 +3927,12 @@
Inherited Members
-
1087def delete_error_pages(gw_session: GatewaySession):
-1088    '''
-1089    Remove the custom error pages.
-1090    '''
-1091    path = '/configuration/error-pages/content'
-1092    delete(gw_session, path, exp_code=200)
+            
1092def delete_error_pages(gw_session: GatewaySession):
+1093    '''
+1094    Remove the custom error pages.
+1095    '''
+1096    path = '/configuration/error-pages/content'
+1097    delete(gw_session, path, exp_code=200)
 
@@ -3942,13 +3952,13 @@
Inherited Members
-
1095def get_default_error_pages(gw_session: GatewaySession) -> bytes:
-1096    '''
-1097    Returns a zip file containing the default error pages.
-1098    '''
-1099    path = '/configuration/error-pages/content/default'
-1100    res = get(gw_session, path, exp_code=200)
-1101    return res.content
+            
1100def get_default_error_pages(gw_session: GatewaySession) -> bytes:
+1101    '''
+1102    Returns a zip file containing the default error pages.
+1103    '''
+1104    path = '/configuration/error-pages/content/default'
+1105    res = get(gw_session, path, exp_code=200)
+1106    return res.content
 
@@ -3968,13 +3978,13 @@
Inherited Members
-
1104def get_expert_settings(gw_session: GatewaySession) -> dict:
-1105    '''
-1106    Returns a dict containing the global expert settings for the Gateway as well as for Apache
-1107    '''
-1108    path = '/configuration/expert-settings'
-1109    res = get(gw_session, path, exp_code=200)
-1110    return res.json().get('data')
+            
1109def get_expert_settings(gw_session: GatewaySession) -> dict:
+1110    '''
+1111    Returns a dict containing the global expert settings for the Gateway as well as for Apache
+1112    '''
+1113    path = '/configuration/expert-settings'
+1114    res = get(gw_session, path, exp_code=200)
+1115    return res.json().get('data')
 
@@ -3994,18 +4004,18 @@
Inherited Members
-
1113def set_expert_settings(gw_session: GatewaySession, attributes: dict) -> None:
-1114    '''
-1115    Updates the global expert settings with the given attributes.
-1116    '''
-1117    path = '/configuration/expert-settings'
-1118    data = {
-1119        "data": {
-1120            "type": 'expert-settings',
-1121            "attributes": attributes
-1122        }
-1123    }
-1124    patch(gw_session, path, data, exp_code=200)
+            
1118def set_expert_settings(gw_session: GatewaySession, attributes: dict) -> None:
+1119    '''
+1120    Updates the global expert settings with the given attributes.
+1121    '''
+1122    path = '/configuration/expert-settings'
+1123    data = {
+1124        "data": {
+1125            "type": 'expert-settings',
+1126            "attributes": attributes
+1127        }
+1128    }
+1129    patch(gw_session, path, data, exp_code=200)