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

Migrate to PEP 517 compliant build #379

Merged
merged 3 commits into from
Jun 5, 2024
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
95 changes: 21 additions & 74 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ on:
branches:
- master

# env:
# WINRM_USERNAME: pywinrm-test
# WINRM_PASSWORD: Password123!

jobs:
test:
runs-on: ${{ matrix.os }}
Expand All @@ -23,14 +19,13 @@ jobs:
- ubuntu-latest
- windows-latest
python-version:
- 2.7
- 3.6
- 3.7
- 3.8
- 3.9
- '3.10'
- pypy-2.7
- pypy-3.7
- '3.11'
- '3.12'
- pypy-3.9
- pypy-3.10
arch:
- x86
- x64
Expand All @@ -39,59 +34,37 @@ jobs:
- os: macos-latest
arch: x86
- os: macos-latest
python-version: pypy-2.7
python-version: 3.8
- os: macos-latest
python-version: 3.9
- os: macos-latest
python-version: '3.10'
- os: macos-latest
python-version: pypy-3.7
python-version: pypy-3.9
- os: macos-latest
python-version: pypy-3.10
- os: ubuntu-latest
arch: x86
- os: windows-latest
python-version: pypy-2.7
python-version: pypy-3.9
- os: windows-latest
python-version: pypy-3.7
python-version: pypy-3.10

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: set up python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.arch }}

# - name: Remove extra modules to speed up PowerShell startup module due to slow WinRM issue
# if: startsWith(matrix.os, 'windows')
# shell: bash
# run: |
# rm -rf "/c/Program Files/WindowsPowerShell/Modules/AWSPowerShell"
# rm -rf "/c/Program Files/WindowsPowerShell/Modules/Microsoft.Graph*"

# - name: set up Windows integration tests
# if: startsWith(matrix.os, 'windows')
# shell: pwsh
# run: |
# Write-Host 'Create local admin user'
# $userParams = @{
# Name = $env:WINRM_USERNAME
# Password = (ConvertTo-SecureString -AsPlainText -Force -String $env:WINRM_PASSWORD)
# AccountNeverExpires = $true
# PasswordNeverExpires = $true
# }
# $null = New-LocalUser @userParams
# Add-LocalGroupMember -Group Administrators -Member $userParams.Name

# Write-Host 'Setting up WinRM settings'
# Enable-PSRemoting -Force -SkipNetworkProfileCheck
# Enable-WSManCredSSP -Role Server -Force
# Set-Item WSMan:\localhost\Service\Auth\Basic $true
# Set-Item WSMan:\localhost\Service\Auth\CredSSP $true
# Set-Item WSMan:\localhost\Service\AllowUnencrypted $true

- name: set up Linux dependencies
if: startsWith(matrix.os, 'ubuntu')
run: >-
sudo apt-get install -y
gcc
python-dev
python3-dev
libkrb5-dev
env:
DEBIAN_FRONTEND: noninteractive
Expand All @@ -102,39 +75,13 @@ jobs:
pip install .[credssp,kerberos]
pip install -r requirements-test.txt

- name: run test - non Windows
if: "!startsWith(matrix.os, 'windows')"
run: |
pytest -v --flake8 --cov=winrm --cov-report=term-missing winrm/tests/

- name: run test - Windows
if: startsWith(matrix.os, 'windows')
- name: run test
run: |
pytest -v --flake8 --cov=winrm --cov-report=term-missing winrm/tests/
# env:
# WINRM_TRANSPORT: basic
# WINRM_ENDPOINT: http://localhost:5985/wsman
python -m black . --check
python -m isort . --check-only
pytest -v --cov=winrm --cov-report=term-missing winrm/tests/

