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

Add support for chocolatey source priority. #61319

Merged
1 change: 1 addition & 0 deletions changelog/61319.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support the --priority flag when adding sources to Chocolatey.
11 changes: 10 additions & 1 deletion salt/modules/chocolatey.py
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,7 @@ def version(name, check_remote=False, source=None, pre_versions=False):
return packages


def add_source(name, source_location, username=None, password=None):
def add_source(name, source_location, username=None, password=None, priority=None):
"""
Instructs Chocolatey to add a source.

Expand All @@ -1144,11 +1144,18 @@ def add_source(name, source_location, username=None, password=None):
Provide password for chocolatey sources that need authentication
credentials.

priority
The priority order of this source as compared to other sources,
lower is better. Defaults to 0 (no priority). All priorities
above 0 will be evaluated first, then zero-based values will be
evaluated in config file order.

CLI Example:

.. code-block:: bash

salt '*' chocolatey.add_source <source name> <source_location>
salt '*' chocolatey.add_source <source name> <source_location> priority=100
salt '*' chocolatey.add_source <source name> <source_location> user=<user> password=<password>

"""
Expand All @@ -1165,6 +1172,8 @@ def add_source(name, source_location, username=None, password=None):
cmd.extend(["--user", username])
if password:
cmd.extend(["--password", password])
if priority:
cmd.extend(["--priority", priority])
result = __salt__["cmd.run_all"](cmd, python_shell=False)

if result["retcode"] != 0:
Expand Down
17 changes: 15 additions & 2 deletions salt/states/chocolatey.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,9 @@ def upgraded(
return ret


def source_present(name, source_location, username=None, password=None, force=False):
def source_present(
name, source_location, username=None, password=None, force=False, priority=None
):
"""
Instructs Chocolatey to add a source if not already present.

Expand All @@ -478,6 +480,12 @@ def source_present(name, source_location, username=None, password=None, force=Fa
Salt will not modify a existing repository with the same name. Set this
option to true to update an existing repository.

priority
The priority order of this source as compared to other sources,
lower is better. Defaults to 0 (no priority). All priorities
above 0 will be evaluated first, then zero-based values will be
evaluated in config file order.

CLI Example:

.. code-block:: yaml
Expand All @@ -488,6 +496,7 @@ def source_present(name, source_location, username=None, password=None, force=Fa
- source: https://repo.exemple.com
- username: myuser
- password: mypassword
- priority: 100
"""
ret = {"name": name, "result": True, "changes": {}, "comment": ""}

Expand Down Expand Up @@ -516,7 +525,11 @@ def source_present(name, source_location, username=None, password=None, force=Fa

# Add the source
result = __salt__["chocolatey.add_source"](
name=name, source_location=source_location, username=username, password=password
name=name,
source_location=source_location,
username=username,
password=password,
priority=priority,
)

if "Running chocolatey failed" not in result:
Expand Down
41 changes: 41 additions & 0 deletions tests/pytests/unit/modules/test_chocolatey.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,44 @@ def test_version_check_remote_true_not_available():
expected = {"ack": {"installed": ["3.1.1"]}}
result = chocolatey.version("ack", check_remote=True)
assert result == expected


def test_add_source(choco_path):
"""
Test add_source when remote is False
"""
cmd_run_all_mock = MagicMock(return_value={"retcode": 0, "stdout": "data"})
cmd_run_which_mock = MagicMock(return_value=choco_path)
with patch.dict(
chocolatey.__salt__,
{"cmd.which": cmd_run_which_mock, "cmd.run_all": cmd_run_all_mock},
):
expected_call = [
choco_path,
"sources",
"add",
"--name",
"source_name",
"--source",
"source_location",
]

result = chocolatey.add_source("source_name", "source_location")
cmd_run_all_mock.assert_called_with(expected_call, python_shell=False)

expected_call = [
choco_path,
"sources",
"add",
"--name",
"source_name",
"--source",
"source_location",
"--priority",
"priority",
]

result = chocolatey.add_source(
"source_name", "source_location", priority="priority"
)
cmd_run_all_mock.assert_called_with(expected_call, python_shell=False)
119 changes: 119 additions & 0 deletions tests/pytests/unit/states/test_chocolatey.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import logging

import pytest

import salt.config
import salt.modules.chocolatey as chocolatey_mod
import salt.states.chocolatey as chocolatey
from tests.support.mock import MagicMock, patch

log = logging.getLogger(__name__)


@pytest.fixture(scope="module")
def choco_path():
return "C:\\path\\to\\chocolatey.exe"


@pytest.fixture
def configure_loader_modules():
opts = salt.config.DEFAULT_MINION_OPTS.copy()
return {
chocolatey: {
"__opts__": opts,
"__salt__": {},
"__context__": {},
},
chocolatey_mod: {
"__opts__": opts,
"__context__": {},
},
}


@pytest.fixture(scope="module")
def pkgs():
return {
"pkga": {"old": "1.0.1", "new": "2.0.1"},
"pkgb": {"old": "1.0.2", "new": "2.0.2"},
"pkgc": {"old": "1.0.3", "new": "2.0.3"},
}


@pytest.fixture(scope="module")
def list_sources():
_ret = {
"chocolatey": {
"URL": "https://community.chocolatey.org/api/v2/",
"Disabled": False,
"User": "user",
},
"community": {
"URL": "https://community.chocolatey.org/api/v2/",
"Disabled": False,
"User": "user",
},
}
return _ret


def test_source_present(list_sources):
"""
Test chocolatey.source_present with simulated changes
"""

before_list_sources = {
"chocolatey": {
"URL": "https://community.chocolatey.org/api/v2/",
"Disabled": False,
"User": "user",
}
}

list_sources_sideeffect = MagicMock(side_effect=[before_list_sources, list_sources])

with patch.dict(
chocolatey.__salt__,
{
"chocolatey.list_sources": list_sources_sideeffect,
},
):

# Run state with test=true
stdout_ret = (
"Added community - https://community.chocolatey.org/api/v2/ (Priority 5)"
)
cmd_run_all_mock = MagicMock(return_value={"retcode": 0, "stdout": stdout_ret})
cmd_run_which_mock = MagicMock(return_value=choco_path)
with patch.dict(
chocolatey.__salt__,
{
"chocolatey.add_source": chocolatey_mod.add_source,
},
), patch.dict(
chocolatey_mod.__salt__,
{
"cmd.which": cmd_run_which_mock,
"cmd.run_all": cmd_run_all_mock,
},
):
ret = chocolatey.source_present(
"community",
source_location="https://community.chocolatey.org/api/v2/",
username="username",
password="password",
priority="5",
)
assert ret["result"] is True
assert ret["name"] == "community"
assert ret["comment"] == "Source community added successfully"
assert ret["changes"] == {
"community": {
"old": "",
"new": {
"URL": "https://community.chocolatey.org/api/v2/",
"Disabled": False,
"User": "user",
},
}
}