Skip to content
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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ jobs:
with:
cache-seed: ${{ needs.prepare-workflow.outputs.cache-seed }}
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.19.0"
relenv-version: "0.19.2"
python-version: "3.10.17"
matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }}
linux_arm_runner: ${{ fromJSON(needs.prepare-workflow.outputs.config)['linux_arm_runner'] }}
Expand All @@ -448,7 +448,7 @@ jobs:
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}
relenv-version: "0.19.0"
relenv-version: "0.19.2"
python-version: "3.10.17"
source: "onedir"
matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ jobs:
with:
cache-seed: ${{ needs.prepare-workflow.outputs.cache-seed }}
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.19.0"
relenv-version: "0.19.2"
python-version: "3.10.17"
matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }}
linux_arm_runner: ${{ fromJSON(needs.prepare-workflow.outputs.config)['linux_arm_runner'] }}
Expand All @@ -501,7 +501,7 @@ jobs:
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}
relenv-version: "0.19.0"
relenv-version: "0.19.2"
python-version: "3.10.17"
source: "onedir"
matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }}
Expand All @@ -521,7 +521,7 @@ jobs:
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}
relenv-version: "0.19.0"
relenv-version: "0.19.2"
python-version: "3.10.17"
source: "src"
matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/scheduled.yml
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ jobs:
with:
cache-seed: ${{ needs.prepare-workflow.outputs.cache-seed }}
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.19.0"
relenv-version: "0.19.2"
python-version: "3.10.17"
matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }}
linux_arm_runner: ${{ fromJSON(needs.prepare-workflow.outputs.config)['linux_arm_runner'] }}
Expand All @@ -491,7 +491,7 @@ jobs:
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}
relenv-version: "0.19.0"
relenv-version: "0.19.2"
python-version: "3.10.17"
source: "onedir"
matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ jobs:
with:
cache-seed: ${{ needs.prepare-workflow.outputs.cache-seed }}
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.19.0"
relenv-version: "0.19.2"
python-version: "3.10.17"
matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }}
linux_arm_runner: ${{ fromJSON(needs.prepare-workflow.outputs.config)['linux_arm_runner'] }}
Expand All @@ -489,7 +489,7 @@ jobs:
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}
relenv-version: "0.19.0"
relenv-version: "0.19.2"
python-version: "3.10.17"
source: "onedir"
matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }}
Expand All @@ -510,7 +510,7 @@ jobs:
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}
relenv-version: "0.19.0"
relenv-version: "0.19.2"
python-version: "3.10.17"
source: "src"
matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }}
Expand Down
1 change: 1 addition & 0 deletions changelog/66627.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added the ability to configure the cluster event port and added documentation for it
2 changes: 1 addition & 1 deletion cicd/shared-gh-workflows-context.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
nox_version: "2022.8.7"
python_version: "3.10.17"
relenv_version: "0.19.0"
relenv_version: "0.19.2"
release_branches:
- "3006.x"
- "3007.x"
Expand Down
26 changes: 26 additions & 0 deletions conf/master
Original file line number Diff line number Diff line change
Expand Up @@ -1357,3 +1357,29 @@

# Set a list of clients to enable in in the API
#netapi_enable_clients: []


##### Master Cluster Settings #####
#####################################################
# Settings for configuring salt master to work in a cluster configuration behind
# a load balancer.

# When defined, the master will operate in cluster mode. The master will send
# the cluster key and id to minions instead of its own key and id. The master
# will also forward its local event bus to other masters defined by
# ``cluster_peers``
#cluster_id: master_cluster

# Defines the other masters in the cluster. Can be IP addresses or hostnames
#cluster_peers:
# - master 2
# - master 3

# When ``cluster_pki_dir`` is defined, this sets the location of where this
# cluster will store its cluster public and private key as well as any minion
# keys. This setting will default to the value of ``pki_dir``, but should be
# changed to the filesystem location shared between peers in the cluster.
#cluster_pki_dir: /my/gluster/share/pki

# The port required to be open for a master cluster to properly function
#cluster_pool_port: 4520
31 changes: 22 additions & 9 deletions doc/ref/configuration/master.rst
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,9 @@ When defined, the master will operate in cluster mode. The master will send the
cluster key and id to minions instead of its own key and id. The master will
also forward its local event bus to other masters defined by ``cluster_peers``


.. code-block:: yaml

cluster_id: master
cluster_id: master_cluster

.. conf_master:: cluster_peers

Expand All @@ -230,8 +229,8 @@ also forward its local event bus to other masters defined by ``cluster_peers``

.. versionadded:: 3007

