Example #1
0
 def get(self, command, context, params=None):
     """Dispatch a GET request to a Microsoft OCS chassis."""
     if params is None:
         params = []
     else:
         params = [param for param in params if bool(param)]
     url_base = "http://{power_address}:{power_port}/".format(**context)
     url = urllib.parse.urljoin(url_base, command) + "?" + "&".join(params)
     authinfo = urllib.request.HTTPPasswordMgrWithDefaultRealm()
     authinfo.add_password(None, url, context["power_user"],
                           context["power_pass"])
     proxy_handler = urllib.request.ProxyHandler({})
     auth_handler = urllib.request.HTTPBasicAuthHandler(authinfo)
     opener = urllib.request.build_opener(proxy_handler, auth_handler)
     urllib.request.install_opener(opener)
     try:
         response = urllib.request.urlopen(url)
     except urllib.error.HTTPError as e:
         raise PowerConnError(
             "Could not make proper connection to Microsoft OCS Chassis."
             " HTTP error code: %s" % e.code)
     except urllib.error.URLError as e:
         raise PowerConnError(
             "Could not make proper connection to Microsoft OCS Chassis."
             " Server could not be reached: %s" % e.reason)
     else:
         return response.read()
Example #2
0
 def post(self, command, urlparams=[], params={}):
     """Dispatch a POST request to a RECS_Master."""
     url = self.build_url(command, urlparams)
     authinfo = urllib.request.HTTPPasswordMgrWithDefaultRealm()
     authinfo.add_password(None, url, self.username, self.password)
     proxy_handler = urllib.request.ProxyHandler({})
     auth_handler = urllib.request.HTTPBasicAuthHandler(authinfo)
     opener = urllib.request.build_opener(proxy_handler, auth_handler)
     urllib.request.install_opener(opener)
     data = urllib.parse.urlencode(params).encode()
     req = urllib.request.Request(url, data, method="POST")
     try:
         response = urllib.request.urlopen(req)
     except urllib.error.HTTPError as e:
         raise PowerConnError(
             "Could not make proper connection to RECS|Box."
             " HTTP error code: %s" % e.code
         )
     except urllib.error.URLError as e:
         raise PowerConnError(
             "Could not make proper connection to RECS|Box."
             " Server could not be reached: %s" % e.reason
         )
     else:
         return response.read()
Example #3
0
class TestGetErrorMessage(MAASTestCase):

    scenarios = [
        ('auth', dict(
            exception=PowerAuthError('auth'),
            message="Could not authenticate to node's BMC: auth",
            )),
        ('conn', dict(
            exception=PowerConnError('conn'),
            message="Could not contact node's BMC: conn",
            )),
        ('setting', dict(
            exception=PowerSettingError('setting'),
            message="Missing or invalid power setting: setting",
            )),
        ('tool', dict(
            exception=PowerToolError('tool'),
            message="Missing power tool: tool",
            )),
        ('action', dict(
            exception=PowerActionError('action'),
            message="Failed to complete power action: action",
            )),
        ('unknown', dict(
            exception=PowerError('unknown error'),
            message="Failed talking to node's BMC: unknown error",
            )),
    ]

    def test_return_msg(self):
        self.assertEqual(self.message, get_error_message(self.exception))
Example #4
0
 def _get_amt_command(self, ip_address, power_pass):
     """Retrieve AMT command to use, either amttool or wsman
     (if AMT version > 8), for the given system.
     """
     # XXX bug=1331214
     # Check if the AMT ver > 8
     # If so, we need wsman, not amttool
     env = self._get_amt_environment(power_pass)
     process = Popen(
         ('amttool', ip_address, 'info'), stdout=PIPE, stderr=PIPE, env=env)
     stdout, stderr = process.communicate()
     stdout = stdout.decode("utf-8")
     stderr = stderr.decode("utf-8")
     if stdout == "" or stdout.isspace():
         for error, error_info in AMT_ERRORS.items():
             if error in stderr:
                 raise error_info.get(
                     'exception')(error_info.get('message'))
         raise PowerConnError(
             "Unable to retrieve AMT version: %s" % stderr)
     else:
         match = re.search("AMT version:\s*([0-9]+)", stdout)
         if match is None:
             raise PowerActionError(
                 "Unable to extract AMT version from "
                 "amttool output: %s" % stdout)
         else:
             version = match.group(1)
             if int(version) > 8:
                 return 'wsman'
             else:
                 return 'amttool'
Example #5
0
    def run_wedge_command(
        self,
        command,
        power_address=None,
        power_user=None,
        power_pass=None,
        **extra
    ):
        """Run a single command and return unparsed text from stdout."""
        try:
            ssh_client = SSHClient()
            ssh_client.set_missing_host_key_policy(AutoAddPolicy())
            ssh_client.connect(
                power_address, username=power_user, password=power_pass
            )
            _, stdout, _ = ssh_client.exec_command(command)
            output = stdout.read().decode("utf-8").strip()
        except (SSHException, EOFError, SOCKETError) as e:
            raise PowerConnError(
                "Could not make SSH connection to Wedge for "
                "%s on %s - %s" % (power_user, power_address, e)
            )
        finally:
            ssh_client.close()

        return output
Example #6
0
 def test_power_off_crashes_for_connection_error(self):
     driver = MicrosoftOCSPowerDriver()
     context = make_context()
     system_id = factory.make_name("system_id")
     mock_get = self.patch(driver, "get")
     mock_get.side_effect = PowerConnError("Connection Error")
     self.assertRaises(PowerActionError, driver.power_off, system_id,
                       context)
