예제 #1
0
    def __call__(self, request):
        """WSGI method that controls (de)serialization and method dispatch."""

        try:
            action_args = self.get_action_args(request.environ)
            action = action_args.pop('action', None)
            deserialized_request = self.deserialize_request(request)
            action_args.update(deserialized_request)
        except exception.InvalidContentType:
            msg = _("Unsupported Content-Type")
            return webob.exc.HTTPUnsupportedMediaType(explanation=msg)
        except exception.MalformedRequestBody:
            msg = _("Malformed request body")
            return webob.exc.HTTPBadRequest(explanation=msg)

        action_result = self.execute_action(action, request, **action_args)

        try:
            response = webob.Response(request=request)
            self.dispatch(self.serializer, action, response, action_result)
            return response
        # return unserializable result (typically a webob exc)
        except Exception:
            try:
                err_body = action_result.get_unserialized_body()
                self.serializer.default(action_result, err_body)
            except Exception:
                LOG.warning(_LW("Unable to serialize exception response"))
            return action_result
예제 #2
0
    def cookbook_deploy_test(self, cookbook):
        """Try to deploy the given cookbook through an serial connection
        :param cookbook: cookbook to deploy
        :return: dict message with results
        """
        LOG.debug("Sending cookbook to %s" % self._ip)
        b_success = True
        msg = {}
        self.connect_session()
        msg['install'] = self.run_install(cookbook)
        b_success &= msg['install']['success']
        msg['test'] = self.run_test(cookbook)
        b_success &= msg['test']['success']
        msg['deploy'] = self.run_deploy(cookbook)
        b_success &= msg['deploy']['success']

        # check execution output
        if b_success:
            msg['result'] = {
                'success': True,
                'result': "Cookbook %s successfully deployed\n" % cookbook
            }
        else:
            msg['result'] = {
                'success': False,
                'result': "Error deploying cookbook {}\n".format(cookbook)
            }
            LOG.error(_LW("%s") % msg)
        self.disconnect_session()
        return msg
예제 #3
0
 def connect_session(self):
     """
     Connect to a session with the internal parameters
     :return:
     """
     self.ssh.set_missing_host_key_policy(AutoAddPolicy())
     try:
         self.ssh.connect(
             self._ip,
             username=self._username,
             password=self._password
         )
     except Exception as e:
         LOG.error(_LW("SSH connect exception %s") % e)
         raise SshConnectException(host=self._ip)
예제 #4
0
    def cookbook_deployment_test(self,
                                 cookbook,
                                 recipe,
                                 image=CONF.clients_docker.image):
        """
        Try to process a cookbook and return results
        :param cookbook: cookbook to deploy
        :param recipe: recipe to deploy
        :param image: image to deploy to
        :return: dictionary with results
        """
        LOG.debug("Sending cookbook to docker server in %s" % self._url)
        b_success = True
        msg = {}
        self.run_container(image)
        # inject custom solo.json/solo.rb file
        json_cont = CONF.clients_chef.cmd_config.format(
            cookbook_name=cookbook, recipe_name=recipe)
        cmd_inject = CONF.clients_chef.cmd_inject.format(config=json_cont)
        self.execute_command(cmd_inject)

        msg['install'] = self.run_install(cookbook)
        b_success &= msg['install']['success']
        msg['test'] = self.run_test(cookbook)
        b_success &= msg['test']['success']
        msg['deploy'] = self.run_deploy(cookbook, recipe)
        b_success &= msg['deploy']['success']

        # check execution output
        if b_success:
            msg['result'] = {
                'success': True,
                'result': "Cookbook %s successfully deployed\n" % cookbook
            }
        else:
            msg['result'] = {
                'success': False,
                'result': "Error deploying cookbook {}\n".format(cookbook)
            }
            LOG.error(_LW("%s") % msg)
        self.remove_container()
        return msg
