def setUp(self): self.raw_values = [{ 'resolve': False }, { 'ping': True }, { 'auth': False }, { 'hostname_valid': False }, { 'fqdn_resolves': False }, { 'fqdn_matches': False }, { 'reverse_resolve': False }, { 'reverse_ping': False }, { 'yum_valid_repos': False }, { 'yum_can_update': False }, { 'openssl': False }] self.values = NameValueList(self.raw_values)
def patch_test_host_contact_task(context, result_attrs={}): from chroma_core.services.job_scheduler.job_scheduler_client import JobSchedulerClient status = NameValueList( [ {"resolve": True}, {"ping": True}, {"auth": True}, {"hostname_valid": True}, {"fqdn_resolves": True}, {"fqdn_matches": True}, {"reverse_resolve": True}, {"reverse_ping": True}, {"yum_valid_repos": True}, {"yum_can_update": True}, {"openssl": True}, ] ) status.add(result_attrs) # Don't overwrite the original reference! if not "old_test_host_contact" in context: context.old_test_host_contact = JobSchedulerClient.test_host_contact def mock_test_host_contact(address, root_pw, pkey, pkey_pw): from chroma_core.models import StepResult, TestHostConnectionJob, Command, TestHostConnectionStep command = Command.objects.create(message="Mock Test Host Contact", complete=True) job = TestHostConnectionJob.objects.create( state="complete", address=address, root_pw=None, pkey=None, pkey_pw=None ) command.jobs.add(job) StepResult.objects.create( job=job, backtrace="an error", step_klass=TestHostConnectionStep, args={"address": address, "credentials_key": 1}, step_index=0, step_count=1, state="complete", result=json.dumps({"address": address, "status": status.collection(), "valid": True}), ) return command JobSchedulerClient.test_host_contact = mock.Mock(side_effect=mock_test_host_contact)
def _post_test_host(self, **body): response = self.chroma_manager.post("/api/test_host/", body=body) self.wait_for_command(self.chroma_manager, response.json["id"]) response = self.chroma_manager.get(response.json["jobs"][0]) self.assertTrue(response.successful, response.text) validations = response.json["step_results"].values()[0] return NameValueList(validations["status"])
def setUp(self): self.raw_values = [ { "resolve": False }, { "ping": True }, { "auth": False }, { "hostname_valid": False }, { "fqdn_resolves": False }, { "fqdn_matches": False }, { "reverse_resolve": False }, { "reverse_ping": False }, { "yum_valid_repos": False }, { "yum_can_update": False }, { "openssl": False }, ] self.values = NameValueList(self.raw_values)
def _post_to_test_host(self, extra_params): """ This is a helper function that calls /api/test_host. Extra params to post can be provided. @type extra_params: dict | (dict) -> dict @param extra_params: If a dict, updates the body directly. If a lambda is given a server config and returns dict based on lookup in that config. @rtype: tests.utils.http_requests.HttpResponse @return: A HttpResponse. """ server_config_1 = config['lustre_servers'][0] body = {'address': server_config_1['address']} if callable(extra_params): extra_params = extra_params(server_config_1) body.update(extra_params) response = self.chroma_manager.post('/api/test_host/', body=body) self.assertEqual(response.successful, True, response.text) command_id = response.json['id'] self.wait_for_command(self.chroma_manager, command_id, timeout=1200) results = [] for job in response.json['jobs']: response = self.chroma_manager.get(job) self.assertEqual(response.successful, True, response.text) for item in response.json['step_results'].items(): results.append(NameValueList(item[1]['status'])) # We have a result for each host, but as we have posted 1 host then 1 result self.assertEqual(len(results), 1) # As we have 1 result just return that result return results[0]
class TestNameValueList(unittest.TestCase): def setUp(self): self.raw_values = [{ 'resolve': False }, { 'ping': True }, { 'auth': False }, { 'hostname_valid': False }, { 'fqdn_resolves': False }, { 'fqdn_matches': False }, { 'reverse_resolve': False }, { 'reverse_ping': False }, { 'yum_valid_repos': False }, { 'yum_can_update': False }, { 'openssl': False }] self.values = NameValueList(self.raw_values) def test_creation_correction(self): for value, raw_value in zip(self.values, self.raw_values): self.assertEqual(value.name, raw_value.keys()[0]) self.assertEqual(value.value, raw_value.values()[0]) def test_name_value_create(self): self.values['execute'] = True self.assertEqual(self.values['execute'], True) pass def test_update(self): self.values['resolve'] = True self.assertEqual(self.values['resolve'], True) def test_type_change(self): self.values['reverse_resolve'] = 'string' self.assertEqual(self.values['reverse_resolve'], 'string') def test_index_constant(self): self.values['reverse_resolve'] = True self.assertEqual(self.values.keys().index('reverse_resolve'), 6) def test_collection_via_json(self): json_string = json.dumps(self.values.collection()) loaded_values = NameValueList(json.loads(json_string)) self.assertEqual(self.values, loaded_values) def test_collection_len(self): self.assertEqual(len(self.values), len(self.values.collection())) def test_collection_values(self): for entry in self.values.collection(): self.assertEqual(entry['value'], self.values[entry['name']])
def test_collection_via_json(self): json_string = json.dumps(self.values.collection()) loaded_values = NameValueList(json.loads(json_string)) self.assertEqual(self.values, loaded_values)
def run(self, kwargs): """Test that a host at this address can be created See create_host_ssh for explanation of parameters TODO: Break this method up, normalize the checks Use threaded timeouts on possible long running commands. The idea is that if the command takes longer than the timeout, you might get a false negative - the command didn't fail, we just cut it short. Not sure this is an issue in practice, so going to stop here no ticket. """ from chroma_core.services.job_scheduler.agent_rpc import AgentSsh credentials = credentials_table[kwargs["credentials_key"]] del credentials_table[kwargs["credentials_key"]] address = kwargs["address"] profiles = kwargs["profiles"] root_pw = credentials["root_pw"] pkey = credentials["pkey"] pkey_pw = credentials["pkey_pw"] agent_ssh = AgentSsh(address, timeout=5) user, hostname, port = agent_ssh.ssh_params() auth_args = agent_ssh.construct_ssh_auth_args(root_pw, pkey, pkey_pw) try: resolved_address = socket.gethostbyname(hostname) except socket.gaierror: resolve = False ping = False else: resolve = True ping = 0 == subprocess.call(["ping", "-c 1", resolved_address]) manager_hostname = urlparse.urlparse(settings.SERVER_HTTP_URL).hostname status = NameValueList([ { "resolve": resolve }, { "ping": ping }, { "auth": False }, { "hostname_valid": False }, { "fqdn_resolves": False }, { "fqdn_matches": False }, { "reverse_resolve": False }, { "reverse_ping": False }, { "yum_can_update": False }, { "openssl": False }, ]) if resolve and ping: try: status["reverse_resolve"], status[ "reverse_ping"] = self._test_reverse_ping( agent_ssh, auth_args, address, manager_hostname) status["hostname_valid"], status["fqdn_resolves"], status[ "fqdn_matches"] = self._test_hostname( agent_ssh, auth_args, address, resolved_address) status["yum_can_update"] = self._test_yum_rpm_sanity( agent_ssh, auth_args, address) status["openssl"] = self._test_openssl(agent_ssh, auth_args, address) except (AuthenticationException, SSHException): # No auth methods available, or wrong credentials status["auth"] = False else: status["auth"] = True all_valid = all(entry.value is True for entry in status) profile_checks = {} if all_valid: properties = get_host_props(agent_ssh, auth_args) profile_checks = get_profile_checks(properties, profiles) return { "address": address, "valid": all_valid, "status": status.collection(), "profiles": profile_checks, }
def run(self, kwargs): """Test that a host at this address can be created See create_host_ssh for explanation of parameters TODO: Break this method up, normalize the checks Use threaded timeouts on possible long running commands. The idea is that if the command takes longer than the timeout, you might get a false negative - the command didn't fail, we just cut it short. Not sure this is an issue in practice, so going to stop here no ticket. """ from chroma_core.services.job_scheduler.agent_rpc import AgentSsh credentials = credentials_table[kwargs['credentials_key']] del credentials_table[kwargs['credentials_key']] address = kwargs['address'] root_pw = credentials['root_pw'] pkey = credentials['pkey'] pkey_pw = credentials['pkey_pw'] agent_ssh = AgentSsh(address, timeout=5) user, hostname, port = agent_ssh.ssh_params() auth_args = agent_ssh.construct_ssh_auth_args(root_pw, pkey, pkey_pw) try: resolved_address = socket.gethostbyname(hostname) except socket.gaierror: resolve = False ping = False else: resolve = True ping = (0 == subprocess.call(['ping', '-c 1', resolved_address])) manager_hostname = urlparse.urlparse(settings.SERVER_HTTP_URL).hostname status = NameValueList([{ 'resolve': resolve }, { 'ping': ping }, { 'auth': False }, { 'hostname_valid': False }, { 'fqdn_resolves': False }, { 'fqdn_matches': False }, { 'reverse_resolve': False }, { 'reverse_ping': False }, { 'yum_can_update': False }, { 'openssl': False }]) if resolve and ping: try: status['reverse_resolve'], status[ 'reverse_ping'] = self._test_reverse_ping( agent_ssh, auth_args, address, manager_hostname) status['hostname_valid'], status['fqdn_resolves'], status[ 'fqdn_matches'] = self._test_hostname( agent_ssh, auth_args, address, resolved_address) status['yum_can_update'] = self._test_yum_sanity( agent_ssh, auth_args, address) status['openssl'] = self._test_openssl(agent_ssh, auth_args, address) except (AuthenticationException, SSHException): # No auth methods available, or wrong credentials status['auth'] = False else: status['auth'] = True return { 'address': address, 'valid': all(entry.value is True for entry in status), 'status': status.collection() }
class TestNameValueList(unittest.TestCase): def setUp(self): self.raw_values = [ { "resolve": False }, { "ping": True }, { "auth": False }, { "hostname_valid": False }, { "fqdn_resolves": False }, { "fqdn_matches": False }, { "reverse_resolve": False }, { "reverse_ping": False }, { "yum_valid_repos": False }, { "yum_can_update": False }, { "openssl": False }, ] self.values = NameValueList(self.raw_values) def test_creation_correction(self): for value, raw_value in zip(self.values, self.raw_values): self.assertEqual(value.name, raw_value.keys()[0]) self.assertEqual(value.value, raw_value.values()[0]) def test_name_value_create(self): self.values["execute"] = True self.assertEqual(self.values["execute"], True) pass def test_update(self): self.values["resolve"] = True self.assertEqual(self.values["resolve"], True) def test_type_change(self): self.values["reverse_resolve"] = "string" self.assertEqual(self.values["reverse_resolve"], "string") def test_index_constant(self): self.values["reverse_resolve"] = True self.assertEqual(self.values.keys().index("reverse_resolve"), 6) def test_collection_via_json(self): json_string = json.dumps(self.values.collection()) loaded_values = NameValueList(json.loads(json_string)) self.assertEqual(self.values, loaded_values) def test_collection_len(self): self.assertEqual(len(self.values), len(self.values.collection())) def test_collection_values(self): for entry in self.values.collection(): self.assertEqual(entry["value"], self.values[entry["name"]])