def test_negative_update_email_subject_prefix(setting_update): """Check email subject prefix is not updated :id: 8a638596-248f-4196-af36-ad2982196382 :parametrized: yes :steps: provide invalid prefix, like string with more than 255 chars :expectedresults: email_subject_prefix is not updated :CaseAutomation: Automated :CaseImportance: Low """ email_subject_prefix_original = Settings.list( {'search': 'name=email_subject_prefix'})[0] email_subject_prefix_value = gen_string('alpha', 256) with pytest.raises(CLIReturnCodeError): Settings.set({ 'name': 'email_subject_prefix', 'value': email_subject_prefix_value }) email_subject_prefix = Settings.list( {'search': 'name=email_subject_prefix'})[0] assert email_subject_prefix == email_subject_prefix_original
def tearDownClass(cls): super(BruteForceLogin, cls).tearDownClass() # reset failed_login_attempts_limit value sleep(301) Settings.set({ u'name': u'failed_login_attempts_limit', u'value': cls.host_value})
def test_positive_update_email_delivery_method_sendmail(setting_update): """Check Updating Sendmail params through settings subcommand :id: 578de898-fde2-4957-b39a-9dd059f490bf :steps: 1. set "delivery_method" to sendmail 2. set all sendmail related properties: 2.1. sendmail_arguments 2.2. sendmail_location :expectedresults: Sendmail properties are updated :CaseImportance: Low :CaseAutomation: Automated """ sendmail_argument_value = gen_string('alphanumeric') sendmail_config_params = { 'delivery_method': 'sendmail', 'sendmail_arguments': f'{sendmail_argument_value}', 'sendmail_location': '/usr/sbin/sendmail', } for key, value in sendmail_config_params.items(): Settings.set({'name': f'{key}', 'value': f'{value}'}) assert Settings.list({'search': f'name={key}'})[0]['value'] == value
def test_positive_failed_login_attempts_limit(self): """automate brute force protection limit configurable function :id: f95407ed-451b-4387-ac9b-2959ae2f51ae :steps: 1. Make sure login works. 2. Save current value and set it to some lower value: 3. Try to login with wrong password till failed_login_attempts_limit 4. Make sure login now does not work: 5. Wait timeout - 5 minutes + 1 second 6. Verify you can now login fine 7. Return the setting to previous value :expectedresults: failed_login_attempts_limit works as expected :caseautomation: automated """ result = ssh.command('hammer -u {0} -p {1} user list'.format( self.foreman_user, self.foreman_password)) self.assertEqual(result.return_code, 0) Settings.set({u'name': u'failed_login_attempts_limit', u'value': '5'}) for i in range(5): output = ssh.command('hammer -u {0} -p BAD_PASS user list'.format( self.foreman_user)) self.assertEqual(output.return_code, 129) result = ssh.command('hammer -u {0} -p {1} user list'.format( self.foreman_user, self.foreman_password)) self.assertEqual(result.return_code, 129) sleep(301) result = ssh.command('hammer -u {0} -p {1} user list'.format( self.foreman_user, self.foreman_password)) self.assertEqual(result.return_code, 0)
def tearDownClass(cls): super(BruteForceLogin, cls).tearDownClass() # reset failed_login_attempts_limit value sleep(301) Settings.set({ u'name': u'failed_login_attempts_limit', u'value': cls.host_value })
def test_positive_update_hostname_prefix_without_value(self): """Update the Hostname_prefix settings without any string(empty values) :id: a84c28ea-6821-4c31-b4ab-8662c22c9135 :expectedresults: Hostname_prefix should be set without any text """ Settings.set({'name': "discovery_prefix", 'value': ""}) discovery_prefix = Settings.list({'search': 'name=discovery_prefix'})[0] self.assertEqual('', discovery_prefix['value'])
def test_positive_update_hostname_default_prefix(self): """Update the default set prefix of hostname_prefix setting :id: a6e46e53-6273-406a-8009-f184d9551d66 :expectedresults: Default set prefix should be updated with new value """ hostname_prefix_value = gen_string('alpha') Settings.set({'name': "discovery_prefix", 'value': hostname_prefix_value}) discovery_prefix = Settings.list({'search': 'name=discovery_prefix'})[0] self.assertEqual(hostname_prefix_value, discovery_prefix['value'])
def test_positive_update_hostname_prefix_without_value(self): """Update the Hostname_prefix settings without any string(empty values) :id: a84c28ea-6821-4c31-b4ab-8662c22c9135 :expectedresults: Hostname_prefix should be set without any text """ Settings.set({'name': "discovery_prefix", 'value': ""}) discovery_prefix = Settings.list({ 'search': 'name=discovery_prefix' })[0] self.assertEqual('', discovery_prefix['value'])
def setUp(self): """Create a directory for export, configure permissions and satellite settings """ super(RepositoryExportTestCase, self).setUp() if not RepositoryExportTestCase.is_set_up: RepositoryExportTestCase.export_dir = gen_string('alphanumeric') # Create a new 'export' directory on the Satellite system result = ssh.command('mkdir /mnt/{0}'.format(self.export_dir)) self.assertEqual(result.return_code, 0) result = ssh.command( 'chown foreman.foreman /mnt/{0}'.format(self.export_dir)) self.assertEqual(result.return_code, 0) result = ssh.command( 'ls -Z /mnt/ | grep {0}'.format(self.export_dir)) self.assertEqual(result.return_code, 0) self.assertGreaterEqual(len(result.stdout), 1) self.assertIn('unconfined_u:object_r:mnt_t:s0', result.stdout[0]) # Fix SELinux policy for new directory result = ssh.command( 'semanage fcontext -a -t foreman_var_run_t "/mnt/{0}(/.*)?"' .format(self.export_dir) ) self.assertEqual(result.return_code, 0) result = ssh.command( 'restorecon -Rv /mnt/{0}'.format(self.export_dir)) self.assertEqual(result.return_code, 0) # Assert that we have the correct policy result = ssh.command( 'ls -Z /mnt/ | grep {0}'.format(self.export_dir)) self.assertEqual(result.return_code, 0) self.assertGreaterEqual(len(result.stdout), 1) self.assertIn( 'unconfined_u:object_r:foreman_var_run_t:s0', result.stdout[0]) # Update the 'pulp_export_destination' settings to new directory Settings.set({ 'name': 'pulp_export_destination', 'value': '/mnt/{0}'.format(self.export_dir), }) # Create an organization to reuse in tests RepositoryExportTestCase.org = make_org() RepositoryExportTestCase.is_set_up = True
def test_positive_session_preceeds_saved_credentials(self): """Check if enabled session is mutually exclusive with saved credentials in hammer config :id: e4277298-1c24-494b-84a6-22f45f96e144 :BZ: 1471099 :Steps: 1. Set use_sessions, set usernam and password, set short expiration time 2. Authenticate, assert credentials are not demanded on next command run 3. Wait until session expires :expectedresults: Session expires after specified time and saved credentials are not applied """ try: idle_timeout = Settings.list({ 'search': 'name=idle_timeout'})[0][u'value'] Settings.set({'name': 'idle_timeout', 'value': 1}) result = configure_sessions(add_default_creds=True) self.assertEqual(result, 0, 'Failed to configure hammer sessions') Auth.login({ 'username': self.uname_admin, 'password': self.password }) result = Auth.with_user().status() self.assertIn( LOGEDIN_MSG.format(self.uname_admin), result[0][u'message'] ) # list organizations without supplying credentials with self.assertNotRaises(CLIReturnCodeError): Org.with_user().list() # wait until session expires sleep(70) with self.assertRaises(CLIReturnCodeError): Org.with_user().list() result = Auth.with_user().status() self.assertIn( LOGEDOFF_MSG.format(self.uname_admin), result[0][u'message'] ) finally: # reset timeout to default Settings.set({'name': 'idle_timeout', 'value': '{}'.format( idle_timeout)})
def test_positive_update_hostname_prefix_without_value(setting_update): """Update the Hostname_prefix settings without any string(empty values) :id: a84c28ea-6821-4c31-b4ab-8662c22c9135 :parametrized: yes :BZ: 1470083 :expectedresults: Error should be raised on setting empty value for discovery_prefix setting """ with pytest.raises(CLIReturnCodeError): Settings.set({'name': "discovery_prefix", 'value': ""})
def setUpClass(cls): """Steps to Configure foreman discovery 1. Build PXE default template 2. Create Organization/Location 3. Update Global parameters to set default org and location for discovered hosts. 4. Enable auto_provision flag to perform discovery via discovery rules. """ super(DiscoveredTestCase, cls).setUpClass() # Build PXE default template to get default PXE file Template.build_pxe_default() # let's just modify the timeouts to speed things up ssh.command("sed -ie 's/TIMEOUT [[:digit:]]\\+/TIMEOUT 1/g' " "/var/lib/tftpboot/pxelinux.cfg/default") ssh.command("sed -ie '/APPEND initrd/s/$/ fdi.countdown=1/' " "/var/lib/tftpboot/pxelinux.cfg/default") # Create Org and location cls.org = make_org() cls.loc = make_location() # Get default settings values cls.default_discovery_loc = Settings.list( {'search': 'name=%s' % 'discovery_location'})[0] cls.default_discovery_org = Settings.list( {'search': 'name=%s' % 'discovery_organization'})[0] cls.default_discovery_auto = Settings.list( {'search': 'name=%s' % 'discovery_auto'})[0] # Update default org and location params to place discovered host Settings.set({'name': 'discovery_location', 'value': cls.loc['name']}) Settings.set({ 'name': 'discovery_organization', 'value': cls.org['name'] }) # Enable flag to auto provision discovered hosts via discovery rules Settings.set({'name': 'discovery_auto', 'value': 'true'}) # Flag which shows whether environment is fully configured for # discovered host provisioning. cls.configured_env = False if bz_bug_is_open(1578290): ssh.command('mkdir /var/lib/tftpboot/boot/fdi-image') ssh.command('ln -s /var/lib/tftpboot/boot/' 'foreman-discovery-image-3.4.4-1.iso-vmlinuz' ' /var/lib/tftpboot/boot/fdi-image/vmlinuz0') ssh.command('ln -s /var/lib/tftpboot/boot/' 'foreman-discovery-image-3.4.4-1.iso-img' ' /var/lib/tftpboot/boot/fdi-image/initrd0.img') ssh.command('chown -R foreman-proxy /var/lib/tftpboot/boot/')
def test_positive_session_preceeds_saved_credentials(self): """Check if enabled session is mutually exclusive with saved credentials in hammer config :id: e4277298-1c24-494b-84a6-22f45f96e144 :BZ: 1471099 :Steps: 1. Set use_sessions, set usernam and password, set short expiration time 2. Authenticate, assert credentials are not demanded on next command run 3. Wait until session expires :expectedresults: Session expires after specified time and saved credentials are not applied """ try: idle_timeout = Settings.list({'search': 'name=idle_timeout'})[0][u'value'] Settings.set({'name': 'idle_timeout', 'value': 1}) result = configure_sessions(add_default_creds=True) self.assertEqual(result, 0, 'Failed to configure hammer sessions') Auth.login({ 'username': self.uname_admin, 'password': self.password }) result = Auth.with_user().status() self.assertIn(LOGEDIN_MSG.format(self.uname_admin), result[0][u'message']) # list organizations without supplying credentials with self.assertNotRaises(CLIReturnCodeError): Org.with_user().list() # wait until session expires sleep(70) with self.assertRaises(CLIReturnCodeError): Org.with_user().list() result = Auth.with_user().status() self.assertIn(LOGEDOFF_MSG.format(self.uname_admin), result[0][u'message']) finally: # reset timeout to default Settings.set({ 'name': 'idle_timeout', 'value': '{}'.format(idle_timeout) })
def test_positive_update_login_page_footer_text_without_value(self): """Updates parameter "login_text" without any string (empty value) :id: 01ce95de-2994-42b6-b9f8-f7882981fb69 :steps: 1. Execute "settings" command with "set" as sub-command without any string(empty value) in value parameter :expectedresults: Message on login screen should be removed """ Settings.set({'name': "login_text", 'value': ""}) login_text = Settings.list({'search': 'name=login_text'})[0] self.assertEqual('', login_text['value'])
def test_negative_update_send_welcome_email(value): """Check email send welcome email is updated :id: 2f75775d-72a1-4b2f-86c2-98c36e446099 :steps: set invalid values: not booleans :expectedresults: send_welcome_email is not updated :caseautomation: automated :caseimportance: low """ with pytest.raises(CLIReturnCodeError): Settings.set({'name': 'send_welcome_email', 'value': value})
def test_negative_update_send_welcome_email(value): """Check email send welcome email is updated :id: 2f75775d-72a1-4b2f-86c2-98c36e446099 :steps: set invalid values: not booleans :expectedresults: send_welcome_email is not updated :caseautomation: automated :caseimportance: low """ with pytest.raises(CLIReturnCodeError): Settings.set({'name': 'send_welcome_email', 'value': value})
def test_positive_update_login_page_footer_text_without_value(self): """Updates parameter "login_text" without any string (empty value) :id: 01ce95de-2994-42b6-b9f8-f7882981fb69 :steps: 1. Execute "settings" command with "set" as sub-command without any string(empty value) in value parameter :expectedresults: Message on login screen should be removed """ Settings.set({'name': "login_text", 'value': ""}) login_text = Settings.list({'search': 'name=login_text'})[0] self.assertEqual('', login_text['value'])
def test_positive_update_email_subject_prefix(self): """Check email subject prefix is updated :id: c8e6b323-7b39-43d6-a9f1-5474f920bba2 :expectedresults: email_subject_prefix is updated :CaseAutomation: automated :CaseImportance: Low """ email_subject_prefix_value = gen_string('alpha') Settings.set({'name': "email_subject_prefix", 'value': email_subject_prefix_value}) email_subject_prefix = Settings.list({'search': 'name=email_subject_prefix'})[0] self.assertEqual(email_subject_prefix_value, email_subject_prefix['value'])
def setUpClass(cls): """Steps to Configure foreman discovery 1. Build PXE default template 2. Create Organization/Location 3. Update Global parameters to set default org and location for discovered hosts. 4. Enable auto_provision flag to perform discovery via discovery rules. """ super(DiscoveredTestCase, cls).setUpClass() # Build PXE default template to get default PXE file Template.build_pxe_default() # let's just modify the timeouts to speed things up ssh.command("sed -ie 's/TIMEOUT [[:digit:]]\\+/TIMEOUT 1/g' " "/var/lib/tftpboot/pxelinux.cfg/default") ssh.command("sed -ie '/APPEND initrd/s/$/ fdi.countdown=1/' " "/var/lib/tftpboot/pxelinux.cfg/default") # Create Org and location cls.org = make_org() cls.loc = make_location() # Get default settings values cls.default_discovery_loc = Settings.list( {'search': 'name=%s' % 'discovery_location'})[0] cls.default_discovery_org = Settings.list( {'search': 'name=%s' % 'discovery_organization'})[0] cls.default_discovery_auto = Settings.list( {'search': 'name=%s' % 'discovery_auto'})[0] # Update default org and location params to place discovered host Settings.set({'name': 'discovery_location', 'value': cls.loc['name']}) Settings.set( {'name': 'discovery_organization', 'value': cls.org['name']}) # Enable flag to auto provision discovered hosts via discovery rules Settings.set({'name': 'discovery_auto', 'value': 'true'}) # Flag which shows whether environment is fully configured for # discovered host provisioning. cls.configured_env = False if bz_bug_is_open(1578290): ssh.command('mkdir /var/lib/tftpboot/boot/fdi-image') ssh.command('ln -s /var/lib/tftpboot/boot/' 'foreman-discovery-image-3.4.4-1.iso-vmlinuz' ' /var/lib/tftpboot/boot/fdi-image/vmlinuz0') ssh.command('ln -s /var/lib/tftpboot/boot/' 'foreman-discovery-image-3.4.4-1.iso-img' ' /var/lib/tftpboot/boot/fdi-image/initrd0.img') ssh.command('chown -R foreman-proxy /var/lib/tftpboot/boot/')
def test_positive_enable_disable_rssfeed(setting_update, rss_enable_value): """Check if the RSS feed can be enabled or disabled :id: 021cefab-2629-44e2-a30d-49c944d0a234 :steps: Set rss_enable true or false :parametrized: yes :expectedresults: rss_enable is updated :CaseAutomation: Automated """ Settings.set({'name': 'rss_enable', 'value': rss_enable_value}) rss_setting = Settings.list({'search': 'name=rss_enable'})[0] assert rss_setting["value"] == rss_enable_value
def test_positive_update_hostname_default_prefix(self): """Update the default set prefix of hostname_prefix setting :id: a6e46e53-6273-406a-8009-f184d9551d66 :expectedresults: Default set prefix should be updated with new value """ hostname_prefix_value = gen_string('alpha') Settings.set({ 'name': "discovery_prefix", 'value': hostname_prefix_value }) discovery_prefix = Settings.list({ 'search': 'name=discovery_prefix' })[0] self.assertEqual(hostname_prefix_value, discovery_prefix['value'])
def test_positive_create_session(self): """Check if user stays authenticated with session enabled :id: fcee7f5f-1040-41a9-bf17-6d0c24a93e22 :Steps: 1. Set use_sessions, set short expiration time 2. Authenticate, assert credentials are not demanded on next command run 3. Wait until session expires, assert credentials are required :expectedresults: The session is successfully created and expires after specified time """ try: idle_timeout = Settings.list({ 'search': 'name=idle_timeout'})[0][u'value'] Settings.set({'name': 'idle_timeout', 'value': 1}) result = configure_sessions() self.assertEqual(result, 0, 'Failed to configure hammer sessions') Auth.login({ 'username': self.uname_admin, 'password': self.password }) result = Auth.with_user().status() self.assertIn( LOGEDIN_MSG.format(self.uname_admin), result[0][u'message'] ) # list organizations without supplying credentials with self.assertNotRaises(CLIReturnCodeError): Org.with_user().list() # wait until session expires sleep(70) with self.assertRaises(CLIReturnCodeError): Org.with_user().list() result = Auth.with_user().status() self.assertIn( LOGEDOFF_MSG.format(self.uname_admin), result[0][u'message'] ) finally: # reset timeout to default Settings.set({'name': 'idle_timeout', 'value': '{}'.format( idle_timeout)})
def test_negative_update_email_reply_address(self): """Check email reply address is not updated :id: 2a2220c2-badf-47d5-ba3f-e6329930ab39 :steps: provide invalid email addresses :expectedresults: email_reply_address is not updated :CaseImportance: Low :CaseAutomation: automated """ for email in invalid_emails_list(): with self.subTest(email): with self.assertRaises(CLIReturnCodeError): Settings.set({'name': 'email_reply_address', 'value': email})
def test_positive_session_preceeds_saved_credentials(admin_user, target_sat): """Check if enabled session is mutually exclusive with saved credentials in hammer config :id: e4277298-1c24-494b-84a6-22f45f96e144 :BZ: 1471099, 1903693 :CaseImportance: High :Steps: 1. Set use_sessions, set username and password, set short expiration time 2. Authenticate, assert credentials are not demanded on next command run 3. Wait until session expires :expectedresults: Session expires after specified time and saved credentials are not applied """ try: idle_timeout = Settings.list({'search': 'name=idle_timeout'})[0]['value'] Settings.set({'name': 'idle_timeout', 'value': 1}) result = configure_sessions(satellite=target_sat, add_default_creds=True) assert result == 0, 'Failed to configure hammer sessions' AuthLogin.basic({ 'username': admin_user['login'], 'password': password }) result = Auth.with_user().status() assert LOGEDIN_MSG.format(admin_user['login']) in result[0]['message'] # list organizations without supplying credentials sleep(70) if not is_open('BZ:1903693'): result = Auth.with_user().status() assert LOGEDOFF_MSG.format( admin_user['login']) in result[0]['message'] with pytest.raises(CLIReturnCodeError): Org.with_user().list() finally: # reset timeout to default Settings.set({'name': 'idle_timeout', 'value': f'{idle_timeout}'})
def test_positive_update_send_welcome_email(self): """Check email send welcome email is updated :id: cdaf6cd0-5eea-4252-87c5-f9ec3ba79ac1 :steps: valid values: boolean true or false :expectedresults: send_welcome_email is updated :CaseAutomation: automated :CaseImportance: Low """ for value in ['true', 'false']: Settings.set({'name': 'send_welcome_email', 'value': value}) host_value = Settings.list({'search': 'name=send_welcome_email'})[0]['value'] assert value == host_value
def test_positive_update_login_page_footer_text(self): """Updates parameter "login_text" in settings :id: 4d4e1151-5bd6-4fa2-8dbb-e182b43ad7ec :steps: 1. Execute "settings" command with "set" as sub-command with any string :expectedresults: Parameter is updated successfully """ for login_text_value in valid_data_list(): with self.subTest(login_text_value): Settings.set({'name': "login_text", 'value': login_text_value}) login_text = Settings.list({'search': 'name=login_text'})[0] self.assertEqual(login_text_value, login_text['value'])
def test_positive_update_login_page_footer_text(self): """Updates parameter "login_text" in settings :id: 4d4e1151-5bd6-4fa2-8dbb-e182b43ad7ec :steps: 1. Execute "settings" command with "set" as sub-command with any string :expectedresults: Parameter is updated successfully """ for login_text_value in valid_data_list(): with self.subTest(login_text_value): Settings.set({'name': "login_text", 'value': login_text_value}) login_text = Settings.list({'search': 'name=login_text'})[0] self.assertEqual(login_text_value, login_text['value'])
def test_positive_create_session(self): """Check if user stays authenticated with session enabled :id: fcee7f5f-1040-41a9-bf17-6d0c24a93e22 :Steps: 1. Set use_sessions, set short expiration time 2. Authenticate, assert credentials are not demanded on next command run 3. Wait until session expires, assert credentials are required :expectedresults: The session is successfully created and expires after specified time """ try: idle_timeout = Settings.list({'search': 'name=idle_timeout'})[0][u'value'] Settings.set({'name': 'idle_timeout', 'value': 1}) result = configure_sessions() self.assertEqual(result, 0, 'Failed to configure hammer sessions') Auth.login({ 'username': self.uname_admin, 'password': self.password }) result = Auth.with_user().status() self.assertIn(LOGEDIN_MSG.format(self.uname_admin), result[0][u'message']) # list organizations without supplying credentials with self.assertNotRaises(CLIReturnCodeError): Org.with_user().list() # wait until session expires sleep(70) with self.assertRaises(CLIReturnCodeError): Org.with_user().list() result = Auth.with_user().status() self.assertIn(LOGEDOFF_MSG.format(self.uname_admin), result[0][u'message']) finally: # reset timeout to default Settings.set({ 'name': 'idle_timeout', 'value': '{}'.format(idle_timeout) })
def test_negative_update_email_reply_address(setting_update): """Check email reply address is not updated :id: 2a2220c2-badf-47d5-ba3f-e6329930ab39 :steps: provide invalid email addresses :parametrized: yes :expectedresults: email_reply_address is not updated :CaseImportance: Low :CaseAutomation: Automated """ invalid_email_address = random.choice(list(invalid_emails_list())) with pytest.raises(CLIReturnCodeError): Settings.set({'name': 'email_reply_address', 'value': invalid_email_address})
def test_positive_update_send_welcome_email(self): """Check email send welcome email is updated :id: cdaf6cd0-5eea-4252-87c5-f9ec3ba79ac1 :steps: valid values: boolean true or false :expectedresults: send_welcome_email is updated :caseautomation: automated :caseimportance: low """ for value in ['true', 'false']: Settings.set({'name': 'send_welcome_email', 'value': value}) host_value = Settings.list( {'search': 'name=send_welcome_email'})[0]['value'] assert value == host_value
def test_positive_generate_ansible_template(self): """Report template named 'Ansible Inventory' (default name is specified in settings) must be present in Satellite 6.7 and later in order to provide enhanced functionality for Ansible Tower inventory synchronization with Satellite. :id: f1f7adfc-9601-4498-95c8-3e82e2b36583 :setup: 1. A user with minimal required permissions: 'Ansible Tower Inventory Reader' role 2. A fake host to be checked in report output :steps: 1. Check settings for default Ansible Inventory template name and ensure the template is present 2. Try to render the template using the user with ATIR role 3. Check the fake host is present in the output :expectedresults: Report template is present, renederable and provides output :CaseImportance: Medium """ settings = Settings.list({'search': 'name=ansible_inventory_template'}) assert 1 == len(settings) template_name = settings[0]['value'] report_list = ReportTemplate.list() assert template_name in [rt['name'] for rt in report_list] login = gen_string('alpha').lower() password = gen_string('alpha').lower() loc = Location.info({'name': DEFAULT_LOC}) org = Org.info({'name': DEFAULT_ORG}) user = make_user( { 'login': login, 'password': password, 'organization-ids': org['id'], 'location-ids': loc['id'], } ) User.add_role({'login': user['login'], 'role': 'Ansible Tower Inventory Reader'}) host_name = gen_string('alpha').lower() host = make_fake_host({'name': host_name}) schedule = ReportTemplate.with_user(username=user['login'], password=password).schedule( {'name': template_name} ) report_data = ReportTemplate.with_user( username=user['login'], password=password ).report_data({'id': template_name, 'job-id': schedule[0].split("Job ID: ", 1)[1]}) assert host['name'] in [item.split(',')[1] for item in report_data if len(item) > 0]
def test_positive_update_login_page_footer_text_with_long_string(self): """Attempt to update parameter "Login_page_footer_text" with long length string under General tab :id: 87ef6b19-fdc5-4541-aba8-e730f1a3caa7 :steps: 1. Execute "settings" command with "set" as sub-command with long length string :expectedresults: Parameter is updated :CaseImportance: Low """ for login_text_value in generate_strings_list(1000): with self.subTest(login_text_value): Settings.set({'name': "login_text", 'value': login_text_value}) login_text = Settings.list({'search': 'name=login_text'})[0] self.assertEqual(login_text_value, login_text['value'])
def test_positive_update_login_page_footer_text_with_long_string(self): """Attempt to update parameter "Login_page_footer_text" with long length string under General tab :id: 87ef6b19-fdc5-4541-aba8-e730f1a3caa7 :steps: 1. Execute "settings" command with "set" as sub-command with long length string :expectedresults: Parameter is updated :caseimportance: low """ for login_text_value in generate_strings_list(1000): with self.subTest(login_text_value): Settings.set({'name': "login_text", 'value': login_text_value}) login_text = Settings.list({'search': 'name=login_text'})[0] self.assertEqual(login_text_value, login_text['value'])
def test_positive_update_email_reply_address(setting_update): """Check email reply address is updated :id: cb0907d1-9cb6-45c4-b2bb-e2790ea55f16 :parametrized: yes :expectedresults: email_reply_address is updated :CaseImportance: Low :CaseAutomation: Automated """ email_address = random.choice(list(valid_emails_list())) email_address = email_address.replace('"', r'\"').replace('`', r'\`') Settings.set({'name': "email_reply_address", 'value': email_address}) email_reply_address = Settings.list({'search': 'name=email_reply_address'}, output_format='json')[0] assert email_reply_address['value'] == email_address
def test_positive_update_login_page_footer_text(setting_update): """Updates parameter "login_text" in settings :id: 4d4e1151-5bd6-4fa2-8dbb-e182b43ad7ec :steps: 1. Execute "settings" command with "set" as sub-command with any string :parametrized: yes :expectedresults: Parameter is updated successfully """ login_text_value = random.choice(list(valid_data_list().values())) Settings.set({'name': "login_text", 'value': login_text_value}) login_text = Settings.list({'search': 'name=login_text'})[0] assert login_text["value"] == login_text_value
def test_positive_failed_login_attempts_limit(setting_update, target_sat): """automate brute force protection limit configurable function :id: f95407ed-451b-4387-ac9b-2959ae2f51ae :steps: 1. Make sure login works. 2. Save current value and set it to some lower value: 3. Try to login with wrong password till failed_login_attempts_limit 4. Make sure login now does not work: 5. Wait timeout - 5 minutes + 1 second 6. Verify you can now login fine 7. Return the setting to previous value :CaseImportance: Critical :CaseLevel: System :parametrized: yes :expectedresults: failed_login_attempts_limit works as expected :CaseAutomation: Automated :BZ: 1778599 """ username = settings.server.admin_username password = settings.server.admin_password assert target_sat.execute( f'hammer -u {username} -p {password} user list').status == 0 Settings.set({'name': 'failed_login_attempts_limit', 'value': '5'}) for _ in range(5): assert target_sat.execute( f'hammer -u {username} -p BAD_PASS user list').status == 129 assert target_sat.execute( f'hammer -u {username} -p {password} user list').status == 129 sleep(301) assert target_sat.execute( f'hammer -u {username} -p {password} user list').status == 0 Settings.set({'name': 'failed_login_attempts_limit', 'value': '0'}) assert Settings.info({'name': 'failed_login_attempts_limit'})['value'] == '0'
def test_positive_update_login_page_footer_text_with_long_string(setting_update): """Attempt to update parameter "Login_page_footer_text" with long length string under General tab :id: 87ef6b19-fdc5-4541-aba8-e730f1a3caa7 :steps: 1. Execute "settings" command with "set" as sub-command with long length string :parametrized: yes :expectedresults: Parameter is updated :CaseImportance: Low """ login_text_value = random.choice(list(generate_strings_list(1000))) Settings.set({'name': "login_text", 'value': login_text_value}) login_text = Settings.list({'search': 'name=login_text'})[0] assert login_text['value'] == login_text_value
def test_negative_update_email_reply_address(self): """Check email reply address is not updated :id: 2a2220c2-badf-47d5-ba3f-e6329930ab39 :steps: provide invalid email addresses :expectedresults: email_reply_address is not updated :caseimportance: low :caseautomation: automated """ for email in invalid_emails_list(): with self.subTest(email): with self.assertRaises(CLIReturnCodeError): Settings.set({ 'name': 'email_reply_address', 'value': email })
def test_positive_update_email_reply_address(self): """Check email reply address is updated :id: cb0907d1-9cb6-45c4-b2bb-e2790ea55f16 :expectedresults: email_reply_address is updated :CaseImportance: Low :CaseAutomation: automated """ for email in valid_emails_list(): with self.subTest(email): # The email must be escaped because some characters to not fail # the parsing of the generated shell command escaped_email = email.replace('"', r'\"').replace('`', r'\`') Settings.set({'name': "email_reply_address", 'value': escaped_email}) email_reply_address = Settings.list( {'search': 'name=email_reply_address'}, output_format='json' )[0] self.assertEqual(email_reply_address['value'], email)
def test_positive_update_rssfeed_url(setting_update): """Check if the RSS feed URL is updated :id: 166ff6f2-e36e-4934-951f-b947139d0d73 :steps: 1. Save the original RSS URL 2. Update RSS feed with a valid URL 3. Assert the RSS feed URL was really updated 4. Restore the original feed URL :parametrized: yes :expectedresults: RSS feed URL is updated :CaseAutomation: Automated """ test_url = random.choice(list(valid_url_list())) Settings.set({'name': 'rss_url', 'value': test_url}) updated_url = Settings.list({'search': 'name=rss_url'})[0] assert updated_url['value'] == test_url
def test_positive_create_with_default_download_policy(self): """Verify if the default download policy is assigned when creating a YUM repo without `--download-policy` @id: 9a3c4d95-d6ca-4377-9873-2c552b7d6ce7 @Assert: YUM repository with a default download policy """ default_dl_policy = Settings.list({"search": "name=default_download_policy"}) self.assertTrue(default_dl_policy) new_repo = self._make_repository({u"content-type": u"yum"}) self.assertEqual(new_repo["download-policy"], default_dl_policy[0]["value"])
def test_positive_failed_login_attempts_limit(self): """automate brute force protection limit configurable function :id: f95407ed-451b-4387-ac9b-2959ae2f51ae :steps: 1. Make sure login works. 2. Save current value and set it to some lower value: 3. Try to login with wrong password till failed_login_attempts_limit 4. Make sure login now does not work: 5. Wait timeout - 5 minutes + 1 second 6. Verify you can now login fine 7. Return the setting to previous value :expectedresults: failed_login_attempts_limit works as expected :caseautomation: automated """ result = ssh.command( 'hammer -u {0} -p {1} user list' .format(self.foreman_user, self.foreman_password)) self.assertEqual(result.return_code, 0) Settings.set({ u'name': u'failed_login_attempts_limit', u'value': '5' }) for i in range(5): output = ssh.command( 'hammer -u {0} -p BAD_PASS user list'.format( self.foreman_user)) self.assertEqual(output.return_code, 129) result = ssh.command( 'hammer -u {0} -p {1} user list' .format(self.foreman_user, self.foreman_password)) self.assertEqual(result.return_code, 129) sleep(301) result = ssh.command( 'hammer -u {0} -p {1} user list' .format(self.foreman_user, self.foreman_password)) self.assertEqual(result.return_code, 0)
def test_positive_create_session(admin_user, target_sat): """Check if user stays authenticated with session enabled :id: fcee7f5f-1040-41a9-bf17-6d0c24a93e22 :Steps: 1. Set use_sessions, set short expiration time 2. Authenticate, assert credentials are not demanded on next command run 3. Wait until session expires, assert credentials are required :expectedresults: The session is successfully created and expires after specified time """ try: idle_timeout = Settings.list({'search': 'name=idle_timeout'})[0]['value'] Settings.set({'name': 'idle_timeout', 'value': 1}) result = configure_sessions(target_sat) assert result == 0, 'Failed to configure hammer sessions' AuthLogin.basic({ 'username': admin_user['login'], 'password': password }) result = Auth.with_user().status() assert LOGEDIN_MSG.format(admin_user['login']) in result[0]['message'] # list organizations without supplying credentials assert Org.with_user().list() # wait until session expires sleep(70) with pytest.raises(CLIReturnCodeError): Org.with_user().list() result = Auth.with_user().status() assert LOGEDOFF_MSG.format(admin_user['login']) in result[0]['message'] finally: # reset timeout to default Settings.set({'name': 'idle_timeout', 'value': f'{idle_timeout}'})
def tearDownClass(cls): """Restore default global setting's values""" Settings.set({'name': 'discovery_location', 'value': cls.default_discovery_loc['value']}) Settings.set( {'name': 'discovery_organization', 'value': cls.default_discovery_org['value']} ) Settings.set({'name': 'discovery_auto', 'value': cls.default_discovery_auto['value']}) super().tearDownClass()
def test_positive_update_email_subject_prefix(self): """Check email subject prefix is updated :id: c8e6b323-7b39-43d6-a9f1-5474f920bba2 :expectedresults: email_subject_prefix is updated :caseautomation: automated :caseimportance: low """ email_subject_prefix_value = gen_string('alpha') Settings.set({ 'name': "email_subject_prefix", 'value': email_subject_prefix_value }) email_subject_prefix = Settings.list({ 'search': 'name=email_subject_prefix' })[0] self.assertEqual( email_subject_prefix_value, email_subject_prefix['value'] )
def test_positive_update_email_reply_address(self): """Check email reply address is updated :id: cb0907d1-9cb6-45c4-b2bb-e2790ea55f16 :expectedresults: email_reply_address is updated :caseimportance: low :caseautomation: automated """ for email in valid_emails_list(): with self.subTest(email): # The email must be escaped because some characters to not fail # the parsing of the generated shell command escaped_email = email.replace( '"', r'\"').replace('`', r'\`') Settings.set({ 'name': "email_reply_address", 'value': escaped_email}) email_reply_address = Settings.list({ 'search': 'name=email_reply_address' }, output_format='json')[0] self.assertEqual(email_reply_address['value'], email)
def setUpClass(cls): """Steps to Configure foreman discovery 1. Build PXE default template 2. Create Organization/Location 3. Update Global parameters to set default org and location for discovered hosts. 4. Enable auto_provision flag to perform discovery via discovery rules. """ super(DiscoveredTestCase, cls).setUpClass() # Build PXE default template to get default PXE file Template.build_pxe_default() # Create Org and location cls.org = make_org() cls.loc = make_location() # Get default settings values cls.default_discovery_loc = Settings.list( {'search': 'name=%s' % 'discovery_location'})[0] cls.default_discovery_org = Settings.list( {'search': 'name=%s' % 'discovery_organization'})[0] cls.default_discovery_auto = Settings.list( {'search': 'name=%s' % 'discovery_auto'})[0] # Update default org and location params to place discovered host Settings.set({'name': 'discovery_location', 'value': cls.loc['name']}) Settings.set( {'name': 'discovery_organization', 'value': cls.org['name']}) # Enable flag to auto provision discovered hosts via discovery rules Settings.set({'name': 'discovery_auto', 'value': 'true'}) # Flag which shows whether environment is fully configured for # discovered host provisioning. cls.configured_env = False
def tearDownClass(cls): """Restore default global setting's values""" Settings.set({ 'name': 'discovery_location', 'value': cls.default_discovery_loc['value'] }) Settings.set({ 'name': 'discovery_organization', 'value': cls.default_discovery_org['value'] }) Settings.set({ 'name': 'discovery_auto', 'value': cls.default_discovery_auto['value'] }) super(DiscoveredTestCase, cls).tearDownClass()
def test_positive_enable_disable_rssfeed(self): """Check if the RSS feed can be enabled or disabled :id: 021cefab-2629-44e2-a30d-49c944d0a234 :steps: Set rss_enable true or false :expectedresults: rss_enable is updated :caseautomation: automated """ orig_value = Settings.list({'search': 'name=rss_enable'})[0]['value'] for value in ['true', 'false']: Settings.set({'name': 'rss_enable', 'value': value}) rss_setting = Settings.list({'search': 'name=rss_enable'})[0] self.assertEqual(value, rss_setting['value']) Settings.set({'name': 'rss_enable', 'value': orig_value})
def test_positive_update_rssfeed_url(self): """Check if the RSS feed URL is updated :id: 166ff6f2-e36e-4934-951f-b947139d0d73 :steps: 1. Save the original RSS URL 2. Update RSS feed with a valid URL 3. Assert the RSS feed URL was really updated 4. Restore the original feed URL :expectedresults: RSS feed URL is updated :caseautomation: automated """ orig_url = Settings.list({'search': 'name=rss_url'})[0]['value'] for test_url in valid_url_list(): Settings.set({'name': 'rss_url', 'value': test_url}) updated_url = Settings.list({'search': 'name=rss_url'})[0] self.assertEqual(test_url, updated_url['value']) Settings.set({'name': 'rss_url', 'value': orig_url})
def setUpClass(cls): super(BruteForceLogin, cls).setUpClass() cls.host_value = Settings.list({ 'search': 'name=failed_login_attempts_limit'})[0]['value']
def tearDown(self): """Will reset the changed value of settings""" Settings.set({ 'name': "outofsync_interval", 'value': "30" })
def test_system_admin_role_end_to_end(self): """Test System admin role with a end to end workflow :id: da6b3549-d1cf-44fc-869f-08d15d407fa2 :steps: 1. Create a System admin role user1 2. Login with the user1 and change global settings "Out of sync interval" to 31 3. Create user2 with system admin role 4. Login with user2 to create a Organization 5. Clone a Org-admin role 6. Edit the Architecture Filter and search name = x86_64 7. Create a User with Cloned Org admin 8. Login with user. :expectedresults: 1. User should be assigned with System Admin role. 2. User with sys admin role should be able to update settings 3. User with sys admin role should be able to create users and assign Organizations to them. 4. System Admin role should be able to create Organization admins 5. User with sys admin role should be able to edit filters on roles :CaseLevel: System """ org = make_org() location = make_location() common_pass = gen_string('alpha') role = Role.info({'name': 'System admin'}) system_admin_1 = make_user({ 'password': common_pass, 'organization-ids': org['id'], 'location-ids': location['id'] }) User.add_role({ 'id': system_admin_1['id'], 'role-id': role['id'] }) Settings.with_user( username=system_admin_1['login'], password=common_pass).set({ 'name': "outofsync_interval", 'value': "32" }) sync_time = Settings.list({ 'search': 'name=outofsync_interval' })[0] # Asserts if the setting was updated successfully self.assertEqual('32', sync_time['value']) # Create another System Admin user using the first one system_admin = User.with_user( username=system_admin_1['login'], password=common_pass).create({ u'auth-source-id': 1, u'firstname': gen_string('alpha'), u'lastname': gen_string('alpha'), u'login': gen_string('alpha'), u'mail': '{0}@example.com'.format(gen_string('alpha')), u'password': common_pass, u'organizations': org['name'], u'role-ids': role['id'], u'locations': location['name'] }) # Create the Org Admin user org_role = Role.with_user( username=system_admin['login'], password=common_pass).clone({ 'name': 'Organization admin', 'new-name': gen_string('alpha'), 'organization-ids': org['id'], 'location-ids': location['id'] }) org_admin = User.with_user( username=system_admin['login'], password=common_pass).create({ u'auth-source-id': 1, u'firstname': gen_string('alpha'), u'lastname': gen_string('alpha'), u'login': gen_string('alpha'), u'mail': '{0}@example.com'.format(gen_string('alpha')), u'password': common_pass, u'organizations': org['name'], u'role-ids': org_role['id'], u'location-ids': location['id'] }) # Assert if the cloning was successful self.assertIsNotNone(org_role['id']) org_role_filters = Role.filters({'id': org_role['id']}) search_filter = None for arch_filter in org_role_filters: if arch_filter['resource-type'] == 'Architecture': search_filter = arch_filter break Filter.with_user( username=system_admin['login'], password=common_pass).update({ 'role-id': org_role['id'], 'id': arch_filter['id'], 'search': 'name=x86_64' }) # Asserts if the filter is updated self.assertIn('name=x86_64', Filter.info({ 'id': search_filter['id'] }).values() ) org_admin = User.with_user( username=system_admin['login'], password=common_pass).info({'id': org_admin['id']}) # Asserts Created Org Admin self.assertIn(org_role['name'], org_admin['roles']) self.assertIn(org['name'], org_admin['organizations'])