When ``cluster_id`` is defined, this setting is a list of other master
(hostnames or ips) that will be in the cluster.
When ``cluster_peers`` is defined, this setting is a list of other master
(hostnames or IPs) that will be in the cluster.

.. code-block:: yaml

Expand All @@ -246,15 +245,29 @@ When ``cluster_id`` is defined, this setting is a list of other master

.. versionadded:: 3007

When ``cluster_id`` is defined, this sets the location of where this cluster
will store its cluster public and private key as well as any minion keys. This
setting will default to the value of ``pki_dir``, but should be changed
to the filesystem location shared between peers in the cluster.
When ``cluster_pki_dir`` is defined, this sets the location of where this
cluster will store its cluster public and private key as well as any minion
keys. This setting will default to the value of ``pki_dir``, but should be
changed to the filesystem location shared between peers in the cluster.

.. code-block:: yaml

cluster_pki: /my/gluster/share/pki
cluster_pki_dir: /my/gluster/share/pki


.. conf_master:: cluster_port

``cluster_pool_port``
---------------------

.. versionadded:: 3007.2

When ``cluster_pool_port`` is defined, it sets the TCP port number HAProxy
listens on for incoming TCP connections. The default is ``4520``

.. code-block:: yaml

cluster_pool_port: 4520

.. conf_master:: extension_modules

Expand Down
2 changes: 1 addition & 1 deletion doc/topics/tutorials/master-cluster.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ when operating as a cluster, minion keys are stored in the `cluster_pki_dir`
instead of the master's `pki_dir`.


Reference Implimentation
Reference Implementation
========================

Gluster: https://docs.gluster.org/en/main/Quick-Start-Guide/Quickstart/
Expand Down
1 change: 0 additions & 1 deletion requirements/constraints.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
wheel
setuptools < 80.0.0
setuptools-scm < 8.0.0
pip >= 23.3,< 24.0 ; python_version < '3.12'
pip >24 ; python_version >= '3.12'
2 changes: 1 addition & 1 deletion salt/channel/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,7 @@ def _publish_daemon(self, **kwargs):
)
os.nice(self.opts["event_publisher_niceness"])
self.io_loop = tornado.ioloop.IOLoop.current()
tcp_master_pool_port = 4520
tcp_master_pool_port = self.opts["cluster_pool_port"]
self.pushers = []
self.auth_errors = {}
for peer in self.opts.get("cluster_peers", []):
Expand Down
7 changes: 5 additions & 2 deletions salt/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ def _gather_buffer_space():
# to define where minion keys and the cluster private key will be
# stored.
"cluster_pki_dir": str,
# The port required to be open for a master cluster to properly function
"cluster_pool_port": int,
# Use a module function to determine the unique identifier. If this is
# set and 'id' is not set, it will allow invocation of a module function
# to determine the value of 'id'. For simple invocations without function
Expand Down Expand Up @@ -1668,6 +1670,7 @@ def _gather_buffer_space():
"cluster_id": None,
"cluster_peers": [],
"cluster_pki_dir": None,
"cluster_pool_port": 4520,
"features": {},
"publish_signing_algorithm": "PKCS1v15-SHA1",
}
Expand Down Expand Up @@ -4103,7 +4106,7 @@ def apply_master_config(overrides=None, defaults=None):

prepend_root_dir(opts, prepend_root_dirs)

# When a cluster id is defined, make sure the other nessicery bits a
# When a cluster id is defined, make sure the other necessary bits are
# defined.
if "cluster_id" not in opts:
opts["cluster_id"] = None
Expand All @@ -4121,7 +4124,7 @@ def apply_master_config(overrides=None, defaults=None):
log.warning("Cluster peers defined without a cluster_id, ignoring.")
opts["cluster_peers"] = []
if opts.get("cluster_pki_dir", None):
log.warning("Cluster pki defined without a cluster_id, ignoring.")
log.warning("Cluster pki dir defined without a cluster_id, ignoring.")
opts["cluster_pki_dir"] = None

