prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Support ECDSA for ssh_check
  ssh_check.py is not support ECDSA ssh key.
  paramiko is support ECDSA ssh key.
  http://docs.paramiko.org/en/1.17/api/keys.html#module-paramiko.ecdsakey
  
  I changes ssh_key.py, but It's not working.
  
  ```
  2016-05-08 17:56:27 JST | ERROR | dd.collector | checks.ssh_check(__init__.py:763) | Check 'ssh_check' instance #0 failed
  Traceback (most recent call last):
    File "/opt/datadog-agent/agent/checks/__init__.py", line 746, in run
      self.check(copy.deepcopy(instance))
    File "/opt/datadog-agent/agent/checks.d/ssh_check.py", line 70, in check
      password=conf.password, pkey=private_key)
    File "/opt/datadog-agent/embedded/lib/python2.7/site-packages/paramiko/client.py", line 307, in connect
      look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host)
    File "/opt/datadog-agent/embedded/lib/python2.7/site-packages/paramiko/client.py", line 519, in _auth
      raise saved_exception
  AuthenticationException: Authentication failed.
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `checks.d/ssh_check.py`
  Content:
  ```
  1 # (C) Datadog, Inc. 2010-2016
  2 # All rights reserved
  3 # Licensed under Simplified BSD License (see LICENSE)
  4 
  5 # stdlib
  6 from collections import namedtuple
  7 import time
  8 
  9 # 3p
  10 import paramiko
  11 
  12 # project
  13 from checks import AgentCheck
  14 
  15 
  16 class CheckSSH(AgentCheck):
  17 
  18     OPTIONS = [
  19         ('host', True, None, str),
  20         ('port', False, 22, int),
  21         ('username', True, None, str),
  22         ('password', False, None, str),
  23         ('private_key_file', False, None, str),
  24         ('sftp_check', False, True, bool),
  25         ('add_missing_keys', False, False, bool),
  26     ]
  27 
  28     Config = namedtuple('Config', [
  29         'host',
  30         'port',
  31         'username',
  32         'password',
  33         'private_key_file',
  34         'sftp_check',
  35         'add_missing_keys',
  36     ])
  37 
  38     def _load_conf(self, instance):
  39         params = []
  40         for option, required, default, expected_type in self.OPTIONS:
  41             value = instance.get(option)
  42             if required and (not value or type(value)) != expected_type :
  43                 raise Exception("Please specify a valid {0}".format(option))
  44 
  45             if value is None or type(value) != expected_type:
  46                 self.log.debug("Bad or missing value for {0} parameter. Using default".format(option))
  47                 value = default
  48 
  49             params.append(value)
  50         return self.Config._make(params)
  51 
  52     def check(self, instance):
  53         conf = self._load_conf(instance)
  54         tags = ["instance:{0}-{1}".format(conf.host, conf.port)]
  55 
  56         private_key = None
  57         try:
  58             private_key = paramiko.RSAKey.from_private_key_file(conf.private_key_file)
  59         except IOError:
  60             self.warning("Unable to find private key file: {}".format(conf.private_key_file))
  61         except paramiko.ssh_exception.PasswordRequiredException:
  62             self.warning("Private key file is encrypted but no password was given")
  63         except paramiko.ssh_exception.SSHException:
  64             self.warning("Private key file is invalid")
  65 
  66         client = paramiko.SSHClient()
  67         if conf.add_missing_keys:
  68             client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  69         client.load_system_host_keys()
  70 
  71         exception_message = None
  72         #Service Availability to check status of SSH
  73         try:
  74             client.connect(conf.host, port=conf.port, username=conf.username,
  75                 password=conf.password, pkey=private_key)
  76             self.service_check('ssh.can_connect', AgentCheck.OK,  tags=tags,
  77                 message=exception_message)
  78 
  79         except Exception as e:
  80             exception_message = str(e)
  81             status = AgentCheck.CRITICAL
  82             self.service_check('ssh.can_connect', status, tags=tags,
  83                 message=exception_message)
  84             if conf.sftp_check:
  85                 self.service_check('sftp.can_connect', status, tags=tags,
  86                     message=exception_message)
  87             raise
  88 
  89         #Service Availability to check status of SFTP
  90         if conf.sftp_check:
  91             try:
  92                 sftp = client.open_sftp()
  93                 #Check response time of SFTP
  94                 start_time = time.time()
  95                 sftp.listdir('.')
  96                 status = AgentCheck.OK
  97                 end_time = time.time()
  98                 time_taken = end_time - start_time
  99                 self.gauge('sftp.response_time', time_taken, tags=tags)
  100 
  101             except Exception as e:
  102                 exception_message = str(e)
  103                 status = AgentCheck.CRITICAL
  104 
  105             if exception_message is None:
  106                 exception_message = "No errors occured"
  107 
  108             self.service_check('sftp.can_connect', status, tags=tags,
  109                 message=exception_message)
  110
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/checks.d/ssh_check.py b/checks.d/ssh_check.py
  --- a/checks.d/ssh_check.py
  +++ b/checks.d/ssh_check.py
  @@ -21,6 +21,7 @@
           ('username', True, None, str),
           ('password', False, None, str),
           ('private_key_file', False, None, str),
  +        ('private_key_type', False, 'rsa', str),
           ('sftp_check', False, True, bool),
           ('add_missing_keys', False, False, bool),
       ]
  @@ -31,6 +32,7 @@
           'username',
           'password',
           'private_key_file',
  +        'private_key_type',
           'sftp_check',
           'add_missing_keys',
       ])
  @@ -55,7 +57,10 @@
   
           private_key = None
           try:
  -            private_key = paramiko.RSAKey.from_private_key_file(conf.private_key_file)
  +            if conf.private_key_type == 'ecdsa':
  +                private_key = paramiko.ECDSAKey.from_private_key_file(conf.private_key_file)
  +            else:
  +                private_key = paramiko.RSAKey.from_private_key_file(conf.private_key_file)
           except IOError:
               self.warning("Unable to find private key file: {}".format(conf.private_key_file))
           except paramiko.ssh_exception.PasswordRequiredException:
  @@ -69,11 +74,11 @@
           client.load_system_host_keys()
   
           exception_message = None
  -        #Service Availability to check status of SSH
  +        # Service Availability to check status of SSH
           try:
               client.connect(conf.host, port=conf.port, username=conf.username,
                   password=conf.password, pkey=private_key)
  -            self.service_check('ssh.can_connect', AgentCheck.OK,  tags=tags,
  +            self.service_check('ssh.can_connect', AgentCheck.OK, tags=tags,
                   message=exception_message)
   
           except Exception as e:
  @@ -86,7 +91,7 @@
                       message=exception_message)
               raise
   
  -        #Service Availability to check status of SFTP
  +        # Service Availability to check status of SFTP
           if conf.sftp_check:
               try:
                   sftp = client.open_sftp()
  
