Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport 49981 #56751

Merged
merged 8 commits into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Versions are `MAJOR.PATCH`.
### Deprecated

### Changed
- [#56751](https://github.com/saltstack/salt/pull/56751) - Backport 49981

- [#56731](https://github.com/saltstack/salt/pull/56731) - Backport #53994
- [#56753](https://github.com/saltstack/salt/pull/56753) - Backport 51095
Expand Down
49 changes: 41 additions & 8 deletions salt/modules/win_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# Import Salt libs
import salt.utils.platform
import salt.utils.winapi
from salt.exceptions import ArgumentValueError, CommandExecutionError
from salt.ext.six.moves import range

# Import 3rd Party Libraries
Expand Down Expand Up @@ -624,6 +625,11 @@ def create_task_from_xml(

Returns:
bool: ``True`` if successful, otherwise ``False``
str: A string with the error message if there is an error

Raises:
ArgumentValueError: If arguments are invalid
CommandExecutionError

CLI Example:

Expand All @@ -637,7 +643,7 @@ def create_task_from_xml(
return "{0} already exists".format(name)

if not xml_text and not xml_path:
return "Must specify either xml_text or xml_path"
raise ArgumentValueError("Must specify either xml_text or xml_path")

# Create the task service object
with salt.utils.winapi.Com():
Expand Down Expand Up @@ -665,6 +671,7 @@ def create_task_from_xml(
logon_type = TASK_LOGON_INTERACTIVE_TOKEN
else:
password = None
logon_type = TASK_LOGON_NONE

# Save the task
try:
Expand All @@ -674,17 +681,43 @@ def create_task_from_xml(

except pythoncom.com_error as error:
hr, msg, exc, arg = error.args # pylint: disable=W0633
error_code = hex(exc[5] + 2 ** 32)
fc = {
-2147216615: "Required element or attribute missing",
-2147216616: "Value incorrectly formatted or out of range",
-2147352571: "Access denied",
0x80041319: "Required element or attribute missing",
0x80041318: "Value incorrectly formatted or out of range",
0x80020005: "Access denied",
0x80041309: "A task's trigger is not found",
0x8004130A: "One or more of the properties required to run this "
"task have not been set",
0x8004130C: "The Task Scheduler service is not installed on this "
"computer",
0x8004130D: "The task object could not be opened",
0x8004130E: "The object is either an invalid task object or is not "
"a task object",
0x8004130F: "No account information could be found in the Task "
"Scheduler security database for the task indicated",
0x80041310: "Unable to establish existence of the account specified",
0x80041311: "Corruption was detected in the Task Scheduler "
"security database; the database has been reset",
0x80041313: "The task object version is either unsupported or invalid",
0x80041314: "The task has been configured with an unsupported "
"combination of account settings and run time options",
0x80041315: "The Task Scheduler Service is not running",
0x80041316: "The task XML contains an unexpected node",
0x80041317: "The task XML contains an element or attribute from an "
"unexpected namespace",
0x8004131A: "The task XML is malformed",
0x0004131C: "The task is registered, but may fail to start. Batch "
"logon privilege needs to be enabled for the task principal",
0x8004131D: "The task XML contains too many nodes of the same type",
}
try:
failure_code = fc[exc[5]]
failure_code = fc[error_code]
except KeyError:
failure_code = "Unknown Failure: {0}".format(error)

log.debug("Failed to create task: %s", failure_code)
failure_code = "Unknown Failure: {0}".format(error_code)
finally:
log.debug("Failed to create task: %s", failure_code)
raise CommandExecutionError(failure_code)

# Verify creation
return name in list_tasks(location)
Expand Down
83 changes: 83 additions & 0 deletions tests/integration/modules/test_win_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals

import salt.modules.win_task as task
import salt.utils.platform
from salt.exceptions import CommandExecutionError
from tests.support.case import ModuleCase
from tests.support.helpers import destructiveTest
from tests.support.unit import skipIf


@skipIf(not salt.utils.platform.is_windows(), "windows test only")
class WinTasksTest(ModuleCase):
"""
Tests for salt.modules.win_task.
"""

@destructiveTest
def test_adding_task_with_xml(self):
"""
Test adding a task using xml
"""
xml_text = r"""
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2015-06-12T15:59:35.691983</Date>
<Author>System</Author>
</RegistrationInfo>
<Triggers>
<LogonTrigger>
<Enabled>true</Enabled>
<Delay>PT30S</Delay>
</LogonTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>System</UserId>
<LogonType>InteractiveToken</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>P3D</ExecutionTimeLimit>
<Priority>4</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>echo</Command>
<Arguments>"hello"</Arguments>
</Exec>
</Actions>
</Task>
"""
self.assertEquals(
self.run_function("task.create_task_from_xml", "foo", xml_text=xml_text),
True,
)
all_tasks = self.run_function("task.list_tasks")
self.assertIn("foo", all_tasks)

@destructiveTest
def test_adding_task_with_invalid_xml(self):
"""
Test adding a task using a malformed xml
"""
xml_text = r"""<Malformed"""
with self.assertRaises(CommandExecutionError):
task.create_task_from_xml("foo", xml_text=xml_text)
2 changes: 1 addition & 1 deletion tests/unit/modules/test_win_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
@skipIf(not salt.utils.platform.is_windows(), "System is not Windows")
class WinTaskTestCase(TestCase):
"""
Test cases for salt.modules.win_task
Test cases for salt.modules.win_task
"""

def test_repeat_interval(self):
Expand Down