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

[master] Add websocket transport #64937

Merged
merged 29 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
874bd3e
Add websocket transport skeleton
dwoz Jul 26, 2023
2fad12f
Add ws transport to factories
dwoz Aug 8, 2023
a9d3988
Clean up tcp imports
dwoz Aug 8, 2023
dfb98cc
Fix up pre-commit (linter)
dwoz Aug 9, 2023
d540b99
Fix up basic ping between master and minion
dwoz Aug 9, 2023
e4565aa
Name conformity
dwoz Aug 9, 2023
af32aae
Fix up tcp ssl and add ssl to ws
dwoz Aug 12, 2023
1f0f10b
Better testing of ssl opts and ws transport
dwoz Aug 12, 2023
c77afd9
Fix tests
dwoz Aug 13, 2023
4e8ae80
Put channel tests under channel not transport
dwoz Aug 13, 2023
23488aa
Request server basic test for all transports
dwoz Aug 13, 2023
9393883
Wean of tcp transport bits in ws transport
dwoz Aug 14, 2023
c662eaa
Update transport docs with websockt transport
dwoz Aug 14, 2023
e3e8cb7
wip
dwoz Aug 18, 2023
4a4a834
Transport test fix
dwoz Nov 21, 2023
4c29ba6
Remove cruft
dwoz Nov 23, 2023
83887bc
Simplify payload unpacking.
dwoz Nov 23, 2023
de970ad
Revert change to zmq transport
dwoz Nov 24, 2023
db3fd71
Fix pre-commit warts from rebase
dwoz Dec 10, 2023
08eb89a
Bump workflow cache seed
dwoz Dec 10, 2023
0b3d527
Fix review comments
dwoz Dec 16, 2023
9e867c3
Fix up docs
dwoz Dec 19, 2023
c1cbf16
Debug windows unit tests
dwoz Dec 19, 2023
6870e49
Fix another spelling wart
dwoz Dec 19, 2023
8312d6d
check change
dwoz Dec 21, 2023
a2d0ebc
Mock blocking connect_pub method
dwoz Dec 22, 2023
183ef8b
Fix more schedule tests
dwoz Dec 22, 2023
03597b8
Mock PublishClient instead of TCPPubClient
dwoz Dec 23, 2023
edfd66a
Fix broken ssh tests
dwoz Dec 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:

env:
COLUMNS: 190
CACHE_SEED: SEED-2 # Bump the number to invalidate all caches
CACHE_SEED: SEED-4 # Bump the number to invalidate all caches
RELENV_DATA: "${{ github.workspace }}/.relenv"

permissions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ on:

env:
COLUMNS: 190
CACHE_SEED: SEED-2 # Bump the number to invalidate all caches
CACHE_SEED: SEED-4 # Bump the number to invalidate all caches
RELENV_DATA: "${{ github.workspace }}/.relenv"

permissions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ on:

env:
COLUMNS: 190
CACHE_SEED: SEED-2 # Bump the number to invalidate all caches
CACHE_SEED: SEED-4 # Bump the number to invalidate all caches
RELENV_DATA: "${{ github.workspace }}/.relenv"

permissions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scheduled.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:

env:
COLUMNS: 190
CACHE_SEED: SEED-2 # Bump the number to invalidate all caches
CACHE_SEED: SEED-4 # Bump the number to invalidate all caches
RELENV_DATA: "${{ github.workspace }}/.relenv"

permissions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ on:

env:
COLUMNS: 190
CACHE_SEED: SEED-2 # Bump the number to invalidate all caches
CACHE_SEED: SEED-4 # Bump the number to invalidate all caches
RELENV_DATA: "${{ github.workspace }}/.relenv"

permissions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/templates/layout.yml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ on:

env:
COLUMNS: 190
CACHE_SEED: SEED-2 # Bump the number to invalidate all caches
CACHE_SEED: SEED-4 # Bump the number to invalidate all caches
RELENV_DATA: "${{ github.workspace }}/.relenv"

<%- endblock env %>
Expand Down
3 changes: 2 additions & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,8 @@ allowed-3rd-party-modules=msgpack,
packaging,
looseversion,
pytestskipmarkers,
cryptography
cryptography,
aiohttp

[EXCEPTIONS]

Expand Down
2 changes: 2 additions & 0 deletions doc/topics/transports/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ The request client sends requests to a Request Server and receives a reply messa

zeromq
tcp
ws
ssl
73 changes: 73 additions & 0 deletions doc/topics/transports/ssl.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
Transport TLS Support
=====================

Whenever possible transports should provide TLS Support. Currently the :doc:`tcp` and
:doc:`ws` transports support encryption and verification using TLS.

.. versionadded:: 2016.11.1

The TCP transport allows for the master/minion communication to be optionally
wrapped in a TLS connection. Enabling this is simple, the master and minion need
to be using the tcp connection, then the ``ssl`` option is enabled. The ``ssl``
option is passed as a dict and roughly corresponds to the options passed to the
Python `ssl.wrap_socket <https://docs.python.org/3/library/ssl.html#ssl.wrap_socket>`_
function for backwards compatability.