예제 #5
0
 def run_install(self, cookbook):
     """Run download and install command
     :param cookbook: cookbook to process
     :return msg: operation result
     """
     try:
         cmd_install = CONF.clients_chef.cmd_install.format(cookbook)
         resp_install = self.execute_command(cmd_install)
         msg = {
             'success': True,
             'response': resp_install
         }
         for line in resp_install.splitlines():
             if "ERROR" in line:
                 msg['success'] = False
     except Exception as e:
         self.disconnect_session()
         LOG.error(_LW("Chef install exception %s") % e)
         raise CookbookInstallException(cookbook=cookbook)
     return msg
예제 #6
0
 def run_test(self, cookbook):
     """Test cookbook syntax
     :param cookbook: cookbook to test
     :return msg: dictionary with results and state
     """
     try:
         cmd_test = CONF.clients_chef.cmd_test.format(cookbook)
         resp_test = self.execute_command(cmd_test)
         msg = {
             'success': True,
             'response': resp_test
         }
         for line in resp_test.splitlines():
             if "ERROR" in line:
                 msg['success'] = False
     except Exception as e:
         self.disconnect_session()
         LOG.error(_LW("Cookbook syntax exception %s") % e)
         raise CookbookSyntaxException(cookbook=cookbook)
     return msg
예제 #7
0
 def run_container(self, image):
     """Run and start a container based on the given image
     :param image: image to run
     :return:
     """
     contname = "{}-validate".format(image).replace("/", "_")
     try:
         try:
             self.dc.remove_container(contname, force=True)
             LOG.info(_LI('Removing old %s container') % contname)
         except NotFound:
             pass
         self.container = self.dc.create_container(
             image,
             tty=True,
             name=contname
         ).get('Id')
         self.dc.start(container=self.container)
     except AttributeError as e:
         LOG.error(_LW("Error creating container: %s") % e)
         raise DockerContainerException(image=image)
예제 #8
0
 def run_deploy(self, cookbook, recipe):
     """Run cookbook deployment
     :param cookbook: cookbook to deploy
     :param recipe: recipe to deploy
     :return msg: dictionary with results and state
     """
     try:
         # launch execution
         cmd_launch = CONF.clients_chef.cmd_launch
         resp_launch = self.execute_command(cmd_launch)
         msg = {
             'success': True,
             'response': resp_launch
         }
         LOG.debug(_("Launch result: %s") % resp_launch)
         if resp_launch is None or "FATAL" in resp_launch:
             msg['success'] = False
     except Exception as e:
         self.remove_container(self.container)
         LOG.error(_LW("Cookbook deployment exception %s") % e)
         raise CookbookDeploymentException(cookbook=cookbook)
     return msg
예제 #9
0
 def run_install(self, cookbook):
     """Run download and install command
     :param cookbook: cookbook to process
     :return msg: operation result
     """
     try:
         cmd_install = CONF.clients_chef.cmd_install.format(
             cookbook_name=cookbook)
         resp_install = self.execute_command(cmd_install)
         msg = {
             'success': True,
             'response': resp_install
         }
         for line in resp_install.splitlines():
             if "ERROR" in line:
                 msg['success'] = False
         LOG.debug(_("Install result: %s") % resp_install)
     except Exception as e:
         LOG.error(_LW("Chef install exception: %s") % e)
         self.remove_container(self.container)
         raise CookbookInstallException(cookbook=cookbook)
     return msg
예제 #10
0
 def run_deploy(self, cookbook):
     """Run cookbook deployment
     :param cookbook: cookbook to deploy
     :return msg: dictionary with results and state
     """
     try:
         # inject custom solo.json file
         json_cont = CONF.clients_chef.cmd_config.format(cookbook)
         cmd_inject = CONF.clients_chef.cmd_inject.format(json_cont)
         self.execute_command(cmd_inject)
         # launch execution
         cmd_launch = CONF.clients_chef.cmd_launch
         resp_launch = self.execute_command(cmd_launch)
         msg = {
             'success': True,
             'response': resp_launch
         }
         if resp_launch is None or "FATAL" in resp_launch:
             msg['success'] = False
     except Exception as e:
         self.disconnect_session()
         LOG.error(_LW("Cookbook deployment exception %s") % e)
         raise CookbookDeploymentException(cookbook=cookbook)
     return msg