diff --git a/examples/Accounts/create_integration_in_child_account.py b/examples/Accounts/create_integration_in_child_account.py new file mode 100644 index 0000000..ab397d2 --- /dev/null +++ b/examples/Accounts/create_integration_in_child_account.py @@ -0,0 +1,74 @@ +""" +Example of creating an integration in a child account using parent account credentials + +The key to successfully interacting with child accounts via the parent account APIs is +pairing the parent account API IKEY/SKEY combination with the api-host of the child account. +Once that connection is established, the child account ID must be passed along with all API interactions. +The duo_client SDK makes that easy by allowing the setting of the child account ID as an instance variable. +""" + +import sys +import getpass +import duo_client + +# Create an interator to be used by the interactive terminal prompt +argv_iter = iter(sys.argv[1:]) + + +def _get_next_arg(prompt, secure=False): + """Read information from STDIN, using getpass when sensitive information should not be echoed to tty""" + try: + return next(argv_iter) + except StopIteration: + if secure is True: + return getpass.getpass(prompt) + else: + return input(prompt) + + +def prompt_for_credentials() -> dict: + """Collect required API credentials from command line prompts + + :return: dictionary containing Duo Accounts API ikey, skey and hostname strings + """ + answers = {'ikey': _get_next_arg('Duo Accounts API integration key ("DI..."): '), + 'skey': _get_next_arg('Duo Accounts API integration secret key: ', secure=True), + 'host': _get_next_arg('Duo API hostname of child account ("api-....duosecurity.com"): '), + 'account_id': _get_next_arg('Child account ID: '), + 'app_name': _get_next_arg('New application name: '), + 'app_type': _get_next_arg('New application type: ')} + return answers + + +def create_child_integration(inputs: dict): + """Create new application integration in child account via the parent account API""" + + # First create a duo_client.Admin instance using the parent account ikey/sky along with the child account api-host + account_client = duo_client.Admin(ikey=inputs['ikey'], skey=inputs['skey'], host=inputs['host']) + # Next assign the child account ID to the duo_client.Admin instance variable. + account_client.account_id = inputs['account_id'] + # Now all API calls made via this instance will contain all of the minimum requirements to interact with the + # child account. + + # Here only the two required arguments (name and type) are passed. + # Normally, much more information would be provided. The type of additional information + # varies by the type of application integration. + try: + new_app = account_client.create_integration( + name=inputs['app_name'], + integration_type=inputs['app_type'], + ) + print(f"New application {inputs['app_name']} (ID: {new_app['integration_key']}) was created successfully.") + except RuntimeError as e_str: + # Any failure of the API call results in a generic Runtime Error + print(f"An error occurred while creating the new application: {e_str}") + + +def main(): + """Main program entry point""" + inputs = prompt_for_credentials() + create_child_integration(inputs) + + +if __name__ == '__main__': + main() diff --git a/examples/Accounts/retrieve_integrations_from_child_account.py b/examples/Accounts/retrieve_integrations_from_child_account.py new file mode 100644 index 0000000..82d7f9c --- /dev/null +++ b/examples/Accounts/retrieve_integrations_from_child_account.py @@ -0,0 +1,53 @@ +""" +Example of creating an integration in a child account using parent account credentials +""" + +import argparse +import duo_client + + +parser = argparse.ArgumentParser() +duo_arg_group = parser.add_argument_group('Duo Accounts API Credentials') +duo_arg_group.add_argument('--ikey', + help='Duo Accounts API IKEY', + required=True + ) +duo_arg_group.add_argument('--skey', + help='Duo Accounts API Secret Key', + required=True, + ) +duo_arg_group.add_argument('--host', + help='Duo child account API apihost', + required=True + ) +parser.add_argument('--child_account_id', + help='The Duo account ID of the child account to query.', + required=True + ) +args = parser.parse_args() + +# It is important to note that we are using the IKEY/SKEY combination for an Accounts API integration in the +# parent account along with the api-hostname of a child account to create a new duo_client.Admin instance +account_client = duo_client.Admin( + ikey=args.ikey, + skey=args.skey, + host=args.host, +) + +# Once the duo_client.Admin instance is created, the child account_id is assigned. This is necessary to ensure +# queries made with this Admin API instance are directed to the proper child account that matches the api-hostname +# used to create the instance. +account_client.account_id = args.child_account_id + + +def main(): + """Main program entry point""" + + print(f"Retrieving integrations for child account {args.child_account_id}") + child_account_integrations = account_client.get_integrations_generator() + for integration in child_account_integrations: + print(f"{integration['name']=}") + + +if __name__ == '__main__': + main()