- name: upload coverage data
if: "!endsWith(matrix.python-version, '2.7')" # Uses an older coverals version that doesn't support GHA
run: coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# - name: run integration with NTLM
# if: startsWith(matrix.os, 'windows')
# run: |
# Set-Item WSMan:\localhost\Service\AllowUnencrypted $false
# py.test -v winrm/tests/test_integration_protocol.py winrm/tests/test_integration_session.py
# env:
# WINRM_TRANSPORT: ntlm
# WINRM_ENDPOINT: http://localhost:5985/wsman

# - name: run integration with CredSSP
# if: startsWith(matrix.os, 'windows')
# run: |
# Set-Item WSMan:\localhost\Service\AllowUnencrypted $false
# py.test -v winrm/tests/test_integration_protocol.py winrm/tests/test_integration_session.py
# env:
# WINRM_TRANSPORT: credssp
# WINRM_ENDPOINT: http://localhost:5985/wsman
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

### Version 0.5.0
- Dropped Python 2.7, 3.6, and 3.7 support, minimum supported version is 3.8
- Migrate to PEP 517 compliant build with a `pyproject.toml` file

### Version 0.4.3
- Fix invalid regex escape sequences.
- Decoding CLIXML failures for `run_ps` will create a `UserWarning` rather than printing the warning.
Expand Down
37 changes: 11 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# pywinrm
# pywinrm
pywinrm is a Python client for the Windows Remote Management (WinRM) service.
It allows you to invoke commands on target Windows machines from any machine
that can run Python.
Expand All @@ -8,8 +8,8 @@ that can run Python.
[![Coverage](https://coveralls.io/repos/diyan/pywinrm/badge.svg)](https://coveralls.io/r/diyan/pywinrm)
[![PyPI](https://img.shields.io/pypi/dm/pywinrm.svg)](https://pypi.python.org/pypi/pywinrm)

WinRM allows you to perform various management tasks remotely. These include,
but are not limited to: running batch scripts, powershell scripts, and fetching
WinRM allows you to perform various management tasks remotely. These include,
but are not limited to: running batch scripts, powershell scripts, and fetching
WMI variables.

Used by [Ansible](https://www.ansible.com/) for Windows support.
Expand All @@ -19,7 +19,7 @@ For more information on WinRM, please visit

## Requirements
* Linux, Mac OS X or Windows
* CPython 2.6-2.7, 3.3-3.5 or PyPy2
* CPython 3.8+ or PyPy3
* [requests-kerberos](http://pypi.python.org/pypi/requests-kerberos) and [requests-credssp](https://github.com/jborean93/requests-credssp) is optional

## Installation
Expand All @@ -32,23 +32,17 @@ $ pip install pywinrm

```bash
# for Debian/Ubuntu/etc:
$ sudo apt-get install gcc python-dev libkrb5-dev
$ sudo apt-get install gcc python3-dev libkrb5-dev
$ pip install pywinrm[kerberos]

# for RHEL/CentOS/etc:
$ sudo yum install gcc python-devel krb5-devel krb5-workstation python-devel
$ sudo dnf install gcc krb5-devel krb5-workstation python3-devel
$ pip install pywinrm[kerberos]
```

### To use CredSSP authentication you need these optional dependencies

```bash
# for Debian/Ubuntu/etc:
$ sudo apt-get install gcc python-dev libssl-dev
$ pip install pywinrm[credssp]

# for RHEL/CentOS/etc:
$ sudo yum install gcc python-devel openssl-devel
$ pip install pywinrm[credssp]
```

Expand Down Expand Up @@ -147,17 +141,15 @@ to enable encrypted communication with pywinrm:

Using an HTTPS endpoint is recommended, as it will encrypt all the data sent
to the server (including all headers), works securely with all
auth types, and can properly verify remote host identity (when used with certificates signed by a
verifiable certificate authority). You can use [this script](https://github.com/ansible/ansible/blob/devel/examples/scripts/ConfigureRemotingForAnsible.ps1)
to easily set up a HTTPS endpoint on WinRM with a self-signed certificate, but
the use of a verifiable certificate authority is recommended in production environments.
auth types, and can properly verify remote host identity (when used with certificates signed by a
verifiable certificate authority).

The second option is to use NTLM, Kerberos, or CredSSP, and set the `message_encryption`
arg to protocol to `auto` (the default value) or `always`. This will use the authentication GSS-API
Wrap and Unwrap methods to encrypt the message contents sent to
the server. This form of encryption is independent of the transport layer, and the strength of the encryption
used varies with the underlying authentication type selected (NTLM generally being the weakest and CredSSP the
strongest).
strongest).

To configure message encryption you can use the `message_encryption` argument
when initialising protocol. This option has 3 values that can be set as shown
Expand All @@ -168,7 +160,7 @@ below.
* `always`: Will always use message encryption even when running over HTTPS (fails if encryption support is unavailable on the selected auth method).

If you set the value to `always` and the transport opt doesn't support message
encryption (e.g., `basic` auth or an old version of `pykerberos` without message
encryption (e.g., `basic` auth or an old version of `pykerberos` without message
encryption support is installed), pywinrm will throw an exception.

If you do not use an HTTPS endpoint or message encryption, a default-configured WinRM
Expand All @@ -185,18 +177,11 @@ winrm set winrm/config/service @{AllowUnencrypted="true"}
Set-Item -Path "WSMan:\localhost\Service\AllowUnencrypted" -Value $true
```

Again, this should *not* be used in production environments, as your credentials and WinRM
Again, this should *not* be used in production environments, as your credentials and WinRM
messages can be trivially recovered.


### Enabling WinRM on remote host
Enable WinRM over HTTP and HTTPS with self-signed certificate (includes firewall rules):

```
# from powershell:
Invoke-Expression ((New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1'))
```

Enable WinRM over HTTP for test usage (includes firewall rules):
```
winrm quickconfig
Expand Down
80 changes: 80 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
[build-system]
requires = [
"setuptools >= 61.0.0", # Support for setuptools config in pyproject.toml
]
build-backend = "setuptools.build_meta"

[project]
name = "pywinrm"
description = "Python library for Windows Remote Management"
readme = "README.md"
requires-python = ">=3.8"
license = { file = "LICENSE" }
authors = [
{ name = "Alexey Diyan", email = "[email protected]" }
]
keywords = ["winrm", "ws-man", "devops", "ws-management"]
classifiers = [
"Development Status :: 4 - Beta",
"Environment :: Console",
"Intended Audience :: Developers",
"Intended Audience :: System Administrators",
"Natural Language :: English",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: System :: Clustering",
"Topic :: System :: Distributed Computing",
"Topic :: System :: Systems Administration"
]
dependencies = [
"requests >= 2.9.1",
"requests_ntlm >= 1.1.0",
"xmltodict"
]
dynamic = ["version"]

[project.urls]
homepage = "http://github.com/diyan/pywinrm/"


[project.optional-dependencies]
credssp = [
"requests-credssp >= 1.0.0"
]
kerberos = [
"pykerberos >= 1.2.1, < 2.0.0; sys_platform != 'win32'",
"winkerberos >= 0.5.0; sys_platform == 'win32'"
]

[tool.setuptools]
include-package-data = true
packages = ["winrm"]

[tool.setuptools.package-data]
"winrm.tests" = ["*.ps1"]

[tool.setuptools.dynamic]
version = { attr = "winrm.__version__" }

[tool.black]
line-length = 160
exclude = '''
/(
\.git
| \.venv
| build
| dist
| winrm/vendor
)/
'''

[tool.isort]
profile = "black"
3 changes: 2 additions & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# this assumes the base requirements have been satisfied via setup.py
black == 24.4.2
isort == 5.13.2
pytest
pytest-cov
pytest-flake8==1.0.7
mock
11 changes: 0 additions & 11 deletions setup.cfg

This file was deleted.

Loading