def test_verify_bugzilla_1103157(self): """Create organization and add two compute resources one by one using different transactions and different users to see that they actually added, but not overwrite each other :id: 5f4fd2b7-d998-4980-b5e7-9822bd54156b :Steps: 1. Use the admin user to create an organization and two compute resources. Make one compute resource point at / belong to the organization. 2. Create a user and give them the ability to update compute resources and organizations. Have this user make the second compute resource point at / belong to the organization. 3. Use the admin user to read information about the organization. Verify that both compute resources are pointing at / belong to the organization. :expectedresults: Organization contains both compute resources :CaseLevel: Integration """ # setUpClass() creates an organization w/admin user. Here, we use admin # to make two compute resources and make first belong to organization. compute_resources = [ entities.LibvirtComputeResource( name=gen_string('alpha'), url='qemu://host.example.com/system').create() for _ in range(2) ] self.organization.compute_resource = compute_resources[:1] # list self.organization = self.organization.update(['compute_resource']) self.assertEqual(len(self.organization.compute_resource), 1) # Create a new user and give them minimal permissions. login = gen_alphanumeric() password = gen_alphanumeric() user = entities.User(login=login, password=password).create() role = entities.Role().create() for perm in ['edit_compute_resources', 'edit_organizations']: permissions = [ entities.Permission(id=permission['id']) for permission in entities.Permission(name=perm).search() ] entities.Filter(permission=permissions, role=role).create() user.role = [role] user = user.update(['role']) # Make new user assign second compute resource to org. cfg = get_nailgun_config() cfg.auth = (login, password) entities.Organization( cfg, id=self.organization.id, compute_resource=compute_resources[1:], # slice returns list ).update(['compute_resource']) # Use admin to verify both compute resources belong to organization. self.assertEqual(len(self.organization.read().compute_resource), 2)
def test_verify_bugzilla_1103157(self): """Create organization and add two compute resources one by one using different transactions and different users to see that they actually added, but not overwrite each other @Feature: Organization - Update @Steps: 1. Use the admin user to create an organization and two compute resources. Make one compute resource point at / belong to the organization. 2. Create a user and give them the ability to update compute resources and organizations. Have this user make the second compute resource point at / belong to the organization. 3. Use the admin user to read information about the organization. Verify that both compute resources are pointing at / belong to the organization. @Assert: Organization contains both compute resources """ # setUpClass() creates an organization w/admin user. Here, we use admin # to make two compute resources and make first belong to organization. compute_resources = [ entities.LibvirtComputeResource( name=gen_string('alpha'), url='qemu://host.example.com/system' ).create() for _ in range(2) ] self.organization.compute_resource = compute_resources[:1] # list self.organization = self.organization.update(['compute_resource']) self.assertEqual(len(self.organization.compute_resource), 1) # Create a new user and give them minimal permissions. login = gen_alphanumeric() password = gen_alphanumeric() user = entities.User(login=login, password=password).create() role = entities.Role().create() for perm in ['edit_compute_resources', 'edit_organizations']: permissions = [ entities.Permission(id=permission['id']) for permission in entities.Permission(name=perm).search() ] entities.Filter(permission=permissions, role=role).create() user.role = [role] user = user.update(['role']) # Make new user assign second compute resource to org. cfg = get_nailgun_config() cfg.auth = (login, password) entities.Organization( cfg, id=self.organization.id, compute_resource=compute_resources[1:], # slice returns list ).update(['compute_resource']) # Use admin to verify both compute resources belong to organization. self.assertEqual(len(self.organization.read().compute_resource), 2)
def setUp(self): # noqa """Create a set of credentials and a user.""" self.cfg = get_nailgun_config() self.cfg.auth = (gen_alphanumeric(), gen_alphanumeric()) # user, pass self.user = entities.User( login=self.cfg.auth[0], password=self.cfg.auth[1], ).create()
def test_positive_reboot_all_pxe_hosts(_module_user, discovered_host_cleanup, discovery_settings, provisioning_env): """Rebooting all pxe-based discovered hosts :id: 69c807f8-5646-4aa6-8b3c-5ecdb69560ed :parametrized: yes :Setup: Provisioning should be configured and a hosts should be discovered via PXE boot. :Steps: PUT /api/v2/discovered_hosts/reboot_all :expectedresults: All disdcovered host should be rebooted successfully :CaseAutomation: Automated :CaseImportance: Medium """ cfg = get_nailgun_config() if _module_user: cfg.auth = (_module_user[0].login, _module_user[1]) # open ssh channels and attach them to foreman-tail output channel_1, channel_2 = ssh.get_client().invoke_shell(), ssh.get_client( ).invoke_shell() channel_1.send('foreman-tail\r') channel_2.send('foreman-tail\r') with LibvirtGuest() as pxe_host_1: _assert_discovered_host(pxe_host_1, channel_1, user_config=cfg) with LibvirtGuest() as pxe_host_2: _assert_discovered_host(pxe_host_2, channel_2, user_config=cfg) # reboot_all method leads to general /discovered_hosts/ path, so it doesn't matter # what DiscoveredHost object we execute this on try: entities.DiscoveredHost().reboot_all() except simplejson.errors.JSONDecodeError as e: if is_open('BZ:1893349'): pass else: raise e # assert that server receives DHCP discover from hosts PXELinux # this means that the hosts got rebooted for pxe_host in [(pxe_host_1, channel_1), (pxe_host_2, channel_2)]: for pattern in [ ( f"DHCPDISCOVER from {pxe_host[0].mac}", "DHCPDISCOVER", ), (f"DHCPACK on [0-9.]+ to {pxe_host[0].mac}", "DHCPACK"), ]: try: _wait_for_log(pxe_host[1], pattern[0], timeout=30) except TimedOutError: # raise assertion error raise AssertionError( f'Timed out waiting for {pattern[1]} from ' f'{pxe_host[0].mac}')
def create_user(self, create_org_loc): """Create a set of credentials and a user.""" self.cfg = get_nailgun_config() self.cfg.auth = (gen_alphanumeric(), gen_alphanumeric()) # user, pass self.user = entities.User( login=self.cfg.auth[0], password=self.cfg.auth[1], organization=[self.org], location=[self.loc], ).create()
def test_positive_provision_pxe_host_non_admin(self): """Provision a pxe-based discovered hosts by non-admin user :id: 02144040-6cf6-4251-abaf-b0fad2c83109 :Setup: Provisioning should be configured and a host should be discovered :Steps: PUT /api/v2/discovered_hosts/:id :expectedresults: Host should be provisioned successfully by non admin user :CaseImportance: Critical :bz: 1638403 """ non_admin = create_org_admin_user(orgs=[self.org.id], locs=[self.loc.id]) nonadmin_config = get_nailgun_config(non_admin) if not self.configured_env: self.__class__.configured_env = configure_env_for_provision( org={ 'id': self.org.id, 'name': self.org.name }, loc={ 'id': self.loc.id, 'name': self.loc.name }, ) with LibvirtGuest() as pxe_host: hostname = pxe_host.guest_name discovered_host = self._assertdiscoveredhost( hostname, nonadmin_config) # Provision just discovered host discovered_host.hostgroup = entities.HostGroup( nonadmin_config, id=self.configured_env['hostgroup']['id']).read() discovered_host.root_pass = gen_string('alphanumeric') discovered_host.update(['hostgroup', 'root_pass']) # Assertions provisioned_host = entities.Host(nonadmin_config).search( query={ 'search': 'name={}.{}'.format(discovered_host.name, self.configured_env['domain']['name']) })[0] assert provisioned_host.subnet.read( ).name == self.configured_env['subnet']['name'] assert (provisioned_host.operatingsystem.read().ptable[0].read(). name == self.configured_env['ptable']['name']) assert (provisioned_host.operatingsystem.read().title == self.configured_env['os']['title']) assert not entities.DiscoveredHost(nonadmin_config).search( query={'search': f'name={discovered_host.name}'})
def setUp(self): # noqa """Create a set of credentials and a user.""" super(UserRoleTestCase, self).setUp() self.cfg = get_nailgun_config() self.cfg.auth = (gen_alphanumeric(), gen_alphanumeric()) # user, pass self.user = entities.User( login=self.cfg.auth[0], password=self.cfg.auth[1], organization=[self.org], location=[self.loc], ).create()
def test_positive_provision_pxe_host(_module_user, discovery_settings, provisioning_env): """Provision a pxe-based discovered hosts :id: e805b9c5-e8f6-4129-a0e6-ab54e5671ddb :parametrized: yes :Setup: Provisioning should be configured and a host should be discovered :Steps: PUT /api/v2/discovered_hosts/:id :expectedresults: Host should be provisioned successfully :CaseImportance: Critical """ cfg = get_nailgun_config() if _module_user: cfg.auth = (_module_user[0].login, _module_user[1]) # open a ssh channel and attach it to foreman-tail output ssh_client = ssh.get_client() with ssh_client.invoke_shell() as channel: channel.send('foreman-tail\r') with LibvirtGuest() as pxe_host: discovered_host = _assert_discovered_host(pxe_host, channel, user_config=cfg) # Provision just discovered host discovered_host.hostgroup = entities.HostGroup( cfg, id=provisioning_env['hostgroup']['id']).read() discovered_host.root_pass = gen_string('alphanumeric') discovered_host.update(['hostgroup', 'root_pass']) # Assertions provisioned_host = entities.Host(cfg).search( query={ 'search': 'name={}.{}'.format(discovered_host.name, provisioning_env['domain']['name']) })[0] assert provisioned_host.subnet.read( ).name == provisioning_env['subnet']['name'] assert (provisioned_host.operatingsystem.read().ptable[0].read(). name == provisioning_env['ptable']['name']) assert provisioned_host.operatingsystem.read( ).title == provisioning_env['os']['title'] assert not entities.DiscoveredHost(cfg).search( query={'search': f'name={discovered_host.name}'})
def test_positive_reboot_pxe_host(_module_user, discovery_settings, provisioning_env): """Rebooting a pxe based discovered host :id: 69c807f8-5646-4aa6-8b3c-5ecab69560fc :parametrized: yes :Setup: Provisioning should be configured and a host should be discovered via PXE boot. :Steps: PUT /api/v2/discovered_hosts/:id/reboot :expectedresults: Selected host should be rebooted successfully :CaseAutomation: Automated :CaseImportance: Medium """ cfg = get_nailgun_config() if _module_user: cfg.auth = (_module_user[0].login, _module_user[1]) # open a ssh channel and attach it to foreman-tail output ssh_client = ssh.get_client() with ssh_client.invoke_shell() as channel: channel.send('foreman-tail\r') with LibvirtGuest() as pxe_host: discovered_host = _assert_discovered_host(pxe_host, channel, user_config=cfg) discovered_host.reboot() # assert that server receives DHCP discover from hosts PXELinux # this means that the host got rebooted for pattern in [ ( f"DHCPDISCOVER from {pxe_host.mac}", "DHCPDISCOVER", ), (f"DHCPACK on [0-9.]+ to {pxe_host.mac}", "DHCPACK"), ]: try: _wait_for_log(channel, pattern[0], timeout=30) except TimedOutError: # raise assertion error raise AssertionError( f'Timed out waiting for {pattern[1]} from VM')
def test_negative_post_unauthorized(self, entity_cls): """POST to an entity-dependent path without credentials. :id: 2ec82336-5bcc-451a-90ed-9abcecc5a0a8 :parametrized: yes :expectedresults: HTTP 401 is returned :BZ: 1122257 """ server_cfg = get_nailgun_config() server_cfg.auth = () return_code = entity_cls(server_cfg).create_raw(create_missing=False).status_code assert http.client.UNAUTHORIZED == return_code
def test_post_unauthorized(self): """@Test: POST to an entity-dependent path without credentials. @Feature: Test multiple API paths @Assert: HTTP 401 is returned """ for entity_cls in valid_entities(): with self.subTest(entity_cls): logger.debug('test_post_unauthorized arg: %s', entity_cls) skip_if_sam(self, entity_cls) server_cfg = get_nailgun_config() server_cfg.auth = () return_code = entity_cls(server_cfg).create_raw( create_missing=False ).status_code self.assertEqual(httplib.UNAUTHORIZED, return_code)
def test_positive_search_with_non_admin_user(self): """Search for specific smart class parameter using non admin user :id: 79bd4071-1baa-44af-91dd-1e093445af29 :expectedresults: Specified smart class parameter can be found in the system :BZ: 1391556 :CaseLevel: Integration """ sc_param = self.sc_params_list.pop() username = gen_string('alpha') password = gen_string('alpha') required_user_permissions = { 'Puppetclass': [ 'view_puppetclasses', ], 'PuppetclassLookupKey': [ 'view_external_parameters', 'create_external_parameters', 'edit_external_parameters', 'destroy_external_parameters', ], } role = entities.Role().create() create_role_permissions(role, required_user_permissions) entities.User( login=username, password=password, role=[role], admin=False ).create() # assert that the user is not an admin one and cannot read the current # role info (note: view_roles is not in the required permissions) cfg = get_nailgun_config() cfg.auth = (username, password) with self.assertRaises(HTTPError) as context: entities.Role(cfg, id=role.id).read() self.assertIn( '403 Client Error: Forbidden', context.exception.message) with Session(self.browser, username, password): self.assertIsNotNone(self.sc_parameters.search(sc_param.parameter))
def test_positive_search_with_non_admin_user(test_name, sc_params_list): """Search for specific smart class parameter using non admin user :id: 79bd4071-1baa-44af-91dd-1e093445af29 :expectedresults: Specified smart class parameter can be found in the system :BZ: 1391556 :CaseLevel: Integration """ sc_param = sc_params_list.pop() username = gen_string('alpha') password = gen_string('alpha') required_user_permissions = { 'Puppetclass': [ 'view_puppetclasses', ], 'PuppetclassLookupKey': [ 'view_external_parameters', 'create_external_parameters', 'edit_external_parameters', 'destroy_external_parameters', ], } role = entities.Role().create() create_role_permissions(role, required_user_permissions) entities.User( login=username, password=password, role=[role], admin=False ).create() # assert that the user is not an admin one and cannot read the current # role info (note: view_roles is not in the required permissions) cfg = get_nailgun_config() cfg.auth = (username, password) with raises(HTTPError) as context: entities.Role(cfg, id=role.id).read() assert '403 Client Error: Forbidden' in str(context.value) with Session(test_name, user=username, password=password) as session: assert session.sc_parameter.search( sc_param.parameter)[0]['Parameter'] == sc_param.parameter
def test_negative_post_unauthorized(self): """POST to an entity-dependent path without credentials. :id: 2ec82336-5bcc-451a-90ed-9abcecc5a0a8 :expectedresults: HTTP 401 is returned :BZ: 1122257 """ exclude_list = (entities.TemplateKind,) # see comments in class definition test_entities = self.get_entities_for_unauthorized(valid_entities(), exclude_list) for entity_cls in test_entities: with self.subTest(entity_cls): self.logger.info('test_post_unauthorized arg: %s', entity_cls) server_cfg = get_nailgun_config() server_cfg.auth = () return_code = entity_cls(server_cfg).create_raw(create_missing=False).status_code self.assertEqual(http.client.UNAUTHORIZED, return_code)
def test_negative_post_unauthorized(self): """POST to an entity-dependent path without credentials. @id: 2ec82336-5bcc-451a-90ed-9abcecc5a0a8 @Assert: HTTP 401 is returned """ exclude_list = ( entities.TemplateKind, # see comments in class definition ) for entity_cls in set(valid_entities()) - set(exclude_list): with self.subTest(entity_cls): self.logger.info('test_post_unauthorized arg: %s', entity_cls) skip_if_sam(self, entity_cls) server_cfg = get_nailgun_config() server_cfg.auth = () return_code = entity_cls(server_cfg).create_raw( create_missing=False ).status_code self.assertEqual(http_client.UNAUTHORIZED, return_code)
def test_negative_post_unauthorized(self): """POST to an entity-dependent path without credentials. @id: 2ec82336-5bcc-451a-90ed-9abcecc5a0a8 @Assert: HTTP 401 is returned """ exclude_list = ( entities.TemplateKind, # see comments in class definition ) for entity_cls in set(valid_entities()) - set(exclude_list): with self.subTest(entity_cls): logger.debug('test_post_unauthorized arg: %s', entity_cls) skip_if_sam(self, entity_cls) server_cfg = get_nailgun_config() server_cfg.auth = () return_code = entity_cls(server_cfg).create_raw( create_missing=False ).status_code self.assertEqual(http_client.UNAUTHORIZED, return_code)
def test_positive_remove_user(self): """Delete any user who has previously created an activation key and check that activation key still exists :id: 02ce92d4-8f49-48a0-bf9e-5d401f84cf46 :expectedresults: Activation Key can be read :BZ: 1291271 """ password = gen_string('alpha') user = entities.User(password=password, login=gen_string('alpha'), admin=True).create() cfg = get_nailgun_config() cfg.auth = (user.login, password) ak = entities.ActivationKey(cfg).create() user.delete() try: entities.ActivationKey(id=ak.id).read() except HTTPError: self.fail("Activation Key can't be read")
def test_post_unauthorized(self): """@Test: POST to an entity-dependent path without credentials. @Feature: Test multiple API paths @Assert: HTTP 401 is returned """ exclude_list = ( entities.TemplateKind, # see comments in class definition ) for entity_cls in set(valid_entities()) - set(exclude_list): with self.subTest(entity_cls): logger.debug('test_post_unauthorized arg: %s', entity_cls) skip_if_sam(self, entity_cls) server_cfg = get_nailgun_config() server_cfg.auth = () return_code = entity_cls(server_cfg).create_raw( create_missing=False ).status_code self.assertEqual(http_client.UNAUTHORIZED, return_code)
def test_positive_update_with_manager_role(self): """Create template providing the initial name, then update its name with manager user role. :id: 0aed79f0-7c9a-4789-99ba-56f2db82f097 :expectedresults: Provisioning Template is created, and its name can be updated. :CaseImportance: Critical :BZ: 1277308 """ user_login = gen_string('alpha') user_password = gen_string('alpha') new_name = gen_string('alpha') org = entities.Organization().create() loc = entities.Location().create() template = entities.ProvisioningTemplate(organization=[org], location=[loc]).create() # Create user with Manager role role = entities.Role().search(query={'search': 'name="Manager"'})[0] entities.User( role=[role], admin=False, login=user_login, password=user_password, organization=[org], location=[loc], ).create() # Update template name with that user cfg = get_nailgun_config() cfg.auth = (user_login, user_password) updated = entities.ProvisioningTemplate(cfg, id=template.id, name=new_name).update(['name']) self.assertEqual(updated.name, new_name)
def test_positive_update_with_manager_role(self): """Create template providing the initial name, then update its name with manager user role. :id: 0aed79f0-7c9a-4789-99ba-56f2db82f097 :expectedresults: Provisioning Template is created, and its name can be updated. :CaseImportance: Critical :BZ: 1277308 """ user_login = gen_string('alpha') user_password = gen_string('alpha') new_name = gen_string('alpha') org = entities.Organization().create() loc = entities.Location().create() template = entities.ProvisioningTemplate( organization=[org], location=[loc]).create() # Create user with Manager role role = entities.Role().search(query={'search': 'name="Manager"'})[0] entities.User( role=[role], admin=False, login=user_login, password=user_password, organization=[org], location=[loc], ).create() # Update template name with that user cfg = get_nailgun_config() cfg.auth = (user_login, user_password) updated = entities.ProvisioningTemplate( cfg, id=template.id, name=new_name).update(['name']) self.assertEqual(updated.name, new_name)
def test_positive_remove_user(self): """Delete any user who has previously created an activation key and check that activation key still exists :id: 02ce92d4-8f49-48a0-bf9e-5d401f84cf46 :expectedresults: Activation Key can be read :BZ: 1291271 """ password = gen_string('alpha') user = entities.User( password=password, login=gen_string('alpha'), admin=True, ).create() cfg = get_nailgun_config() cfg.auth = (user.login, password) ak = entities.ActivationKey(cfg).create() user.delete() try: entities.ActivationKey(id=ak.id).read() except HTTPError: self.fail("Activation Key can't be read")
def test_positive_end_to_end_crud(self, module_org, module_location, module_user): """Create a new provisioning template with several attributes, update them, clone the provisioning template and then delete it :id: 8dfbb234-7a52-4873-be72-4de086472670 :expectedresults: Template is created, with all the given attributes, updated, cloned and deleted :CaseImportance: Critical """ cfg = get_nailgun_config() cfg.auth = (module_user[1], module_user[2]) name = gen_string('alpha') new_name = gen_string('alpha') template_kind = choice(entities.TemplateKind().search()) template = entities.ProvisioningTemplate( name=name, organization=[module_org], location=[module_location], snippet=False, template_kind=template_kind, ).create() assert template.name == name assert len(template.organization ) == 1, "Template should be assigned to a single org here" assert template.organization[0].id == module_org.id assert len( template.location ) == 1, "Template should be assigned to a single location here" assert template.location[0].id == module_location.id assert template.snippet is False, "Template snippet attribute is True instead of False" assert template.template_kind.id == template_kind.id # negative create with pytest.raises(HTTPError) as e1: entities.ProvisioningTemplate( name=gen_choice(invalid_names_list())).create() assert e1.value.response.status_code == 422 invalid = entities.ProvisioningTemplate(snippet=False) invalid.create_missing() invalid.template_kind = None invalid.template_kind_name = gen_string('alpha') with pytest.raises(HTTPError) as e2: invalid.create(create_missing=False) assert e2.value.response.status_code == 422 # update assert template.template_kind.id == template_kind.id, "Template kind id doesn't match" updated = entities.ProvisioningTemplate(cfg, id=template.id, name=new_name).update(['name']) assert updated.name == new_name, "The Provisioning template wasn't properly renamed" # clone template_origin = template.read_json() # remove unique keys unique_keys = ('updated_at', 'created_at', 'id', 'name') template_origin = { key: value for key, value in template_origin.items() if key not in unique_keys } dupe_name = gen_choice(list(valid_data_list().values())) dupe_json = entities.ProvisioningTemplate(id=template.clone( data={'name': dupe_name})['id']).read_json() dupe_template = entities.ProvisioningTemplate(id=dupe_json['id']) dupe_json = { key: value for key, value in dupe_json.items() if key not in unique_keys } assert template_origin == dupe_json # delete dupe_template.delete() template.delete() with pytest.raises(HTTPError) as e3: updated.read() assert e3.value.response.status_code == 404
def test_positive_provision_pxe_host_dhcp_change(self, discovery_settings, provisioning_env, target_sat): """Discovered host is provisioned in dhcp range defined in subnet entity :id: 7ab654de-16dd-4a8b-946d-f6adde310340 :bz: 1367549 :customerscenario: true :Setup: Provisioning should be configured and a host should be discovered :Steps: 1. Set some dhcp range in dhcpd.conf in satellite. 2. Create subnet entity in satellite with a range different from whats defined in `dhcpd.conf`. 3. Create Hostgroup with the step 2 subnet. 4. Discover a new host in satellite. 5. Provision a host with the hostgroup created in step 3. :expectedresults: 1. The discovered host should be discovered with range defined in dhcpd.conf 2. But provisoning the discovered host should acquire an IP from dhcp range defined in subnet entity. :CaseImportance: Critical """ subnet = target_sat.api.Subnet( id=provisioning_env['subnet']['id']).read() # Updating satellite subnet component and dhcp conf ranges # Storing now for restoring later old_sub_from = subnet.from_ old_sub_to = subnet.to old_sub_to_4o = old_sub_to.split('.')[-1] # Calculating Subnet's new `from` range in Satellite Subnet Component new_subnet_from = subnet.from_[:subnet.from_.rfind('.') + 1] + str(int(old_sub_to_4o) - 9) # Same time, calculating dhcp confs new `to` range new_dhcp_conf_to = subnet.to[:subnet.to.rfind('.') + 1] + str(int(old_sub_to_4o) - 10) cfg = get_nailgun_config() with target_sat.session.shell() as shell: shell.send('foreman-tail') try: # updating the ranges in component and in dhcp.conf subnet.from_ = new_subnet_from subnet.update(['from_']) target_sat.execute( f'cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd_backup.conf && ' f'sed -ie \'s/{subnet.to}/{new_dhcp_conf_to}/\' /etc/dhcp/dhcpd.conf && ' f'systemctl restart dhcpd') with LibvirtGuest() as pxe_host: discovered_host = _assert_discovered_host( pxe_host, shell, cfg) # Assert Discovered host discovered within dhcp.conf range before provisioning assert int(discovered_host.ip.split('.')[-1]) <= int( new_dhcp_conf_to.split('.')[-1]) # Provision just discovered host discovered_host.hostgroup = target_sat.api.HostGroup( id=provisioning_env['hostgroup']['id']).read() discovered_host.root_pass = gen_string('alphanumeric') discovered_host.update(['hostgroup', 'root_pass']) # Assertions provisioned_host = target_sat.api.Host().search( query={ 'search': 'name={}.{}'.format( discovered_host.name, provisioning_env['domain']['name']) })[0] assert int(provisioned_host.ip.split('.')[-1]) >= int( new_subnet_from.split('.')[-1]) assert int(provisioned_host.ip.split('.')[-1]) <= int( old_sub_to_4o) assert not target_sat.api.DiscoveredHost().search( query={'search': f'name={discovered_host.name}'}) finally: subnet.from_ = old_sub_from subnet.update(['from_']) target_sat.execute( 'mv /etc/dhcp/dhcpd_backup.conf /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf' )
def test_positive_update_bookmark_public(session, random_entity, module_viewer_user, module_user, test_name): """Update and save a bookmark public state :id: 63646c41-5441-4547-a4d0-744286122405 :Setup: 1. Create 2 bookmarks of a random name with random query, one public and one private 2. Create a non-admin user with 'viewer' role :Steps: 1. Login to Satellite server (establish a UI session) as the pre-created user 2. Navigate to the entity 3. List the bookmarks by clicking the drop down menu 4. Verify that only the public bookmark is listed 5. Log out 6. Login to Satellite server (establish a UI session) as the admin user 7. List the bookmarks (Navigate to Administer -> Bookmarks) 8. Click the public pre-created bookmark 9. Uncheck 'public' 10. Submit 11. Click the private pre-created bookmark 12. Check 'public' 13. Submit 14. Logout 15. Login to Satellite server (establish a UI session) as the pre-created user 16. Navigate to the entity 17. List the bookmarks by clicking the drop down menu :expectedresults: New public bookmark is listed, and the private one is hidden :CaseLevel: Integration """ public_name = gen_string('alphanumeric') nonpublic_name = gen_string('alphanumeric') cfg = get_nailgun_config() cfg.auth = (module_user.login, module_user.password) for name in (public_name, nonpublic_name): entities.Bookmark( cfg, name=name, controller=random_entity['controller'], public=name == public_name, ).create() with Session(test_name, module_viewer_user.login, module_viewer_user.password) as non_admin_session: assert non_admin_session.bookmark.search( public_name)[0]['Name'] == public_name assert not non_admin_session.bookmark.search(nonpublic_name) with session: session.bookmark.update(public_name, {'public': False}) session.bookmark.update(nonpublic_name, {'public': True}) with Session(test_name, module_viewer_user.login, module_viewer_user.password) as non_admin_session: assert non_admin_session.bookmark.search( nonpublic_name)[0]['Name'] == nonpublic_name assert not non_admin_session.bookmark.search(public_name)
def test_positive_end_to_end(self, fake_manifest_is_set, default_sat, rhel7_contenthost): """Perform end to end smoke tests using RH and custom repos. 1. Create a new user with admin permissions 2. Using the new user from above 1. Create a new organization 2. Clone and upload manifest 3. Create a new lifecycle environment 4. Create a custom product 5. Create a custom YUM repository 6. Enable a Red Hat repository 7. Synchronize these two repositories 8. Create a new content view 9. Associate the YUM and Red Hat repositories to new content view 10. Publish content view 11. Promote content view to the lifecycle environment 12. Create a new activation key 13. Add the products to the activation key 14. Create a new libvirt compute resource 15. Create a new subnet 16. Create a new domain 17. Create a new hostgroup and associate previous entities to it 18. Provision a client ** NOT CURRENTLY PROVISIONING :id: b2f73740-d3ce-4e6e-abc7-b23e5562bac1 :expectedresults: All tests should succeed and Content should be successfully fetched by client. :parametrized: yes """ # step 1: Create a new user with admin permissions login = gen_string('alphanumeric') password = gen_string('alphanumeric') entities.User(admin=True, login=login, password=password).create() # step 2.1: Create a new organization server_config = get_nailgun_config() server_config.auth = (login, password) org = entities.Organization(server_config).create() # step 2.2: Clone and upload manifest if fake_manifest_is_set: with manifests.clone() as manifest: upload_manifest(org.id, manifest.content) # step 2.3: Create a new lifecycle environment le1 = entities.LifecycleEnvironment(server_config, organization=org).create() # step 2.4: Create a custom product prod = entities.Product(server_config, organization=org).create() repositories = [] # step 2.5: Create custom YUM repository custom_repo = entities.Repository(server_config, product=prod, content_type='yum', url=CUSTOM_RPM_REPO).create() repositories.append(custom_repo) # step 2.6: Enable a Red Hat repository if fake_manifest_is_set: rhel_repo = entities.Repository(id=enable_rhrepo_and_fetchid( basearch='x86_64', org_id=org.id, product=constants.PRDS['rhel'], repo=constants.REPOS['rhst7']['name'], reposet=constants.REPOSET['rhst7'], )) repositories.append(rhel_repo) # step 2.7: Synchronize these two repositories for repo in repositories: repo.sync() # step 2.8: Create content view content_view = entities.ContentView(server_config, organization=org).create() # step 2.9: Associate the YUM and Red Hat repositories to new content view content_view.repository = repositories content_view = content_view.update(['repository']) # step 2.10: Publish content view content_view.publish() # step 2.11: Promote content view to the lifecycle environment content_view = content_view.read() assert len(content_view.version) == 1 cv_version = content_view.version[0].read() assert len(cv_version.environment) == 1 promote(cv_version, le1.id) # check that content view exists in lifecycle content_view = content_view.read() assert len(content_view.version) == 1 cv_version = cv_version.read() # step 2.12: Create a new activation key activation_key_name = gen_string('alpha') activation_key = entities.ActivationKey( name=activation_key_name, environment=le1, organization=org, content_view=content_view).create() # step 2.13: Add the products to the activation key for sub in entities.Subscription(organization=org).search(): if sub.name == constants.DEFAULT_SUBSCRIPTION_NAME: activation_key.add_subscriptions(data={ 'quantity': 1, 'subscription_id': sub.id }) break # step 2.13.1: Enable product content if fake_manifest_is_set: activation_key.content_override( data={ 'content_overrides': [{ 'content_label': constants.REPOS['rhst7']['id'], 'value': '1' }] }) # BONUS: Create a content host and associate it with promoted # content view and last lifecycle where it exists content_host = entities.Host( content_facet_attributes={ 'content_view_id': content_view.id, 'lifecycle_environment_id': le1.id, }, organization=org, ).create() # check that content view matches what we passed assert content_host.content_facet_attributes[ 'content_view_id'] == content_view.id # check that lifecycle environment matches assert content_host.content_facet_attributes[ 'lifecycle_environment_id'] == le1.id # step 2.14: Create a new libvirt compute resource entities.LibvirtComputeResource( server_config, url=f'qemu+ssh://root@{settings.libvirt.libvirt_hostname}/system', ).create() # step 2.15: Create a new subnet subnet = entities.Subnet(server_config).create() # step 2.16: Create a new domain domain = entities.Domain(server_config).create() # step 2.17: Create a new hostgroup and associate previous entities to it entities.HostGroup(server_config, domain=domain, subnet=subnet).create() # step 2.18: Provision a client # TODO this isn't provisioning through satellite as intended # Note it wasn't well before the change that added this todo rhel7_contenthost.install_katello_ca(default_sat) # Register client with foreman server using act keys rhel7_contenthost.register_contenthost(org.label, activation_key_name) assert rhel7_contenthost.subscribed # Install rpm on client package_name = 'katello-agent' result = rhel7_contenthost.execute(f'yum install -y {package_name}') assert result.status == 0 # Verify that the package is installed by querying it result = rhel7_contenthost.run(f'rpm -q {package_name}') assert result.status == 0
def test_positive_smoke(self): """Check that basic content can be created 1. Create a new user with admin permissions 2. Using the new user from above 1. Create a new organization 2. Create two new lifecycle environments 3. Create a custom product 4. Create a custom YUM repository 5. Create a custom PUPPET repository 6. Synchronize both custom repositories 7. Create a new content view 8. Associate both repositories to new content view 9. Publish content view 10. Promote content view to both lifecycles 11. Create a new libvirt compute resource 12. Create a new subnet 13. Create a new domain 14. Create a new hostgroup and associate previous entities to it @Feature: Smoke Test @Assert: All entities are created and associated. """ # prep work # # FIXME: Use a larger charset when authenticating users. # # It is possible to create a user with a wide range of characters. (see # the "User" entity). However, Foreman supports only HTTP Basic # authentication, and the requests lib enforces the latin1 charset in # this auth mode. We then further restrict ourselves to the # alphanumeric charset, because Foreman complains about incomplete # multi-byte chars when latin1 chars are used. login = gen_string('alphanumeric') password = gen_string('alphanumeric') # step 1: Create a new user with admin permissions entities.User(admin=True, login=login, password=password).create() # step 2.1: Create a new organization server_config = get_nailgun_config() server_config.auth = (login, password) org = entities.Organization(server_config).create() # step 2.2: Create 2 new lifecycle environments le1 = entities.LifecycleEnvironment(server_config, organization=org).create() le2 = entities.LifecycleEnvironment( server_config, organization=org, prior=le1, ).create() # step 2.3: Create a custom product prod = entities.Product(server_config, organization=org).create() # step 2.4: Create custom YUM repository repo1 = entities.Repository(server_config, product=prod, content_type=u'yum', url=GOOGLE_CHROME_REPO).create() # step 2.5: Create custom PUPPET repository repo2 = entities.Repository(server_config, product=prod, content_type=u'puppet', url=FAKE_0_PUPPET_REPO).create() # step 2.6: Synchronize both repositories for repo in [repo1, repo2]: repo.sync() # step 2.7: Create content view content_view = entities.ContentView(server_config, organization=org).create() # step 2.8: Associate YUM repository to new content view content_view.repository = [repo1] content_view = content_view.update(['repository']) # Fetch all available puppet modules puppet_mods = content_view.available_puppet_modules() self.assertGreater(puppet_mods['results'], 0) # Select a random puppet module from the results puppet_module = random.choice(puppet_mods['results']) # ... and associate it to the content view puppet = entities.ContentViewPuppetModule( author=puppet_module['author'], name=puppet_module['name'], content_view=content_view, ).create() self.assertEqual( puppet.name, puppet_module['name'], ) # step 2.9: Publish content view content_view.publish() # step 2.10: Promote content view to both lifecycles content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = content_view.version[0].read() self.assertEqual(len(cv_version.environment), 1) promote(cv_version, le1.id) # Check that content view exists in 2 lifecycles content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = cv_version.read() self.assertEqual(len(cv_version.environment), 2) promote(cv_version, le2.id) # Check that content view exists in 2 lifecycles content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = cv_version.read() self.assertEqual(len(cv_version.environment), 3) # BONUS: Create a content host and associate it with promoted # content view and last lifecycle where it exists content_host = entities.System(server_config, content_view=content_view, environment=le2).create() # Check that content view matches what we passed self.assertEqual(content_host.content_view.id, content_view.id) # Check that lifecycle environment matches self.assertEqual(content_host.environment.id, le2.id) # step 2.11: Create a new libvirt compute resource entities.LibvirtComputeResource( server_config, url=u'qemu+tcp://{0}:16509/system'.format( settings.server.hostname), ).create() # step 2.12: Create a new subnet subnet = entities.Subnet(server_config).create() # step 2.13: Create a new domain domain = entities.Domain(server_config).create() # step 2.14: Create a new hostgroup and associate previous entities to # it entities.HostGroup(server_config, domain=domain, subnet=subnet).create()
def test_positive_auto_provision_pxe_host(_module_user, module_org, module_location, discovery_settings, provisioning_env): """Auto provision a pxe-based host by executing discovery rules :id: c93fd7c9-41ef-4eb5-8042-f72e87e67e10 :parametrized: yes :Setup: Provisioning should be configured and a host should be discovered :Steps: POST /api/v2/discovered_hosts/:id/auto_provision :expectedresults: Selected Host should be auto-provisioned successfully :CaseAutomation: Automated :CaseImportance: Critical """ cfg = get_nailgun_config() if _module_user: cfg.auth = (_module_user[0].login, _module_user[1]) # open a ssh channel and attach it to foreman-tail output ssh_client = ssh.get_client() with ssh_client.invoke_shell() as channel: channel.send('foreman-tail\r') with LibvirtGuest() as pxe_host: discovered_host = _assert_discovered_host(pxe_host, channel, user_config=cfg) # Provision just discovered host discovered_host.hostgroup = entities.HostGroup( cfg, id=provisioning_env['hostgroup']['id']).read() # create a discovery rule that will match hosts MAC address entities.DiscoveryRule( name=gen_string('alphanumeric'), search_=f"mac = {discovered_host.mac}", organization=[module_org], location=[module_location], hostgroup=entities.HostGroup( cfg, id=provisioning_env['hostgroup']['id']).read(), ).create() # Auto-provision the host discovered_host.auto_provision() # Assertions provisioned_host = entities.Host(cfg).search( query={ 'search': 'name={}.{}'.format(discovered_host.name, provisioning_env['domain']['name']) })[0] assert provisioned_host.subnet.read( ).name == provisioning_env['subnet']['name'] assert (provisioned_host.operatingsystem.read().ptable[0].read(). name == provisioning_env['ptable']['name']) assert provisioned_host.operatingsystem.read( ).title == provisioning_env['os']['title'] assert not entities.DiscoveredHost(cfg).search( query={'search': f'name={discovered_host.name}'})
def test_positive_end_to_end(self): """Perform end to end smoke tests using RH and custom repos. 1. Create a new user with admin permissions 2. Using the new user from above 1. Create a new organization 2. Clone and upload manifest 3. Create a new lifecycle environment 4. Create a custom product 5. Create a custom YUM repository 6. Create a custom PUPPET repository 7. Enable a Red Hat repository 8. Synchronize the three repositories 9. Create a new content view 10. Associate the YUM and Red Hat repositories to new content view 11. Add a PUPPET module to new content view 12. Publish content view 13. Promote content view to the lifecycle environment 14. Create a new activation key 15. Add the products to the activation key 16. Create a new libvirt compute resource 17. Create a new subnet 18. Create a new domain 19. Create a new hostgroup and associate previous entities to it 20. Provision a client @Feature: End to End Test @Assert: All tests should succeed and Content should be successfully fetched by client. """ # step 1: Create a new user with admin permissions login = gen_string('alphanumeric') password = gen_string('alphanumeric') entities.User(admin=True, login=login, password=password).create() # step 2.1: Create a new organization server_config = get_nailgun_config() server_config.auth = (login, password) org = entities.Organization(server_config).create() # step 2.2: Clone and upload manifest with manifests.clone() as manifest: upload_manifest(org.id, manifest.content) # step 2.3: Create a new lifecycle environment le1 = entities.LifecycleEnvironment( server_config, organization=org ).create() # step 2.4: Create a custom product prod = entities.Product(server_config, organization=org).create() # step 2.5: Create custom YUM repository repo1 = entities.Repository( server_config, product=prod, content_type=u'yum', url=GOOGLE_CHROME_REPO ).create() # step 2.6: Create custom PUPPET repository repo2 = entities.Repository( server_config, product=prod, content_type=u'puppet', url=FAKE_0_PUPPET_REPO ).create() # step 2.7: Enable a Red Hat repository repo3 = entities.Repository(id=enable_rhrepo_and_fetchid( basearch='x86_64', org_id=org.id, product=PRDS['rhel'], repo=REPOS['rhva6']['name'], reposet=REPOSET['rhva6'], releasever='6Server', )) # step 2.8: Synchronize the three repositories for repo in [repo1, repo2, repo3]: repo.sync() # step 2.9: Create content view content_view = entities.ContentView( server_config, organization=org ).create() # step 2.10: Associate the YUM and Red Hat repositories to new content # view content_view.repository = [repo1, repo3] content_view = content_view.update(['repository']) # step 2.11: Add a PUPPET module to new content view puppet_mods = content_view.available_puppet_modules() self.assertGreater(len(puppet_mods['results']), 0) puppet_module = random.choice(puppet_mods['results']) puppet = entities.ContentViewPuppetModule( author=puppet_module['author'], content_view=content_view, name=puppet_module['name'], ).create() self.assertEqual( puppet.name, puppet_module['name'], ) # step 2.12: Publish content view content_view.publish() # step 2.13: Promote content view to the lifecycle environment content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = content_view.version[0].read() self.assertEqual(len(cv_version.environment), 1) promote(cv_version, le1.id) # check that content view exists in lifecycle content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = cv_version.read() # step 2.14: Create a new activation key activation_key_name = gen_string('alpha') activation_key = entities.ActivationKey( name=activation_key_name, environment=le1, organization=org, content_view=content_view, ).create() # step 2.15: Add the products to the activation key for sub in entities.Subscription(organization=org).search(): if sub.read_json()['product_name'] == DEFAULT_SUBSCRIPTION_NAME: activation_key.add_subscriptions(data={ 'quantity': 1, 'subscription_id': sub.id, }) break # step 2.15.1: Enable product content activation_key.content_override(data={'content_override': { u'content_label': AK_CONTENT_LABEL, u'value': u'1', }}) # BONUS: Create a content host and associate it with promoted # content view and last lifecycle where it exists content_host = entities.Host( content_facet_attributes={ 'content_view_id': content_view.id, 'lifecycle_environment_id': le1.id, }, organization=org, ).create() # check that content view matches what we passed self.assertEqual( content_host.content_facet_attributes['content_view_id'], content_view.id ) # check that lifecycle environment matches self.assertEqual( content_host.content_facet_attributes['lifecycle_environment_id'], le1.id ) # step 2.16: Create a new libvirt compute resource entities.LibvirtComputeResource( server_config, url=u'qemu+tcp://{0}:16509/system'.format( settings.server.hostname), ).create() # step 2.17: Create a new subnet subnet = entities.Subnet(server_config).create() # step 2.18: Create a new domain domain = entities.Domain(server_config).create() # step 2.19: Create a new hostgroup and associate previous entities to # it entities.HostGroup( server_config, domain=domain, subnet=subnet ).create() # step 2.20: Provision a client self.client_provisioning(activation_key_name, org.label)
def test_positive_end_to_end(self): """Perform end to end smoke tests using RH and custom repos. 1. Create a new user with admin permissions 2. Using the new user from above 1. Create a new organization 2. Clone and upload manifest 3. Create a new lifecycle environment 4. Create a custom product 5. Create a custom YUM repository 6. Create a custom PUPPET repository 7. Enable a Red Hat repository 8. Synchronize the three repositories 9. Create a new content view 10. Associate the YUM and Red Hat repositories to new content view 11. Add a PUPPET module to new content view 12. Publish content view 13. Promote content view to the lifecycle environment 14. Create a new activation key 15. Add the products to the activation key 16. Create a new libvirt compute resource 17. Create a new subnet 18. Create a new domain 19. Create a new hostgroup and associate previous entities to it 20. Provision a client :id: b2f73740-d3ce-4e6e-abc7-b23e5562bac1 :expectedresults: All tests should succeed and Content should be successfully fetched by client. """ # step 1: Create a new user with admin permissions login = gen_string('alphanumeric') password = gen_string('alphanumeric') entities.User(admin=True, login=login, password=password).create() # step 2.1: Create a new organization server_config = get_nailgun_config() server_config.auth = (login, password) org = entities.Organization(server_config).create() # step 2.2: Clone and upload manifest if self.fake_manifest_is_set: with manifests.clone() as manifest: upload_manifest(org.id, manifest.content) # step 2.3: Create a new lifecycle environment le1 = entities.LifecycleEnvironment(server_config, organization=org).create() # step 2.4: Create a custom product prod = entities.Product(server_config, organization=org).create() repositories = [] # step 2.5: Create custom YUM repository repo1 = entities.Repository(server_config, product=prod, content_type='yum', url=CUSTOM_RPM_REPO).create() repositories.append(repo1) # step 2.6: Create custom PUPPET repository repo2 = entities.Repository(server_config, product=prod, content_type='puppet', url=FAKE_0_PUPPET_REPO).create() repositories.append(repo2) # step 2.7: Enable a Red Hat repository if self.fake_manifest_is_set: repo3 = entities.Repository(id=enable_rhrepo_and_fetchid( basearch='x86_64', org_id=org.id, product=PRDS['rhel'], repo=REPOS['rhva6']['name'], reposet=REPOSET['rhva6'], releasever='6Server', )) repositories.append(repo3) # step 2.8: Synchronize the three repositories for repo in repositories: repo.sync() # step 2.9: Create content view content_view = entities.ContentView(server_config, organization=org).create() # step 2.10: Associate the YUM and Red Hat repositories to new content # view repositories.remove(repo2) content_view.repository = repositories content_view = content_view.update(['repository']) # step 2.11: Add a PUPPET module to new content view puppet_mods = content_view.available_puppet_modules() self.assertGreater(len(puppet_mods['results']), 0) puppet_module = random.choice(puppet_mods['results']) puppet = entities.ContentViewPuppetModule( author=puppet_module['author'], content_view=content_view, name=puppet_module['name']).create() self.assertEqual(puppet.name, puppet_module['name']) # step 2.12: Publish content view content_view.publish() # step 2.13: Promote content view to the lifecycle environment content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = content_view.version[0].read() self.assertEqual(len(cv_version.environment), 1) promote(cv_version, le1.id) # check that content view exists in lifecycle content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = cv_version.read() # step 2.14: Create a new activation key activation_key_name = gen_string('alpha') activation_key = entities.ActivationKey( name=activation_key_name, environment=le1, organization=org, content_view=content_view).create() # step 2.15: Add the products to the activation key for sub in entities.Subscription(organization=org).search(): if sub.name == DEFAULT_SUBSCRIPTION_NAME: activation_key.add_subscriptions(data={ 'quantity': 1, 'subscription_id': sub.id }) break # step 2.15.1: Enable product content if self.fake_manifest_is_set: activation_key.content_override( data={ 'content_overrides': [{ 'content_label': AK_CONTENT_LABEL, 'value': '1' }] }) # BONUS: Create a content host and associate it with promoted # content view and last lifecycle where it exists content_host = entities.Host( content_facet_attributes={ 'content_view_id': content_view.id, 'lifecycle_environment_id': le1.id, }, organization=org, ).create() # check that content view matches what we passed self.assertEqual( content_host.content_facet_attributes['content_view_id'], content_view.id) # check that lifecycle environment matches self.assertEqual( content_host.content_facet_attributes['lifecycle_environment_id'], le1.id) # step 2.16: Create a new libvirt compute resource entities.LibvirtComputeResource( server_config, url='qemu+ssh://root@{0}/system'.format( settings.compute_resources.libvirt_hostname), ).create() # step 2.17: Create a new subnet subnet = entities.Subnet(server_config).create() # step 2.18: Create a new domain domain = entities.Domain(server_config).create() # step 2.19: Create a new hostgroup and associate previous entities to # it entities.HostGroup(server_config, domain=domain, subnet=subnet).create() # step 2.20: Provision a client self.client_provisioning(activation_key_name, org.label)
def test_positive_smoke(self): """@Test: Check that basic content can be created 1. Create a new user with admin permissions 2. Using the new user from above: 1. Create a new organization 2. Create two new lifecycle environments 3. Create a custom product 4. Create a custom YUM repository 5. Create a custom PUPPET repository 6. Synchronize both custom repositories 7. Create a new content view 8. Associate both repositories to new content view 9. Publish content view 10. Promote content view to both lifecycles 11. Create a new libvirt compute resource 12. Create a new subnet 13. Create a new domain 14. Create a new hostgroup and associate previous entities to it @Feature: Smoke Test @Assert: All entities are created and associated. """ # prep work # # FIXME: Use a larger charset when authenticating users. # # It is possible to create a user with a wide range of characters. (see # the "User" entity). However, Foreman supports only HTTP Basic # authentication, and the requests lib enforces the latin1 charset in # this auth mode. We then further restrict ourselves to the # alphanumeric charset, because Foreman complains about incomplete # multi-byte chars when latin1 chars are used. login = gen_string('alphanumeric') password = gen_string('alphanumeric') # step 1: Create a new user with admin permissions entities.User(admin=True, login=login, password=password).create() # step 2.1: Create a new organization server_config = get_nailgun_config() server_config.auth = (login, password) org = entities.Organization(server_config).create() # step 2.2: Create 2 new lifecycle environments le1 = entities.LifecycleEnvironment( server_config, organization=org ).create() le2 = entities.LifecycleEnvironment( server_config, organization=org, prior=le1, ).create() # step 2.3: Create a custom product prod = entities.Product(server_config, organization=org).create() # step 2.4: Create custom YUM repository repo1 = entities.Repository( server_config, product=prod, content_type=u'yum', url=GOOGLE_CHROME_REPO ).create() # step 2.5: Create custom PUPPET repository repo2 = entities.Repository( server_config, product=prod, content_type=u'puppet', url=FAKE_0_PUPPET_REPO ).create() # step 2.6: Synchronize both repositories for repo in [repo1, repo2]: repo.sync() # step 2.7: Create content view content_view = entities.ContentView( server_config, organization=org ).create() # step 2.8: Associate YUM repository to new content view content_view.repository = [repo1] content_view = content_view.update(['repository']) # Fetch all available puppet modules puppet_mods = content_view.available_puppet_modules() self.assertGreater(puppet_mods['results'], 0) # Select a random puppet module from the results puppet_module = random.choice(puppet_mods['results']) # ... and associate it to the content view puppet = entities.ContentViewPuppetModule( author=puppet_module['author'], name=puppet_module['name'], content_view=content_view, ).create() self.assertEqual( puppet.name, puppet_module['name'], ) # step 2.9: Publish content view content_view.publish() # step 2.10: Promote content view to both lifecycles content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = content_view.version[0].read() self.assertEqual(len(cv_version.environment), 1) promote(cv_version, le1.id) # Check that content view exists in 2 lifecycles content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = cv_version.read() self.assertEqual(len(cv_version.environment), 2) promote(cv_version, le2.id) # Check that content view exists in 2 lifecycles content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = cv_version.read() self.assertEqual(len(cv_version.environment), 3) # BONUS: Create a content host and associate it with promoted # content view and last lifecycle where it exists content_host = entities.System( server_config, content_view=content_view, environment=le2 ).create() # Check that content view matches what we passed self.assertEqual(content_host.content_view.id, content_view.id) # Check that lifecycle environment matches self.assertEqual(content_host.environment.id, le2.id) # step 2.11: Create a new libvirt compute resource entities.LibvirtComputeResource( server_config, url=u'qemu+tcp://{0}:16509/system'.format( settings.server.hostname), ).create() # step 2.12: Create a new subnet subnet = entities.Subnet(server_config).create() # step 2.13: Create a new domain domain = entities.Domain(server_config).create() # step 2.14: Create a new hostgroup and associate previous entities to # it entities.HostGroup( server_config, domain=domain, subnet=subnet ).create()