def test_positive_post_hash(self): """Do not wrap API calls in an extra hash. @Assert: It is possible to associate an activation key with an organization. @Feature: Architecture """ name = gen_utf8() os_id = entities.OperatingSystem().create_json()['id'] response = client.post( entities.Architecture().path(), {u'name': name, u'operatingsystem_ids': [os_id]}, auth=settings.server.get_credentials(), verify=False, ) response.raise_for_status() attrs = response.json() # The server will accept some POSTed attributes (name) and silently # ignore others (operatingsystem_ids). self.assertIn('name', attrs) self.assertEqual(name, attrs['name']) self.assertIn('operatingsystems', attrs) self.assertEqual([os_id], attrs['operatingsystems'])
def test_positive_build_pxe_default(self, tftpboot): """Call the "build_pxe_default" path. :id: ca19d9da-1049-4b39-823b-933fc1a0cebd :expectedresults: The response is a JSON payload, all templates are deployed to TFTP/HTTP and are rendered correctly :CaseLevel: Integration :CaseImportance: Critical :BZ: 1202564 """ response = client.post( entities.ProvisioningTemplate().path('build_pxe_default'), auth=settings.server.get_credentials(), verify=False, ) response.raise_for_status() assert type(response.json()) == dict for template in tftpboot.values(): if template['path'].startswith('http'): r = client.get(template['path'], verify=False) r.raise_for_status() rendered = r.text else: rendered = ssh.command(f"cat {template['path']}").stdout[0] assert (rendered == f"{settings.server.scheme}://" f"{settings.server.hostname} {template['kind']}")
def test_positive_post_hash(self): """Do not wrap API calls in an extra hash. @id: 44654ec5-5211-4326-bcad-9824f36a036f @Assert: It is possible to associate an activation key with an organization. @CaseLevel: Integration """ name = gen_string('utf8') os = entities.OperatingSystem().create() response = client.post( entities.Architecture().path(), {u'name': name, u'operatingsystem_ids': [os.id]}, auth=settings.server.get_credentials(), verify=False, ) response.raise_for_status() attrs = response.json() # The server will accept some POSTed attributes (name) and silently # ignore others (operatingsystem_ids). self.assertIn('name', attrs) self.assertEqual(name, attrs['name']) self.assertIn('operatingsystems', attrs) self.assertEqual(os.id, attrs['operatingsystems'][0]['id'])
def test_positive_post_hash(self): """Do not wrap API calls in an extra hash. @Assert: It is possible to associate an activation key with an organization. @Feature: Architecture """ name = gen_utf8() os_id = entities.OperatingSystem().create_json()['id'] response = client.post( entities.Architecture().path(), { u'name': name, u'operatingsystem_ids': [os_id] }, auth=settings.server.get_credentials(), verify=False, ) response.raise_for_status() attrs = response.json() # The server will accept some POSTed attributes (name) and silently # ignore others (operatingsystem_ids). self.assertIn('name', attrs) self.assertEqual(name, attrs['name']) self.assertIn('operatingsystems', attrs) self.assertEqual([os_id], attrs['operatingsystems'])
def create_raw(self, auth=None, create_missing=True): """Create an entity. Generate values for required, unset fields by calling :meth:`create_missing`. Only do this if ``create_missing`` is true. Then make an HTTP POST call to ``self.path('base')``. Return the response received from the server. :param tuple auth: A ``(username, password)`` pair to use when communicating with the API. If ``None``, the credentials returned by :func:`robottelo.common.helpers.get_server_credentials` are used. :param bool create_missing: Should :meth:`create_missing` be called? In other words, should values be generated for required, empty fields? :return: A ``requests.response`` object. """ if auth is None: auth = helpers.get_server_credentials() if create_missing: self.create_missing(auth) return client.post( self.path('base'), self.create_payload(), auth=auth, verify=False, )
def test_update_contents(self): """@Test: Create a repository and upload RPM contents. @Assert: The repository's contents include one RPM. @Feature: Repository """ # Create a repository and upload RPM content. repo_id = entities.Repository(product=self.prod_id).create_json()['id'] client.post( entities.Repository(id=repo_id).path(which='upload_content'), {}, auth=get_server_credentials(), files={u'content': open(get_data_file(RPM_TO_UPLOAD), 'rb')}, verify=False, ).raise_for_status() # Verify the repository's contents. attrs = entities.Repository(id=repo_id).read_json() self.assertEqual(attrs[u'content_counts'][u'rpm'], 1)
def test_update_contents(self): """@Test: Create a repository and upload RPM contents. @Assert: The repository's contents include one RPM. @Feature: Repository """ # Create a repository and upload RPM content. repo_id = entities.Repository(product=self.prod_id).create()['id'] client.post( entities.Repository(id=repo_id).path(which='upload_content'), {}, auth=get_server_credentials(), files={ u'content': open(get_data_file(RPM_TO_UPLOAD), 'rb') }, verify=False, ).raise_for_status() # Verify the repository's contents. attrs = entities.Repository(id=repo_id).read_json() self.assertEqual(attrs[u'content_counts'][u'rpm'], 1)
def test_create_text_plain(self): """@Test Create an organization using a 'text/plain' content-type. @Assert: HTTP 415 is returned. @Feature: Organization """ organization = entities.Organization() organization.create_missing() response = client.post( organization.path(), organization.create_payload(), auth=get_server_credentials(), headers={'content-type': 'text/plain'}, verify=False, ) self.assertEqual(httplib.UNSUPPORTED_MEDIA_TYPE, response.status_code)
def test_positive_create_text_plain(self): """Create an organization using a 'text/plain' content-type. @id: 6f67a3f0-0c1d-498c-9a35-28207b0faec2 @Assert: HTTP 415 is returned. """ organization = entities.Organization() organization.create_missing() response = client.post( organization.path(), organization.create_payload(), auth=settings.server.get_credentials(), headers={'content-type': 'text/plain'}, verify=False, ) self.assertEqual( http_client.UNSUPPORTED_MEDIA_TYPE, response.status_code)
def test_positive_create_text_plain(self): """Create an organization using a 'text/plain' content-type. @id: 6f67a3f0-0c1d-498c-9a35-28207b0faec2 @Assert: HTTP 415 is returned. """ organization = entities.Organization() organization.create_missing() response = client.post( organization.path(), organization.create_payload(), auth=settings.server.get_credentials(), headers={'content-type': 'text/plain'}, verify=False, ) self.assertEqual(http_client.UNSUPPORTED_MEDIA_TYPE, response.status_code)
def test_positive_create(self): """Create an organization using a 'text/plain' content-type. :id: 6f67a3f0-0c1d-498c-9a35-28207b0faec2 :expectedresults: HTTP 415 is returned. :CaseImportance: Critical """ organization = entities.Organization() organization.create_missing() response = client.post( organization.path(), organization.create_payload(), auth=settings.server.get_credentials(), headers={'content-type': 'text/plain'}, verify=False, ) assert http.client.UNSUPPORTED_MEDIA_TYPE == response.status_code
def create_raw(self, create_missing=None): """Create an entity. Possibly call :meth:`create_missing`. Then make an HTTP POST call to ``self.path('base')``. The request payload consists of whatever is returned by :meth:`create_payload`. Return the response. :param create_missing: Should :meth:`create_missing` be called? In other words, should values be generated for required, empty fields? Defaults to :data:`nailgun.entity_mixins.CREATE_MISSING`. :return: A ``requests.response`` object. """ if create_missing is None: create_missing = CREATE_MISSING if create_missing: self.create_missing() return client.post(self.path('base'), self.create_payload(), **self._server_config.get_client_kwargs())
def test_bz_1120800(self): """@Test: Create a host with the ``name`` parameter in the outer hash. @Feature: Host @Assert: A host is created. """ host = entities.Host() host.create_missing() payload = host.create_payload() payload['name'] = payload['host'].pop('name') response = client.post( host.path(), payload, auth=get_server_credentials(), verify=False, ) response.raise_for_status() self.assertTrue('id' in response.json())
def create_raw(self, create_missing=None): """Create an entity. Possibly call :meth:`create_missing`. Then make an HTTP POST call to ``self.path('base')``. The request payload consists of whatever is returned by :meth:`create_payload`. Return the response. :param create_missing: Should :meth:`create_missing` be called? In other words, should values be generated for required, empty fields? Defaults to :data:`nailgun.entity_mixins.CREATE_MISSING`. :return: A ``requests.response`` object. """ if create_missing is None: create_missing = CREATE_MISSING if create_missing: self.create_missing() return client.post( self.path('base'), self.create_payload(), **self._server_config.get_client_kwargs() )
def create_raw(self, create_missing=None): """Create an entity. Generate values for required, unset fields by calling :meth:`create_missing`. Only do this if ``create_missing`` is true. Then make an HTTP POST call to ``self.path('base')``. Return the response received from the server. :param create_missing: Should :meth:`create_missing` be called? In other words, should values be generated for required, empty fields? Defaults to :data:`nailgun.entity_mixins.CREATE_MISSING`. :return: A ``requests.response`` object. """ if create_missing is None: create_missing = CREATE_MISSING if create_missing: self.create_missing() return client.post( self.path('base'), self.create_payload(), auth=self._server_config.auth, verify=self._server_config.verify, )
def test_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(organization=org['id']).create() le2 = entities.LifecycleEnvironment( organization=org['id'], prior=le1['id']).create() # step 2.3: Create a custom product prod = entities.Product(organization=org['id']).create() # step 2.4: Create custom YUM repository repo1 = entities.Repository( product=prod['id'], content_type=u'yum', url=GOOGLE_CHROME_REPO ).create() # step 2.5: Create custom PUPPET repository repo2 = entities.Repository( product=prod['id'], content_type=u'puppet', url=FAKE_0_PUPPET_REPO ).create() # step 2.6: Synchronize both repositories for repo in [repo1, repo2]: response = client.post( entities.Repository(id=repo['id']).path('sync'), {u'ids': [repo['id']], u'organization_id': org['id']}, auth=get_server_credentials(), verify=False, ).json() self.assertGreater( len(response['id']), 1, u'Was not able to fetch a task ID.') task_status = entities.ForemanTask(id=response['id']).poll() self.assertEqual( task_status['result'], u'success', u'Sync for repository {0} failed.'.format(repo['name']) ) # step 2.7: Create content view content_view = entities.ContentView(organization=org['id']).create() # step 2.8: Associate YUM repository to new content view response = client.put( entities.ContentView(id=content_view['id']).path(), {u'repository_ids': [repo1['id']]}, auth=get_server_credentials(), verify=False, ) # Fetch all available puppet modules puppet_mods = client.get( entities.ContentView(id=content_view['id']).path( 'available_puppet_module_names' ), auth=get_server_credentials(), verify=False).json() self.assertGreater( puppet_mods['results'], 0, u"No puppet modules were found") # Select a random puppet module from the results puppet_mod = random.choice(puppet_mods['results']) # ... and associate it to the content view path = entities.ContentView(id=content_view['id']).path( 'content_view_puppet_modules') response = client.post( path, {u'name': puppet_mod['module_name']}, auth=get_server_credentials(), verify=False, ) self.assertEqual( response.status_code, httplib.OK, status_code_error(path, httplib.OK, response) ) self.assertEqual( response.json()['name'], puppet_mod['module_name'], ) # step 2.9: Publish content view task_status = entities.ContentView(id=content_view['id']).publish() self.assertEqual( task_status['result'], u'success', u"Publishing {0} failed.".format(content_view['name'])) # step 2.10: Promote content view to both lifecycles content_view = entities.ContentView(id=content_view['id']).read_json() self.assertEqual( len(content_view['versions']), 1, u'There should only be 1 version published.') self.assertEqual( len(content_view['versions'][0]['environment_ids']), 1, u"Content view should be present on 1 lifecycle only") task_status = entities.ContentViewVersion( id=content_view['versions'][0]['id'] ).promote(le1['id']) self.assertEqual( task_status['result'], u'success', u"Promoting {0} to {1} failed.".format( content_view['name'], le1['name'])) # Check that content view exists in 2 lifecycles content_view = entities.ContentView(id=content_view['id']).read_json() self.assertEqual( len(content_view['versions']), 1, u'There should only be 1 version published.') self.assertEqual( len(content_view['versions'][0]['environment_ids']), 2, u"Content view should be present on 2 lifecycles only") task_status = entities.ContentViewVersion( id=content_view['versions'][0]['id'] ).promote(le2['id']) self.assertEqual( task_status['result'], u'success', u"Promoting {0} to {1} failed.".format( content_view['name'], le2['name'])) # Check that content view exists in 2 lifecycles content_view = entities.ContentView(id=content_view['id']).read_json() self.assertEqual( len(content_view['versions']), 1, u'There should only be 1 version published.') self.assertEqual( len(content_view['versions'][0]['environment_ids']), 3, u"Content view should be present on 3 lifecycle only") # BONUS: Create a content host and associate it with promoted # content view and last lifecycle where it exists content_host = entities.System( content_view=content_view['id'], environment=le2['id'] ).create() # Check that content view matches what we passed self.assertEqual( content_host['content_view_id'], content_view['id'], u"Content views do not match." ) # Check that lifecycle environment matches self.assertEqual( content_host['environment']['id'], le2['id'], u"Environments do not match." )
def test_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 org = entities.Organization().create(auth=(login, password)) # step 2.2: Create 2 new lifecycle environments le1 = entities.LifecycleEnvironment(organization=org['id']).create() le2 = entities.LifecycleEnvironment( organization=org['id'], prior=le1['id']).create() # step 2.3: Create a custom product prod = entities.Product(organization=org['id']).create() # step 2.4: Create custom YUM repository repo1 = entities.Repository( product=prod['id'], content_type=u'yum', url=GOOGLE_CHROME_REPO ).create() # step 2.5: Create custom PUPPET repository repo2 = entities.Repository( product=prod['id'], content_type=u'puppet', url=FAKE_0_PUPPET_REPO ).create() # step 2.6: Synchronize both repositories for repo in [repo1, repo2]: response = client.post( entities.Repository(id=repo['id']).path('sync'), { u'ids': [repo['id']], u'organization_id': org['id'] }, auth=get_server_credentials(), verify=False, ).json() self.assertGreater( len(response['id']), 1, u"Was not able to fetch a task ID.") task_status = entities.ForemanTask(id=response['id']).poll() self.assertEqual( task_status['result'], u'success', u"Sync for repository {0} failed.".format(repo['name'])) # step 2.7: Create content view content_view = entities.ContentView(organization=org['id']).create() # step 2.8: Associate YUM repository to new content view response = client.put( entities.ContentView(id=content_view['id']).path(), auth=get_server_credentials(), verify=False, data={u'repository_ids': [repo1['id']]}) # Fetch all available puppet modules puppet_mods = client.get( entities.ContentView(id=content_view['id']).path( 'available_puppet_module_names'), auth=get_server_credentials(), verify=False).json() self.assertGreater( puppet_mods['results'], 0, u"No puppet modules were found") # Select a random puppet module from the results puppet_mod = random.choice(puppet_mods['results']) # ... and associate it to the content view path = entities.ContentView(id=content_view['id']).path( 'content_view_puppet_modules') response = client.post( path, auth=get_server_credentials(), verify=False, data={u'name': puppet_mod['module_name']}) self.assertEqual( response.status_code, httplib.OK, status_code_error(path, httplib.OK, response) ) self.assertEqual( response.json()['name'], puppet_mod['module_name'], ) # step 2.9: Publish content view task_status = entities.ContentView(id=content_view['id']).publish() self.assertEqual( task_status['result'], u'success', u"Publishing {0} failed.".format(content_view['name'])) # step 2.10: Promote content view to both lifecycles content_view = entities.ContentView(id=content_view['id']).read_json() self.assertEqual( len(content_view['versions']), 1, u'There should only be 1 version published.') self.assertEqual( len(content_view['versions'][0]['environment_ids']), 1, u"Content view should be present on 1 lifecycle only") task_status = entities.ContentViewVersion( id=content_view['versions'][0]['id'] ).promote(le1['id']) self.assertEqual( task_status['result'], u'success', u"Promoting {0} to {1} failed.".format( content_view['name'], le1['name'])) # Check that content view exists in 2 lifecycles content_view = entities.ContentView(id=content_view['id']).read_json() self.assertEqual( len(content_view['versions']), 1, u'There should only be 1 version published.') self.assertEqual( len(content_view['versions'][0]['environment_ids']), 2, u"Content view should be present on 2 lifecycles only") task_status = entities.ContentViewVersion( id=content_view['versions'][0]['id'] ).promote(le2['id']) self.assertEqual( task_status['result'], u'success', u"Promoting {0} to {1} failed.".format( content_view['name'], le2['name'])) # Check that content view exists in 2 lifecycles content_view = entities.ContentView(id=content_view['id']).read_json() self.assertEqual( len(content_view['versions']), 1, u'There should only be 1 version published.') self.assertEqual( len(content_view['versions'][0]['environment_ids']), 3, u"Content view should be present on 3 lifecycle only") # BONUS: Create a content host and associate it with promoted # content view and last lifecycle where it exists content_host = entities.System( content_view=content_view['id'], environment=le2['id'] ).create() # Check that content view matches what we passed self.assertEqual( content_host['content_view_id'], content_view['id'], u"Content views do not match." ) # Check that lifecycle environment matches self.assertEqual( content_host['environment']['id'], le2['id'], u"Environments do not match." )
def test_inherit_puppetclass(self): """Host that created from HostGroup entity with PuppetClass assigned to it should inherit such puppet class information under 'all_puppetclasses' field :id: 7b840f3d-413c-40bb-9a7d-cd9dad3c0737 :expectedresults: Host inherited 'all_puppetclasses' details from HostGroup that was used for such Host create procedure :BZ: 1107708, 1222118, 1487586 :CaseLevel: System """ # Creating entities like organization, content view and lifecycle_env # with not utf-8 names for easier interaction with puppet environment # further in test org = entities.Organization(name=gen_string('alpha')).create() location = entities.Location(organization=[org]).create() # Creating puppet repository with puppet module assigned to it product = entities.Product(organization=org).create() puppet_repo = entities.Repository(content_type='puppet', product=product).create() # Working with 'ntp' module as we know for sure that it contains at # least few puppet classes with open(get_data_file(PUPPET_MODULE_NTP_PUPPETLABS), 'rb') as handle: puppet_repo.upload_content(files={'content': handle}) content_view = entities.ContentView(name=gen_string('alpha'), organization=org).create() result = content_view.available_puppet_modules()['results'] assert len(result) == 1 entities.ContentViewPuppetModule(author=result[0]['author'], name=result[0]['name'], content_view=content_view).create() content_view.publish() content_view = content_view.read() lc_env = entities.LifecycleEnvironment(name=gen_string('alpha'), organization=org).create() promote(content_view.version[0], lc_env.id) content_view = content_view.read() assert len(content_view.version) == 1 assert len(content_view.puppet_module) == 1 # Form environment name variable for our test env_name = f'KT_{org.name}_{lc_env.name}_{content_view.name}_{content_view.id}' # Get all environments for current organization. # We have two environments (one created after publishing and one more # was created after promotion), so we need to select promoted one environments = entities.Environment().search( query={'organization_id': org.id}) assert len(environments) == 2 environments = [ environment for environment in environments if environment.name == env_name ] assert len(environments) == 1 environment = environments[0].read() environment.location = [location] environment.update() # Create a host group and it dependencies. mac = entity_fields.MACAddressField().gen_value() root_pass = entity_fields.StringField(length=(8, 30)).gen_value() domain = entities.Domain().create() architecture = entities.Architecture().create() ptable = entities.PartitionTable().create() operatingsystem = entities.OperatingSystem(architecture=[architecture], ptable=[ptable]).create() medium = entities.Media(operatingsystem=[operatingsystem]).create() hostgroup = entities.HostGroup( architecture=architecture, domain=domain, environment=environment, location=[location.id], medium=medium, name=gen_string('alpha'), operatingsystem=operatingsystem, organization=[org.id], ptable=ptable, ).create() assert len(hostgroup.read_json()['all_puppetclasses']) == 0 # Get puppet class id for ntp module response = client.get( environment.path('self') + '/puppetclasses', auth=get_credentials(), verify=False, ) response.raise_for_status() results = response.json()['results'] puppet_class_id = results['ntp'][0]['id'] # Assign puppet class client.post( hostgroup.path('self') + '/puppetclass_ids', data={ 'puppetclass_id': puppet_class_id }, auth=get_credentials(), verify=False, ).raise_for_status() hostgroup_attrs = hostgroup.read_json() assert len(hostgroup_attrs['all_puppetclasses']) == 1 assert hostgroup_attrs['all_puppetclasses'][0]['name'] == 'ntp' # Create Host entity using HostGroup host = entities.Host( hostgroup=hostgroup, mac=mac, root_pass=root_pass, environment=environment, location=location, organization=org, content_facet_attributes={ 'content_view_id': content_view.id, 'lifecycle_environment_id': lc_env.id, }, name=gen_string('alpha'), ).create(False) host_attrs = host.read_json() assert len(host_attrs['all_puppetclasses']) == 1 assert host_attrs['all_puppetclasses'][0]['name'] == 'ntp'
def test_verify_bugzilla_1107708(self): """Host that created from HostGroup entity with PuppetClass assigned to it should inherit such puppet class information under 'all_puppetclasses' field @id: 7b840f3d-413c-40bb-9a7d-cd9dad3c0737 @Assert: Host inherited 'all_puppetclasses' details from HostGroup that was used for such Host create procedure @CaseLevel: System """ # Creating entities like organization, content view and lifecycle_env # with not utf-8 names for easier interaction with puppet environment # further in test org = entities.Organization(name=gen_string('alpha')).create() location = entities.Location(organization=[org]).create() # Creating puppet repository with puppet module assigned to it product = entities.Product(organization=org).create() puppet_repo = entities.Repository( content_type='puppet', product=product, ).create() # Working with 'ntp' module as we know for sure that it contains at # least few puppet classes with open(get_data_file(PUPPET_MODULE_NTP_PUPPETLABS), 'rb') as handle: puppet_repo.upload_content(files={'content': handle}) content_view = entities.ContentView( name=gen_string('alpha'), organization=org, ).create() result = content_view.available_puppet_modules()['results'] self.assertEqual(len(result), 1) entities.ContentViewPuppetModule( author=result[0]['author'], name=result[0]['name'], content_view=content_view, ).create() content_view.publish() content_view = content_view.read() lc_env = entities.LifecycleEnvironment( name=gen_string('alpha'), organization=org, ).create() promote(content_view.version[0], lc_env.id) content_view = content_view.read() self.assertEqual(len(content_view.version), 1) self.assertEqual(len(content_view.puppet_module), 1) # Form environment name variable for our test env_name = 'KT_{0}_{1}_{2}_{3}'.format( org.name, lc_env.name, content_view.name, str(content_view.id), ) # Get all environments for current organization. # We have two environments (one created after publishing and one more # was created after promotion), so we need to select promoted one environments = entities.Environment().search( query={'search': 'organization_id={0}'.format(org.id)} ) self.assertEqual(len(environments), 2) environments = [ environment for environment in environments if environment.name == env_name ] self.assertEqual(len(environments), 1) environment = environments[0].read() # Create a host group and it dependencies. mac = entity_fields.MACAddressField().gen_value() root_pass = entity_fields.StringField(length=(8, 30)).gen_value() domain = entities.Domain().create() architecture = entities.Architecture().create() ptable = entities.PartitionTable().create() operatingsystem = entities.OperatingSystem( architecture=[architecture], ptable=[ptable], ).create() medium = entities.Media(operatingsystem=[operatingsystem]).create() host_group = entities.HostGroup( architecture=architecture, domain=domain, environment=environment, location=[location.id], medium=medium, name=gen_string('alpha'), operatingsystem=operatingsystem, organization=[org.id], ptable=ptable, ).create() self.assertEqual(len(host_group.read_json()['all_puppetclasses']), 0) # Get puppet class id for ntp module response = client.get( environment.path('self') + '/puppetclasses', auth=settings.server.get_credentials(), verify=False, ) response.raise_for_status() results = response.json()['results'] puppet_class_id = results['ntp'][0]['id'] # Assign puppet class client.post( host_group.path('self') + '/puppetclass_ids', data={u'puppetclass_id': puppet_class_id}, auth=settings.server.get_credentials(), verify=False ).raise_for_status() host_group_attrs = host_group.read_json() self.assertEqual(len(host_group_attrs['all_puppetclasses']), 1) self.assertEqual( host_group_attrs['all_puppetclasses'][0]['name'], 'ntp', ) # Create Host entity using HostGroup host = entities.Host( hostgroup=host_group, mac=mac, root_pass=root_pass, environment=environment, location=location, organization=org, name=gen_string('alpha') ).create(False) host_attrs = host.read_json() self.assertEqual(len(host_attrs['all_puppetclasses']), 1) self.assertEqual(host_attrs['all_puppetclasses'][0]['name'], 'ntp')
def test_inherit_puppetclass(self, session_puppet_enabled_sat): """Host that created from HostGroup entity with PuppetClass assigned to it should inherit such puppet class information under 'all_puppetclasses' field :id: 7b840f3d-413c-40bb-9a7d-cd9dad3c0737 :expectedresults: Host inherited 'all_puppetclasses' details from HostGroup that was used for such Host create procedure :BZ: 1107708, 1222118, 1487586 :CaseLevel: System """ # Creating entities like organization, content view and lifecycle_env # with not utf-8 names for easier interaction with puppet environment # further in test org = session_puppet_enabled_sat.api.Organization( name=gen_string('alpha')).create() location = session_puppet_enabled_sat.api.Location( organization=[org]).create() # Working with 'api_test_classparameters' module as we know for sure that it contains # at least few puppet classes, the name of the repo is the same as the name of puppet_class repo = puppet_class = 'api_test_classparameters' env_name = session_puppet_enabled_sat.create_custom_environment( repo=repo) content_view = session_puppet_enabled_sat.api.ContentView( name=gen_string('alpha'), organization=org).create() content_view.publish() content_view = content_view.read() lc_env = session_puppet_enabled_sat.api.LifecycleEnvironment( name=gen_string('alpha'), organization=org).create() promote(content_view.version[0], lc_env.id) content_view = content_view.read() assert len(content_view.version) == 1 # Get environments that contains chosen puppet module environment = session_puppet_enabled_sat.api.Environment().search( query={'search': f'name={env_name}'}) assert len(environment) == 1 environment = environment[0] environment.location = [location] environment.organization = [org] environment.update() # Create a host group and it dependencies. mac = entity_fields.MACAddressField().gen_value() root_pass = entity_fields.StringField(length=(8, 30)).gen_value() domain = session_puppet_enabled_sat.api.Domain().create() architecture = session_puppet_enabled_sat.api.Architecture().create() ptable = session_puppet_enabled_sat.api.PartitionTable().create() operatingsystem = session_puppet_enabled_sat.api.OperatingSystem( architecture=[architecture], ptable=[ptable]).create() medium = session_puppet_enabled_sat.api.Media( operatingsystem=[operatingsystem]).create() hostgroup = session_puppet_enabled_sat.api.HostGroup( architecture=architecture, domain=domain, environment=environment, location=[location.id], medium=medium, name=gen_string('alpha'), operatingsystem=operatingsystem, organization=[org.id], ptable=ptable, ).create() assert len(hostgroup.read_json()['all_puppetclasses']) == 0 # Get puppet class id for ntp module response = client.get( environment.path('self') + '/puppetclasses', auth=get_credentials(), verify=False, ) response.raise_for_status() results = response.json()['results'] puppet_class_id = results[puppet_class][0]['id'] # Assign puppet class client.post( hostgroup.path('self') + '/puppetclass_ids', data={ 'puppetclass_id': puppet_class_id }, auth=get_credentials(), verify=False, ).raise_for_status() hostgroup_attrs = hostgroup.read_json() assert len(hostgroup_attrs['all_puppetclasses']) == 1 assert hostgroup_attrs['all_puppetclasses'][0]['name'] == puppet_class # Create Host entity using HostGroup host = session_puppet_enabled_sat.api.Host( hostgroup=hostgroup, mac=mac, root_pass=root_pass, environment=environment, location=location, organization=org, content_facet_attributes={ 'content_view_id': content_view.id, 'lifecycle_environment_id': lc_env.id, }, name=gen_string('alpha'), ).create(False) host_attrs = host.read_json() assert len(host_attrs['all_puppetclasses']) == 1 assert host_attrs['all_puppetclasses'][0]['name'] == puppet_class