diff --git a/.copier-answers.yml b/.copier-answers.yml new file mode 100644 index 0000000..4d8438e --- /dev/null +++ b/.copier-answers.yml @@ -0,0 +1,28 @@ +# Autogenerated. Do not edit this by hand, use `copier update`. +--- +_commit: 0.3.7 +_src_path: https://github.com/salt-extensions/salt-extension-copier +author: Salt Core Team +author_email: saltproject@vmware.com +coc_contact: '' +copyright_begin: 2023 +deploy_docs: rolling +docs_url: https://salt-extensions.github.io/saltext-apache/ +integration_name: Apache +license: apache +loaders: + - module + - state +max_salt_version: 3007 +no_saltext_namespace: false +package_name: apache +project_name: apache +python_requires: '3.8' +salt_version: '3006' +source_url: https://github.com/salt-extensions/saltext-apache +ssh_fixtures: false +summary: Salt Extension for interacting with Apache +test_containers: false +tracker_url: https://github.com/salt-extensions/saltext-apache/issues +url: https://github.com/salt-extensions/saltext-apache +workflows: org diff --git a/.coveragerc b/.coveragerc index a54b433..d696c6a 100644 --- a/.coveragerc +++ b/.coveragerc @@ -36,7 +36,7 @@ ignore_errors = True [paths] source = - saltext/saltext_apache - src/saltext/saltext_apache + saltext/apache + src/saltext/apache testsuite = tests/ diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..879568e --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,11 @@ +### Description of Issue + + +### Setup +(Please provide relevant configs and/or SLS files (Be sure to remove sensitive info).) + +### Steps to Reproduce Issue +(Include debug logs if possible and relevant.) + +### Versions Report +(Provided by running `salt --versions-report`. Please also mention any differences in master/minion versions.) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..b232a42 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,48 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[BUG]" +labels: bug, needs-triage +assignees: '' + +--- + +**Description** +A clear and concise description of what the bug is. + +**Setup** +(Please provide relevant configs and/or SLS files (be sure to remove sensitive info. There is no general set-up of Salt.) + +Please be as specific as possible and give set-up details. + +- [ ] on-prem machine +- [ ] VM (Virtualbox, KVM, etc. please specify) +- [ ] VM running on a cloud service, please be explicit and add details +- [ ] container (Kubernetes, Docker, containerd, etc. please specify) +- [ ] or a combination, please be explicit +- [ ] jails if it is FreeBSD +- [ ] classic packaging +- [ ] onedir packaging +- [ ] used bootstrap to install + + +**Steps to Reproduce the behavior** +(Include debug logs if possible and relevant) + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Versions Report** +
salt --versions-report +(Provided by running salt --versions-report. Please also mention any differences in master/minion versions.) + +```yaml +PASTE HERE +``` +
+ +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..4cf0d28 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +blank_issues_enabled: true +contact_links: + - name: Salt Community Slack + url: https://saltstackcommunity.slack.com/ + about: Please ask and answer questions here. + - name: Salt-Users Forum + url: https://groups.google.com/forum/#!forum/salt-users + about: Please ask and answer questions here. + - name: Salt on LiberaChat + url: https://web.libera.chat/#salt + about: Please ask and answer questions here. + - name: Security vulnerabilities + email: saltproject-security.pdl@broadcom.com + about: Please report security vulnerabilities here. diff --git a/.github/ISSUE_TEMPLATE/docs.md b/.github/ISSUE_TEMPLATE/docs.md new file mode 100644 index 0000000..59af749 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/docs.md @@ -0,0 +1,23 @@ +--- +name: Docs +about: Issue related to Salt Documentation +title: "[DOCS]" +labels: documentation, needs-triage +assignees: '' + +--- + +**Description** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Suggested Fix** +What did you expect to see in the documentation that is missing or needs updating? + +**Type of documentation** +This could be module documentation or a guide. + +**Location or format of documentation** +Insert page URL if applicable. + +**Additional context** +Add any other context or screenshots here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..0e0a390 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[FEATURE REQUEST]" +labels: feature, needs-triage +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/tech-debt.md b/.github/ISSUE_TEMPLATE/tech-debt.md new file mode 100644 index 0000000..5a546c6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tech-debt.md @@ -0,0 +1,13 @@ +--- +name: Tech Debt +about: Issue is related to tech debt. This includes compatibility changes for newer versions of software and OSes that salt interacts with. +title: "[TECH DEBT]" +labels: tech-debt +assignees: '' + +--- + +### Description of the tech debt to be addressed, include links and screenshots + +### Versions Report +(Provided by running `salt --versions-report`. Please also mention any differences in master/minion versions.) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..7d63a7c --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,24 @@ +### What does this PR do? + +### What issues does this PR fix or reference? +Fixes: + +### Previous Behavior +Remove this section if not relevant + +### New Behavior +Remove this section if not relevant + +### Merge requirements satisfied? +**[NOTICE] Bug fixes or features added to Salt require tests.** + +- [ ] Docs +- [ ] Changelog - https://docs.saltproject.io/en/master/topics/development/changelog.html +- [ ] Tests written/updated + +### Commits signed with GPG? +Yes/No + +Please review [Salt's Contributing Guide](https://docs.saltproject.io/en/master/topics/development/contributing.html) for best practices. + +See GitHub's [page on GPG signing](https://help.github.com/articles/signing-commits-using-gpg/) for more information about signing commits with GPG. diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..47c40ed --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,21 @@ +name: Pull Request or Push + +on: + push: + branches: + - 'main' # Run on pushes to main + tags-ignore: + - '*' # Ignore pushes to tags + pull_request: + +jobs: + call_central_workflow: + name: CI + uses: salt-extensions/central-artifacts/.github/workflows/ci.yml@main + with: + deploy-docs: true + permissions: + contents: write + id-token: write + pages: write + pull-requests: read diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml new file mode 100644 index 0000000..dab0796 --- /dev/null +++ b/.github/workflows/tag.yml @@ -0,0 +1,33 @@ +name: Tagged Releases + +on: + push: + tags: + - "v*" # Only tags starting with "v" for "v1.0.0", etc. + +jobs: + get_tag_version: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.get_version.outputs.version }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Extract tag name + id: get_version + run: echo "version=$(echo ${GITHUB_REF#refs/tags/v})" >> $GITHUB_OUTPUT + + call_central_workflow: + needs: get_tag_version + uses: salt-extensions/central-artifacts/.github/workflows/ci.yml@main + with: + deploy-docs: true + release: true + version: ${{ needs.get_tag_version.outputs.version }} + permissions: + contents: write + id-token: write + pages: write + pull-requests: read + secrets: inherit diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 667dcc7..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,427 +0,0 @@ - -name: Testing - -on: [push, pull_request] - -jobs: - Pre-Commit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Python - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - name: Set Cache Key - run: echo "PY=$(python --version --version | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV - - name: Install System Deps - run: | - sudo apt-get update - sudo apt-get install -y libxml2 libxml2-dev libxslt-dev - - uses: actions/cache@v1 - with: - path: ~/.cache/pre-commit - key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} - - uses: pre-commit/action@v1.0.1 - - Docs: - runs-on: ubuntu-latest - needs: Pre-Commit - - timeout-minutes: 10 - - steps: - - uses: actions/checkout@v2 - - - name: Set up Python 3.7 For Nox - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - - name: Install Nox - run: | - python -m pip install --upgrade pip - pip install nox - - - name: Install Doc Requirements - run: | - nox --force-color -e docs --install-only - - - name: Build Docs - env: - SKIP_REQUIREMENTS_INSTALL: YES - run: | - nox --force-color -e docs - - Linux: - runs-on: ubuntu-latest - needs: Pre-Commit - - timeout-minutes: 15 - - strategy: - fail-fast: false - max-parallel: 4 - matrix: - include: - - {"salt-version": "3005.0", "python-version": "3.7"} - - {"salt-version": "3005.0", "python-version": "3.8"} - - {"salt-version": "3005.0", "python-version": "3.9"} - - {"salt-version": "3006.0", "python-version": "3.7"} - - {"salt-version": "3006.0", "python-version": "3.8"} - - {"salt-version": "3006.0", "python-version": "3.9"} - - {"salt-version": "3006.0", "python-version": "3.10"} - - steps: - - uses: actions/checkout@v2 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - - name: Install Nox - run: | - python -m pip install --upgrade pip - pip install nox - - - name: Install Test Requirements - env: - SALT_REQUIREMENT: salt==${{ matrix.salt-version }} - run: | - nox --force-color -e tests-3 --install-only - - - name: Test - env: - SALT_REQUIREMENT: salt==${{ matrix.salt-version }} - SKIP_REQUIREMENTS_INSTALL: YES - run: | - nox --force-color -e tests-3 -- -vv tests/ - - - name: Create CodeCov Flags - if: always() - id: codecov-flags - run: | - echo ::set-output name=flags::$(python -c "import sys; print('{},{},salt_{}'.format('${{ runner.os }}'.replace('-latest', ''), 'py{}{}'.format(*sys.version_info), '_'.join(str(v) for v in '${{ matrix.salt-version }}'.replace('==', '_').split('.'))))") - - - name: Upload Project Code Coverage - if: always() - shell: bash - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},project - REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-project - REPORT_PATH: artifacts/coverage-project.xml - run: | - if [ ! -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - if [ -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - - - name: Upload Tests Code Coverage - if: always() - shell: bash - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},tests - REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-tests - REPORT_PATH: artifacts/coverage-tests.xml - run: | - if [ ! -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - if [ -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - - - name: Upload Logs - if: always() - uses: actions/upload-artifact@main - with: - name: runtests-${{ runner.os }}-py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}.log - path: artifacts/runtests-*.log - - Windows: - runs-on: windows-latest - needs: Pre-Commit - - timeout-minutes: 40 - - strategy: - fail-fast: false - max-parallel: 3 - matrix: - include: - - {"salt-version": "3005.0", "python-version": "3.8"} - - {"salt-version": "3006.0", "python-version": "3.8"} - - {"salt-version": "3006.0", "python-version": "3.9"} - - {"salt-version": "3006.0", "python-version": "3.10"} - - steps: - - uses: actions/checkout@v2 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - - name: Download libeay32.dll - run: | - export PY_LOC=$(which python.exe) - echo ${PY_LOC} - export PY_DIR=$(dirname ${PY_LOC}) - echo ${PY_DIR} - curl https://repo.saltproject.io/windows/dependencies/64/libeay32.dll --output ${PY_DIR}/libeay32.dll - shell: bash - - - name: Install Nox - run: | - python -m pip install --upgrade pip - pip install nox - - - name: Install Test Requirements - shell: bash - env: - SALT_REQUIREMENT: salt==${{ matrix.salt-version }} - EXTRA_REQUIREMENTS_INSTALL: Cython - run: | - export PATH="/C/Program Files (x86)/Windows Kits/10/bin/10.0.18362.0/x64;$PATH" - nox --force-color -e tests-3 --install-only - - - name: Test - shell: bash - env: - SALT_REQUIREMENT: salt==${{ matrix.salt-version }} - SKIP_REQUIREMENTS_INSTALL: YES - run: | - export PATH="/C/Program Files (x86)/Windows Kits/10/bin/10.0.18362.0/x64;$PATH" - nox --force-color -e tests-3 -- -vv tests/ - - - name: Create CodeCov Flags - if: always() - id: codecov-flags - run: | - echo ::set-output name=flags::$(python -c "import sys; print('{},{},salt_{}'.format('${{ runner.os }}'.replace('-latest', ''), 'py{}{}'.format(*sys.version_info), '_'.join(str(v) for v in '${{ matrix.salt-version }}'.replace('==', '_').split('.'))))") - - - name: Upload Project Code Coverage - if: always() - shell: bash - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},project - REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-project - REPORT_PATH: artifacts/coverage-project.xml - run: | - if [ ! -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - if [ -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - - - name: Upload Tests Code Coverage - if: always() - shell: bash - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},tests - REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-tests - REPORT_PATH: artifacts/coverage-tests.xml - run: | - if [ ! -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - if [ -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - - - name: Upload Logs - if: always() - uses: actions/upload-artifact@main - with: - name: runtests-${{ runner.os }}-py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}.log - path: artifacts/runtests-*.log - - macOS: - runs-on: macOS-latest - needs: Pre-Commit - - timeout-minutes: 40 - - strategy: - fail-fast: false - max-parallel: 3 - matrix: - include: - - {"salt-version": "3005.0", "python-version": "3.9", "source": "pypi"} - - {"salt-version": "3006.0", "python-version": "3.9", "source": "pypi"} - - {"salt-version": "3006.0", "python-version": "3.10", "source": "pypi"} - - steps: - - uses: actions/checkout@v2 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - - name: Install Nox - run: | - python -m pip install --upgrade pip - pip install nox - - - name: Install Test Requirements - env: - SALT_REQUIREMENT: salt==${{ matrix.salt-version }} - run: | - nox --force-color -e tests-3 --install-only - - - name: Test - env: - SALT_REQUIREMENT: salt==${{ matrix.salt-version }} - SKIP_REQUIREMENTS_INSTALL: YES - run: | - nox --force-color -e tests-3 -- -vv tests/ - - - name: Create CodeCov Flags - if: always() - id: codecov-flags - run: | - echo ::set-output name=flags::$(python -c "import sys; print('{},{},salt_{}'.format('${{ runner.os }}'.replace('-latest', ''), 'py{}{}'.format(*sys.version_info), '_'.join(str(v) for v in '${{ matrix.salt-version }}'.replace('==', '_').split('.'))))") - - - name: Upload Project Code Coverage - if: always() - shell: bash - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},project - REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-project - REPORT_PATH: artifacts/coverage-project.xml - run: | - if [ ! -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - if [ -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - - - name: Upload Tests Code Coverage - if: always() - shell: bash - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},tests - REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-tests - REPORT_PATH: artifacts/coverage-tests.xml - run: | - if [ ! -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - if [ -f codecov.sh ]; then - n=0 - until [ "$n" -ge 5 ] - do - if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then - break - fi - n=$((n+1)) - sleep 15 - done - fi - - - name: Upload Logs - if: always() - uses: actions/upload-artifact@main - with: - name: runtests-${{ runner.os }}-py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}.log - path: artifacts/runtests-*.log diff --git a/.gitignore b/.gitignore index e275e58..95186b1 100644 --- a/.gitignore +++ b/.gitignore @@ -129,7 +129,7 @@ dmypy.json .pyre/ # Ignore the setuptools_scm auto-generated version module -src/saltext/saltext_apache/version.py +src/saltext/apache/version.py # Ignore CI generated artifacts artifacts/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml old mode 100644 new mode 100755 index 69d0270..42e7abe --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ minimum_pre_commit_version: 2.4.0 repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + rev: v4.6.0 hooks: - id: check-merge-conflict # Check for files that contain merge conflict strings. - id: trailing-whitespace # Trims trailing whitespace. @@ -25,7 +25,7 @@ repos: name: Check CLI examples on execution modules entry: python .pre-commit-hooks/check-cli-examples.py language: system - files: ^src/saltext/saltext_apache/modules/.*\.py$ + files: ^src/saltext/apache/modules/.*\.py$ - repo: local hooks: @@ -37,17 +37,17 @@ repos: - repo: https://github.com/s0undt3ch/salt-rewrite # Automatically rewrite code with known rules - rev: 1.3.3 + rev: 2.5.2 hooks: - id: salt-rewrite alias: rewrite-docstrings name: Salt extensions docstrings auto-fixes - files: ^src/saltext/saltext_apache/.*\.py$ + files: ^src/saltext/apache/.*\.py$ args: [--silent] - repo: https://github.com/s0undt3ch/salt-rewrite # Automatically rewrite code with known rules - rev: 1.3.3 + rev: 2.5.2 hooks: - id: salt-rewrite alias: rewrite-tests @@ -56,55 +56,52 @@ repos: args: [--silent, -E, fix_docstrings] - repo: https://github.com/asottile/pyupgrade - rev: v2.31.0 + rev: v3.15.2 hooks: - id: pyupgrade - name: Rewrite Code to be Py3.6+ + name: Rewrite Code to be Py3.8+ args: [ - --py36-plus + --py38-plus ] - exclude: src/saltext/saltext_apache/version.py + exclude: src/saltext/apache/version.py - - repo: https://github.com/asottile/reorder_python_imports - rev: v2.6.0 + - repo: https://github.com/PyCQA/isort + rev: 5.13.2 hooks: - - id: reorder-python-imports + - id: isort args: [ - --py3-plus, + --py 38, ] - exclude: src/saltext/saltext_apache/version.py + exclude: src/saltext/apache/(__init__|version).py - repo: https://github.com/psf/black - rev: 21.7b0 + rev: 24.2.0 hooks: - id: black args: [-l 100] - exclude: src/saltext/saltext_apache/version.py - additional_dependencies: - - click<8.1.0 + exclude: src/saltext/apache/version.py - - repo: https://github.com/asottile/blacken-docs - rev: v1.10.0 + - repo: https://github.com/adamchainz/blacken-docs + rev: 1.16.0 hooks: - id: blacken-docs args: [--skip-errors] - files: ^(docs/.*\.rst|src/saltext/saltext_apache/.*\.py)$ + files: ^(docs/.*\.rst|src/saltext/apache/.*\.py)$ additional_dependencies: - - black==21.7b0 - - click<8.1.0 + - black==24.2.0 # <---- Formatting ----------------------------------------------------------------------------- # ----- Security ------------------------------------------------------------------------------> - repo: https://github.com/PyCQA/bandit - rev: "1.7.0" + rev: 1.7.8 hooks: - id: bandit alias: bandit-salt name: Run bandit against the code base args: [--silent, -lll, --skip, B701] - exclude: src/saltext/saltext_apache/version.py + exclude: src/saltext/apache/version.py - repo: https://github.com/PyCQA/bandit - rev: "1.7.0" + rev: 1.7.8 hooks: - id: bandit alias: bandit-tests @@ -114,168 +111,29 @@ repos: # <---- Security ------------------------------------------------------------------------------- # ----- Code Analysis -------------------------------------------------------------------------> - # - repo: https://github.com/saltstack/mirrors-nox - # rev: v2021.6.12 - # hooks: - # - id: nox - # alias: lint-src - # name: Lint Source Code - # files: ^((setup|noxfile)|src/.*)\.py$ - # args: - # - -e - # - lint-code-pre-commit - # - -- + - repo: https://github.com/saltstack/mirrors-nox + rev: v2022.11.21 + hooks: + - id: nox + alias: lint-src + name: Lint Source Code + files: ^((setup|noxfile)|src/.*)\.py$ + require_serial: true + args: + - -e + - lint-code-pre-commit + - -- - repo: https://github.com/saltstack/mirrors-nox - rev: v2021.6.12 + rev: v2022.11.21 hooks: - id: nox alias: lint-tests name: Lint Tests files: ^tests/.*\.py$ + require_serial: true args: - -e - lint-tests-pre-commit - -- # <---- Code Analysis -------------------------------------------------------------------------- - - # ----- Static Test Requirements --------------------------------------------------------------> - - repo: https://github.com/saltstack/pip-tools-compile-impersonate - rev: '4.1' - hooks: - - id: pip-tools-compile - alias: compile-3.6-test-requirements - name: Py3.6 Test Requirements - files: ^requirements/tests.in$ - pass_filenames: false - args: - - -v - - --py-version=3.6 - - --platform=linux - - requirements/tests.in - - - id: pip-tools-compile - alias: compile-3.7-test-requirements - name: Py3.7 Test Requirements - files: ^requirements/tests.in$ - pass_filenames: false - args: - - -v - - --py-version=3.7 - - --platform=linux - - requirements/tests.in - - - id: pip-tools-compile - alias: compile-3.8-test-requirements - name: Py3.8 Test Requirements - files: ^requirements/tests.in$ - pass_filenames: false - args: - - -v - - --py-version=3.8 - - --platform=linux - - requirements/tests.in - - - id: pip-tools-compile - alias: compile-3.9-test-requirements - name: Py3.9 Test Requirements - files: ^requirements/tests.in$ - pass_filenames: false - args: - - -v - - --py-version=3.9 - - --platform=linux - - requirements/tests.in - # <---- Static Test Requirements --------------------------------------------------------------- - - # ----- Static Lint Requirements --------------------------------------------------------------> - - id: pip-tools-compile - alias: compile-3.6-test-requirements - name: Py3.6 Lint Requirements - files: ^requirements/lint.in$ - pass_filenames: false - args: - - -v - - --py-version=3.6 - - --platform=linux - - requirements/lint.in - - - id: pip-tools-compile - alias: compile-3.7-test-requirements - name: Py3.7 Lint Requirements - files: ^requirements/lint.in$ - pass_filenames: false - args: - - -v - - --py-version=3.7 - - --platform=linux - - requirements/lint.in - - - id: pip-tools-compile - alias: compile-3.8-test-requirements - name: Py3.8 Lint Requirements - files: ^requirements/lint.in$ - pass_filenames: false - args: - - -v - - --py-version=3.8 - - --platform=linux - - requirements/lint.in - - - id: pip-tools-compile - alias: compile-3.9-test-requirements - name: Py3.9 Lint Requirements - files: ^requirements/lint.in$ - pass_filenames: false - args: - - -v - - --py-version=3.9 - - --platform=linux - - requirements/lint.in - # <---- Static Lint Requirements --------------------------------------------------------------- - - # ----- Static Docs Requirements --------------------------------------------------------------> - - id: pip-tools-compile - alias: compile-3.6-test-requirements - name: Py3.6 Docs Requirements - files: ^requirements/docs.in$ - pass_filenames: false - args: - - -v - - --py-version=3.6 - - --platform=linux - - requirements/docs.in - - - id: pip-tools-compile - alias: compile-3.7-test-requirements - name: Py3.7 Docs Requirements - files: ^requirements/docs.in$ - pass_filenames: false - args: - - -v - - --py-version=3.7 - - --platform=linux - - requirements/docs.in - - - id: pip-tools-compile - alias: compile-3.8-test-requirements - name: Py3.8 Docs Requirements - files: ^requirements/docs.in$ - pass_filenames: false - args: - - -v - - --py-version=3.8 - - --platform=linux - - requirements/docs.in - - - id: pip-tools-compile - alias: compile-3.9-test-requirements - name: Py3.9 Docs Requirements - files: ^requirements/docs.in$ - pass_filenames: false - args: - - -v - - --py-version=3.9 - - --platform=linux - - requirements/docs.in - # <---- Static Docs Requirements --------------------------------------------------------------- diff --git a/.pre-commit-hooks/check-cli-examples.py b/.pre-commit-hooks/check-cli-examples.py index 50389c8..5633e60 100644 --- a/.pre-commit-hooks/check-cli-examples.py +++ b/.pre-commit-hooks/check-cli-examples.py @@ -4,7 +4,7 @@ import sys CODE_ROOT = pathlib.Path(__file__).resolve().parent.parent -EXECUTION_MODULES_PATH = CODE_ROOT / "src" / "saltext" / " saltext_apache" / "modules" +EXECUTION_MODULES_PATH = CODE_ROOT / "src" / "saltext" / "apache" / "modules" def check_cli_examples(files): diff --git a/.pre-commit-hooks/make-autodocs.py b/.pre-commit-hooks/make-autodocs.py index a3ad186..63fc8da 100644 --- a/.pre-commit-hooks/make-autodocs.py +++ b/.pre-commit-hooks/make-autodocs.py @@ -1,59 +1,118 @@ +import ast +import os.path import subprocess -import sys -from enum import IntEnum from pathlib import Path - repo_path = Path(subprocess.check_output(["git", "rev-parse", "--show-toplevel"]).decode().strip()) -src_dir = repo_path / "src" / " saltext" / "saltext-apache" +src_dir = repo_path / "src" / "saltext" / "apache" doc_dir = repo_path / "docs" docs_by_kind = {} +changed_something = False + + +def _find_virtualname(path): + tree = ast.parse(path.read_text()) + for node in ast.walk(tree): + if isinstance(node, ast.Assign): + for target in node.targets: + if isinstance(target, ast.Name) and target.id == "__virtualname__": + if isinstance(node.value, ast.Str): + virtualname = node.value.s + break + else: + continue + break + else: + virtualname = path.with_suffix("").name + return virtualname + + +def write_module(rst_path, path, use_virtualname=True): + if use_virtualname: + virtualname = "``" + _find_virtualname(path) + "``" + else: + virtualname = make_import_path(path) + module_contents = f"""\ +{virtualname} +{'='*len(virtualname)} + +.. automodule:: {make_import_path(path)} + :members: +""" + if not rst_path.exists() or rst_path.read_text() != module_contents: + print(rst_path) + rst_path.write_text(module_contents) + return True + return False + + +def write_index(index_rst, import_paths, kind): + if kind == "utils": + header_text = "Utilities" + common_path = os.path.commonpath(tuple(x.replace(".", "/") for x in import_paths)).replace( + "/", "." + ) + if any(x == common_path for x in import_paths): + common_path = common_path[: common_path.rfind(".")] + else: + header_text = ( + "execution modules" if kind.lower() == "modules" else kind.rstrip("s") + " modules" + ) + common_path = import_paths[0][: import_paths[0].rfind(".")] + header = f"{'_'*len(header_text)}\n{header_text.title()}\n{'_'*len(header_text)}" + index_contents = f"""\ +.. all-saltext.apache.{kind}: + +{header} + +.. currentmodule:: {common_path} + +.. autosummary:: + :toctree: + +{chr(10).join(sorted(' '+p[len(common_path)+1:] for p in import_paths))} +""" + if not index_rst.exists() or index_rst.read_text() != index_contents: + print(index_rst) + index_rst.write_text(index_contents) + return True + return False def make_import_path(path): - return ".".join(path.with_suffix("").parts[-4:]) + if path.name == "__init__.py": + path = path.parent + return ".".join(path.relative_to(repo_path / "src").with_suffix("").parts) -for path in Path(__file__).parent.parent.joinpath("src/saltext/saltext-apache/").glob("*/*.py"): +for path in src_dir.glob("*/*.py"): if path.name != "__init__.py": kind = path.parent.name - docs_by_kind.setdefault(kind, set()).add(path) + if kind != "utils": + docs_by_kind.setdefault(kind, set()).add(path) + +# Utils can have subdirectories, treat them separately +for path in (src_dir / "utils").rglob("*.py"): + if path.name == "__init__.py" and not path.read_text(): + continue + docs_by_kind.setdefault("utils", set()).add(path) for kind in docs_by_kind: kind_path = doc_dir / "ref" / kind - all_rst = kind_path / "all.rst" + index_rst = kind_path / "index.rst" import_paths = [] for path in sorted(docs_by_kind[kind]): import_path = make_import_path(path) import_paths.append(import_path) - rst_path = kind_path.joinpath(import_path).with_suffix(".rst") - print(rst_path) + rst_path = kind_path / (import_path + ".rst") rst_path.parent.mkdir(parents=True, exist_ok=True) - rst_path.write_text( - f""" -{import_path} -{'='*len(import_path)} + change = write_module(rst_path, path, use_virtualname=kind != "utils") + changed_something = changed_something or change -.. automodule:: {import_path} - :members: -""" - ) + write_index(index_rst, import_paths, kind) - header_text = ( - "execution modules" if kind.lower() == "modules" else kind.rstrip("s") + " modules" - ) - header = f"{'_'*len(header_text)}\n{header_text.title()}\n{'_'*len(header_text)}" - - all_rst.write_text( - f""" -.. all-saltext.saltext-apache.{kind}: - -{header} -.. autosummary:: - :toctree: - -{chr(10).join(sorted(' '+p for p in import_paths))} -""" - ) +# Ensure pre-commit realizes we did something +if changed_something: + exit(2) diff --git a/.pylintrc b/.pylintrc old mode 100644 new mode 100755 index b8b733a..5692f3b --- a/.pylintrc +++ b/.pylintrc @@ -72,7 +72,7 @@ ignored-modules= # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the # number of processors available to use, and will cap the count on Windows to # avoid hangs. -jobs=1 +jobs=0 # Control the amount of potential inferred values when inferring a single # object. This can help the performance when dealing with large functions or @@ -632,7 +632,28 @@ signature-mutators= # List of additional names supposed to be defined in builtins. Remember that # you should avoid defining new builtins when possible. -additional-builtins= +additional-builtins=__opts__, + __salt__, + __pillar__, + __grains__, + __context__, + __runner__, + __ret__, + __env__, + __low__, + __states__, + __lowstate__, + __running__, + __active_provider_name__, + __master_opts__, + __jid_event__, + __instance_id__, + __salt_system_encoding__, + __proxy__, + __serializers__, + __reg__, + __executors__, + __events__ # Tells whether unused global variables should be treated as a violation. allow-global-unused-variables=yes diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..aec3363 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +This project uses [Semantic Versioning](https://semver.org/) - MAJOR.MINOR.PATCH + +# Changelog diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md new file mode 100644 index 0000000..925ac4a --- /dev/null +++ b/CODE-OF-CONDUCT.md @@ -0,0 +1,127 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in Salt +Extension Modules for Apache project and our community a +harassment-free experience for everyone, regardless of age, body size, visible +or invisible disability, ethnicity, sex characteristics, gender identity and +expression, level of experience, education, socio-economic status, nationality, +personal appearance, race, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..ae08684 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,14 @@ +Thanks for your interest in contributing to the Salt Extension Modules for +Apache! We welcome any contribution, large or small - from +adding a new feature to fixing a single letter typo. + +This is a companion to the Salt Project and the [Salt Contributing +Guide][salt-contributing] should be considered the default for this project. +Where this project disagrees with the Salt Project, the guidelines here take +precedence. Where this project is silent, the Salt guidelines should be used. + +See the **Contributing** section in the [README][README.md] for a quickstart. + + +[README.md]: README.md +[salt-contributing]: https://docs.saltproject.io/en/master/topics/development/contributing.html diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..3527ecc --- /dev/null +++ b/NOTICE @@ -0,0 +1,10 @@ +Salt Extension Modules for Apache +Copyright 2023 Salt Core Team + +This product is licensed to you under the Apache 2.0 license (the "License"). +You may not use this product except in compliance with the Apache 2.0 License. + +This product may include a number of subcomponents with separate copyright +notices and license terms. Your use of these subcomponents is subject to the +terms and conditions of the subcomponent's license, as noted in the LICENSE +file. diff --git a/README.md b/README.md index f1f3456..4891ae7 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,87 @@ -# saltext-apache +# Salt Extension for Apache Salt Extension for interacting with Apache -## Quickstart +## Security -To get started with your new project: +If you think you have found a security vulnerability, see +[Salt's security guide][security]. - # Create a new venv - python3 -m venv env --prompt saltext-apache - source env/bin/activate +## User Documentation - # On mac, you may need to upgrade pip - python -m pip install --upgrade pip +This README is for people aiming to contribute to the project. +If you just want to get started with the extension, check out the +[User Documentation][docs]. - # On WSL or some flavors of linux you may need to install the `enchant` - # library in order to build the docs - sudo apt-get install -y enchant +## Contributing - # Install extension + test/dev/doc dependencies into your environment - python -m pip install -e .[tests,dev,docs] +The saltext-apache project team welcomes contributions from the community. - # Run tests! - python -m nox -e tests-3 +The [Salt Contributing guide][salt-contributing] has a lot of relevant +information, but if you'd like to jump right in here's how to get started: - # skip requirements install for next time - export SKIP_REQUIREMENTS_INSTALL=1 - # Build the docs, serve, and view in your web browser: - python -m nox -e docs && (cd docs/_build/html; python -m webbrowser localhost:8000; python -m http.server; cd -) +```bash +# Clone the repo +git clone --origin salt git@github.com:salt-extensions/saltext-apache.git - # Run the example function - salt-call --local saltext-apache.example_function text="Happy Hacking!" +# Change to the repo dir +cd saltext-apache + +# Create a new venv +python3 -m venv env --prompt saltext-apache +source env/bin/activate + +# On mac, you may need to upgrade pip +python -m pip install --upgrade pip + +# On WSL or some flavors of linux you may need to install the `enchant` +# library in order to build the docs +sudo apt-get install -y enchant + +# Install extension + test/dev/doc dependencies into your environment +python -m pip install -e '.[tests,dev,docs]' + +# Run tests! +python -m nox -e tests-3 + +# skip requirements install for next time +export SKIP_REQUIREMENTS_INSTALL=1 + +# Build the docs, serve, and view in your web browser: +python -m nox -e docs && (cd docs/_build/html; python -m webbrowser localhost:8000; python -m http.server; cd -) +``` + +Writing code isn't the only way to contribute! We value contributions in any of +these areas: + +* Documentation - especially examples of how to use this module to solve + specific problems. +* Triaging [issues][issues] and participating in [discussions][discussions] +* Reviewing [Pull Requests][PRs] (we really like + [Conventional Comments][comments]!) + +You could also contribute in other ways: + +* Writing blog posts +* Posting on social media about how you used Salt + Apache to solve your + problems, including videos +* Giving talks at conferences +* Publishing videos +* Asking/answering questions in IRC, Discord or email groups + +Any of these things are super valuable to our community, and we sincerely +appreciate every contribution! + + +For more information, build the docs and head over to http://localhost:8000/ — +that's where you'll find the rest of the documentation. + + +[security]: https://github.com/saltstack/salt/blob/master/SECURITY.md +[salt-contributing]: https://docs.saltproject.io/en/master/topics/development/contributing.html +[issues]: https://github.com/salt-extensions/saltext-apache/issues +[PRs]: https://github.com/salt-extensions/saltext-apache/pulls +[discussions]: https://github.com/salt-extensions/saltext-apache/discussions +[comments]: https://conventionalcomments.org/ +[docs]: https://salt-extensions.github.io/saltext-apache/ diff --git a/changelog/.template.jinja b/changelog/.template.jinja new file mode 100644 index 0000000..0cf429a --- /dev/null +++ b/changelog/.template.jinja @@ -0,0 +1,15 @@ +{% if sections[""] %} +{% for category, val in definitions.items() if category in sections[""] %} + +### {{ definitions[category]['name'] }} + +{% for text, values in sections[""][category].items() %} +- {{ text }} {{ values|join(', ') }} +{% endfor %} + +{% endfor %} +{% else %} +No significant changes. + + +{% endif %} diff --git a/docs/_ext/saltdomain.py b/docs/_ext/saltdomain.py new file mode 100644 index 0000000..7a85489 --- /dev/null +++ b/docs/_ext/saltdomain.py @@ -0,0 +1,18 @@ +""" +Copied/distilled from Salt doc/_ext/saltdomain.py in order to be able +to use Salt's custom doc refs. +""" + + +def setup(app): + app.add_crossref_type( + directivename="conf_master", + rolename="conf_master", + indextemplate="pair: %s; conf/master", + ) + app.add_crossref_type( + directivename="conf_minion", + rolename="conf_minion", + indextemplate="pair: %s; conf/minion", + ) + return {"parallel_read_safe": True, "parallel_write_safe": True} diff --git a/docs/all.rst b/docs/all.rst deleted file mode 100644 index bcb6fca..0000000 --- a/docs/all.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. _all the states/modules: - -Complete List of saltext-apache -=============================== - - -.. toctree:: - :maxdepth: 2 - - ref/modules.rst - - -.. toctree:: - :maxdepth: 2 - - ref/states.rst diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 0000000..2f5367b --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,12 @@ +# Changelog + +The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +This project uses [Semantic Versioning](https://semver.org/) - MAJOR.MINOR.PATCH + +```{towncrier-draft-entries} +``` + +```{include} ../CHANGELOG.md +:start-after: '# Changelog' +``` diff --git a/docs/conf.py b/docs/conf.py old mode 100644 new mode 100755 index af927ee..2573ac0 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,8 +9,10 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import datetime +import email.policy import os import sys +from pathlib import Path try: from importlib_metadata import distribution @@ -25,25 +27,40 @@ # assume we're in the doc/ directory docs_basepath = os.path.abspath(os.path.dirname(".")) +PROJECT_ROOT_DIR = Path(docs_basepath).parent + addtl_paths = ( - os.path.join(os.pardir, "src"), # saltext.saltext-apache itself (for autodoc) + os.path.join(os.pardir, "src"), # saltext.apache itself (for autodoc) "_ext", # custom Sphinx extensions ) for addtl_path in addtl_paths: sys.path.insert(0, os.path.abspath(os.path.join(docs_basepath, addtl_path))) -dist = distribution("saltext.saltext-apache") +dist = distribution("saltext.apache") # -- Project information ----------------------------------------------------- this_year = datetime.datetime.today().year -if this_year == 2021: - copyright_year = 2021 +if this_year == 2023: + copyright_year = "2023" else: - copyright_year = f"2021 - {this_year}" + copyright_year = f"2023 - {this_year}" project = dist.metadata["Summary"] -author = dist.metadata["Author"] +author = dist.metadata.get("Author") + +if author is None: + # Core metadata is serialized differently with pyproject.toml: + # https://packaging.python.org/en/latest/specifications/pyproject-toml/#authors-maintainers + author_email = dist.metadata["Author-email"] + em = email.message_from_string( + f"To: {author_email}", + policy=email.policy.default, + ) + if em["To"].addresses and em["To"].addresses[0]: + author = em["To"].addresses[0].display_name + author = author or "" + copyright = f"{copyright_year}, {author}" # The full version, including alpha/beta/rc tags @@ -62,6 +79,8 @@ # -- General configuration --------------------------------------------------- +linkcheck_ignore = [r"http://localhost:\d+"] + # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. @@ -75,6 +94,16 @@ "sphinx.ext.coverage", "sphinx_copybutton", "sphinxcontrib.spelling", + "saltdomain", + "sphinxcontrib.towncrier.ext", + "myst_parser", + "sphinx_inline_tabs", +] + +myst_enable_extensions = [ + "colon_fence", + "deflist", + "tasklist", ] # Add any paths that contain templates here, relative to this directory. @@ -95,7 +124,7 @@ "sitevars.rst", ] -autosummary_generate = True +autosummary_generate = False # -- Options for HTML output ------------------------------------------------- @@ -136,7 +165,7 @@ # ----- Intersphinx Config ----------------------------------------------------------------------------------------> intersphinx_mapping = { "python": ("https://docs.python.org/3", None), - "pytest": ("https://pytest.readthedocs.io/en/stable", None), + "pytest": ("https://docs.pytest.org/en/stable", None), "salt": ("https://docs.saltproject.io/en/latest", None), } # <---- Intersphinx Config ----------------------------------------------------------------------------------------- @@ -146,6 +175,11 @@ autodoc_mock_imports = ["salt"] # <---- Autodoc Config ----------------------------------------------------------------------------------------------- +# Towncrier draft config +towncrier_draft_autoversion_mode = "sphinx-release" +towncrier_draft_include_empty = True +towncrier_draft_working_directory = str(PROJECT_ROOT_DIR) + def setup(app): app.add_crossref_type( diff --git a/docs/index.rst b/docs/index.rst index aa9f512..1ce5a2e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,11 +1,30 @@ -Welcome to saltext-apache Documentation! -======================================== +``saltext-apache``: Integrate Salt with Apache +============================================== + +Salt Extension for interacting with Apache + +.. toctree:: + :maxdepth: 2 + :caption: Guides + :hidden: + + topics/installation .. toctree:: :maxdepth: 2 - :caption: Contents: + :caption: Provided Modules + :hidden: + + ref/modules/index + ref/states/index + +.. toctree:: + :maxdepth: 2 + :caption: Reference + :hidden: + + changelog - all.rst Indices and tables ================== diff --git a/docs/ref/modules/all/salt.modules.apache.rst b/docs/ref/modules/all/salt.modules.apache.rst deleted file mode 100644 index 90858f3..0000000 --- a/docs/ref/modules/all/salt.modules.apache.rst +++ /dev/null @@ -1,5 +0,0 @@ -salt.modules.apache -=================== - -.. automodule:: salt.modules.apache - :members: diff --git a/docs/ref/modules/all/salt.modules.deb_apache.rst b/docs/ref/modules/all/salt.modules.deb_apache.rst deleted file mode 100644 index 8fe0caf..0000000 --- a/docs/ref/modules/all/salt.modules.deb_apache.rst +++ /dev/null @@ -1,5 +0,0 @@ -salt.modules.deb_apache -======================= - -.. automodule:: salt.modules.deb_apache - :members: diff --git a/docs/ref/modules/all/salt.modules.suse_apache.rst b/docs/ref/modules/all/salt.modules.suse_apache.rst deleted file mode 100644 index 2ece825..0000000 --- a/docs/ref/modules/all/salt.modules.suse_apache.rst +++ /dev/null @@ -1,5 +0,0 @@ -salt.modules.suse_apache -======================== - -.. automodule:: salt.modules.suse_apache - :members: diff --git a/docs/ref/modules/index.rst b/docs/ref/modules/index.rst new file mode 100644 index 0000000..1295bf6 --- /dev/null +++ b/docs/ref/modules/index.rst @@ -0,0 +1,14 @@ +.. all-saltext.apache.modules: + +_________________ +Execution Modules +_________________ + +.. currentmodule:: saltext.apache.modules + +.. autosummary:: + :toctree: + + apache + deb_apache + suse_apache diff --git a/docs/ref/modules/saltext.apache.modules.apache.rst b/docs/ref/modules/saltext.apache.modules.apache.rst new file mode 100644 index 0000000..a73808a --- /dev/null +++ b/docs/ref/modules/saltext.apache.modules.apache.rst @@ -0,0 +1,5 @@ +``apache`` +========== + +.. automodule:: saltext.apache.modules.apache + :members: diff --git a/docs/ref/modules/saltext.apache.modules.deb_apache.rst b/docs/ref/modules/saltext.apache.modules.deb_apache.rst new file mode 100644 index 0000000..71034ae --- /dev/null +++ b/docs/ref/modules/saltext.apache.modules.deb_apache.rst @@ -0,0 +1,5 @@ +``apache`` +========== + +.. automodule:: saltext.apache.modules.deb_apache + :members: diff --git a/docs/ref/modules/saltext.apache.modules.suse_apache.rst b/docs/ref/modules/saltext.apache.modules.suse_apache.rst new file mode 100644 index 0000000..ae2cd23 --- /dev/null +++ b/docs/ref/modules/saltext.apache.modules.suse_apache.rst @@ -0,0 +1,5 @@ +``apache`` +========== + +.. automodule:: saltext.apache.modules.suse_apache + :members: diff --git a/docs/ref/states/all/salt.states.apache.rst b/docs/ref/states/all/salt.states.apache.rst deleted file mode 100644 index 61940db..0000000 --- a/docs/ref/states/all/salt.states.apache.rst +++ /dev/null @@ -1,5 +0,0 @@ -salt.states.apache -================== - -.. automodule:: salt.states.apache - :members: diff --git a/docs/ref/states/all/salt.states.apache_conf.rst b/docs/ref/states/all/salt.states.apache_conf.rst deleted file mode 100644 index 0739e6e..0000000 --- a/docs/ref/states/all/salt.states.apache_conf.rst +++ /dev/null @@ -1,5 +0,0 @@ -salt.states.apache_conf -======================= - -.. automodule:: salt.states.apache_conf - :members: diff --git a/docs/ref/states/all/salt.states.apache_module.rst b/docs/ref/states/all/salt.states.apache_module.rst deleted file mode 100644 index cb68a0c..0000000 --- a/docs/ref/states/all/salt.states.apache_module.rst +++ /dev/null @@ -1,5 +0,0 @@ -salt.states.apache_module -========================= - -.. automodule:: salt.states.apache_module - :members: diff --git a/docs/ref/states/all/salt.states.apache_site.rst b/docs/ref/states/all/salt.states.apache_site.rst deleted file mode 100644 index 5f675f7..0000000 --- a/docs/ref/states/all/salt.states.apache_site.rst +++ /dev/null @@ -1,5 +0,0 @@ -salt.states.apache_site -======================= - -.. automodule:: salt.states.apache_site - :members: diff --git a/docs/ref/states/index.rst b/docs/ref/states/index.rst new file mode 100644 index 0000000..26ded87 --- /dev/null +++ b/docs/ref/states/index.rst @@ -0,0 +1,15 @@ +.. all-saltext.apache.states: + +_____________ +State Modules +_____________ + +.. currentmodule:: saltext.apache.states + +.. autosummary:: + :toctree: + + apache + apache_conf + apache_module + apache_site diff --git a/docs/ref/states/saltext.apache.states.apache.rst b/docs/ref/states/saltext.apache.states.apache.rst new file mode 100644 index 0000000..498a375 --- /dev/null +++ b/docs/ref/states/saltext.apache.states.apache.rst @@ -0,0 +1,5 @@ +``apache`` +========== + +.. automodule:: saltext.apache.states.apache + :members: diff --git a/docs/ref/states/saltext.apache.states.apache_conf.rst b/docs/ref/states/saltext.apache.states.apache_conf.rst new file mode 100644 index 0000000..177d59c --- /dev/null +++ b/docs/ref/states/saltext.apache.states.apache_conf.rst @@ -0,0 +1,5 @@ +``apache_conf`` +=============== + +.. automodule:: saltext.apache.states.apache_conf + :members: diff --git a/docs/ref/states/saltext.apache.states.apache_module.rst b/docs/ref/states/saltext.apache.states.apache_module.rst new file mode 100644 index 0000000..c600a7f --- /dev/null +++ b/docs/ref/states/saltext.apache.states.apache_module.rst @@ -0,0 +1,5 @@ +``apache_module`` +================= + +.. automodule:: saltext.apache.states.apache_module + :members: diff --git a/docs/ref/states/saltext.apache.states.apache_site.rst b/docs/ref/states/saltext.apache.states.apache_site.rst new file mode 100644 index 0000000..cf78a7b --- /dev/null +++ b/docs/ref/states/saltext.apache.states.apache_site.rst @@ -0,0 +1,5 @@ +``apache_site`` +=============== + +.. automodule:: saltext.apache.states.apache_site + :members: diff --git a/docs/topics/installation.md b/docs/topics/installation.md new file mode 100644 index 0000000..67068fe --- /dev/null +++ b/docs/topics/installation.md @@ -0,0 +1,28 @@ +# Installation + +Generally, extensions need to be installed into the same Python environment Salt uses. + +:::{tab} State +```yaml +Install Salt Apache extension: + pip.installed: + - name: saltext-apache +``` +::: + +:::{tab} Onedir installation +```bash +salt-pip install saltext-apache +``` +::: + +:::{tab} Regular installation +```bash +pip install saltext-apache +``` +::: + +:::{hint} +Saltexts are not distributed automatically via the fileserver like custom modules, they need to be installed +on each node you want them to be available on. +::: diff --git a/noxfile.py b/noxfile.py old mode 100644 new mode 100755 index 5d3b396..31a246d --- a/noxfile.py +++ b/noxfile.py @@ -19,17 +19,17 @@ nox.options.error_on_missing_interpreters = False # Python versions to test against -PYTHON_VERSIONS = ("3", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10") +PYTHON_VERSIONS = ("3", "3.8", "3.9", "3.10", "3.11", "3.12") # Be verbose when running under a CI context CI_RUN = ( os.environ.get("JENKINS_URL") or os.environ.get("CI") or os.environ.get("DRONE") is not None ) PIP_INSTALL_SILENT = CI_RUN is False -SKIP_REQUIREMENTS_INSTALL = "SKIP_REQUIREMENTS_INSTALL" in os.environ +SKIP_REQUIREMENTS_INSTALL = os.environ.get("SKIP_REQUIREMENTS_INSTALL", "0") == "1" EXTRA_REQUIREMENTS_INSTALL = os.environ.get("EXTRA_REQUIREMENTS_INSTALL") -COVERAGE_VERSION_REQUIREMENT = "coverage==5.2" -SALT_REQUIREMENT = os.environ.get("SALT_REQUIREMENT") or "salt>=3003" +COVERAGE_REQUIREMENT = os.environ.get("COVERAGE_REQUIREMENT") or "coverage==7.5.1" +SALT_REQUIREMENT = os.environ.get("SALT_REQUIREMENT") or "salt>=3006" if SALT_REQUIREMENT == "salt==master": SALT_REQUIREMENT = "git+https://github.com/saltstack/salt.git@master" @@ -70,8 +70,8 @@ def _get_session_python_version_info(session): def _get_pydir(session): version_info = _get_session_python_version_info(session) - if version_info < (3, 5): - session.error("Only Python >= 3.5 is supported") + if version_info < (3, 8): + session.error("Only Python >= 3.8 is supported") return f"py{version_info[0]}.{version_info[1]}" @@ -89,9 +89,7 @@ def _install_requirements( # Always have the wheel package installed session.install("--progress-bar=off", "wheel", silent=PIP_INSTALL_SILENT) if install_coverage_requirements: - session.install( - "--progress-bar=off", COVERAGE_VERSION_REQUIREMENT, silent=PIP_INSTALL_SILENT - ) + session.install("--progress-bar=off", COVERAGE_REQUIREMENT, silent=PIP_INSTALL_SILENT) if install_salt: session.install("--progress-bar=off", SALT_REQUIREMENT, silent=PIP_INSTALL_SILENT) @@ -195,7 +193,7 @@ def tests(session): "-o", str(COVERAGE_REPORT_PROJECT), "--omit=tests/*", - "--include=src/saltext/saltext_apache/*", + "--include=src/saltext/apache/*", ) # Generate report for tests code coverage session.run( @@ -203,18 +201,16 @@ def tests(session): "xml", "-o", str(COVERAGE_REPORT_TESTS), - "--omit=src/saltext/saltext_apache/*", + "--omit=src/saltext/apache/*", "--include=tests/*", ) try: - session.run( - "coverage", "report", "--show-missing", "--include=src/saltext/saltext_apache/*" - ) + session.run("coverage", "report", "--show-missing", "--include=src/saltext/apache/*") # If you also want to display the code coverage report on the CLI # for the tests, comment the call above and uncomment the line below # session.run( # "coverage", "report", "--show-missing", - # "--include=src/saltext/saltext_apache/*,tests/*" + # "--include=src/saltext/apache/*,tests/*" # ) finally: # Move the coverage DB to artifacts/coverage in order for it to be archived by CI @@ -525,5 +521,5 @@ def gen_api_docs(session): "-o", "docs/ref/", "src/saltext", - "src/saltext/saltext_apache/config/schemas", + "src/saltext/apache/config/schemas", ) diff --git a/pyproject.toml b/pyproject.toml index dfa9765..38a2586 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,153 @@ [build-system] -requires = ["setuptools>=50.3.2", "wheel", "setuptools-declarative-requirements", "setuptools_scm[toml]>=3.4"] +requires = [ + "wheel", + "setuptools>=50.3.2", + "setuptools_scm[toml]>=3.4", +] build-backend = "setuptools.build_meta" [tool.setuptools_scm] -write_to = "src/saltext/saltext_apache/version.py" +write_to = "src/saltext/apache/version.py" write_to_template = "__version__ = \"{version}\"" +[project] +name = "saltext.apache" +description = "Salt Extension for interacting with Apache" +authors = [ + {name = "Salt Core Team", email = "saltproject@vmware.com"}, +] +keywords = [ + "salt-extension", +] +license = {text = "Apache Software License"} +classifiers = [ + "Programming Language :: Python", + "Programming Language :: Cython", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "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", + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", +] +requires-python = ">= 3.8" +dynamic = ["version"] +dependencies = [ + "salt>=3006", +] + +[project.readme] +file = "README.md" +content-type = "text/markdown" + +[project.urls] +Homepage = "https://github.com/salt-extensions/saltext-apache" +Documentation = "https://salt-extensions.github.io/saltext-apache/" +Source = "https://github.com/salt-extensions/saltext-apache" +Tracker = "https://github.com/salt-extensions/saltext-apache/issues" + +[project.optional-dependencies] +changelog = ["towncrier==22.12.0"] +dev = [ + "nox", + "pre-commit>=2.4.0", + "pylint", + "saltpylint", +] +docs = [ + "sphinx", + "sphinx-prompt", + "sphinxcontrib-spelling", + "sphinx-copybutton", + "towncrier==22.12.0", + "sphinxcontrib-towncrier", + "myst_parser", + "furo", + "sphinx-inline-tabs", +] +docsauto = ["sphinx-autobuild"] +lint = [ + "pylint", + "saltpylint", +] +tests = [ + "pytest>=7.2.0", + "pytest-salt-factories>=1.0.0", +] + +[project.entry-points."salt.loader"] +"saltext.apache" = "saltext.apache" + +[tool.setuptools] +zip-safe = false +include-package-data = true +platforms = ["any"] + +[tool.setuptools.packages.find] +where = ["src"] +exclude = ["tests"] + +[tool.distutils.bdist_wheel] +# Use this option if your package is pure-python +universal = 1 + +[tool.distutils.sdist] +owner = "root" +group = "root" + +[tool.build_sphinx] +source_dir = "docs" +build_dir = "build/sphinx" + [tool.black] line-length = 100 + +[tool.isort] +force_single_line = true +skip = ["src/saltext/apache/__init__.py"] +profile = "black" +line_length = 100 + +[tool.towncrier] +package = "saltext.apache" +filename = "CHANGELOG.md" +template = "changelog/.template.jinja" +directory = "changelog/" +start_string = "# Changelog\n" +underlines = ["", "", ""] +title_format = "## {version} ({project_date})" +issue_format = "[#{issue}](https://github.com/salt-extensions/saltext-apache/issues/{issue})" + +[[tool.towncrier.type]] +directory = "removed" +name = "Removed" +showcontent = true + +[[tool.towncrier.type]] +directory = "deprecated" +name = "Deprecated" +showcontent = true + +[[tool.towncrier.type]] +directory = "changed" +name = "Changed" +showcontent = true + +[[tool.towncrier.type]] +directory = "fixed" +name = "Fixed" +showcontent = true + +[[tool.towncrier.type]] +directory = "added" +name = "Added" +showcontent = true + +[[tool.towncrier.type]] +directory = "security" +name = "Security" +showcontent = true diff --git a/requirements/changelog.txt b/requirements/changelog.txt deleted file mode 100644 index fe1c872..0000000 --- a/requirements/changelog.txt +++ /dev/null @@ -1 +0,0 @@ -towncrier==21.9.0rc1 diff --git a/requirements/dev.txt b/requirements/dev.txt deleted file mode 100644 index e26ef85..0000000 --- a/requirements/dev.txt +++ /dev/null @@ -1,4 +0,0 @@ --r base.txt -nox==2021.6.12 -pre-commit==2.13.0 -pylint diff --git a/requirements/docs-auto.txt b/requirements/docs-auto.txt deleted file mode 100644 index 231419d..0000000 --- a/requirements/docs-auto.txt +++ /dev/null @@ -1 +0,0 @@ -sphinx-autobuild diff --git a/requirements/docs.txt b/requirements/docs.txt deleted file mode 100644 index a9debea..0000000 --- a/requirements/docs.txt +++ /dev/null @@ -1,9 +0,0 @@ --r base.txt --r changelog.txt -sphinx -furo -sphinx-copybutton -sphinx-prompt -sphinxcontrib-spelling -importlib_metadata; python_version < "3.8" -pyyaml diff --git a/requirements/tests.txt b/requirements/tests.txt deleted file mode 100644 index be9128b..0000000 --- a/requirements/tests.txt +++ /dev/null @@ -1,15 +0,0 @@ --r base.txt -mock >= 3.0.0 -# PyTest -pytest >= 7.0.1; python_version <= "3.6" -pytest >= 7.2.0; python_version > "3.6" -pytest-salt-factories >= 1.0.0rc21; sys_platform == 'win32' -pytest-salt-factories[docker] >= 1.0.0rc21; sys_platform != 'win32' -pytest-tempdir >= 2019.10.12 -pytest-helpers-namespace >= 2019.1.8 -pytest-subtests -pytest-timeout -pytest-httpserver -pytest-custom-exit-code >= 0.3 -flaky -markupsafe==2.0.1 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 31211d4..0000000 --- a/setup.cfg +++ /dev/null @@ -1,79 +0,0 @@ -[metadata] -name = saltext.saltext-apache -description = Salt Extension for interacting with Apache -long_description = file: README.md -long_description_content_type = text/markdown -author = Salt Core Team -author_email = saltproject@vmware.com -keywords = salt-extension -url = https://github.com/salt-extensions/saltext-apache -project_urls = - Source=https://github.com/salt-extensions/saltext-apache - Tracker=https://github.com/salt-extensions/saltext-apache/issues -license = Apache Software License -classifiers = - Programming Language :: Python - Programming Language :: Cython - Programming Language :: Python :: 3 - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.5 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Development Status :: 4 - Beta - Intended Audience :: Developers - License :: OSI Approved :: Apache Software License -platforms = any - -[options] -zip_safe = False -include_package_data = True -package_dir = - =src -packages = find_namespace: -python_requires = >= 3.5 -setup_requires = - wheel - setuptools>=50.3.2 - setuptools_scm[toml]>=3.4 - setuptools-declarative-requirements -install_requires = - salt>=3003 - # Add other module install requirements above this line - -[options.packages.find] -where = src -exclude = - tests - -# When targetting Salt < 3003, you can remove the other 'options.entry_points' section and use this one -#[options.entry_points] -#salt.loader= -# - -[options.entry_points] -salt.loader= - saltext.saltext-apache = saltext.saltext_apache - -[requirements-files] -install_requires = requirements/base.txt -tests_require = requirements/tests.txt -extras_require = - dev = requirements/dev.txt - tests = requirements/tests.txt - docs = requirements/docs.txt - docsauto = requirements/docs-auto.txt - changelog = requirements/changelog.txt - -[bdist_wheel] -# Use this option if your package is pure-python -universal = 1 - -[build_sphinx] -source_dir = docs -build_dir = build/sphinx - -[sdist] -owner = root -group = root diff --git a/src/saltext/saltext_apache/__init__.py b/src/saltext/apache/__init__.py similarity index 100% rename from src/saltext/saltext_apache/__init__.py rename to src/saltext/apache/__init__.py diff --git a/tests/pytests/unit/__init__.py b/src/saltext/apache/modules/__init__.py similarity index 100% rename from tests/pytests/unit/__init__.py rename to src/saltext/apache/modules/__init__.py diff --git a/src/saltext/saltext_apache/modules/apache.py b/src/saltext/apache/modules/apache.py similarity index 97% rename from src/saltext/saltext_apache/modules/apache.py rename to src/saltext/apache/modules/apache.py index c79bf46..0425528 100644 --- a/src/saltext/saltext_apache/modules/apache.py +++ b/src/saltext/apache/modules/apache.py @@ -7,6 +7,7 @@ deb_apache.py, but will still load under the ``apache`` namespace when a Debian-based system is detected. """ + import io import logging import re @@ -381,6 +382,7 @@ def _parse_config(conf, slot=None): print(f"{conf}", file=ret, end="") elif isinstance(conf, list): is_section = False + slot_this = None for item in conf: if "this" in item: is_section = True @@ -397,12 +399,12 @@ def _parse_config(conf, slot=None): print(_parse_config(value, str(slot)), file=ret) elif isinstance(conf, dict): try: - print("<{} {}>".format(slot, conf["this"]), file=ret) - except KeyError: + print(f"<{slot} {conf['this']}>", file=ret) + except KeyError as err: raise SaltException( - 'Apache section container "<{}>" expects attribute. ' - 'Specify it using key "this".'.format(slot) - ) + f'Apache section container "<{slot}>" expects attribute. ' + 'Specify it using key "this".' + ) from err for key, value in conf.items(): if key != "this": if isinstance(value, str): diff --git a/src/saltext/saltext_apache/modules/deb_apache.py b/src/saltext/apache/modules/deb_apache.py similarity index 99% rename from src/saltext/saltext_apache/modules/deb_apache.py rename to src/saltext/apache/modules/deb_apache.py index 54e7291..ce257fd 100644 --- a/src/saltext/saltext_apache/modules/deb_apache.py +++ b/src/saltext/apache/modules/deb_apache.py @@ -5,6 +5,7 @@ separate file will allow them to load only on Debian-based systems, while still loading under the ``apache`` namespace. """ + import logging import os diff --git a/src/saltext/saltext_apache/modules/suse_apache.py b/src/saltext/apache/modules/suse_apache.py similarity index 99% rename from src/saltext/saltext_apache/modules/suse_apache.py rename to src/saltext/apache/modules/suse_apache.py index c800cd0..5501fa2 100644 --- a/src/saltext/saltext_apache/modules/suse_apache.py +++ b/src/saltext/apache/modules/suse_apache.py @@ -5,6 +5,7 @@ separate file will allow them to load only on SUSE systems, while still loading under the ``apache`` namespace. """ + import logging import salt.utils.path diff --git a/tests/pytests/unit/modules/__init__.py b/src/saltext/apache/states/__init__.py similarity index 100% rename from tests/pytests/unit/modules/__init__.py rename to src/saltext/apache/states/__init__.py diff --git a/src/saltext/saltext_apache/states/apache.py b/src/saltext/apache/states/apache.py similarity index 99% rename from src/saltext/saltext_apache/states/apache.py rename to src/saltext/apache/states/apache.py index 375abb1..60ed48f 100644 --- a/src/saltext/saltext_apache/states/apache.py +++ b/src/saltext/apache/states/apache.py @@ -83,6 +83,7 @@ this: "\b" do: another thing """ + import os import salt.utils.files diff --git a/src/saltext/saltext_apache/states/apache_conf.py b/src/saltext/apache/states/apache_conf.py similarity index 99% rename from src/saltext/saltext_apache/states/apache_conf.py rename to src/saltext/apache/states/apache_conf.py index 24ad155..bda2eee 100644 --- a/src/saltext/saltext_apache/states/apache_conf.py +++ b/src/saltext/apache/states/apache_conf.py @@ -15,6 +15,7 @@ apache_conf.disabled: - name: security """ + import salt.utils.path diff --git a/src/saltext/saltext_apache/states/apache_module.py b/src/saltext/apache/states/apache_module.py similarity index 100% rename from src/saltext/saltext_apache/states/apache_module.py rename to src/saltext/apache/states/apache_module.py diff --git a/src/saltext/saltext_apache/states/apache_site.py b/src/saltext/apache/states/apache_site.py similarity index 100% rename from src/saltext/saltext_apache/states/apache_site.py rename to src/saltext/apache/states/apache_site.py diff --git a/src/saltext/saltext_apache/loader.py b/src/saltext/saltext_apache/loader.py deleted file mode 100644 index 5d2e0b6..0000000 --- a/src/saltext/saltext_apache/loader.py +++ /dev/null @@ -1,5 +0,0 @@ -""" -Define the required entry-points functions in order for Salt to know -what and from where it should load this extension's loaders -""" -from . import PACKAGE_ROOT # pylint: disable=unused-import diff --git a/src/saltext/saltext_apache/modules/__init__.py b/src/saltext/saltext_apache/modules/__init__.py deleted file mode 100644 index 95433ea..0000000 --- a/src/saltext/saltext_apache/modules/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -Execution Module Directory -""" diff --git a/src/saltext/saltext_apache/states/__init__.py b/src/saltext/saltext_apache/states/__init__.py deleted file mode 100644 index a3d87d2..0000000 --- a/src/saltext/saltext_apache/states/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -States Directory -""" diff --git a/tests/conftest.py b/tests/conftest.py index 4da6367..c675b79 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,18 +1,29 @@ +import logging import os import pytest -from saltext.saltext_apache import PACKAGE_ROOT from saltfactories.utils import random_string +from saltext.apache import PACKAGE_ROOT + +# Reset the root logger to its default level(because salt changed it) +logging.root.setLevel(logging.WARNING) + + +# This swallows all logging to stdout. +# To show select logs, set --log-cli-level= +for handler in logging.root.handlers[:]: + logging.root.removeHandler(handler) + handler.close() + @pytest.fixture(scope="session") def salt_factories_config(): """ - Return a dictionary with the keyworkd arguments for FactoriesManager + Return a dictionary with the keyword arguments for FactoriesManager """ return { "code_dir": str(PACKAGE_ROOT), - "inject_coverage": "COVERAGE_PROCESS_START" in os.environ, "inject_sitecustomize": "COVERAGE_PROCESS_START" in os.environ, "start_timeout": 120 if os.environ.get("CI") else 60, } diff --git a/tests/pytests/unit/states/__init__.py b/tests/functional/__init__.py similarity index 100% rename from tests/pytests/unit/states/__init__.py rename to tests/functional/__init__.py diff --git a/tests/pytests/functional/conftest.py b/tests/functional/conftest.py similarity index 91% rename from tests/pytests/functional/conftest.py rename to tests/functional/conftest.py index 2fb2246..2c7c84a 100644 --- a/tests/pytests/functional/conftest.py +++ b/tests/functional/conftest.py @@ -33,8 +33,8 @@ def state_tree_prod(tmp_path_factory): @pytest.fixture(scope="module") def minion_config_defaults(): """ - Functional test modules can provide this fixture to tweak the default configuration dictionary - passed to the minion factory + Functional test modules can provide this fixture to tweak the default + configuration dictionary passed to the minion factory """ return {} @@ -81,8 +81,8 @@ def minion_opts( @pytest.fixture(scope="module") def master_config_defaults(): """ - Functional test modules can provide this fixture to tweak the default configuration dictionary - passed to the master factory + Functional test modules can provide this fixture to tweak the default + configuration dictionary passed to the master factory """ return {} @@ -138,3 +138,13 @@ def reset_loaders_state(loaders): finally: # Reset the loaders state loaders.reset_state() + + +@pytest.fixture(scope="module") +def modules(loaders): + return loaders.modules + + +@pytest.fixture(scope="module") +def states(loaders): + return loaders.states diff --git a/tests/pytests/unit/states/apache/__init__.py b/tests/functional/modules/__init__.py similarity index 100% rename from tests/pytests/unit/states/apache/__init__.py rename to tests/functional/modules/__init__.py diff --git a/docs/ref/.gitkeep b/tests/functional/states/__init__.py similarity index 100% rename from docs/ref/.gitkeep rename to tests/functional/states/__init__.py diff --git a/requirements/base.txt b/tests/integration/modules/__init__.py similarity index 100% rename from requirements/base.txt rename to tests/integration/modules/__init__.py diff --git a/tests/integration/states/__init__.py b/tests/integration/states/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/pytests/integration/conftest.py b/tests/pytests/integration/conftest.py deleted file mode 100644 index ed1c25a..0000000 --- a/tests/pytests/integration/conftest.py +++ /dev/null @@ -1,108 +0,0 @@ -""" - tests.pytests.integration.conftest - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - PyTest fixtures -""" -import logging - -import pytest - -log = logging.getLogger(__name__) - - -@pytest.fixture(scope="package") -def salt_master(salt_master_factory): - """ - A running salt-master fixture - """ - with salt_master_factory.started(): - yield salt_master_factory - - -@pytest.fixture(scope="package") -def salt_minion(salt_master, salt_minion_factory): - """ - A running salt-minion fixture - """ - assert salt_master.is_running() - with salt_minion_factory.started(): - # Sync All - salt_call_cli = salt_minion_factory.salt_call_cli() - ret = salt_call_cli.run("saltutil.sync_all", _timeout=120) - assert ret.returncode == 0, ret - yield salt_minion_factory - - -@pytest.fixture(scope="module") -def salt_sub_minion(salt_master, salt_sub_minion_factory): - """ - A second running salt-minion fixture - """ - assert salt_master.is_running() - with salt_sub_minion_factory.started(): - # Sync All - salt_call_cli = salt_sub_minion_factory.salt_call_cli() - ret = salt_call_cli.run("saltutil.sync_all", _timeout=120) - assert ret.returncode == 0, ret - yield salt_sub_minion_factory - - -@pytest.fixture(scope="package") -def salt_cli(salt_master): - """ - The ``salt`` CLI as a fixture against the running master - """ - assert salt_master.is_running() - return salt_master.salt_cli(timeout=30) - - -@pytest.fixture(scope="package") -def salt_call_cli(salt_minion): - """ - The ``salt-call`` CLI as a fixture against the running minion - """ - assert salt_minion.is_running() - return salt_minion.salt_call_cli(timeout=30) - - -@pytest.fixture(scope="package") -def salt_cp_cli(salt_master): - """ - The ``salt-cp`` CLI as a fixture against the running master - """ - assert salt_master.is_running() - return salt_master.salt_cp_cli(timeout=30) - - -@pytest.fixture(scope="package") -def salt_key_cli(salt_master): - """ - The ``salt-key`` CLI as a fixture against the running master - """ - assert salt_master.is_running() - return salt_master.salt_key_cli(timeout=30) - - -@pytest.fixture(scope="package") -def salt_run_cli(salt_master): - """ - The ``salt-run`` CLI as a fixture against the running master - """ - assert salt_master.is_running() - return salt_master.salt_run_cli(timeout=30) - - -@pytest.fixture(scope="module") -def salt_ssh_cli(salt_master, salt_ssh_roster_file, sshd_config_dir): - """ - The ``salt-ssh`` CLI as a fixture against the running master - """ - assert salt_master.is_running() - return salt_master.salt_ssh_cli( - timeout=180, - roster_file=salt_ssh_roster_file, - target_host="localhost", - client_key=str(sshd_config_dir / "client_key"), - base_script_args=["--ignore-host-keys"], - ) diff --git a/tests/pytests/unit/conftest.py b/tests/unit/conftest.py similarity index 52% rename from tests/pytests/unit/conftest.py rename to tests/unit/conftest.py index 0ad0fe3..b3b6ced 100644 --- a/tests/pytests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -1,3 +1,5 @@ +import os + import pytest import salt.config @@ -5,7 +7,8 @@ @pytest.fixture def minion_opts(tmp_path): """ - Default minion configuration with relative temporary paths to not require root permissions. + Default minion configuration with relative temporary paths to not + require root permissions. """ root_dir = tmp_path / "minion" opts = salt.config.DEFAULT_MINION_OPTS.copy() @@ -16,16 +19,18 @@ def minion_opts(tmp_path): dirpath.mkdir(parents=True) opts[name] = str(dirpath) opts["log_file"] = "logs/minion.log" + opts["conf_file"] = os.path.join(opts["conf_dir"], "minion") return opts @pytest.fixture def master_opts(tmp_path): """ - Default master configuration with relative temporary paths to not require root permissions. + Default master configuration with relative temporary paths to not + require root permissions. """ root_dir = tmp_path / "master" - opts = salt.config.DEFAULT_MASTER_OPTS.copy() + opts = salt.config.master_config(None) opts["__role"] = "master" opts["root_dir"] = str(root_dir) for name in ("cachedir", "pki_dir", "sock_dir", "conf_dir"): @@ -33,4 +38,25 @@ def master_opts(tmp_path): dirpath.mkdir(parents=True) opts[name] = str(dirpath) opts["log_file"] = "logs/master.log" + opts["conf_file"] = os.path.join(opts["conf_dir"], "master") + return opts + + +@pytest.fixture +def syndic_opts(tmp_path): + """ + Default master configuration with relative temporary paths to not + require root permissions. + """ + root_dir = tmp_path / "syndic" + opts = salt.config.DEFAULT_MINION_OPTS.copy() + opts["syndic_master"] = "127.0.0.1" + opts["__role"] = "minion" + opts["root_dir"] = str(root_dir) + for name in ("cachedir", "pki_dir", "sock_dir", "conf_dir"): + dirpath = root_dir / name + dirpath.mkdir(parents=True) + opts[name] = str(dirpath) + opts["log_file"] = "logs/syndic.log" + opts["conf_file"] = os.path.join(opts["conf_dir"], "syndic") return opts diff --git a/tests/unit/modules/__init__.py b/tests/unit/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/pytests/unit/modules/test_apache.py b/tests/unit/modules/test_apache.py similarity index 87% rename from tests/pytests/unit/modules/test_apache.py rename to tests/unit/modules/test_apache.py index db5c77c..16970c9 100644 --- a/tests/pytests/unit/modules/test_apache.py +++ b/tests/unit/modules/test_apache.py @@ -1,15 +1,17 @@ """ :codeauthor: Jayesh Kariya """ + import urllib.error from unittest.mock import MagicMock from unittest.mock import mock_open from unittest.mock import patch import pytest -import saltext.saltext_apache.modules.apache as apache from salt.utils.odict import OrderedDict +from saltext.apache.modules import apache + @pytest.fixture def configure_loader_modules(): @@ -23,9 +25,7 @@ def test_version(): """ Test if return server version (``apachectl -v``) """ - with patch( - "saltext.saltext_apache.modules.apache._detect_os", MagicMock(return_value="apachectl") - ): + with patch("saltext.apache.modules.apache._detect_os", MagicMock(return_value="apachectl")): mock = MagicMock(return_value="Server version: Apache/2.4.7") with patch.dict(apache.__salt__, {"cmd.run": mock}): assert apache.version() == "Apache/2.4.7" @@ -38,9 +38,7 @@ def test_fullversion(): """ Test if return server version (``apachectl -V``) """ - with patch( - "saltext.saltext_apache.modules.apache._detect_os", MagicMock(return_value="apachectl") - ): + with patch("saltext.apache.modules.apache._detect_os", MagicMock(return_value="apachectl")): mock = MagicMock(return_value="Server version: Apache/2.4.7") with patch.dict(apache.__salt__, {"cmd.run": mock}): assert apache.fullversion() == { @@ -56,9 +54,7 @@ def test_modules(): """ Test if return list of static and shared modules """ - with patch( - "saltext.saltext_apache.modules.apache._detect_os", MagicMock(return_value="apachectl") - ): + with patch("saltext.apache.modules.apache._detect_os", MagicMock(return_value="apachectl")): mock = MagicMock( return_value=( "unixd_module (static)\n " @@ -79,9 +75,7 @@ def test_servermods(): """ Test if return list of modules compiled into the server """ - with patch( - "saltext.saltext_apache.modules.apache._detect_os", MagicMock(return_value="apachectl") - ): + with patch("saltext.apache.modules.apache._detect_os", MagicMock(return_value="apachectl")): mock = MagicMock(return_value="core.c\nmod_so.c") with patch.dict(apache.__salt__, {"cmd.run": mock}): assert apache.servermods() == ["core.c", "mod_so.c"] @@ -94,9 +88,7 @@ def test_directives(): """ Test if return list of directives """ - with patch( - "saltext.saltext_apache.modules.apache._detect_os", MagicMock(return_value="apachectl") - ): + with patch("saltext.apache.modules.apache._detect_os", MagicMock(return_value="apachectl")): mock = MagicMock(return_value="Salt") with patch.dict(apache.__salt__, {"cmd.run": mock}): assert apache.directives() == {"Salt": ""} @@ -109,9 +101,7 @@ def test_vhosts(): """ Test if it shows the virtualhost settings """ - with patch( - "saltext.saltext_apache.modules.apache._detect_os", MagicMock(return_value="apachectl") - ): + with patch("saltext.apache.modules.apache._detect_os", MagicMock(return_value="apachectl")): mock = MagicMock(return_value="") with patch.dict(apache.__salt__, {"cmd.run": mock}): assert not apache.vhosts() @@ -124,9 +114,7 @@ def test_signal(): """ Test if return no signal for httpd """ - with patch( - "saltext.saltext_apache.modules.apache._detect_os", MagicMock(return_value="apachectl") - ): + with patch("saltext.apache.modules.apache._detect_os", MagicMock(return_value="apachectl")): mock = MagicMock(return_value="") with patch.dict(apache.__salt__, {"cmd.run": mock}): assert apache.signal(None) is None @@ -136,9 +124,7 @@ def test_signal_args(): """ Test if return httpd signal to start, restart, or stop. """ - with patch( - "saltext.saltext_apache.modules.apache._detect_os", MagicMock(return_value="apachectl") - ): + with patch("saltext.apache.modules.apache._detect_os", MagicMock(return_value="apachectl")): ret = 'Command: "apachectl -k start" completed successfully!' mock = MagicMock(return_value={"retcode": 1, "stderr": "", "stdout": ""}) with patch.dict(apache.__salt__, {"cmd.run_all": mock}): @@ -188,7 +174,7 @@ def test_server_status(): """ Test if return get information from the Apache server-status """ - with patch("saltext.saltext_apache.modules.apache.server_status", MagicMock(return_value={})): + with patch("saltext.apache.modules.apache.server_status", MagicMock(return_value={})): mock = MagicMock(return_value="") with patch.dict(apache.__salt__, {"config.get": mock}): assert apache.server_status() == {} @@ -212,9 +198,7 @@ def test_config(): """ Test if it create VirtualHost configuration files """ - with patch( - "saltext.saltext_apache.modules.apache._parse_config", MagicMock(return_value="Listen 22") - ): + with patch("saltext.apache.modules.apache._parse_config", MagicMock(return_value="Listen 22")): with patch("salt.utils.files.fopen", mock_open()): assert apache.config("/ports.conf", [{"Listen": "22"}]) == "Listen 22" diff --git a/tests/pytests/unit/modules/test_deb_apache.py b/tests/unit/modules/test_deb_apache.py similarity index 99% rename from tests/pytests/unit/modules/test_deb_apache.py rename to tests/unit/modules/test_deb_apache.py index f9bd7db..36259dc 100644 --- a/tests/pytests/unit/modules/test_deb_apache.py +++ b/tests/unit/modules/test_deb_apache.py @@ -1,11 +1,13 @@ """ :codeauthor: Jayesh Kariya """ + from unittest.mock import MagicMock from unittest.mock import patch import pytest -import salt.modules.deb_apache as deb_apache + +from saltext.apache.modules import deb_apache @pytest.fixture diff --git a/tests/unit/states/__init__.py b/tests/unit/states/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/pytests/unit/states/apache/test_apache.py b/tests/unit/states/test_apache.py similarity index 97% rename from tests/pytests/unit/states/apache/test_apache.py rename to tests/unit/states/test_apache.py index f3a6513..6731379 100644 --- a/tests/pytests/unit/states/apache/test_apache.py +++ b/tests/unit/states/test_apache.py @@ -1,13 +1,15 @@ """ :codeauthor: Jayesh Kariya """ + from unittest.mock import MagicMock from unittest.mock import mock_open from unittest.mock import patch import pytest import salt.utils.files -import saltext.saltext_apache.states.apache as apache + +from saltext.apache.states import apache @pytest.fixture diff --git a/tests/pytests/unit/states/apache/test_conf.py b/tests/unit/states/test_conf.py similarity index 97% rename from tests/pytests/unit/states/apache/test_conf.py rename to tests/unit/states/test_conf.py index 8f8f82c..73b7360 100644 --- a/tests/pytests/unit/states/apache/test_conf.py +++ b/tests/unit/states/test_conf.py @@ -2,7 +2,8 @@ from unittest.mock import patch import pytest -import saltext.saltext_apache.states.apache_conf as apache_conf + +from saltext.apache.states import apache_conf @pytest.fixture diff --git a/tests/pytests/unit/states/apache/test_module.py b/tests/unit/states/test_module.py similarity index 97% rename from tests/pytests/unit/states/apache/test_module.py rename to tests/unit/states/test_module.py index eadeff1..5fb026e 100644 --- a/tests/pytests/unit/states/apache/test_module.py +++ b/tests/unit/states/test_module.py @@ -1,11 +1,13 @@ """ :codeauthor: Jayesh Kariya """ + from unittest.mock import MagicMock from unittest.mock import patch import pytest -import saltext.saltext_apache.states.apache_module as apache_module + +from saltext.apache.states import apache_module @pytest.fixture diff --git a/tests/pytests/unit/states/apache/test_site.py b/tests/unit/states/test_site.py similarity index 97% rename from tests/pytests/unit/states/apache/test_site.py rename to tests/unit/states/test_site.py index fac553e..e22a3cb 100644 --- a/tests/pytests/unit/states/apache/test_site.py +++ b/tests/unit/states/test_site.py @@ -2,7 +2,8 @@ from unittest.mock import patch import pytest -import saltext.saltext_apache.states.apache_site as apache_site + +from saltext.apache.states import apache_site @pytest.fixture