def execute(ctx, workflow, nick, output_format, artifacts): """Execute an arbitrary provider action COMMAND: broker execute --workflow "workflow-name" --workflow-arg1 something or COMMAND: broker execute --nick "nickname" :param ctx: clicks context object :param workflow: workflow template stored in Ansible Tower, passed in as a string :param nick: shortcut for arguments saved in settings.yaml, passed in as a string :param output_format: change the format of the output to one of the choice options :param artifacts: AnsibleTower provider specific option for choosing what to return """ broker_args = {} if nick: broker_args["nick"] = nick if workflow: broker_args["workflow"] = workflow if artifacts: broker_args["artifacts"] = True # if additional arguments were passed, include them in the broker args broker_args.update(dict(zip(ctx.args[::2], ctx.args[1::2]))) broker_inst = VMBroker(**broker_args) result = broker_inst.execute() if output_format == "raw": print(result) elif output_format == "log": logger.info(result) elif output_format == "yaml": print(helpers.yaml_format(result))
def duplicate(vm, background, count, all_, filter): """Duplicate a broker-procured vm COMMAND: broker duplicate <vm hostname>|<local id>|all :param vm: Hostname or local id of host :param background: run a new broker subprocess to carry out command :param all_: Click option all :param filter: a filter string matching broker's specification """ if background: helpers.fork_broker() inventory = helpers.load_inventory(filter=filter) for num, host in enumerate(inventory): if str(num ) in vm or host["hostname"] in vm or host["name"] in vm or all_: broker_args = host.get("_broker_args") if broker_args: if count: broker_args["_count"] = count logger.info(f"Duplicating: {host['hostname']}") broker_inst = VMBroker(**broker_args) broker_inst.checkout() else: logger.warning( f"Unable to duplicate {host['hostname']}, no _broker_args found" )
def checkin(vm, background, all_, sequential, filter): """Checkin or "remove" a VM or series of VM broker instances COMMAND: broker checkin <vm hostname>|<local id>|all :param vm: Hostname or local id of host :param background: run a new broker subprocess to carry out command :param all_: Flag for whether to checkin everything :param sequential: Flag for whether to run checkins sequentially :param filter: a filter string matching broker's specification """ if background: helpers.fork_broker() inventory = helpers.load_inventory(filter=filter) to_remove = [] for num, host in enumerate(inventory): if str(num ) in vm or host["hostname"] in vm or host["name"] in vm or all_: to_remove.append(VMBroker().reconstruct_host(host)) broker_inst = VMBroker(hosts=to_remove) broker_inst.checkin(sequential=sequential)
def checkout(ctx, background, nick, count, args_file, **kwargs): """Checkout or "create" a Virtual Machine broker instance COMMAND: broker checkout --workflow "workflow-name" --workflow-arg1 something or COMMAND: broker checkout --nick "nickname" :param ctx: clicks context object :param background: run a new broker subprocess to carry out command :param nick: shortcut for arguments saved in settings.yaml, passed in as a string :param args_file: this broker argument wil be replaced with the contents of the file passed in """ broker_args = helpers.clean_dict(kwargs) if nick: broker_args["nick"] = nick if count: broker_args["_count"] = count if args_file: broker_args["args_file"] = args_file # if additional arguments were passed, include them in the broker args # strip leading -- characters broker_args.update({(key[2:] if key.startswith("--") else key): val for key, val in zip(ctx.args[::2], ctx.args[1::2])}) broker_args = helpers.resolve_file_args(broker_args) if background: helpers.fork_broker() broker_inst = VMBroker(**broker_args) broker_inst.checkout()
def checkout(ctx, background, workflow, nick): """Checkout or "create" a Virtual Machine broker instance COMMAND: broker checkout --workflow "workflow-name" --workflow-arg1 something or COMMAND: broker checkout --nick "nickname" :param ctx: clicks context object :param background: run a new broker subprocess to carry out command :param workflow: workflow template stored in Ansible Tower, passed in as a string :param nick: shortcut for arguments saved in settings.yaml, passed in as a string """ broker_args = {} if nick: broker_args["nick"] = nick if workflow: broker_args["workflow"] = workflow # if additional arguments were passed, include them in the broker args broker_args.update(dict(zip(ctx.args[::2], ctx.args[1::2]))) if background: fork_broker() broker_inst = VMBroker(**broker_args) broker_inst.checkout()
def extend(vm, background, all_, sequential, filter, **kwargs): """Extend a host's lease time COMMAND: broker extend <vm hostname>|<vm name>|<local id> :param vm: Hostname, VM Name, or local id of host :param background: run a new broker subprocess to carry out command :param all_: Click option all :param sequential: Flag for whether to run extends sequentially :param filter: a filter string matching broker's specification """ broker_args = helpers.clean_dict(kwargs) if background: helpers.fork_broker() inventory = helpers.load_inventory(filter=filter) to_extend = [] for num, host in enumerate(inventory): if str(num ) in vm or host["hostname"] in vm or host["name"] in vm or all_: to_extend.append(VMBroker().reconstruct_host(host)) broker_inst = VMBroker(hosts=to_extend, **broker_args) broker_inst.extend(sequential=sequential)
def nick_help(ctx, workflow): """Get information from an action to determine accepted arguments COMMAND: broker nick-help --<action> <argument> """ broker_args = {} if workflow: broker_args["workflow"] = workflow # if additional arguments were passed, include them in the broker args broker_args.update(dict(zip(ctx.args[::2], ctx.args[1::2]))) broker_inst = VMBroker(**broker_args) broker_inst.nick_help()
def checkin(vm, all_): """Checkin or "remove" a VM or series of VM broker instances COMMAND: broker checkin <vm hostname>|<local id>|all :param vm: Hostname or local id of host """ inventory = helpers.load_inventory() to_remove = [] for num, host_export in enumerate(inventory): if str(num) in vm or host_export["hostname"] in vm or all_: to_remove.append(VMBroker.reconstruct_host(host_export)) broker_inst = VMBroker(hosts=to_remove) broker_inst.checkin()
def execute(ctx, background, workflow, job_template, nick, output_format, artifacts, args_file): """Execute an arbitrary provider action COMMAND: broker execute --workflow "workflow-name" --workflow-arg1 something or COMMAND: broker execute --nick "nickname" :param ctx: clicks context object :param background: run a new broker subprocess to carry out command :param workflow: workflow template stored in Ansible Tower, passed in as a string :param job-template: job template stored in Ansible Tower, passed in as a string :param nick: shortcut for arguments saved in settings.yaml, passed in as a string :param output_format: change the format of the output to one of the choice options :param artifacts: AnsibleTower provider specific option for choosing what to return :param args_file: this broker argument wil be replaced with the contents of the file passed in """ broker_args = {} if nick: broker_args["nick"] = nick if workflow: broker_args["workflow"] = workflow if job_template: broker_args["job_template"] = job_template if artifacts: broker_args["artifacts"] = artifacts if args_file: broker_args["args_file"] = args_file # if additional arguments were passed, include them in the broker args # strip leading -- characters broker_args.update({(key[2:] if key.startswith("--") else key): val for key, val in zip(ctx.args[::2], ctx.args[1::2])}) broker_args = helpers.resolve_file_args(broker_args) if background: fork_broker() broker_inst = VMBroker(**broker_args) result = broker_inst.execute() if output_format == "raw": print(result) elif output_format == "log": logger.info(result) elif output_format == "yaml": print(helpers.yaml_format(result))
def inventory(details, sync): """Get a list of all VMs you've checked out showing hostname and local id hostname pulled from list of dictionaries """ if sync: VMBroker.sync_inventory(provider=sync) logger.info("Pulling local inventory") inventory = helpers.load_inventory() for num, host in enumerate(inventory): if details: logger.info( f"{num}: {host['hostname'] or host['name']}, Details: {helpers.yaml_format(host)}" ) else: logger.info(f"{num}: {host['hostname'] or host['name']}")
def nick_help(ctx, workflow, provider): """Get information from an action to determine accepted arguments or get a list of valid actions available from a provider COMMAND: broker nick-help --<action> <argument> COMMAND: broker nick-help --provider <ProviderName> """ broker_args = {} if workflow: broker_args["workflow"] = workflow if provider: broker_args["provider"] = provider # if additional arguments were passed, include them in the broker args broker_args.update(dict(zip(ctx.args[::2], ctx.args[1::2]))) broker_inst = VMBroker(**broker_args) broker_inst.nick_help()
def test_host_creation(tower_stub): vmb = VMBroker() job = tower_stub.execute(workflow="deploy-base-rhel") host = tower_stub.construct_host(job, vmb.host_classes) assert isinstance(host, vmb.host_classes["host"]) assert host.hostname == "fake.host.test.com" assert host._broker_args["os_distribution_version"] == "7.8"
def test_positive_connection_option(organization_ak_setup, default_sat, distro): """Verify that 'insights-client --test-connection' successfully tests the proxy connection via the Satellite. :id: 61a4a39e-b484-49f4-a6fd-46ffc7736e50 :Steps: 1. Create RHEL7 and RHEL8 VM and register to insights within org having manifest. 2. Run 'insights-client --test-connection'. :expectedresults: 'insights-client --test-connection' should return 0. :CaseImportance: Critical """ org, activation_key = organization_ak_setup with VMBroker(nick=distro, host_classes={'host': ContentHost}) as vm: vm.configure_rhai_client(default_sat, activation_key.name, org.label, distro) result = vm.run('insights-client --test-connection') assert result.status == 0, ( 'insights-client --test-connection failed.\n' f'status: {result.status}\n' f'stdout: {result.stdout}\n' f'stderr: {result.stderr}')
def test_positive_generate_entitlements_report(setup_content): """Generate a report using the Subscription - Entitlement Report template. :id: 722e8802-367b-4399-bcaa-949daab26632 :setup: Installed Satellite with Organization, Activation key, Content View, Content Host, and Subscriptions. :steps: 1. Get /api/report_templates/130-Subscription - Entitlement Report/generate/id/report_format :expectedresults: Report is generated showing all necessary information for entitlements. :CaseImportance: High """ with VMBroker(nick='rhel7', host_classes={'host': ContentHost}) as vm: ak, org = setup_content vm.install_katello_ca() vm.register_contenthost(org.label, ak.name) assert vm.subscribed rt = (entities.ReportTemplate().search( query={'search': 'name="Subscription - Entitlement Report"'}) [0].read()) res = rt.generate( data={ "organization_id": org.id, "report_format": "json", "input_values": { "Days from Now": "no limit" }, }) assert res[0]['Host Name'] == vm.hostname assert res[0]['Subscription Name'] == DEFAULT_SUBSCRIPTION_NAME
def test_host_creation(tower_stub): vmb = VMBroker() job = tower_stub.execute(workflow="deploy-base-rhel") host = tower_stub.construct_host(job, vmb.host_classes) assert isinstance(host, vmb.host_classes["host"]) assert host.hostname == "fake.host.test.com" assert host._broker_args == {"provider": "rhv", "host_type": "host"}
def hosts(request): """Deploy hosts via broker.""" num_hosts = getattr(request, 'param', 2) with VMBroker(nick=DISTRO_RHEL7, host_classes={'host': ContentHost}, _count=num_hosts) as hosts: if type(hosts) is not list or len(hosts) != num_hosts: pytest.fail('Failed to provision the expected number of hosts.') yield hosts
def checkin(vm, background, all_): """Checkin or "remove" a VM or series of VM broker instances COMMAND: broker checkin <vm hostname>|<local id>|all :param vm: Hostname or local id of host :param background: run a new broker subprocess to carry out command """ if background: fork_broker() inventory = helpers.load_inventory() to_remove = [] for num, host_export in enumerate(inventory): if str(num) in vm or host_export["hostname"] in vm or all_: to_remove.append(VMBroker.reconstruct_host(host_export)) broker_inst = VMBroker(hosts=to_remove) broker_inst.checkin()
def checkout(ctx, workflow, nick): """Checkout a Virtual Machine COMMAND: broker checkout --<action> <argument> """ broker_args = {} if nick: broker_args = helpers.resolve_nick(nick) if workflow: broker_args["workflow"] = workflow # if additional arguments were passes, include them in the broker args broker_args.update(dict(zip(ctx.args[::2], ctx.args[1::2]))) broker_inst = VMBroker(**broker_args) broker_inst.checkout() new_hosts = [] for host in broker_inst._hosts: logger.info(f"{host.__class__.__name__}: {host.hostname}") new_hosts.append(host.to_dict()) helpers.update_inventory(new_hosts)
def vm_rhel8(activation_key, module_org): with VMBroker(nick='rhel8', host_classes={'host': ContentHost}) as vm: vm.configure_rhai_client( activation_key=activation_key.name, org=module_org.label, rhel_distro=DISTRO_RHEL8, register=False, ) add_remote_execution_ssh_key(vm.ip_addr) yield vm
def extend(vm, background, all_): """Extend a host's lease time COMMAND: broker extend <vm hostname>|<vm name>|<local id> :param vm: Hostname, VM Name, or local id of host :param background: run a new broker subprocess to carry out command :param all_: Click option all """ if background: fork_broker() inventory = helpers.load_inventory() to_extend = [] for num, host in enumerate(inventory): if str(num) in vm or host["hostname"] in vm or host["name"] in vm or all_: to_extend.append(VMBroker().reconstruct_host(host)) broker_inst = VMBroker(hosts=to_extend) broker_inst.extend()
def satellite_latest(): """A fixture that provides a latest Satellite""" version_args = dict( deploy_sat_version=settings.server.version.get('release', ''), deploy_snap_version=settings.server.version.get('snap', ''), ) with VMBroker(host_classes={'host': Satellite}, workflow=settings.server.deploy_workflow, **version_args) as sat: yield sat
def factory(retry_limit=3, delay=300, **broker_args): vmb = VMBroker(host_classes={'host': Capsule}, workflow=settings.capsule.deploy_workflow, **broker_args) timeout = (1200 + delay) * retry_limit cap = wait_for(vmb.checkout, func_kwargs=broker_args, timeout=timeout, delay=delay, fail_condition=[]) return cap.out
def factory(retry_limit=3, delay=300, **broker_args): vmb = VMBroker(host_classes={'host': Satellite}, workflow=settings.server.deploy_workflow, **broker_args) timeout = (1200 + delay) * retry_limit sat = wait_for(vmb.checkout, func_kwargs=broker_args, timeout=timeout, delay=delay, fail_condition=[]) return sat.out
def duplicate(vm, all_): """Duplicate a broker-procured vm COMMAND: broker duplicate <vm hostname>|<local id>|all :param vm: Hostname or local id of host :param all_: Click option all """ inventory = helpers.load_inventory() for num, host in enumerate(inventory): if str(num) in vm or host["hostname"] in vm or all_: broker_args = host.get("_broker_args") if broker_args: logger.info(f"Duplicating: {host['hostname']}") broker_inst = VMBroker(**broker_args) broker_inst.checkout() else: logger.warning( f"Unable to duplicate {host['hostname']}, no _broker_args found" )
def capsule_latest(): """A fixture that provides an unconfigured latest Capsule""" version_args = dict( deploy_sat_version=settings.server.version.get('release', ''), deploy_snap_version=settings.server.version.get('snap', ''), ) with VMBroker( host_classes={'host': Capsule}, workflow=str(settings.capsule.deploy_workflow), **version_args, ) as cap: yield cap
def rhel_contenthost(request): """A function-level fixture that provides a content host object parametrized""" # Request should be parametrized through pytest_fixtures.fixture_markers # unpack params dict workflow = request.param.get('workflow', settings.content_host.deploy_workflow) rhel_version = request.param.get( 'rhel', settings.content_host.default_rhel_version) # TODO: target_memory/cores, host type, other fields? with VMBroker(workflow=workflow, rhel_version=rhel_version, host_classes={'host': ContentHost}) as host: yield host
def factory(retry_limit=3, delay=300, workflow=None, **broker_args): if settings.capsule.deploy_arguments: broker_args.update(settings.capsule.deploy_arguments) vmb = VMBroker( host_classes={'host': Capsule}, workflow=workflow or settings.capsule.deploy_workflow, **broker_args, ) timeout = (1200 + delay) * retry_limit cap = wait_for(vmb.checkout, timeout=timeout, delay=delay, fail_condition=[]) return cap.out
def test_positive_connection_option(module_org, activation_key): """Verify that '--test-connection' option for insights-client client rpm tests the connection with the satellite server connection with satellite server :id: 167758c9-cbfa-4a81-9a11-27f88aaf9118 :expectedresults: 'insights-client --test-connection' should return zero on a successfully registered machine to RHAI service """ with VMBroker(nick='rhel7', host_classes={'host': ContentHost}) as vm: vm.configure_rhai_client(activation_key.name, module_org.label, DISTRO_RHEL7) test_connection = vm.run('insights-client --test-connection') assert test_connection.status == 0
def vm_setup(self, request, cert_data): """Create VM and register content host""" target_cores = request.param.get('target_cores', 1) target_memory = request.param.get('target_memory', '1GiB') with VMBroker( nick=request.param['nick'], host_classes={'host': ContentHost}, target_cores=target_cores, target_memory=target_memory, ) as host: cert_data['key_file_name'] = f'{host.hostname}/{host.hostname}.key' cert_data[ 'cert_file_name'] = f'{host.hostname}/{host.hostname}.crt' host.custom_cert_generate(cert_data['capsule_hostname']) yield cert_data, host
def test_positive_schedule_entitlements_report(setup_content): """Schedule a report using the Subscription - Entitlement Report template. :id: 5152c518-b0da-4c27-8268-2be78289249f :setup: Installed Satellite with Organization, Activation key, Content View, Content Host, and Subscriptions. :steps: 1. POST /api/report_templates/130-Subscription - Entitlement Report/schedule_report/ :expectedresults: Report is scheduled and contains all necessary information for entitlements. :CaseImportance: High """ with VMBroker(nick='rhel7', host_classes={'host': ContentHost}) as vm: ak, org = setup_content vm.install_katello_ca() vm.register_contenthost(org.label, ak.name) assert vm.subscribed rt = (entities.ReportTemplate().search( query={'search': 'name="Subscription - Entitlement Report"'}) [0].read()) scheduled_csv = rt.schedule_report( data={ 'id': f'{rt.id}-Subscription - Entitlement Report', 'organization_id': org.id, 'report_format': 'csv', "input_values": { "Days from Now": "no limit" }, }) data_csv, _ = wait_for( rt.report_data, func_kwargs={ 'data': { 'id': rt.id, 'job_id': scheduled_csv['job_id'] } }, fail_condition=None, timeout=300, delay=10, ) assert vm.hostname in data_csv assert DEFAULT_SUBSCRIPTION_NAME in data_csv