Beispiel #1
0
    def test_exception_restore_temp_action_files(self):
        CLONE_ACTION_8 = clone_action_db(
            SOURCE_ACTION_WITH_SHELL_SCRIPT_RUNNER, TEST_DEST_PACK,
            "clone_action_8")
        clone_action_files(SOURCE_ACTION_WITH_SHELL_SCRIPT_RUNNER,
                           CLONE_ACTION_8, TEST_DEST_PACK_PATH)
        dest_action_metadata_file = CLONE_ACTION_8["metadata_file"]
        dest_action_entry_point_file = CLONE_ACTION_8["entry_point"]
        dest_action_files_path = os.path.join(TEST_DEST_PACK_PATH, "actions")
        for file in os.listdir(dest_action_files_path):
            if os.path.isfile(os.path.join(dest_action_files_path, file)):
                os.remove(os.path.join(dest_action_files_path, file))
        temp_sub_dir = str(uuid.uuid4())
        dest_action_metadata_file_path = os.path.join(
            TEST_DEST_PACK_PATH, dest_action_metadata_file)
        expected_msg = (
            'Unable to copy file to "%s". Please check the logs or ask your '
            "administrator to clone the files manually." %
            dest_action_metadata_file_path)
        with mock.patch("shutil.copy") as mock_copy:
            mock_copy.side_effect = Exception
            with self.assertRaisesRegexp(Exception, expected_msg):
                restore_temp_action_files(
                    TEST_DEST_PACK_PATH,
                    dest_action_metadata_file,
                    dest_action_entry_point_file,
                    temp_sub_dir,
                )

        remove_temp_action_files(temp_sub_dir)
Beispiel #2
0
    def test_permission_error_restore_temp_action_files(self):
        CLONE_ACTION_9 = clone_action_db(
            SOURCE_ACTION_WITH_SHELL_SCRIPT_RUNNER, TEST_DEST_PACK,
            "clone_action_9")
        clone_action_files(SOURCE_ACTION_WITH_SHELL_SCRIPT_RUNNER,
                           CLONE_ACTION_9, TEST_DEST_PACK_PATH)
        dest_action_metadata_file = CLONE_ACTION_9["metadata_file"]
        dest_action_entry_point_file = CLONE_ACTION_9["entry_point"]
        dest_action_files_path = os.path.join(TEST_DEST_PACK_PATH, "actions")
        for file in os.listdir(dest_action_files_path):
            if os.path.isfile(os.path.join(dest_action_files_path, file)):
                os.remove(os.path.join(dest_action_files_path, file))
        temp_sub_dir = str(uuid.uuid4())
        dest_action_metadata_file_path = os.path.join(
            TEST_DEST_PACK_PATH, dest_action_metadata_file)
        expected_msg = 'Unable to copy file to "%s".' % dest_action_metadata_file_path
        with mock.patch("shutil.copy") as mock_copy:
            mock_copy.side_effect = PermissionError
            with self.assertRaisesRegexp(PermissionError, expected_msg):
                restore_temp_action_files(
                    TEST_DEST_PACK_PATH,
                    dest_action_metadata_file,
                    dest_action_entry_point_file,
                    temp_sub_dir,
                )

        remove_temp_action_files(temp_sub_dir)
Beispiel #3
0
    def test_exception_temp_backup_action_files(self):
        CLONE_ACTION_6 = clone_action_db(
            SOURCE_ACTION_WITH_SHELL_SCRIPT_RUNNER, TEST_DEST_PACK,
            "clone_action_6")
        clone_action_files(SOURCE_ACTION_WITH_SHELL_SCRIPT_RUNNER,
                           CLONE_ACTION_6, TEST_DEST_PACK_PATH)
        dest_action_metadata_file = CLONE_ACTION_6["metadata_file"]
        dest_action_entry_point_file = CLONE_ACTION_6["entry_point"]
        temp_sub_dir = str(uuid.uuid4())
        temp_dir_path = "/tmp/%s" % temp_sub_dir
        tmp_action_metadata_file_path = os.path.join(
            temp_dir_path, dest_action_metadata_file)
        expected_msg = (
            'Unable to copy file to "%s". Please check the logs or ask your '
            "administrator to clone the files manually." %
            tmp_action_metadata_file_path)
        with mock.patch("shutil.copy") as mock_copy:
            mock_copy.side_effect = Exception
            with self.assertRaisesRegexp(Exception, expected_msg):
                temp_backup_action_files(
                    TEST_DEST_PACK_PATH,
                    dest_action_metadata_file,
                    dest_action_entry_point_file,
                    temp_sub_dir,
                )

        remove_temp_action_files(temp_sub_dir)