Example #7
0
 def test_power_query_crashes_for_connection_error(self):
     driver = MSCMPowerDriver()
     system_id = factory.make_name("system_id")
     context = make_context()
     run_mscm_command = self.patch(driver, "run_mscm_command")
     run_mscm_command.side_effect = PowerConnError("Connection Error")
     self.assertRaises(PowerActionError, driver.power_query, system_id,
                       context)
Example #8
0
 def test_power_off_crashes_for_connection_error(self):
     driver = WedgePowerDriver()
     system_id = factory.make_name('system_id')
     context = make_context()
     run_wedge_command = self.patch(driver, "run_wedge_command")
     run_wedge_command.side_effect = PowerConnError("Connection Error")
     self.assertRaises(
         PowerActionError, driver.power_off, system_id, context)
Example #9
0
 def test_power_on_crashes_for_connection_error(self):
     driver = MicrosoftOCSPowerDriver()
     context = make_context()
     system_id = factory.make_name("system_id")
     self.patch(driver, "power_query", Mock(return_value="off"))
     self.patch(driver, "set_next_boot_device")
     mock_get = self.patch(driver, "get")
     mock_get.side_effect = PowerConnError("Connection Error")
     self.assertRaises(PowerActionError, driver.power_on, system_id,
                       context)
Example #10
0
 def test_power_on_crashes_for_connection_error(self):
     driver = HMCPowerDriver()
     system_id = factory.make_name("system_id")
     context = make_context()
     power_query = self.patch(driver, "power_query")
     power_query.return_value = "off"
     run_hmc_command = self.patch(driver, "run_hmc_command")
     run_hmc_command.side_effect = PowerConnError("Connection Error")
     self.assertRaises(PowerActionError, driver.power_on, system_id,
                       context)
Example #11
0
 def test_power_query_crashes_for_connection_error(self):
     driver = MicrosoftOCSPowerDriver()
     context = make_context()
     system_id = factory.make_name("system_id")
     mock_extract_from_response = self.patch(driver,
                                             "extract_from_response")
     mock_extract_from_response.side_effect = PowerConnError(
         "Connection Error")
     self.patch(driver, "get")
     self.assertRaises(PowerActionError, driver.power_query, system_id,
                       context)
Example #12
0
 def test_power_on_crashes_for_connection_error(self):
     driver = MSCMPowerDriver()
     system_id = factory.make_name('system_id')
     context = make_context()
     power_query = self.patch(driver, "power_query")
     power_query.return_value = 'off'
     self.patch(driver, "configure_node_bootonce_pxe")
     run_mscm_command = self.patch(driver, "run_mscm_command")
     run_mscm_command.side_effect = PowerConnError("Connection Error")
     self.assertRaises(PowerActionError, driver.power_on, system_id,
                       context)
Example #13
0
 def _get_amt_command(self, ip_address, power_pass):
     """Retrieve AMT command to use, either amttool or wsman
     (if AMT version > 8), for the given system.
     """
     # XXX bug=1331214
     # Check if the AMT ver > 8
     # If so, we need wsman, not amttool
     env = self._get_amt_environment(power_pass)
     process = Popen(
         (
             "wsman",
             "identify",
             "--port",
             "16992",
             "--hostname",
             ip_address,
             "--username",
             "admin",
             "--password",
             power_pass,
         ),
         stdout=PIPE,
         stderr=PIPE,
         env=env,
     )
     stdout, stderr = process.communicate()
     stdout = stdout.decode("utf-8")
     stderr = stderr.decode("utf-8")
     if stdout == "" or stdout.isspace():
         for error, error_info in AMT_ERRORS.items():
             if error in stderr:
                 raise error_info.get("exception")(
                     error_info.get("message"))
         raise PowerConnError("Unable to retrieve AMT version: %s" % stderr)
     else:
         match = re.search(r"ProductVersion>AMT\s*([0-9]+)", stdout)
         if match is None:
             raise PowerActionError("Unable to extract AMT version from "
                                    "amttool output: %s" % stdout)
         else:
             version = match.group(1)
             if int(version) > 8:
                 return "wsman"
             else:
                 return "amttool"
Example #14
0
 def _get_amt_command(self, ip_address, power_pass):
     """Retrieve AMT command to use, either amttool or wsman
     (if AMT version > 8), for the given system.
     """
     # XXX bug=1331214
     # Check if the AMT ver > 8
     # If so, we need wsman, not amttool
     result = shell.run_command(
         "wsman",
         "identify",
         "--port",
         "16992",
         "--hostname",
         ip_address,
         "--username",
         "admin",
         "--password",
         power_pass,
     )
     if not result.stdout:
         for error, error_info in AMT_ERRORS.items():
             if error in result.stderr:
                 raise error_info.get("exception")(
                     error_info.get("message"))
         raise PowerConnError(
             f"Unable to retrieve AMT version: {result.stderr}")
     else:
         match = re.search(r"ProductVersion>AMT\s*([0-9]+)", result.stdout)
         if match is None:
             raise PowerActionError("Unable to extract AMT version from "
                                    f"amttool output: {result.stdout}")
         else:
             version = match.group(1)
             if int(version) > 8:
                 return "wsman"
             else:
                 return "amttool"