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)
Example #2
0
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)
Example #3
0
    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"])
Example #4
0
    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)
Example #8
0
    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()
        }
Example #10
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"]])