Beispiel #4
0
    def test_exception_remove_temp_action_files(self):
        CLONE_ACTION_4 = clone_action_db(
            SOURCE_ACTION_WITH_PYTHON_SCRIPT_RUNNER, TEST_DEST_PACK,
            "clone_action_4")
        clone_action_files(SOURCE_ACTION_WITH_PYTHON_SCRIPT_RUNNER,
                           CLONE_ACTION_4, TEST_DEST_PACK_PATH)
        dest_action_metadata_file = CLONE_ACTION_4["metadata_file"]
        dest_action_entry_point_file = CLONE_ACTION_4["entry_point"]
        temp_sub_dir = str(uuid.uuid4())
        temp_backup_action_files(
            TEST_DEST_PACK_PATH,
            dest_action_metadata_file,
            dest_action_entry_point_file,
            temp_sub_dir,
        )
        temp_dir_path = "/tmp/%s" % temp_sub_dir
        self.assertTrue(os.path.isdir(temp_dir_path))
        expected_msg = (
            'The temporary directory "%s" could not be removed from disk, please check the logs '
            "or ask your StackStorm administrator to check and delete the temporary directory "
            "manually" % temp_dir_path)
        with mock.patch("shutil.rmtree") as mock_rmdir:
            mock_rmdir.side_effect = Exception
            with self.assertRaisesRegexp(Exception, expected_msg):
                remove_temp_action_files(temp_sub_dir)

        remove_temp_action_files(temp_sub_dir)
Beispiel #5
0
 def _restore_action(self, action_db, pack_base_path, temp_sub_dir):
     restore_temp_action_files(
         pack_base_path,
         action_db["metadata_file"],
         action_db["entry_point"],
         temp_sub_dir,
     )
     action_db.id = None
     Action.add_or_update(action_db)
     remove_temp_action_files(temp_sub_dir)
Beispiel #6
0
    def test_permission_error_temp_backup_action_files(self):
        CLONE_ACTION_7 = clone_action_db(
            SOURCE_ACTION_WITH_SHELL_SCRIPT_RUNNER, TEST_DEST_PACK,
            "clone_action_7")
        clone_action_files(SOURCE_ACTION_WITH_SHELL_SCRIPT_RUNNER,
                           CLONE_ACTION_7, TEST_DEST_PACK_PATH)
        dest_action_metadata_file = CLONE_ACTION_7["metadata_file"]
        dest_action_entry_point_file = CLONE_ACTION_7["entry_point"]
        temp_sub_dir = str(uuid.uuid4())
        temp_dir_path = "/tmp/%s" % temp_sub_dir
        tmp_action_metadata_file_path = os.path.join(
            temp_dir_path, dest_action_metadata_file)
        expected_msg = 'Unable to copy file to "%s".' % tmp_action_metadata_file_path
        with mock.patch("shutil.copy") as mock_copy:
            mock_copy.side_effect = PermissionError
            with self.assertRaisesRegexp(PermissionError, expected_msg):
                temp_backup_action_files(
                    TEST_DEST_PACK_PATH,
                    dest_action_metadata_file,
                    dest_action_entry_point_file,
                    temp_sub_dir,
                )

        remove_temp_action_files(temp_sub_dir)
Beispiel #7
0
    def test_permission_error_remove_temp_action_files(self):
        CLONE_ACTION_5 = clone_action_db(
            SOURCE_ACTION_WITH_PYTHON_SCRIPT_RUNNER, TEST_DEST_PACK,
            "clone_action_5")
        clone_action_files(SOURCE_ACTION_WITH_PYTHON_SCRIPT_RUNNER,
                           CLONE_ACTION_5, TEST_DEST_PACK_PATH)
        dest_action_metadata_file = CLONE_ACTION_5["metadata_file"]
        dest_action_entry_point_file = CLONE_ACTION_5["entry_point"]
        temp_sub_dir = str(uuid.uuid4())
        temp_backup_action_files(
            TEST_DEST_PACK_PATH,
            dest_action_metadata_file,
            dest_action_entry_point_file,
            temp_sub_dir,
        )
        temp_dir_path = "/tmp/%s" % temp_sub_dir
        self.assertTrue(os.path.isdir(temp_dir_path))
        expected_msg = 'No permission to delete the "%s" directory' % temp_dir_path
        with mock.patch("shutil.rmtree") as mock_rmdir:
            mock_rmdir.side_effect = PermissionError
            with self.assertRaisesRegexp(PermissionError, expected_msg):
                remove_temp_action_files(temp_sub_dir)

        remove_temp_action_files(temp_sub_dir)