verification_info: {"golden_diff": "diff --git a/checks.d/ssh_check.py b/checks.d/ssh_check.py\n--- a/checks.d/ssh_check.py\n+++ b/checks.d/ssh_check.py\n@@ -21,6 +21,7 @@\n         ('username', True, None, str),\n         ('password', False, None, str),\n         ('private_key_file', False, None, str),\n+        ('private_key_type', False, 'rsa', str),\n         ('sftp_check', False, True, bool),\n         ('add_missing_keys', False, False, bool),\n     ]\n@@ -31,6 +32,7 @@\n         'username',\n         'password',\n         'private_key_file',\n+        'private_key_type',\n         'sftp_check',\n         'add_missing_keys',\n     ])\n@@ -55,7 +57,10 @@\n \n         private_key = None\n         try:\n-            private_key = paramiko.RSAKey.from_private_key_file(conf.private_key_file)\n+            if conf.private_key_type == 'ecdsa':\n+                private_key = paramiko.ECDSAKey.from_private_key_file(conf.private_key_file)\n+            else:\n+                private_key = paramiko.RSAKey.from_private_key_file(conf.private_key_file)\n         except IOError:\n             self.warning(\"Unable to find private key file: {}\".format(conf.private_key_file))\n         except paramiko.ssh_exception.PasswordRequiredException:\n@@ -69,11 +74,11 @@\n         client.load_system_host_keys()\n \n         exception_message = None\n-        #Service Availability to check status of SSH\n+        # Service Availability to check status of SSH\n         try:\n             client.connect(conf.host, port=conf.port, username=conf.username,\n                 password=conf.password, pkey=private_key)\n-            self.service_check('ssh.can_connect', AgentCheck.OK,  tags=tags,\n+            self.service_check('ssh.can_connect', AgentCheck.OK, tags=tags,\n                 message=exception_message)\n \n         except Exception as e:\n@@ -86,7 +91,7 @@\n                     message=exception_message)\n             raise\n \n-        #Service Availability to check status of SFTP\n+        # Service Availability to check status of SFTP\n         if conf.sftp_check:\n             try:\n                 sftp = client.open_sftp()\n", "issue": "Support ECDSA for ssh_check\nssh_check.py is not support ECDSA ssh key.\nparamiko is support ECDSA ssh key.\nhttp://docs.paramiko.org/en/1.17/api/keys.html#module-paramiko.ecdsakey\n\nI changes ssh_key.py, but It's not working.\n\n```\n2016-05-08 17:56:27 JST | ERROR | dd.collector | checks.ssh_check(__init__.py:763) | Check 'ssh_check' instance #0 failed\nTraceback (most recent call last):\n  File \"/opt/datadog-agent/agent/checks/__init__.py\", line 746, in run\n    self.check(copy.deepcopy(instance))\n  File \"/opt/datadog-agent/agent/checks.d/ssh_check.py\", line 70, in check\n    password=conf.password, pkey=private_key)\n  File \"/opt/datadog-agent/embedded/lib/python2.7/site-packages/paramiko/client.py\", line 307, in connect\n    look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host)\n  File \"/opt/datadog-agent/embedded/lib/python2.7/site-packages/paramiko/client.py\", line 519, in _auth\n    raise saved_exception\nAuthenticationException: Authentication failed.\n```\n\n", "before_files": [{"content": "# (C) Datadog, Inc. 2010-2016\n# All rights reserved\n# Licensed under Simplified BSD License (see LICENSE)\n\n# stdlib\nfrom collections import namedtuple\nimport time\n\n# 3p\nimport paramiko\n\n# project\nfrom checks import AgentCheck\n\n\nclass CheckSSH(AgentCheck):\n\n    OPTIONS = [\n        ('host', True, None, str),\n        ('port', False, 22, int),\n        ('username', True, None, str),\n        ('password', False, None, str),\n        ('private_key_file', False, None, str),\n        ('sftp_check', False, True, bool),\n        ('add_missing_keys', False, False, bool),\n    ]\n\n    Config = namedtuple('Config', [\n        'host',\n        'port',\n        'username',\n        'password',\n        'private_key_file',\n        'sftp_check',\n        'add_missing_keys',\n    ])\n\n    def _load_conf(self, instance):\n        params = []\n        for option, required, default, expected_type in self.OPTIONS:\n            value = instance.get(option)\n            if required and (not value or type(value)) != expected_type :\n                raise Exception(\"Please specify a valid {0}\".format(option))\n\n            if value is None or type(value) != expected_type:\n                self.log.debug(\"Bad or missing value for {0} parameter. Using default\".format(option))\n                value = default\n\n            params.append(value)\n        return self.Config._make(params)\n\n    def check(self, instance):\n        conf = self._load_conf(instance)\n        tags = [\"instance:{0}-{1}\".format(conf.host, conf.port)]\n\n        private_key = None\n        try:\n            private_key = paramiko.RSAKey.from_private_key_file(conf.private_key_file)\n        except IOError:\n            self.warning(\"Unable to find private key file: {}\".format(conf.private_key_file))\n        except paramiko.ssh_exception.PasswordRequiredException:\n            self.warning(\"Private key file is encrypted but no password was given\")\n        except paramiko.ssh_exception.SSHException:\n            self.warning(\"Private key file is invalid\")\n\n        client = paramiko.SSHClient()\n        if conf.add_missing_keys:\n            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())\n        client.load_system_host_keys()\n\n        exception_message = None\n        #Service Availability to check status of SSH\n        try:\n            client.connect(conf.host, port=conf.port, username=conf.username,\n                password=conf.password, pkey=private_key)\n            self.service_check('ssh.can_connect', AgentCheck.OK,  tags=tags,\n                message=exception_message)\n\n        except Exception as e:\n            exception_message = str(e)\n            status = AgentCheck.CRITICAL\n            self.service_check('ssh.can_connect', status, tags=tags,\n                message=exception_message)\n            if conf.sftp_check:\n                self.service_check('sftp.can_connect', status, tags=tags,\n                    message=exception_message)\n            raise\n\n        #Service Availability to check status of SFTP\n        if conf.sftp_check:\n            try:\n                sftp = client.open_sftp()\n                #Check response time of SFTP\n                start_time = time.time()\n                sftp.listdir('.')\n                status = AgentCheck.OK\n                end_time = time.time()\n                time_taken = end_time - start_time\n                self.gauge('sftp.response_time', time_taken, tags=tags)\n\n            except Exception as e:\n                exception_message = str(e)\n                status = AgentCheck.CRITICAL\n\n            if exception_message is None:\n                exception_message = \"No errors occured\"\n\n            self.service_check('sftp.can_connect', status, tags=tags,\n                message=exception_message)\n", "path": "checks.d/ssh_check.py"}], "after_files": [{"content": "# (C) Datadog, Inc. 2010-2016\n# All rights reserved\n# Licensed under Simplified BSD License (see LICENSE)\n\n# stdlib\nfrom collections import namedtuple\nimport time\n\n# 3p\nimport paramiko\n\n# project\nfrom checks import AgentCheck\n\n\nclass CheckSSH(AgentCheck):\n\n    OPTIONS = [\n        ('host', True, None, str),\n        ('port', False, 22, int),\n        ('username', True, None, str),\n        ('password', False, None, str),\n        ('private_key_file', False, None, str),\n        ('private_key_type', False, 'rsa', str),\n        ('sftp_check', False, True, bool),\n        ('add_missing_keys', False, False, bool),\n    ]\n\n    Config = namedtuple('Config', [\n        'host',\n        'port',\n        'username',\n        'password',\n        'private_key_file',\n        'private_key_type',\n        'sftp_check',\n        'add_missing_keys',\n    ])\n\n    def _load_conf(self, instance):\n        params = []\n        for option, required, default, expected_type in self.OPTIONS:\n            value = instance.get(option)\n            if required and (not value or type(value)) != expected_type :\n                raise Exception(\"Please specify a valid {0}\".format(option))\n\n            if value is None or type(value) != expected_type:\n                self.log.debug(\"Bad or missing value for {0} parameter. Using default\".format(option))\n                value = default\n\n            params.append(value)\n        return self.Config._make(params)\n\n    def check(self, instance):\n        conf = self._load_conf(instance)\n        tags = [\"instance:{0}-{1}\".format(conf.host, conf.port)]\n\n        private_key = None\n        try:\n            if conf.private_key_type == 'ecdsa':\n                private_key = paramiko.ECDSAKey.from_private_key_file(conf.private_key_file)\n            else:\n                private_key = paramiko.RSAKey.from_private_key_file(conf.private_key_file)\n        except IOError:\n            self.warning(\"Unable to find private key file: {}\".format(conf.private_key_file))\n        except paramiko.ssh_exception.PasswordRequiredException:\n            self.warning(\"Private key file is encrypted but no password was given\")\n        except paramiko.ssh_exception.SSHException:\n            self.warning(\"Private key file is invalid\")\n\n        client = paramiko.SSHClient()\n        if conf.add_missing_keys:\n            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())\n        client.load_system_host_keys()\n\n        exception_message = None\n        # Service Availability to check status of SSH\n        try:\n            client.connect(conf.host, port=conf.port, username=conf.username,\n                password=conf.password, pkey=private_key)\n            self.service_check('ssh.can_connect', AgentCheck.OK, tags=tags,\n                message=exception_message)\n\n        except Exception as e:\n            exception_message = str(e)\n            status = AgentCheck.CRITICAL\n            self.service_check('ssh.can_connect', status, tags=tags,\n                message=exception_message)\n            if conf.sftp_check:\n                self.service_check('sftp.can_connect', status, tags=tags,\n                    message=exception_message)\n            raise\n\n        # Service Availability to check status of SFTP\n        if conf.sftp_check:\n            try:\n                sftp = client.open_sftp()\n                #Check response time of SFTP\n                start_time = time.time()\n                sftp.listdir('.')\n                status = AgentCheck.OK\n                end_time = time.time()\n                time_taken = end_time - start_time\n                self.gauge('sftp.response_time', time_taken, tags=tags)\n\n            except Exception as e:\n                exception_message = str(e)\n                status = AgentCheck.CRITICAL\n\n            if exception_message is None:\n                exception_message = \"No errors occured\"\n\n            self.service_check('sftp.can_connect', status, tags=tags,\n                message=exception_message)\n", "path": "checks.d/ssh_check.py"}]}