# Enabling open mode requires that the value be set to True, and
Expand Down
2 changes: 1 addition & 1 deletion salt/master.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ def handle_key_rotate(self, now, drop_file_wait=5):
self.opts["cachedir"], self.opts["user"], self.opts["id"]
)
# There is currently no concept of a leader in a master
# cluster. Lets fake it till we make it with a little
# cluster. Let's fake it till we make it with a little
# waiting period.
time.sleep(drop_file_wait)
to_rotate = (
Expand Down
1 change: 0 additions & 1 deletion tests/pytests/integration/cli/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@


@pytest.fixture(scope="package")
@pytest.mark.core_test
def salt_eauth_account(salt_eauth_account_factory):
with salt_eauth_account_factory as account:
yield account
29 changes: 14 additions & 15 deletions tests/pytests/integration/pillar/test_fileclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ def test_pillar_using_cp_module(salt_master, salt_minion, salt_cli, tmp_path):
"*":
- my_pillar
"""
my_pillar = """
{{% set file_content = salt.cp.get_file_str("{}") %}}
""".format(
str(tmp_path / "myfile.txt")
)
my_file = """
foobar
my_file = tmp_path / "my_file.txt"
my_file.write_text("foobar")
my_pillar = f"""
{{%- set something = salt['cp.get_file_str']("{str(my_file)}") %}}
file_content: {{{{ something }}}}
"""
(tmp_path / "myfile.txt").write_text(my_file)
with salt_master.pillar_tree.base.temp_file("top.sls", pillar_top):
with salt_master.pillar_tree.base.temp_file("my_pillar.sls", my_pillar):
with salt_master.pillar_tree.base.temp_file("my_pillar.sls", my_pillar):
ret = salt_cli.run("state.apply", minion_tgt=salt_minion.id)
assert ret.returncode == 1
assert (
ret.json["no_|-states_|-states_|-None"]["comment"]
== "No states found for this minion"
)

ret = salt_cli.run("saltutil.pillar_refresh", minion_tgt=salt_minion.id)
assert ret.returncode == 0

pillar_ret = salt_cli.run(
"pillar.item", "file_content", minion_tgt=salt_minion.id
)
assert pillar_ret.returncode == 0
assert '"file_content": "foobar"' in pillar_ret.stdout
24 changes: 9 additions & 15 deletions tests/pytests/integration/pillar/test_httpclient_in_pillar.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def test_pillar_using_http_query(salt_master, salt_minion, salt_cli, tmp_path):
def test_pillar_using_http_query(salt_master, salt_minion, salt_cli):
pillar_top = """
base:
"*":
Expand All @@ -11,19 +11,13 @@ def test_pillar_using_http_query(salt_master, salt_minion, salt_cli, tmp_path):

with salt_master.pillar_tree.base.temp_file("top.sls", pillar_top):
with salt_master.pillar_tree.base.temp_file("http_pillar_test.sls", my_pillar):
with salt_master.pillar_tree.base.temp_file(
"http_pillar_test.sls", my_pillar
):
ret = salt_cli.run("state.apply", minion_tgt=salt_minion.id)
assert ret.returncode == 1
assert (
ret.data["no_|-states_|-states_|-None"]["comment"]
== "No states found for this minion"
)

pillar_ret = salt_cli.run(
"pillar.item", "http_query_test", minion_tgt=salt_minion.id
)
assert pillar_ret.returncode == 0
# We may need this for the following pillar.item to work
ret = salt_cli.run("saltutil.pillar_refresh", minion_tgt=salt_minion.id)
assert ret.returncode == 0

assert '"http_query_test": 200' in pillar_ret.stdout
pillar_ret = salt_cli.run(
"pillar.item", "http_query_test", minion_tgt=salt_minion.id
)
assert pillar_ret.returncode == 0
assert '"http_query_test": 200' in pillar_ret.stdout
11 changes: 11 additions & 0 deletions tests/pytests/unit/config/test_master_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ def test_apply_no_cluster_id():
assert opts["cluster_id"] is None
assert "cluster_pki_dir" in opts
assert opts["cluster_pki_dir"] is None
assert "cluster_pool_port" in opts
assert opts["cluster_pool_port"] == 4520


def test_apply_default_for_cluster():
Expand All @@ -33,6 +35,10 @@ def test_apply_default_for_cluster():
assert "cluster_peers" in opts
assert [] == opts["cluster_peers"]

# the cluster pool port defaults to 4520
assert "cluster_pool_port" in opts
assert opts["cluster_pool_port"] == 4520


def test_apply_for_cluster():
defaults = salt.config.DEFAULT_MASTER_OPTS.copy()
Expand All @@ -46,6 +52,7 @@ def test_apply_for_cluster():
"127.0.0.3",
],
"cluster_pki_dir": cluster_dir,
"cluster_pool_port": 5500,
}

opts = salt.config.apply_master_config(overrides, defaults)
Expand All @@ -56,6 +63,10 @@ def test_apply_for_cluster():
assert "cluster_pki_dir" in opts
assert cluster_dir == opts["cluster_pki_dir"]

# the cluster pool port defaults to 4520
assert "cluster_pool_port" in opts
assert opts["cluster_pool_port"] == 5500

# the cluster peers defaults to empty list
assert "cluster_peers" in opts
assert isinstance(opts["cluster_peers"], list)
Expand Down