Beispiel #8
0
    def clone(self, dest_data, ref_or_id, requester_user):
        """
        Clone an action from source pack to destination pack.
        Handles requests:
            POST /actions/{ref_or_id}/clone
        """

        source_action_db = self._get_by_ref_or_id(ref_or_id=ref_or_id)
        if not source_action_db:
            msg = "The requested source for cloning operation doesn't exists"
            abort(http_client.BAD_REQUEST, six.text_type(msg))

        extra = {"action_db": source_action_db}
        LOG.audit("Source action found. Action.id=%s" % (source_action_db.id),
                  extra=extra)

        try:
            permission_type = PermissionType.ACTION_VIEW
            rbac_utils = get_rbac_backend().get_utils_class()
            rbac_utils.assert_user_has_resource_db_permission(
                user_db=requester_user,
                resource_db=source_action_db,
                permission_type=permission_type,
            )
        except ResourceAccessDeniedError as e:
            abort(http_client.UNAUTHORIZED, six.text_type(e))

        cloned_dest_action_db = clone_action_db(
            source_action_db=source_action_db,
            dest_pack=dest_data.dest_pack,
            dest_action=dest_data.dest_action,
        )

        cloned_action_api = ActionAPI.from_model(cloned_dest_action_db)

        try:
            permission_type = PermissionType.ACTION_CREATE
            rbac_utils.assert_user_has_resource_api_permission(
                user_db=requester_user,
                resource_api=cloned_action_api,
                permission_type=permission_type,
            )
        except ResourceAccessDeniedError as e:
            abort(http_client.UNAUTHORIZED, six.text_type(e))

        dest_pack_base_path = get_pack_base_path(pack_name=dest_data.dest_pack)

        if not os.path.isdir(dest_pack_base_path):
            msg = "Destination pack '%s' doesn't exist" % (dest_data.dest_pack)
            abort(http_client.BAD_REQUEST, six.text_type(msg))

        dest_pack_base_path = get_pack_base_path(pack_name=dest_data.dest_pack)
        dest_ref = ".".join([dest_data.dest_pack, dest_data.dest_action])
        dest_action_db = self._get_by_ref(resource_ref=dest_ref)

        try:
            validate_not_part_of_system_pack_by_name(dest_data.dest_pack)
        except ValueValidationException as e:
            abort(http_client.BAD_REQUEST, six.text_type(e))

        if dest_action_db:
            if not dest_data.overwrite:
                msg = "The requested destination action already exists"
                abort(http_client.BAD_REQUEST, six.text_type(msg))

            try:
                permission_type = PermissionType.ACTION_DELETE
                rbac_utils.assert_user_has_resource_db_permission(
                    user_db=requester_user,
                    resource_db=dest_action_db,
                    permission_type=permission_type,
                )
                options = GenericRequestParam(remove_files=True)
                dest_metadata_file = dest_action_db["metadata_file"]
                dest_entry_point = dest_action_db["entry_point"]
                temp_sub_dir = str(uuid.uuid4())
                temp_backup_action_files(
                    dest_pack_base_path,
                    dest_metadata_file,
                    dest_entry_point,
                    temp_sub_dir,
                )
                self.delete(options, dest_ref, requester_user)
            except ResourceAccessDeniedError as e:
                abort(http_client.UNAUTHORIZED, six.text_type(e))
            except Exception as e:
                LOG.debug(
                    "Exception encountered during deleting existing destination action. "
                    "Exception was: %s",
                    e,
                )
                abort(http_client.INTERNAL_SERVER_ERROR, six.text_type(e))

        try:
            post_response = self.post(cloned_action_api, requester_user)
            if post_response.status_code != http_client.CREATED:
                raise Exception("Could not add cloned action to database.")
            cloned_dest_action_db["id"] = post_response.json["id"]
            clone_action_files(
                source_action_db=source_action_db,
                dest_action_db=cloned_dest_action_db,
                dest_pack_base_path=dest_pack_base_path,
            )
            extra = {"cloned_acion_db": cloned_dest_action_db}
            LOG.audit("Action cloned. Action.id=%s" %
                      (cloned_dest_action_db.id),
                      extra=extra)
            if dest_action_db:
                remove_temp_action_files(temp_sub_dir)
            return post_response
        except PermissionError as e:
            LOG.error("No permission to clone the action. Exception was %s", e)
            delete_action_files_from_pack(
                pack_name=cloned_dest_action_db["pack"],
                entry_point=cloned_dest_action_db["entry_point"],
                metadata_file=cloned_dest_action_db["metadata_file"],
            )
            if post_response.status_code == http_client.CREATED:
                Action.delete(cloned_dest_action_db)
            if dest_action_db:
                self._restore_action(dest_action_db, dest_pack_base_path,
                                     temp_sub_dir)
            abort(http_client.FORBIDDEN, six.text_type(e))
        except Exception as e:
            LOG.error(
                "Exception encountered during cloning action. Exception was %s",
                e,
            )
            delete_action_files_from_pack(
                pack_name=cloned_dest_action_db["pack"],
                entry_point=cloned_dest_action_db["entry_point"],
                metadata_file=cloned_dest_action_db["metadata_file"],
            )
            if post_response.status_code == http_client.CREATED:
                Action.delete(cloned_dest_action_db)
            if dest_action_db:
                self._restore_action(dest_action_db, dest_pack_base_path,
                                     temp_sub_dir)

            abort(http_client.INTERNAL_SERVER_ERROR, six.text_type(e))