.. versionadded:: 3007.0

The ``ssl`` option accepts ``verify_locations`` and ``verify_flags``. The
``verify_locations`` option is a list of strings or dictionaries. Strings are
passed as a single argument to the SSL context's ``load_verify_locations``
method. Dictionary keys are expected to be one of ``cafile``, ``capath``,
``cadata``. For each corresponding key, the key and value will be passed as a
keyword argument to ``load_verify_locations``. The ``verify_flags`` option is
a list of string names of verification flags which will be set on the SSL
context. All paths are assumed to be the full path to the file or directory.

A simple setup looks like this, on the Salt Master add the ``ssl`` option to the
master configuration file:

.. code-block:: yaml

ssl:
keyfile: <path_to_keyfile>
certfile: <path_to_certfile>

A more complex setup looks like this, on the Salt Master add the ``ssl``
option to the master's configuration file. In this example the Salt Master will
require valid client side certificates from Minions by setting ``cert_reqs`` to
``CERT_REQUIRED``. The Salt Master will also check a certificate revocation list
if one is provided in ``verify_locations``:

.. code-block:: yaml

ssl:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if the following paths have to be absolute or can be relative to something ?

keyfile: <path_to_keyfile>
certfile: <path_to_certfile>
cert_reqs: CERT_REQUIRED
verify_locations:
- <path_to_ca_cert>
- capath: <directory_of_certs>
- cafile: <path_to_crl>
verify_flags:
- VERIFY_CRL_CHECK_CHAIN


The minimal `ssl` option in the minion configuration file looks like this:

.. code-block:: yaml

ssl: True
# Versions below 2016.11.4:
ssl: {}

A Minion can be configured to present a client certificate to the master like this:

.. code-block:: yaml

ssl:
keyfile: <path_to_keyfile>
certfile: <path_to_certfile>

Specific options can be sent to the minion also, as defined in the Python
`ssl.wrap_socket` function.
52 changes: 9 additions & 43 deletions doc/topics/transports/tcp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ to ``tcp`` on each Salt minion and Salt master.
use the same transport. We're investigating a report of an error when using
mixed transport types at very heavy loads.


TLS Support
===========

The TLS transport supports full encryption and verification using both server
and client certificates. See :doc:`ssl` for more details.


Wire Protocol
=============
This implementation over TCP focuses on flexibility over absolute efficiency.
Expand All @@ -37,51 +45,9 @@ actual message that we are sending. With this flexible wire protocol we can
implement any message semantics that we'd like-- including multiplexed message
passing on a single socket.

TLS Support
===========

.. versionadded:: 2016.11.1

The TCP transport allows for the master/minion communication to be optionally
wrapped in a TLS connection. Enabling this is simple, the master and minion need
to be using the tcp connection, then the `ssl` option is enabled. The `ssl`
option is passed as a dict and corresponds to the options passed to the
Python `ssl.wrap_socket <https://docs.python.org/3/library/ssl.html#ssl.wrap_socket>`_
function.

A simple setup looks like this, on the Salt Master add the `ssl` option to the
master configuration file:

.. code-block:: yaml

ssl:
keyfile: <path_to_keyfile>
certfile: <path_to_certfile>
ssl_version: PROTOCOL_TLSv1_2
ciphers: ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384

The minimal `ssl` option in the minion configuration file looks like this:

.. code-block:: yaml

ssl: True
# Versions below 2016.11.4:
ssl: {}

Specific options can be sent to the minion also, as defined in the Python
`ssl.wrap_socket` function.

.. note::

While setting the ssl_version is not required, we recommend it. Some older
versions of python do not support the latest TLS protocol and if this is
the case for your version of python we strongly recommend upgrading your
version of Python. Ciphers specification might be omitted, but strongly
recommended as otherwise all available ciphers will be enabled.


Crypto
======

The current implementation uses the same crypto as the ``zeromq`` transport.


Expand Down
21 changes: 21 additions & 0 deletions doc/topics/transports/ws.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
===================
Websocket Transport
===================

The Websocket transport is an implementation of Salt's transport using the websocket protocol.
The Websocket transport is enabled by changing the :conf_minion:`transport` setting
to ``ws`` on each Salt minion and Salt master.

TLS Support
===========

The Websocket transport supports full encryption and verification using both server
and client certificates. See :doc:`ssl` for more details.

Publish Server and Client
=========================
The publish server and client are implemented using aiohttp.

Request Server and Client
=========================
The request server and client are implemented using aiohttp.
1 change: 1 addition & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ psutil>=5.0.0
packaging>=21.3
looseversion
tornado>=6.3.3
aiohttp>=3.9.0