Beispiel #9
0
    def test_temp_backup_restore_remove_action_files(self):
        CLONE_ACTION_1 = clone_action_db(
            SOURCE_ACTION_WITH_PYTHON_SCRIPT_RUNNER, TEST_DEST_PACK,
            "clone_action_1")
        clone_action_files(SOURCE_ACTION_WITH_PYTHON_SCRIPT_RUNNER,
                           CLONE_ACTION_1, TEST_DEST_PACK_PATH)
        dest_action_metadata_file = CLONE_ACTION_1["metadata_file"]
        dest_action_entry_point_file = CLONE_ACTION_1["entry_point"]
        temp_sub_dir = str(uuid.uuid4())

        # creating backup of dest action files at /tmp/<uuid>
        temp_backup_action_files(
            TEST_DEST_PACK_PATH,
            dest_action_metadata_file,
            dest_action_entry_point_file,
            temp_sub_dir,
        )
        temp_dir_path = "/tmp/%s" % temp_sub_dir
        self.assertTrue(os.path.isdir(temp_dir_path))
        temp_metadata_file_path = os.path.join(temp_dir_path,
                                               dest_action_metadata_file)
        temp_entry_point_file_path = os.path.join(
            temp_dir_path, "actions", dest_action_entry_point_file)
        # asserting backup files exists
        self.assertTrue(os.path.exists(temp_metadata_file_path))
        self.assertTrue(os.path.exists(temp_entry_point_file_path))

        # removing destination action files
        dest_action_files_path = os.path.join(TEST_DEST_PACK_PATH, "actions")
        for file in os.listdir(dest_action_files_path):
            if os.path.isfile(os.path.join(dest_action_files_path, file)):
                os.remove(os.path.join(dest_action_files_path, file))
        dest_action_metadata_file_path = os.path.join(
            TEST_DEST_PACK_PATH, dest_action_metadata_file)
        dest_action_entry_point_file_path = os.path.join(
            TEST_DEST_PACK_PATH, "actions", dest_action_entry_point_file)
        # asserting destination action files doesn't exist
        self.assertFalse(os.path.isfile(dest_action_metadata_file_path))
        self.assertFalse(os.path.isfile(dest_action_entry_point_file_path))

        # restoring temp backed action files to destination
        restore_temp_action_files(
            TEST_DEST_PACK_PATH,
            dest_action_metadata_file,
            dest_action_entry_point_file,
            temp_sub_dir,
        )
        # asserting action files restored at destination
        self.assertTrue(os.path.isfile(dest_action_metadata_file_path))
        self.assertTrue(os.path.isfile(dest_action_entry_point_file_path))
        # asserting temp_dir and backed action files exits
        self.assertTrue(os.path.isdir(temp_dir_path))
        self.assertTrue(os.path.exists(temp_metadata_file_path))
        self.assertTrue(os.path.exists(temp_entry_point_file_path))

        # removing temp_dir and backed action files
        remove_temp_action_files(temp_sub_dir)
        # asserting temp_dir and backed action files doesn't exit
        self.assertFalse(os.path.isdir(temp_dir_path))
        self.assertFalse(os.path.exists(temp_metadata_file_path))
        self.assertFalse(os.path.exists(temp_entry_point_file_path))