# We need contextvars for salt-ssh.
# Even on python versions which ships with contextvars in the standard library!
Expand Down
28 changes: 20 additions & 8 deletions requirements/static/ci/py3.10/darwin.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@
#
# pip-compile --no-emit-index-url --output-file=requirements/static/ci/py3.10/darwin.txt requirements/darwin.txt requirements/pytest.txt requirements/static/ci/common.in requirements/static/ci/darwin.in requirements/static/pkg/darwin.in
#
aiohttp==3.9.0
# via etcd3-py
aiohttp==3.9.1
# via
# -c requirements/static/ci/../pkg/py3.10/darwin.txt
# -r requirements/base.txt
# etcd3-py
aiosignal==1.3.1
# via aiohttp
# via
# -c requirements/static/ci/../pkg/py3.10/darwin.txt
# aiohttp
apache-libcloud==3.7.0 ; sys_platform != "win32"
# via -r requirements/static/ci/common.in
asn1crypto==1.5.1
# via
# certvalidator
# oscrypto
async-timeout==4.0.2
# via aiohttp
async-timeout==4.0.3
# via
# -c requirements/static/ci/../pkg/py3.10/darwin.txt
# aiohttp
attrs==23.1.0
# via
# -c requirements/static/ci/../pkg/py3.10/darwin.txt
# aiohttp
# jsonschema
# pytest-salt-factories
Expand Down Expand Up @@ -119,8 +127,9 @@ filelock==3.13.1
# via virtualenv
flaky==3.7.0
# via -r requirements/pytest.txt
frozenlist==1.3.3
frozenlist==1.4.0
# via
# -c requirements/static/ci/../pkg/py3.10/darwin.txt
# aiohttp
# aiosignal
future==0.18.3
Expand Down Expand Up @@ -247,6 +256,7 @@ msgpack==1.0.7
# pytest-salt-factories
multidict==6.0.4
# via
# -c requirements/static/ci/../pkg/py3.10/darwin.txt
# aiohttp
# yarl
napalm==4.1.0 ; sys_platform != "win32"
Expand Down Expand Up @@ -546,8 +556,10 @@ yamllint==1.32.0
# via -r requirements/static/ci/darwin.in
yamlordereddictloader==0.4.0
# via junos-eznc
yarl==1.9.2
# via aiohttp
yarl==1.9.4
# via
# -c requirements/static/ci/../pkg/py3.10/darwin.txt
# aiohttp
zc.lockfile==3.0.post1
# via
# -c requirements/static/ci/../pkg/py3.10/darwin.txt
Expand Down
28 changes: 20 additions & 8 deletions requirements/static/ci/py3.10/freebsd.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@
#
# pip-compile --no-emit-index-url --output-file=requirements/static/ci/py3.10/freebsd.txt requirements/base.txt requirements/pytest.txt requirements/static/ci/common.in requirements/static/ci/freebsd.in requirements/static/pkg/freebsd.in requirements/zeromq.txt
#
aiohttp==3.9.0
# via etcd3-py
aiohttp==3.9.1
# via
# -c requirements/static/ci/../pkg/py3.10/freebsd.txt
# -r requirements/base.txt
# etcd3-py
aiosignal==1.3.1
# via aiohttp
# via
# -c requirements/static/ci/../pkg/py3.10/freebsd.txt
# aiohttp
apache-libcloud==3.7.0 ; sys_platform != "win32"
# via -r requirements/static/ci/common.in
asn1crypto==1.5.1
# via
# certvalidator
# oscrypto
async-timeout==4.0.2
# via aiohttp
async-timeout==4.0.3
# via
# -c requirements/static/ci/../pkg/py3.10/freebsd.txt
# aiohttp
attrs==23.1.0
# via
# -c requirements/static/ci/../pkg/py3.10/freebsd.txt
# aiohttp
# jsonschema
# pytest-salt-factories
Expand Down Expand Up @@ -118,8 +126,9 @@ filelock==3.13.1
# via virtualenv
flaky==3.7.0
# via -r requirements/pytest.txt
frozenlist==1.3.3
frozenlist==1.4.0
# via
# -c requirements/static/ci/../pkg/py3.10/freebsd.txt
# aiohttp
# aiosignal
future==0.18.3
Expand Down Expand Up @@ -250,6 +259,7 @@ msgpack==1.0.7
# pytest-salt-factories
multidict==6.0.4
# via
# -c requirements/static/ci/../pkg/py3.10/freebsd.txt
# aiohttp
# yarl
napalm==4.1.0 ; sys_platform != "win32"
Expand Down Expand Up @@ -551,8 +561,10 @@ yamllint==1.32.0
# via -r requirements/static/ci/freebsd.in
yamlordereddictloader==0.4.0
# via junos-eznc
yarl==1.9.2
# via aiohttp
yarl==1.9.4
# via
# -c requirements/static/ci/../pkg/py3.10/freebsd.txt
# aiohttp
zc.lockfile==3.0.post1
# via
# -c requirements/static/ci/../pkg/py3.10/freebsd.txt
Expand Down