new accounts puppet module for newer distros

This commit is contained in:
Z. Cliffe Schreuders
2022-07-29 12:30:21 +01:00
parent eb59300b38
commit f4b3bd7ebf
131 changed files with 6844 additions and 18 deletions

View File

@@ -34,7 +34,7 @@
<requires>
<module_path>utilities/unix/system/accounts</module_path>
<module_path>utilities/unix/system/.*/accounts</module_path>
</requires>
</service>

View File

@@ -42,7 +42,7 @@
<module_path>.*docker</module_path>
</requires>
<requires>
<module_path>utilities/unix/system/accounts</module_path>
<module_path>utilities/unix/system/.*/accounts</module_path>
</requires>
<requires>

View File

@@ -50,7 +50,7 @@
<module_path>.*docker</module_path>
</requires> -->
<!-- <requires>
<module_path>utilities/unix/system/accounts</module_path>
<module_path>utilities/unix/system/.*/accounts</module_path>
</requires> -->
<requires>

View File

@@ -16,4 +16,10 @@
<!--optional details-->
<reference>https://forge.puppet.com/puppetlabs/accounts</reference>
<conflict>
<module_path>.*/bases/.*kali.*</name>
</conflict>
<conflict>
<module_path>.*/bases/.*buster.*</name>
</conflict>
</utility>

View File

@@ -0,0 +1,6 @@
FROM puppet/pdk:latest
# [Optional] Uncomment this section to install additional packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>

View File

@@ -0,0 +1,34 @@
# devcontainer
For format details, see https://aka.ms/devcontainer.json.
For config options, see the README at:
https://github.com/microsoft/vscode-dev-containers/tree/v0.140.1/containers/puppet
``` json
{
"name": "Puppet Development Kit (Community)",
"dockerFile": "Dockerfile",
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"puppet.puppet-vscode",
"rebornix.Ruby"
]
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pdk --version",
}
```

View File

@@ -0,0 +1,17 @@
{
"name": "Puppet Development Kit (Community)",
"dockerFile": "Dockerfile",
"settings": {
"terminal.integrated.profiles.linux": {
"bash": {
"path": "bash",
}
}
},
"extensions": [
"puppet.puppet-vscode",
"rebornix.Ruby"
]
}

View File

@@ -0,0 +1,13 @@
fixtures:
repositories:
sshkeys_core:
repo: 'https://github.com/puppetlabs/puppetlabs-sshkeys_core'
puppet_version: '>= 6.0.0'
stdlib:
repo: 'https://github.com/puppetlabs/puppetlabs-stdlib.git'
ref: '5.0.0'
facts: 'https://github.com/puppetlabs/puppetlabs-facts.git'
puppet_agent: 'https://github.com/puppetlabs/puppetlabs-puppet_agent.git'
provision: 'https://github.com/puppetlabs/provision.git'
symlinks:
accounts: "#{source_dir}"

View File

@@ -0,0 +1,6 @@
*.rb eol=lf
*.erb eol=lf
*.pp eol=lf
*.sh eol=lf
*.epp eol=lf
files/shell/* eol=lf

View File

@@ -0,0 +1,90 @@
name: "Auto release"
on:
workflow_dispatch:
env:
HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6
HONEYCOMB_DATASET: litmus tests
CHANGELOG_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
auto_release:
name: "Automatic release prep"
runs-on: ubuntu-20.04
steps:
- name: "Honeycomb: Start recording"
uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
with:
apikey: ${{ env.HONEYCOMB_WRITEKEY }}
dataset: ${{ env.HONEYCOMB_DATASET }}
job-status: ${{ job.status }}
- name: "Honeycomb: start first step"
run: |
echo STEP_ID="auto-release" >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: "Checkout Source"
if: ${{ github.repository_owner == 'puppetlabs' }}
uses: actions/checkout@v2
with:
fetch-depth: 0
persist-credentials: false
- name: "PDK Release prep"
uses: docker://puppet/iac_release:ci
with:
args: 'release prep --force'
env:
CHANGELOG_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Get Version"
if: ${{ github.repository_owner == 'puppetlabs' }}
id: gv
run: |
echo "::set-output name=ver::$(jq --raw-output .version metadata.json)"
- name: "Check if a release is necessary"
if: ${{ github.repository_owner == 'puppetlabs' }}
id: check
run: |
git diff --quiet CHANGELOG.md && echo "::set-output name=release::false" || echo "::set-output name=release::true"
- name: "Commit changes"
if: ${{ github.repository_owner == 'puppetlabs' && steps.check.outputs.release == 'true' }}
run: |
git config --local user.email "${{ github.repository_owner }}@users.noreply.github.com"
git config --local user.name "GitHub Action"
git add .
git commit -m "Release prep v${{ steps.gv.outputs.ver }}"
- name: Create Pull Request
id: cpr
uses: puppetlabs/peter-evans-create-pull-request@v3
if: ${{ github.repository_owner == 'puppetlabs' && steps.check.outputs.release == 'true' }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "Release prep v${{ steps.gv.outputs.ver }}"
branch: "release-prep"
delete-branch: true
title: "Release prep v${{ steps.gv.outputs.ver }}"
body: |
Automated release-prep through [pdk-templates](https://github.com/puppetlabs/pdk-templates/blob/main/moduleroot/.github/workflows/auto_release.yml.erb) from commit ${{ github.sha }}.
Please verify before merging:
- [ ] last [nightly](https://github.com/${{ github.repository }}/actions/workflows/nightly.yml) run is green
- [ ] [Changelog](https://github.com/${{ github.repository }}/blob/release-prep/CHANGELOG.md) is readable and has no unlabeled pull requests
- [ ] Ensure the [changelog](https://github.com/${{ github.repository }}/blob/release-prep/CHANGELOG.md) version and [metadata](https://github.com/${{ github.repository }}/blob/release-prep/metadata.json) version match
labels: "maintenance"
- name: PR outputs
if: ${{ github.repository_owner == 'puppetlabs' && steps.check.outputs.release == 'true' }}
run: |
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
- name: "Honeycomb: Record finish step"
if: ${{ always() }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Finished auto release workflow'

View File

@@ -0,0 +1,22 @@
name: community-labeller
on:
issues:
types:
- opened
pull_request_target:
types:
- opened
jobs:
label:
runs-on: ubuntu-latest
steps:
- uses: puppetlabs/community-labeller@v0
name: Label issues or pull requests
with:
label_name: community
label_color: '5319e7'
org_membership: puppetlabs
token: ${{ secrets.IAC_COMMUNITY_LABELER }}

View File

@@ -0,0 +1,204 @@
name: "nightly"
on:
schedule:
- cron: '0 0 * * *'
env:
HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6
HONEYCOMB_DATASET: litmus tests
jobs:
setup_matrix:
if: ${{ github.repository_owner == 'puppetlabs' }}
name: "Setup Test Matrix"
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.get-matrix.outputs.matrix }}
steps:
- name: "Honeycomb: Start recording"
uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
with:
apikey: ${{ env.HONEYCOMB_WRITEKEY }}
dataset: ${{ env.HONEYCOMB_DATASET }}
job-status: ${{ job.status }}
- name: "Honeycomb: Start first step"
run: |
echo STEP_ID=setup-environment >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Checkout Source
uses: actions/checkout@v2
if: ${{ github.repository_owner == 'puppetlabs' }}
- name: Activate Ruby 2.7
uses: ruby/setup-ruby@v1
if: ${{ github.repository_owner == 'puppetlabs' }}
with:
ruby-version: "2.7"
bundler-cache: true
- name: Print bundle environment
if: ${{ github.repository_owner == 'puppetlabs' }}
run: |
echo ::group::bundler environment
buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
echo ::endgroup::
- name: "Honeycomb: Record Setup Environment time"
if: ${{ github.repository_owner == 'puppetlabs' }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Environment'
echo STEP_ID=Setup-Acceptance-Test-Matrix >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Setup Acceptance Test Matrix
id: get-matrix
if: ${{ github.repository_owner == 'puppetlabs' }}
run: |
if [ '${{ github.repository_owner }}' == 'puppetlabs' ]; then
buildevents cmd $TRACE_ID $STEP_ID matrix_from_metadata -- bundle exec matrix_from_metadata_v2
else
echo "::set-output name=matrix::{}"
fi
- name: "Honeycomb: Record Setup Test Matrix time"
if: ${{ always() }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Test Matrix'
Acceptance:
name: "${{matrix.platforms.label}}, ${{matrix.collection}}"
needs:
- setup_matrix
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix: ${{fromJson(needs.setup_matrix.outputs.matrix)}}
env:
BUILDEVENT_FILE: '../buildevents.txt'
steps:
- run: |
echo 'platform=${{ matrix.platforms.image }}' >> $BUILDEVENT_FILE
echo 'collection=${{ matrix.collection }}' >> $BUILDEVENT_FILE
echo 'label=${{ matrix.platforms.label }}' >> $BUILDEVENT_FILE
- name: "Honeycomb: Start recording"
uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
with:
apikey: ${{ env.HONEYCOMB_WRITEKEY }}
dataset: ${{ env.HONEYCOMB_DATASET }}
job-status: ${{ job.status }}
matrix-key: ${{ matrix.platforms.label }}-${{ matrix.collection }}
- name: "Honeycomb: start first step"
run: |
echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-1 >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Checkout Source
uses: actions/checkout@v2
- name: Activate Ruby 2.7
uses: ruby/setup-ruby@v1
with:
ruby-version: "2.7"
bundler-cache: true
- name: Print bundle environment
run: |
echo ::group::bundler environment
buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
echo ::endgroup::
- name: "Honeycomb: Record Setup Environment time"
if: ${{ always() }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Environment'
echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-2 >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Provision test environment
run: |
buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:provision ${{ matrix.platforms.image }}' -- bundle exec rake 'litmus:provision[${{matrix.platforms.provider}},${{ matrix.platforms.image }}]'
echo ::group::=== REQUEST ===
cat request.json || true
echo
echo ::endgroup::
echo ::group::=== INVENTORY ===
if [ -f 'spec/fixtures/litmus_inventory.yaml' ];
then
FILE='spec/fixtures/litmus_inventory.yaml'
elif [ -f 'inventory.yaml' ];
then
FILE='inventory.yaml'
fi
sed -e 's/password: .*/password: "[redacted]"/' < $FILE || true
echo ::endgroup::
- name: Install agent
run: |
buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:install_agent ${{ matrix.collection }}' -- bundle exec rake 'litmus:install_agent[${{ matrix.collection }}]'
- name: Install module
run: |
buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:install_module' -- bundle exec rake 'litmus:install_module'
- name: "Honeycomb: Record deployment times"
if: ${{ always() }}
run: |
echo ::group::honeycomb step
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Deploy test system'
echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-3 >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
echo ::endgroup::
- name: Run acceptance tests
run: |
buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:acceptance:parallel' -- bundle exec rake 'litmus:acceptance:parallel'
- name: "Honeycomb: Record acceptance testing times"
if: ${{ always() }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Run acceptance tests'
echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-4 >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Remove test environment
if: ${{ always() }}
continue-on-error: true
run: |
if [[ -f inventory.yaml || -f spec/fixtures/litmus_inventory.yaml ]]; then
buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:tear_down' -- bundle exec rake 'litmus:tear_down'
echo ::group::=== REQUEST ===
cat request.json || true
echo
echo ::endgroup::
fi
- name: "Honeycomb: Record removal times"
if: ${{ always() }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Remove test environment'
slack-workflow-status:
if: ${{ github.repository_owner == 'puppetlabs' }}
name: Post Workflow Status To Slack
needs:
- Acceptance
runs-on: ubuntu-20.04
steps:
- name: Slack Workflow Notification
uses: puppetlabs/Gamesight-slack-workflow-status@pdk-templates-v1
with:
# Required Input
repo_token: ${{ secrets.GITHUB_TOKEN }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK }}
# Optional Input
channel: '#team-cat-bots'
name: 'GABot'

View File

@@ -0,0 +1,185 @@
name: "PR Testing"
on: [pull_request]
env:
HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6
HONEYCOMB_DATASET: litmus tests
jobs:
setup_matrix:
name: "Setup Test Matrix"
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.get-matrix.outputs.matrix }}
steps:
- name: "Honeycomb: Start recording"
uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
with:
apikey: ${{ env.HONEYCOMB_WRITEKEY }}
dataset: ${{ env.HONEYCOMB_DATASET }}
job-status: ${{ job.status }}
- name: "Honeycomb: Start first step"
run: |
echo STEP_ID=setup-environment >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Checkout Source
uses: actions/checkout@v2
if: ${{ github.repository_owner == 'puppetlabs' }}
- name: Activate Ruby 2.7
uses: ruby/setup-ruby@v1
if: ${{ github.repository_owner == 'puppetlabs' }}
with:
ruby-version: "2.7"
bundler-cache: true
- name: Print bundle environment
if: ${{ github.repository_owner == 'puppetlabs' }}
run: |
echo ::group::bundler environment
buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
echo ::endgroup::
- name: "Honeycomb: Record Setup Environment time"
if: ${{ github.repository_owner == 'puppetlabs' }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Environment'
echo STEP_ID=Setup-Acceptance-Test-Matrix >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Run validation steps
run: |
bundle exec rake validate
if: ${{ github.repository_owner == 'puppetlabs' }}
- name: Setup Acceptance Test Matrix
id: get-matrix
run: |
if [ '${{ github.repository_owner }}' == 'puppetlabs' ]; then
buildevents cmd $TRACE_ID $STEP_ID matrix_from_metadata -- bundle exec matrix_from_metadata_v2
else
echo "::set-output name=matrix::{}"
fi
- name: "Honeycomb: Record Setup Test Matrix time"
if: ${{ always() }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Test Matrix'
Acceptance:
name: "${{matrix.platforms.label}}, ${{matrix.collection}}"
needs:
- setup_matrix
if: ${{ needs.setup_matrix.outputs.matrix != '{}' }}
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix: ${{fromJson(needs.setup_matrix.outputs.matrix)}}
env:
BUILDEVENT_FILE: '../buildevents.txt'
steps:
- run: |
echo 'platform=${{ matrix.platforms.image }}' >> $BUILDEVENT_FILE
echo 'collection=${{ matrix.collection }}' >> $BUILDEVENT_FILE
echo 'label=${{ matrix.platforms.label }}' >> $BUILDEVENT_FILE
- name: "Honeycomb: Start recording"
uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
with:
apikey: ${{ env.HONEYCOMB_WRITEKEY }}
dataset: ${{ env.HONEYCOMB_DATASET }}
job-status: ${{ job.status }}
matrix-key: ${{ matrix.platforms.label }}-${{ matrix.collection }}
- name: "Honeycomb: start first step"
run: |
echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-1 >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Checkout Source
uses: actions/checkout@v2
- name: Activate Ruby 2.7
uses: ruby/setup-ruby@v1
with:
ruby-version: "2.7"
bundler-cache: true
- name: Print bundle environment
run: |
echo ::group::bundler environment
buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
echo ::endgroup::
- name: "Honeycomb: Record Setup Environment time"
if: ${{ always() }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Environment'
echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-2 >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Provision test environment
run: |
buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:provision ${{ matrix.platforms.image }}' -- bundle exec rake 'litmus:provision[${{matrix.platforms.provider}},${{ matrix.platforms.image }}]'
echo ::group::=== REQUEST ===
cat request.json || true
echo
echo ::endgroup::
echo ::group::=== INVENTORY ===
if [ -f 'spec/fixtures/litmus_inventory.yaml' ];
then
FILE='spec/fixtures/litmus_inventory.yaml'
elif [ -f 'inventory.yaml' ];
then
FILE='inventory.yaml'
fi
sed -e 's/password: .*/password: "[redacted]"/' < $FILE || true
echo ::endgroup::
- name: Install agent
run: |
buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:install_agent ${{ matrix.collection }}' -- bundle exec rake 'litmus:install_agent[${{ matrix.collection }}]'
- name: Install module
run: |
buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:install_module' -- bundle exec rake 'litmus:install_module'
- name: "Honeycomb: Record deployment times"
if: ${{ always() }}
run: |
echo ::group::honeycomb step
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Deploy test system'
echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-3 >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
echo ::endgroup::
- name: Run acceptance tests
run: |
buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:acceptance:parallel' -- bundle exec rake 'litmus:acceptance:parallel'
- name: "Honeycomb: Record acceptance testing times"
if: ${{ always() }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Run acceptance tests'
echo STEP_ID=${{ matrix.platforms.image }}-${{ matrix.collection }}-4 >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Remove test environment
if: ${{ always() }}
continue-on-error: true
run: |
if [[ -f inventory.yaml || -f spec/fixtures/litmus_inventory.yaml ]]; then
buildevents cmd $TRACE_ID $STEP_ID 'rake litmus:tear_down' -- bundle exec rake 'litmus:tear_down'
echo ::group::=== REQUEST ===
cat request.json || true
echo
echo ::endgroup::
fi
- name: "Honeycomb: Record removal times"
if: ${{ always() }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Remove test environment'

View File

@@ -0,0 +1,47 @@
name: "Publish module"
on:
workflow_dispatch:
jobs:
create-github-release:
name: Deploy GitHub Release
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: ${{ github.ref }}
clean: true
fetch-depth: 0
- name: Get Version
id: gv
run: |
echo "::set-output name=ver::$(jq --raw-output .version metadata.json)"
- name: Create Release
uses: actions/create-release@v1
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: "v${{ steps.gv.outputs.ver }}"
draft: false
prerelease: false
deploy-forge:
name: Deploy to Forge
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: ${{ github.ref }}
clean: true
- name: "PDK Build"
uses: docker://puppet/pdk:nightly
with:
args: 'build'
- name: "Push to Forge"
uses: docker://puppet/pdk:nightly
with:
args: 'release publish --forge-token ${{ secrets.FORGE_API_KEY }} --force'

View File

@@ -0,0 +1,126 @@
name: "Spec Tests"
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
pull_request:
env:
HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6
HONEYCOMB_DATASET: litmus tests
jobs:
setup_matrix:
name: "Setup Test Matrix"
runs-on: ubuntu-20.04
outputs:
spec_matrix: ${{ steps.get-matrix.outputs.spec_matrix }}
steps:
- name: "Honeycomb: Start recording"
uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
with:
apikey: ${{ env.HONEYCOMB_WRITEKEY }}
dataset: ${{ env.HONEYCOMB_DATASET }}
job-status: ${{ job.status }}
- name: "Honeycomb: Start first step"
run: |
echo STEP_ID=setup-environment >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Checkout Source
uses: actions/checkout@v2
if: ${{ github.repository_owner == 'puppetlabs' }}
- name: Activate Ruby 2.7
uses: ruby/setup-ruby@v1
if: ${{ github.repository_owner == 'puppetlabs' }}
with:
ruby-version: "2.7"
bundler-cache: true
- name: Print bundle environment
if: ${{ github.repository_owner == 'puppetlabs' }}
run: |
echo ::group::bundler environment
buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
echo ::endgroup::
- name: "Honeycomb: Record Setup Environment time"
if: ${{ github.repository_owner == 'puppetlabs' }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Environment'
echo STEP_ID=Setup-Acceptance-Test-Matrix >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: Run Static & Syntax Tests
if: ${{ github.repository_owner == 'puppetlabs' }}
run: |
buildevents cmd $TRACE_ID $STEP_ID 'static_syntax_checks' -- bundle exec rake syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop
- name: Setup Spec Test Matrix
id: get-matrix
run: |
if [ '${{ github.repository_owner }}' == 'puppetlabs' ]; then
buildevents cmd $TRACE_ID $STEP_ID matrix_from_metadata -- bundle exec matrix_from_metadata_v2
else
echo "::set-output name=spec_matrix::{}"
fi
- name: "Honeycomb: Record Setup Test Matrix time"
if: ${{ always() }}
run: |
buildevents step $TRACE_ID $STEP_ID $STEP_START 'Setup Test Matrix'
Spec:
name: "Spec Tests (Puppet: ${{matrix.puppet_version}}, Ruby Ver: ${{matrix.ruby_version}})"
needs:
- setup_matrix
if: ${{ needs.setup_matrix.outputs.spec_matrix != '{}' }}
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix: ${{fromJson(needs.setup_matrix.outputs.spec_matrix)}}
env:
BUILDEVENT_FILE: '../buildevents.txt'
PUPPET_GEM_VERSION: ${{ matrix.puppet_version }}
FACTER_GEM_VERSION: 'https://github.com/puppetlabs/facter#main'
steps:
- run: |
echo "SANITIZED_PUPPET_VERSION=$(echo '${{ matrix.puppet_version }}' | sed 's/~> //g')" >> $GITHUB_ENV
- run: |
echo 'puppet_version=${{ env.SANITIZED_PUPPET_VERSION }}' >> $BUILDEVENT_FILE
- name: "Honeycomb: Start first step"
run: |
echo "STEP_ID=${{ env.SANITIZED_PUPPET_VERSION }}-spec" >> $GITHUB_ENV
echo STEP_START=$(date +%s) >> $GITHUB_ENV
- name: "Honeycomb: Start recording"
uses: puppetlabs/kvrhdn-gha-buildevents@pdk-templates-v1
with:
apikey: ${{ env.HONEYCOMB_WRITEKEY }}
dataset: ${{ env.HONEYCOMB_DATASET }}
job-status: ${{ job.status }}
matrix-key: ${{ env.SANITIZED_PUPPET_VERSION }}
- name: Checkout Source
uses: actions/checkout@v2
- name: "Activate Ruby ${{ matrix.ruby_version }}"
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{matrix.ruby_version}}
bundler-cache: true
- name: Print bundle environment
run: |
echo ::group::bundler environment
buildevents cmd $TRACE_ID $STEP_ID 'bundle env' -- bundle env
echo ::endgroup::
- name: Run parallel_spec tests
run: |
buildevents cmd $TRACE_ID $STEP_ID 'rake parallel_spec Puppet ${{ matrix.puppet_version }}, Ruby ${{ matrix.ruby_version }}' -- bundle exec rake parallel_spec

View File

@@ -0,0 +1,36 @@
name: Audit aging issues/PRs
on:
schedule:
- cron: "30 1 * * *"
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-issue-stale: 90
days-before-pr-stale: 60
days-before-pr-close: 7
stale-issue-message: |
Hello! 👋
This issue has been open for a while and has had no recent activity. We've labelled it with `attention-needed` so that we can get a clear view of which issues need our attention.
If you are waiting on a response from us we will try and address your comments on a future Community Day.
Alternatively, if it is no longer relevant to you please close the issue with a comment.
stale-issue-label: 'attention-needed'
stale-pr-message: |
Hello! 👋
This pull request has been open for a while and has had no recent activity. We've labelled it with `attention-needed` so that we can get a clear view of which PRs need our attention.
If you are waiting on a response from us we will try and address your comments on a future Community Day.
Alternatively, if it is no longer relevant to you please close the PR with a comment.
Please note that if a pull request receives no update for 7 after it has been labelled, it will be closed. We are always happy to re-open pull request if they have been closed in error.
stale-pr-label: 'attention-needed'

View File

@@ -0,0 +1,28 @@
.git/
.*.sw[op]
.metadata
.yardoc
.yardwarns
*.iml
/.bundle/
/.idea/
/.vagrant/
/coverage/
/bin/
/doc/
/Gemfile.local
/Gemfile.lock
/junit/
/log/
/pkg/
/spec/fixtures/manifests/
/spec/fixtures/modules/
/tmp/
/vendor/
/convert_report.txt
/update_report.txt
.DS_Store
.project
.envrc
/inventory.yaml
/spec/fixtures/litmus_inventory.yaml

View File

@@ -0,0 +1,18 @@
FROM gitpod/workspace-full
RUN sudo wget https://apt.puppet.com/puppet-tools-release-bionic.deb && \
wget https://apt.puppetlabs.com/puppet6-release-bionic.deb && \
sudo dpkg -i puppet6-release-bionic.deb && \
sudo dpkg -i puppet-tools-release-bionic.deb && \
sudo apt-get update && \
sudo apt-get install -y pdk zsh puppet-agent && \
sudo apt-get clean && \
sudo rm -rf /var/lib/apt/lists/*
RUN sudo usermod -s $(which zsh) gitpod && \
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" && \
echo "plugins=(git gitignore github gem pip bundler python ruby docker docker-compose)" >> /home/gitpod/.zshrc && \
echo 'PATH="$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/puppetlabs/bin:/opt/puppetlabs/puppet/bin"' >> /home/gitpod/.zshrc && \
sudo /opt/puppetlabs/puppet/bin/gem install puppet-debugger hub -N && \
mkdir -p /home/gitpod/.config/puppet && \
/opt/puppetlabs/puppet/bin/ruby -r yaml -e "puts ({'disabled' => true}).to_yaml" > /home/gitpod/.config/puppet/analytics.yml
RUN rm -f puppet6-release-bionic.deb puppet-tools-release-bionic.deb
ENTRYPOINT /usr/bin/zsh

View File

@@ -0,0 +1,9 @@
image:
file: .gitpod.Dockerfile
tasks:
- init: pdk bundle install
vscode:
extensions:
- puppet.puppet-vscode@1.2.0:f5iEPbmOj6FoFTOV6q8LTg==

View File

@@ -0,0 +1,47 @@
.git/
.*.sw[op]
.metadata
.yardoc
.yardwarns
*.iml
/.bundle/
/.idea/
/.vagrant/
/coverage/
/bin/
/doc/
/Gemfile.local
/Gemfile.lock
/junit/
/log/
/pkg/
/spec/fixtures/manifests/
/spec/fixtures/modules/
/tmp/
/vendor/
/convert_report.txt
/update_report.txt
.DS_Store
.project
.envrc
/inventory.yaml
/spec/fixtures/litmus_inventory.yaml
/appveyor.yml
/.editorconfig
/.fixtures.yml
/Gemfile
/.gitattributes
/.gitignore
/.gitlab-ci.yml
/.pdkignore
/.puppet-lint.rc
/Rakefile
/rakelib/
/.rspec
/.rubocop.yml
/.travis.yml
/.yardopts
/spec/
/.vscode/
/.sync.yml
/.devcontainer/

View File

@@ -0,0 +1 @@
--relative

View File

@@ -0,0 +1,2 @@
--color
--format documentation

View File

@@ -0,0 +1,519 @@
---
require:
- rubocop-performance
- rubocop-rspec
AllCops:
DisplayCopNames: true
TargetRubyVersion: '2.5'
Include:
- "**/*.rb"
Exclude:
- bin/*
- ".vendor/**/*"
- "**/Gemfile"
- "**/Rakefile"
- pkg/**/*
- spec/fixtures/**/*
- vendor/**/*
- "**/Puppetfile"
- "**/Vagrantfile"
- "**/Guardfile"
Layout/LineLength:
Description: People have wide screens, use them.
Max: 200
RSpec/BeforeAfterAll:
Description: Beware of using after(:all) as it may cause state to leak between tests.
A necessary evil in acceptance testing.
Exclude:
- spec/acceptance/**/*.rb
RSpec/HookArgument:
Description: Prefer explicit :each argument, matching existing module's style
EnforcedStyle: each
RSpec/DescribeSymbol:
Exclude:
- spec/unit/facter/**/*.rb
Style/BlockDelimiters:
Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to
be consistent then.
EnforcedStyle: braces_for_chaining
Style/ClassAndModuleChildren:
Description: Compact style reduces the required amount of indentation.
EnforcedStyle: compact
Style/EmptyElse:
Description: Enforce against empty else clauses, but allow `nil` for clarity.
EnforcedStyle: empty
Style/FormatString:
Description: Following the main puppet project's style, prefer the % format format.
EnforcedStyle: percent
Style/FormatStringToken:
Description: Following the main puppet project's style, prefer the simpler template
tokens over annotated ones.
EnforcedStyle: template
Style/Lambda:
Description: Prefer the keyword for easier discoverability.
EnforcedStyle: literal
Style/RegexpLiteral:
Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168
EnforcedStyle: percent_r
Style/TernaryParentheses:
Description: Checks for use of parentheses around ternary conditions. Enforce parentheses
on complex expressions for better readability, but seriously consider breaking
it up.
EnforcedStyle: require_parentheses_when_complex
Style/TrailingCommaInArguments:
Description: Prefer always trailing comma on multiline argument lists. This makes
diffs, and re-ordering nicer.
EnforcedStyleForMultiline: comma
Style/TrailingCommaInArrayLiteral:
Description: Prefer always trailing comma on multiline literals. This makes diffs,
and re-ordering nicer.
EnforcedStyleForMultiline: comma
Style/SymbolArray:
Description: Using percent style obscures symbolic intent of array's contents.
EnforcedStyle: brackets
RSpec/MessageSpies:
EnforcedStyle: receive
Style/Documentation:
Exclude:
- lib/puppet/parser/functions/**/*
- spec/**/*
Style/WordArray:
EnforcedStyle: brackets
Performance/AncestorsInclude:
Enabled: true
Performance/BigDecimalWithNumericArgument:
Enabled: true
Performance/BlockGivenWithExplicitBlock:
Enabled: true
Performance/CaseWhenSplat:
Enabled: true
Performance/ConstantRegexp:
Enabled: true
Performance/MethodObjectAsBlock:
Enabled: true
Performance/RedundantSortBlock:
Enabled: true
Performance/RedundantStringChars:
Enabled: true
Performance/ReverseFirst:
Enabled: true
Performance/SortReverse:
Enabled: true
Performance/Squeeze:
Enabled: true
Performance/StringInclude:
Enabled: true
Performance/Sum:
Enabled: true
Style/CollectionMethods:
Enabled: true
Style/MethodCalledOnDoEndBlock:
Enabled: true
Style/StringMethods:
Enabled: true
Bundler/InsecureProtocolSource:
Enabled: false
Gemspec/DuplicatedAssignment:
Enabled: false
Gemspec/OrderedDependencies:
Enabled: false
Gemspec/RequiredRubyVersion:
Enabled: false
Gemspec/RubyVersionGlobalsUsage:
Enabled: false
Layout/ArgumentAlignment:
Enabled: false
Layout/BeginEndAlignment:
Enabled: false
Layout/ClosingHeredocIndentation:
Enabled: false
Layout/EmptyComment:
Enabled: false
Layout/EmptyLineAfterGuardClause:
Enabled: false
Layout/EmptyLinesAroundArguments:
Enabled: false
Layout/EmptyLinesAroundAttributeAccessor:
Enabled: false
Layout/EndOfLine:
Enabled: false
Layout/FirstArgumentIndentation:
Enabled: false
Layout/HashAlignment:
Enabled: false
Layout/HeredocIndentation:
Enabled: false
Layout/LeadingEmptyLines:
Enabled: false
Layout/SpaceAroundMethodCallOperator:
Enabled: false
Layout/SpaceInsideArrayLiteralBrackets:
Enabled: false
Layout/SpaceInsideReferenceBrackets:
Enabled: false
Lint/BigDecimalNew:
Enabled: false
Lint/BooleanSymbol:
Enabled: false
Lint/ConstantDefinitionInBlock:
Enabled: false
Lint/DeprecatedOpenSSLConstant:
Enabled: false
Lint/DisjunctiveAssignmentInConstructor:
Enabled: false
Lint/DuplicateElsifCondition:
Enabled: false
Lint/DuplicateRequire:
Enabled: false
Lint/DuplicateRescueException:
Enabled: false
Lint/EmptyConditionalBody:
Enabled: false
Lint/EmptyFile:
Enabled: false
Lint/ErbNewArguments:
Enabled: false
Lint/FloatComparison:
Enabled: false
Lint/HashCompareByIdentity:
Enabled: false
Lint/IdentityComparison:
Enabled: false
Lint/InterpolationCheck:
Enabled: false
Lint/MissingCopEnableDirective:
Enabled: false
Lint/MixedRegexpCaptureTypes:
Enabled: false
Lint/NestedPercentLiteral:
Enabled: false
Lint/NonDeterministicRequireOrder:
Enabled: false
Lint/OrderedMagicComments:
Enabled: false
Lint/OutOfRangeRegexpRef:
Enabled: false
Lint/RaiseException:
Enabled: false
Lint/RedundantCopEnableDirective:
Enabled: false
Lint/RedundantRequireStatement:
Enabled: false
Lint/RedundantSafeNavigation:
Enabled: false
Lint/RedundantWithIndex:
Enabled: false
Lint/RedundantWithObject:
Enabled: false
Lint/RegexpAsCondition:
Enabled: false
Lint/ReturnInVoidContext:
Enabled: false
Lint/SafeNavigationConsistency:
Enabled: false
Lint/SafeNavigationWithEmpty:
Enabled: false
Lint/SelfAssignment:
Enabled: false
Lint/SendWithMixinArgument:
Enabled: false
Lint/ShadowedArgument:
Enabled: false
Lint/StructNewOverride:
Enabled: false
Lint/ToJSON:
Enabled: false
Lint/TopLevelReturnWithArgument:
Enabled: false
Lint/TrailingCommaInAttributeDeclaration:
Enabled: false
Lint/UnreachableLoop:
Enabled: false
Lint/UriEscapeUnescape:
Enabled: false
Lint/UriRegexp:
Enabled: false
Lint/UselessMethodDefinition:
Enabled: false
Lint/UselessTimes:
Enabled: false
Metrics/AbcSize:
Enabled: false
Metrics/BlockLength:
Enabled: false
Metrics/BlockNesting:
Enabled: false
Metrics/ClassLength:
Enabled: false
Metrics/CyclomaticComplexity:
Enabled: false
Metrics/MethodLength:
Enabled: false
Metrics/ModuleLength:
Enabled: false
Metrics/ParameterLists:
Enabled: false
Metrics/PerceivedComplexity:
Enabled: false
Migration/DepartmentName:
Enabled: false
Naming/AccessorMethodName:
Enabled: false
Naming/BlockParameterName:
Enabled: false
Naming/HeredocDelimiterCase:
Enabled: false
Naming/HeredocDelimiterNaming:
Enabled: false
Naming/MemoizedInstanceVariableName:
Enabled: false
Naming/MethodParameterName:
Enabled: false
Naming/RescuedExceptionsVariableName:
Enabled: false
Naming/VariableNumber:
Enabled: false
Performance/BindCall:
Enabled: false
Performance/DeletePrefix:
Enabled: false
Performance/DeleteSuffix:
Enabled: false
Performance/InefficientHashSearch:
Enabled: false
Performance/UnfreezeString:
Enabled: false
Performance/UriDefaultParser:
Enabled: false
RSpec/Be:
Enabled: false
RSpec/Capybara/CurrentPathExpectation:
Enabled: false
RSpec/Capybara/FeatureMethods:
Enabled: false
RSpec/Capybara/VisibilityMatcher:
Enabled: false
RSpec/ContextMethod:
Enabled: false
RSpec/ContextWording:
Enabled: false
RSpec/DescribeClass:
Enabled: false
RSpec/EmptyHook:
Enabled: false
RSpec/EmptyLineAfterExample:
Enabled: false
RSpec/EmptyLineAfterExampleGroup:
Enabled: false
RSpec/EmptyLineAfterHook:
Enabled: false
RSpec/ExampleLength:
Enabled: false
RSpec/ExampleWithoutDescription:
Enabled: false
RSpec/ExpectChange:
Enabled: false
RSpec/ExpectInHook:
Enabled: false
RSpec/FactoryBot/AttributeDefinedStatically:
Enabled: false
RSpec/FactoryBot/CreateList:
Enabled: false
RSpec/FactoryBot/FactoryClassName:
Enabled: false
RSpec/HooksBeforeExamples:
Enabled: false
RSpec/ImplicitBlockExpectation:
Enabled: false
RSpec/ImplicitSubject:
Enabled: false
RSpec/LeakyConstantDeclaration:
Enabled: false
RSpec/LetBeforeExamples:
Enabled: false
RSpec/MissingExampleGroupArgument:
Enabled: false
RSpec/MultipleExpectations:
Enabled: false
RSpec/MultipleMemoizedHelpers:
Enabled: false
RSpec/MultipleSubjects:
Enabled: false
RSpec/NestedGroups:
Enabled: false
RSpec/PredicateMatcher:
Enabled: false
RSpec/ReceiveCounts:
Enabled: false
RSpec/ReceiveNever:
Enabled: false
RSpec/RepeatedExampleGroupBody:
Enabled: false
RSpec/RepeatedExampleGroupDescription:
Enabled: false
RSpec/RepeatedIncludeExample:
Enabled: false
RSpec/ReturnFromStub:
Enabled: false
RSpec/SharedExamples:
Enabled: false
RSpec/StubbedMock:
Enabled: false
RSpec/UnspecifiedException:
Enabled: false
RSpec/VariableDefinition:
Enabled: false
RSpec/VoidExpect:
Enabled: false
RSpec/Yield:
Enabled: false
Security/Open:
Enabled: false
Style/AccessModifierDeclarations:
Enabled: false
Style/AccessorGrouping:
Enabled: false
Style/AsciiComments:
Enabled: false
Style/BisectedAttrAccessor:
Enabled: false
Style/CaseLikeIf:
Enabled: false
Style/ClassEqualityComparison:
Enabled: false
Style/ColonMethodDefinition:
Enabled: false
Style/CombinableLoops:
Enabled: false
Style/CommentedKeyword:
Enabled: false
Style/Dir:
Enabled: false
Style/DoubleCopDisableDirective:
Enabled: false
Style/EmptyBlockParameter:
Enabled: false
Style/EmptyLambdaParameter:
Enabled: false
Style/Encoding:
Enabled: false
Style/EvalWithLocation:
Enabled: false
Style/ExpandPathArguments:
Enabled: false
Style/ExplicitBlockArgument:
Enabled: false
Style/ExponentialNotation:
Enabled: false
Style/FloatDivision:
Enabled: false
Style/FrozenStringLiteralComment:
Enabled: false
Style/GlobalStdStream:
Enabled: false
Style/HashAsLastArrayItem:
Enabled: false
Style/HashLikeCase:
Enabled: false
Style/HashTransformKeys:
Enabled: false
Style/HashTransformValues:
Enabled: false
Style/IfUnlessModifier:
Enabled: false
Style/KeywordParametersOrder:
Enabled: false
Style/MinMax:
Enabled: false
Style/MixinUsage:
Enabled: false
Style/MultilineWhenThen:
Enabled: false
Style/NegatedUnless:
Enabled: false
Style/NumericPredicate:
Enabled: false
Style/OptionalBooleanParameter:
Enabled: false
Style/OrAssignment:
Enabled: false
Style/RandomWithOffset:
Enabled: false
Style/RedundantAssignment:
Enabled: false
Style/RedundantCondition:
Enabled: false
Style/RedundantConditional:
Enabled: false
Style/RedundantFetchBlock:
Enabled: false
Style/RedundantFileExtensionInRequire:
Enabled: false
Style/RedundantRegexpCharacterClass:
Enabled: false
Style/RedundantRegexpEscape:
Enabled: false
Style/RedundantSelfAssignment:
Enabled: false
Style/RedundantSort:
Enabled: false
Style/RescueStandardError:
Enabled: false
Style/SingleArgumentDig:
Enabled: false
Style/SlicingWithRange:
Enabled: false
Style/SoleNestedConditional:
Enabled: false
Style/StderrPuts:
Enabled: false
Style/StringConcatenation:
Enabled: false
Style/Strip:
Enabled: false
Style/SymbolProc:
Enabled: false
Style/TrailingBodyOnClass:
Enabled: false
Style/TrailingBodyOnMethodDefinition:
Enabled: false
Style/TrailingBodyOnModule:
Enabled: false
Style/TrailingCommaInHashLiteral:
Enabled: false
Style/TrailingMethodEndStatement:
Enabled: false
Style/UnpackFirst:
Enabled: false
Lint/DuplicateBranch:
Enabled: false
Lint/DuplicateRegexpCharacterClassElement:
Enabled: false
Lint/EmptyBlock:
Enabled: false
Lint/EmptyClass:
Enabled: false
Lint/NoReturnInBeginEndBlocks:
Enabled: false
Lint/ToEnumArguments:
Enabled: false
Lint/UnexpectedBlockArity:
Enabled: false
Lint/UnmodifiedReduceAccumulator:
Enabled: false
Performance/CollectionLiteralInLoop:
Enabled: false
Style/ArgumentsForwarding:
Enabled: false
Style/CollectionCompact:
Enabled: false
Style/DocumentDynamicEvalDefinition:
Enabled: false
Style/NegatedIfElseCondition:
Enabled: false
Style/NilLambda:
Enabled: false
Style/RedundantArgument:
Enabled: false
Style/SwapValues:
Enabled: false

View File

@@ -0,0 +1,33 @@
---
.gitattributes:
include:
'files/shell/*': 'eol=lf'
".gitlab-ci.yml":
delete: true
appveyor.yml:
delete: true
Gemfile:
optional:
":development":
- gem: github_changelog_generator
spec/spec_helper.rb:
mock_with: ":rspec"
coverage_report: true
.gitpod.Dockerfile:
unmanaged: false
.gitpod.yml:
unmanaged: false
.github/workflows/nightly.yml:
unmanaged: false
.github/workflows/pr_test.yml:
unmanaged: false
.github/workflows/auto_release.yml:
unmanaged: false
.github/workflows/spec.yml:
checks: 'syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop'
unmanaged: false
.github/workflows/release.yml:
unmanaged: false
.travis.yml:
delete: true

View File

@@ -0,0 +1,6 @@
{
"recommendations": [
"puppet.puppet-vscode",
"rebornix.Ruby"
]
}

View File

@@ -0,0 +1 @@
--markup markdown

View File

@@ -0,0 +1,339 @@
# Change log
All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org).
## [v7.2.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v7.2.0) - 2022-05-16
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v7.1.1...v7.2.0)
### Added
- Added new SSH key type. [#410](https://github.com/puppetlabs/puppetlabs-accounts/pull/410) ([PorkCharsui79](https://github.com/PorkCharsui79))
- pdksync - (IAC-1753) - Add Support for AlmaLinux 8 [#397](https://github.com/puppetlabs/puppetlabs-accounts/pull/397) ([david22swan](https://github.com/david22swan))
- pdksync - (IAC-1751) - Add Support for Rocky 8 [#395](https://github.com/puppetlabs/puppetlabs-accounts/pull/395) ([david22swan](https://github.com/david22swan))
### Fixed
- pdksync - (GH-iac-334) Remove Support for Ubuntu 16.04 [#401](https://github.com/puppetlabs/puppetlabs-accounts/pull/401) ([david22swan](https://github.com/david22swan))
- pdksync - (IAC-1787) Remove Support for CentOS 6 [#398](https://github.com/puppetlabs/puppetlabs-accounts/pull/398) ([david22swan](https://github.com/david22swan))
- pdksync - (IAC-1598) - Remove Support for Debian 8 [#394](https://github.com/puppetlabs/puppetlabs-accounts/pull/394) ([david22swan](https://github.com/david22swan))
## [v7.1.1](https://github.com/puppetlabs/puppetlabs-accounts/tree/v7.1.1) (2021-08-25)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v7.1.0...v7.1.1)
### Fixed
- \(IAC-1741\) Allow stdlib v8.0.0 [\#392](https://github.com/puppetlabs/puppetlabs-accounts/pull/392) ([david22swan](https://github.com/david22swan))
## [v7.1.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v7.1.0) (2021-08-16)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v7.0.2...v7.1.0)
### Added
- pdksync - \(IAC-1709\) - Add Support for Debian 11 [\#391](https://github.com/puppetlabs/puppetlabs-accounts/pull/391) ([david22swan](https://github.com/david22swan))
- MODULES-11100 - Add sk-ecdsa public key support, and implement tests for sk-ecdsa and ecdsa keys [\#388](https://github.com/puppetlabs/puppetlabs-accounts/pull/388) ([vollmerk](https://github.com/vollmerk))
## [v7.0.2](https://github.com/puppetlabs/puppetlabs-accounts/tree/v7.0.2) (2021-03-29)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v7.0.1...v7.0.2)
### Fixed
- \(IAC-1497\) - Removal of unsupported `translate` dependency [\#373](https://github.com/puppetlabs/puppetlabs-accounts/pull/373) ([david22swan](https://github.com/david22swan))
- \(MODULES-10892\) Update name.pp [\#353](https://github.com/puppetlabs/puppetlabs-accounts/pull/353) ([LooOOooM](https://github.com/LooOOooM))
## [v7.0.1](https://github.com/puppetlabs/puppetlabs-accounts/tree/v7.0.1) (2021-03-15)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v7.0.0...v7.0.1)
### Fixed
- \(MODULES-10960\) Selector needs multiple checks in brackets. [\#369](https://github.com/puppetlabs/puppetlabs-accounts/pull/369) ([tuxmea](https://github.com/tuxmea))
## [v7.0.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v7.0.0) (2021-03-01)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v6.4.0...v7.0.0)
### Changed
- Update metadata.json - remove ubuntu 14.04 [\#368](https://github.com/puppetlabs/puppetlabs-accounts/pull/368) ([daianamezdrea](https://github.com/daianamezdrea))
- pdksync - Remove Puppet 5 from testing and bump minimal version to 6.0.0 [\#359](https://github.com/puppetlabs/puppetlabs-accounts/pull/359) ([carabasdaniel](https://github.com/carabasdaniel))
### Fixed
- \(MODULES-10867\) Ensure ssh key name is unique based on type, content and description [\#340](https://github.com/puppetlabs/puppetlabs-accounts/pull/340) ([mdklapwijk](https://github.com/mdklapwijk))
## [v6.4.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v6.4.0) (2020-12-14)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v6.3.0...v6.4.0)
### Added
- pdksync - \(maint\) - Add support for Puppet 7 [\#350](https://github.com/puppetlabs/puppetlabs-accounts/pull/350) ([pmcmaw](https://github.com/pmcmaw))
- MODULES-10862 add support for authorized\_keys file mode [\#338](https://github.com/puppetlabs/puppetlabs-accounts/pull/338) ([simondeziel](https://github.com/simondeziel))
## [v6.3.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v6.3.0) (2020-09-22)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v6.2.0...v6.3.0)
### Added
- Allow for Sensitive type passwords in accounts::user [\#333](https://github.com/puppetlabs/puppetlabs-accounts/pull/333) ([jarretlavallee](https://github.com/jarretlavallee))
### Fixed
- \(MODULES-10798\) Ensure group is created for user only if undefined [\#334](https://github.com/puppetlabs/puppetlabs-accounts/pull/334) ([michaeltlombardi](https://github.com/michaeltlombardi))
## [v6.2.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v6.2.0) (2020-08-20)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v6.1.1...v6.2.0)
### Added
- pdksync - \(IAC-973\) - Update travis/appveyor to run on new default branch main [\#318](https://github.com/puppetlabs/puppetlabs-accounts/pull/318) ([david22swan](https://github.com/david22swan))
- \(IAC-746\) - Add ubuntu 20.04 support [\#312](https://github.com/puppetlabs/puppetlabs-accounts/pull/312) ([david22swan](https://github.com/david22swan))
### Fixed
- \(IAC-975\) - Removal of inappropriate terminology in module [\#320](https://github.com/puppetlabs/puppetlabs-accounts/pull/320) ([pmcmaw](https://github.com/pmcmaw))
## [v6.1.1](https://github.com/puppetlabs/puppetlabs-accounts/tree/v6.1.1) (2020-04-30)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v6.1.0...v6.1.1)
### Fixed
- MODULES-10550 fix keyspec parsing to allow whitespaces in options and… [\#291](https://github.com/puppetlabs/puppetlabs-accounts/pull/291) ([janit42](https://github.com/janit42))
## [v6.1.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v6.1.0) (2020-02-03)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v6.0.0...v6.1.0)
### Added
- Employ more lenient username checks \(allow capitals\) [\#286](https://github.com/puppetlabs/puppetlabs-accounts/pull/286) ([mvandegarde](https://github.com/mvandegarde))
- \(MODULES-10242\) Re-add Ubuntu 14 to supported OS list [\#281](https://github.com/puppetlabs/puppetlabs-accounts/pull/281) ([sheenaajay](https://github.com/sheenaajay))
## [v6.0.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v6.0.0) (2019-11-11)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v5.0.0...v6.0.0)
### Changed
- pdksync - FM-8499 - remove ubuntu14 support [\#277](https://github.com/puppetlabs/puppetlabs-accounts/pull/277) ([lionce](https://github.com/lionce))
### Added
- \(FM-8671\) - Support added for CentOS 8 [\#278](https://github.com/puppetlabs/puppetlabs-accounts/pull/278) ([david22swan](https://github.com/david22swan))
### Fixed
- fix small typo on the root\_home key at Debian.yaml [\#260](https://github.com/puppetlabs/puppetlabs-accounts/pull/260) ([wandenberg](https://github.com/wandenberg))
- Use user group instead of user name for sshkey owner group [\#258](https://github.com/puppetlabs/puppetlabs-accounts/pull/258) ([florindragos](https://github.com/florindragos))
## [v5.0.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v5.0.0) (2019-09-10)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v4.2.0...v5.0.0)
### Changed
- \(MODULES-9712\) Move data into hiera. [\#241](https://github.com/puppetlabs/puppetlabs-accounts/pull/241) ([pillarsdotnet](https://github.com/pillarsdotnet))
### Added
- \(FM-8392\) Add debian 10 to provision.yaml [\#251](https://github.com/puppetlabs/puppetlabs-accounts/pull/251) ([ThoughtCrhyme](https://github.com/ThoughtCrhyme))
### Fixed
- \(MODULES-9849\) wrong order when removing user with custom sshkey file [\#250](https://github.com/puppetlabs/puppetlabs-accounts/pull/250) ([tuxmea](https://github.com/tuxmea))
- fix problematic parsing of keyspec [\#246](https://github.com/puppetlabs/puppetlabs-accounts/pull/246) ([EECOLOR](https://github.com/EECOLOR))
- \(MODULES-9697\) fix for correct management of sshkey\_custom\_path [\#242](https://github.com/puppetlabs/puppetlabs-accounts/pull/242) ([tuxmea](https://github.com/tuxmea))
## [v4.2.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v4.2.0) (2019-08-02)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v4.1.0...v4.2.0)
### Added
- \(FM-8231\) Convert testing to litmus [\#230](https://github.com/puppetlabs/puppetlabs-accounts/pull/230) ([eimlav](https://github.com/eimlav))
### Fixed
- MODULES-9447 -- Narrow dependency between removed user and group. [\#232](https://github.com/puppetlabs/puppetlabs-accounts/pull/232) ([pillarsdotnet](https://github.com/pillarsdotnet))
## [v4.1.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v4.1.0) (2019-05-29)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/v4.0.0...v4.1.0)
### Added
- \(FM-8023\) Add RedHat 8 support [\#227](https://github.com/puppetlabs/puppetlabs-accounts/pull/227) ([eimlav](https://github.com/eimlav))
- \(MODULES-7469\) Add password\_max\_age parameter [\#221](https://github.com/puppetlabs/puppetlabs-accounts/pull/221) ([eimlav](https://github.com/eimlav))
### Fixed
- \(MODULES-8968\) Test account removal. [\#226](https://github.com/puppetlabs/puppetlabs-accounts/pull/226) ([pillarsdotnet](https://github.com/pillarsdotnet))
## [v4.0.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/v4.0.0) (2019-05-10)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/3.2.0...v4.0.0)
### Changed
- pdksync - \(MODULES-8444\) - Raise lower Puppet bound [\#218](https://github.com/puppetlabs/puppetlabs-accounts/pull/218) ([david22swan](https://github.com/david22swan))
- \(MODULES-8909\) Add type-aliases and auto-loading. [\#214](https://github.com/puppetlabs/puppetlabs-accounts/pull/214) ([pillarsdotnet](https://github.com/pillarsdotnet))
### Fixed
- \(MODULES-8909\) Allow periods in usernames. [\#220](https://github.com/puppetlabs/puppetlabs-accounts/pull/220) ([pillarsdotnet](https://github.com/pillarsdotnet))
- Remove user when custom sshkey file is set [\#213](https://github.com/puppetlabs/puppetlabs-accounts/pull/213) ([tuxmea](https://github.com/tuxmea))
## [3.2.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/3.2.0) (2019-01-18)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/3.1.0...3.2.0)
### Added
- \(MODULES-8302\) - Add allowdupe parameter [\#199](https://github.com/puppetlabs/puppetlabs-accounts/pull/199) ([eimlav](https://github.com/eimlav))
- \(MODULES-8149\) - Addition of support for SLES 15 [\#197](https://github.com/puppetlabs/puppetlabs-accounts/pull/197) ([david22swan](https://github.com/david22swan))
### Fixed
- \(MODULES-8216\) - Fix fail when custom\_sshkey\_path and managehome=false [\#194](https://github.com/puppetlabs/puppetlabs-accounts/pull/194) ([eimlav](https://github.com/eimlav))
- Fixing the limitations section of the README [\#191](https://github.com/puppetlabs/puppetlabs-accounts/pull/191) ([HelenCampbell](https://github.com/HelenCampbell))
## [3.1.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/3.1.0) (2018-09-27)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/3.0.0...3.1.0)
### Added
- pdksync - \(FM-7392\) puppet 6 testing changes [\#187](https://github.com/puppetlabs/puppetlabs-accounts/pull/187) ([tphoney](https://github.com/tphoney))
- pdksync - \(MODULES-6805\) metadata.json shows support for puppet 6 [\#185](https://github.com/puppetlabs/puppetlabs-accounts/pull/185) ([tphoney](https://github.com/tphoney))
- \(LOC-173\) Delivering translation for readmes/README\_ja\_JP.markdown [\#177](https://github.com/puppetlabs/puppetlabs-accounts/pull/177) ([ehom](https://github.com/ehom))
### Fixed
- \(maint\) corrected filename extension for both en and ja [\#182](https://github.com/puppetlabs/puppetlabs-accounts/pull/182) ([ehom](https://github.com/ehom))
- Only take care of ssh-keys if ensure is set to 'present' [\#174](https://github.com/puppetlabs/puppetlabs-accounts/pull/174) ([opteamax](https://github.com/opteamax))
- Rename README.markdown to README.MD [\#173](https://github.com/puppetlabs/puppetlabs-accounts/pull/173) ([clairecadman](https://github.com/clairecadman))
## [3.0.0](https://github.com/puppetlabs/puppetlabs-accounts/tree/3.0.0) (2018-09-07)
[Full Changelog](https://github.com/puppetlabs/puppetlabs-accounts/compare/2.0.0...3.0.0)
### Changed
- Adding ability to specify custom ssh\_key location [\#149](https://github.com/puppetlabs/puppetlabs-accounts/pull/149) ([ggeldenhuis](https://github.com/ggeldenhuis))
### Added
- \(MODULES-7687\) - Added Darwin compatibility [\#167](https://github.com/puppetlabs/puppetlabs-accounts/pull/167) ([eimlav](https://github.com/eimlav))
- \(FM-7287\) - i18n Process Implemented. [\#159](https://github.com/puppetlabs/puppetlabs-accounts/pull/159) ([david22swan](https://github.com/david22swan))
- \(MODULES-5222\) - managevim option added to manifests. [\#156](https://github.com/puppetlabs/puppetlabs-accounts/pull/156) ([david22swan](https://github.com/david22swan))
- \(FM-7289\) - Added Puppet 4 data types to parameters [\#155](https://github.com/puppetlabs/puppetlabs-accounts/pull/155) ([eimlav](https://github.com/eimlav))
- \(MODULES-7671\) - Support spaces in ssh key options [\#153](https://github.com/puppetlabs/puppetlabs-accounts/pull/153) ([dleske](https://github.com/dleske))
- \(FM-7254\) - Addition of support for Ubuntu 18.04 [\#150](https://github.com/puppetlabs/puppetlabs-accounts/pull/150) ([david22swan](https://github.com/david22swan))
### Fixed
- pdksync - \(MODULES-7658\) use beaker4 in puppet-module-gems [\#170](https://github.com/puppetlabs/puppetlabs-accounts/pull/170) ([tphoney](https://github.com/tphoney))
- Fix error when deploying key into directory not owned by user [\#152](https://github.com/puppetlabs/puppetlabs-accounts/pull/152) ([tuxmea](https://github.com/tuxmea))
## 2.0.0
### Summary
This release drops support for Debian 7, adds support for Debian 9 and includes several small features and bug fixes.
#### Added
- [FM-7052] Addition of Debian 9 support to accounts
- (MODULES-3989) Allow management of local accounts despite an NSS
- Allow mode for homedir to be undef
- Add expiry property to user resource.
#### Fixed
- (MODULES-6607) - Update docs to reflect correct default value for ignore_password_if_empty.
- Update tests and README
- Removed Debian 7 support
#### Bugfixes
- Allow sshkeys to be reused for multiple accounts
- Set `home_mode` explicitly in tests
- Fix test for ssh key to allow new comment format
## Supported Release [1.3.0]
### Summary
This release uses the PDK convert functionality which in return makes the module PDK compliant. It also includes a roll up of maintenance changes.
#### Added
- PDK Convert accounts ([MODULES-6328](https://tickets.puppet.com/browse/MODULES-6328)).
#### Fixed
- Don't create accounts::home_dir resources.
- Multiple maintenance changes.
## Supported Release [1.2.1]
### Summary
This release is to update the formatting of the module, Rubocop having been run for all ruby files and been set to run automatically on all future commits.
### Changed
- Rubocop has been implemented.
## Supported Release 1.2.0
### Summary
This release is a rollup of changes. Several attributes have been added as requested and submitted from our community.
#### Added
- Attribute ignore_password\_if\_empty is added which, if set to true, shall ignore password changes if the password is empty.
- Removal of dependency on group resource if create\_group is set to false.
- Add attribute to allow custom group names.
- Add attribute to set system user or group.
- Add attribute to set the user or group to be the system account.
- Add attribute to create a group (or not) with the username.
- Add support for .forward.
- Add support for ssh options in authorization_keys.
- Add ECDSA support.
- Add support for ssh authorized key options.
- Allow the use of the \`source\` param for bash files
- Removal of end-of-life Ubuntu 12.04 support from metadata.
- Update Puppet version compatibility.
- Modulesync and Gemfile updates.
#### Fixed
- Multiple fixes to tests.
## Supported Release 1.1.0
### Summary
A feature rich release, with the addition of Debian 8 support. Also several generic fixes to tests.
#### Features
- Now allows SSH keys to be purged from user.
- Multiple updates and fixes to the README.
- RSpec-puppet has now been unpinned.
- Addition of Debian 8 compatibility to metadata.
- Addition of OSfamily fact to tests.
- Several modulesync updates.
#### Bugfixes
- Multiple fixes to tests.
## Supported Release 1.0.0
### Summary:
This is the initial release of the rewrite of puppetlabs-pe\_accounts for a more general usage.
Differences from the pe\_accounts module is that the data model is gone, and thus the base class that accepts hashes (ie, from hiera). Instead, the module is designed around the use of the `accounts::user` defined resource.
To regain the old hiera behavior, use the `create_resources()` function in combination with `accounts::user`; eg: `create_resources('accounts::user', hiera_hash('accounts::users'))`
[1.3.0]:https://github.com/puppetlabs/puppetlabs-accounts/compare/1.2.1...1.3.0
[1.2.1]:https://github.com/puppetlabs/puppetlabs-accounts/compare/1.2.0...1.2.1
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*

View File

@@ -0,0 +1,2 @@
# Setting ownership to the modules team
* @puppetlabs/modules

View File

@@ -0,0 +1,3 @@
# Contributing to Puppet modules
Check out our [Contributing to Supported Modules Blog Post](https://puppetlabs.github.io/iac/docs/contributing_to_a_module.html) to find all the information that you will need.

View File

@@ -0,0 +1,64 @@
source ENV['GEM_SOURCE'] || 'https://rubygems.org'
def location_for(place_or_version, fake_version = nil)
git_url_regex = %r{\A(?<url>(https?|git)[:@][^#]*)(#(?<branch>.*))?}
file_url_regex = %r{\Afile:\/\/(?<path>.*)}
if place_or_version && (git_url = place_or_version.match(git_url_regex))
[fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact
elsif place_or_version && (file_url = place_or_version.match(file_url_regex))
['>= 0', { path: File.expand_path(file_url[:path]), require: false }]
else
[place_or_version, { require: false }]
end
end
ruby_version_segments = Gem::Version.new(RUBY_VERSION.dup).segments
minor_version = ruby_version_segments[0..1].join('.')
group :development do
gem "json", '= 2.0.4', require: false if Gem::Requirement.create('~> 2.4.2').satisfied_by?(Gem::Version.new(RUBY_VERSION.dup))
gem "json", '= 2.1.0', require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup))
gem "json", '= 2.3.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 2.8.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup))
gem "puppet-module-posix-default-r#{minor_version}", '~> 1.0', require: false, platforms: [:ruby]
gem "puppet-module-posix-dev-r#{minor_version}", '~> 1.0', require: false, platforms: [:ruby]
gem "puppet-module-win-default-r#{minor_version}", '~> 1.0', require: false, platforms: [:mswin, :mingw, :x64_mingw]
gem "puppet-module-win-dev-r#{minor_version}", '~> 1.0', require: false, platforms: [:mswin, :mingw, :x64_mingw]
gem "voxpupuli-puppet-lint-plugins", '>= 3.0', require: false, platforms: [:ruby]
gem "github_changelog_generator", require: false
end
group :system_tests do
gem "puppet-module-posix-system-r#{minor_version}", '~> 1.0', require: false, platforms: [:ruby]
gem "puppet-module-win-system-r#{minor_version}", '~> 1.0', require: false, platforms: [:mswin, :mingw, :x64_mingw]
end
puppet_version = ENV['PUPPET_GEM_VERSION']
facter_version = ENV['FACTER_GEM_VERSION']
hiera_version = ENV['HIERA_GEM_VERSION']
gems = {}
gems['puppet'] = location_for(puppet_version)
# If facter or hiera versions have been specified via the environment
# variables
gems['facter'] = location_for(facter_version) if facter_version
gems['hiera'] = location_for(hiera_version) if hiera_version
gems.each do |gem_name, gem_params|
gem gem_name, *gem_params
end
# Evaluate Gemfile.local and ~/.gemfile if they exist
extra_gemfiles = [
"#{__FILE__}.local",
File.join(Dir.home, '.gemfile'),
]
extra_gemfiles.each do |gemfile|
if File.file?(gemfile) && File.readable?(gemfile)
eval(File.read(gemfile), binding)
end
end
# vim: syntax=ruby

View File

@@ -0,0 +1,87 @@
## 2.0.0
### Summary
This release drops support for Debian 7, adds support for Debian 9 and includes several small features and bug fixes.
#### Added
- [FM-7052] Addition of Debian 9 support to accounts
- (MODULES-3989) Allow management of local accounts despite an NSS
- Allow mode for homedir to be undef
- Add expiry property to user resource.
#### Fixed
- (MODULES-6607) - Update docs to reflect correct default value for ignore_password_if_empty.
- Update tests and README
- Removed Debian 7 support
#### Bugfixes
- Allow sshkeys to be reused for multiple accounts
- Set `home_mode` explicitly in tests
- Fix test for ssh key to allow new comment format
## Supported Release [1.3.0]
### Summary
This release uses the PDK convert functionality which in return makes the module PDK compliant. It also includes a roll up of maintenance changes.
#### Added
- PDK Convert accounts ([MODULES-6328](https://tickets.puppet.com/browse/MODULES-6328)).
#### Fixed
- Don't create accounts::home_dir resources.
- Multiple maintenance changes.
## Supported Release [1.2.1]
### Summary
This release is to update the formatting of the module, Rubocop having been run for all ruby files and been set to run automatically on all future commits.
### Changed
- Rubocop has been implemented.
## Supported Release 1.2.0
### Summary
This release is a rollup of changes. Several attributes have been added as requested and submitted from our community.
#### Added
- Attribute ignore_password\_if\_empty is added which, if set to true, shall ignore password changes if the password is empty.
- Removal of dependency on group resource if create\_group is set to false.
- Add attribute to allow custom group names.
- Add attribute to set system user or group.
- Add attribute to set the user or group to be the system account.
- Add attribute to create a group (or not) with the username.
- Add support for .forward.
- Add support for ssh options in authorization_keys.
- Add ECDSA support.
- Add support for ssh authorized key options.
- Allow the use of the \`source\` param for bash files
- Removal of end-of-life Ubuntu 12.04 support from metadata.
- Update Puppet version compatibility.
- Modulesync and Gemfile updates.
#### Fixed
- Multiple fixes to tests.
## Supported Release 1.1.0
### Summary
A feature rich release, with the addition of Debian 8 support. Also several generic fixes to tests.
#### Features
- Now allows SSH keys to be purged from user.
- Multiple updates and fixes to the README.
- RSpec-puppet has now been unpinned.
- Addition of Debian 8 compatibility to metadata.
- Addition of OSfamily fact to tests.
- Several modulesync updates.
#### Bugfixes
- Multiple fixes to tests.
## Supported Release 1.0.0
### Summary:
This is the initial release of the rewrite of puppetlabs-pe\_accounts for a more general usage.
Differences from the pe\_accounts module is that the data model is gone, and thus the base class that accepts hashes (ie, from hiera). Instead, the module is designed around the use of the `accounts::user` defined resource.
To regain the old hiera behavior, use the `create_resources()` function in combination with `accounts::user`; eg: `create_resources('accounts::user', hiera_hash('accounts::users'))`
[1.3.0]:https://github.com/puppetlabs/puppetlabs-accounts/compare/1.2.1...1.3.0
[1.2.1]:https://github.com/puppetlabs/puppetlabs-accounts/compare/1.2.0...1.2.1

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,15 @@
Puppet Module - puppetlabs-accounts
Copyright 2018 Puppet, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,255 @@
# accounts
#### Table of Contents
1. [Description](#description)
2. [Setup - The basics of getting started with accounts](#setup)
3. [Usage - Configuration options and additional functionality](#usage)
* [Declare user accounts](#declare-user-accounts)
* [Customize the home directory](#customize-the-home-directory)
* [Lock accounts](#lock-accounts)
* [Manage SSH keys](#manage-ssh-keys)
* [Data in hiera](#data-in-hiera)
4. [Reference - An under-the-hood peek at what the module is doing and how](#reference)
* [Data Types](#data-types)
5. [Limitations - OS compatibility, etc.](#limitations)
6. [Development - Guide for contributing to the module](#development)
## Description
The accounts module manages resources related to login and service accounts.
This module works on many UNIX/Linux operating systems. It does not support configuring accounts on Microsoft Windows platforms.
## Setup
### Beginning with accounts
Declare the `accounts` class in a Puppet-managed node's manifest:
~~~puppet
node default {
accounts::user { 'dan': }
accounts::user { 'morgan': }
}
~~~
The above example creates accounts, home directories, and groups for Dan and Morgan.
## Usage
### Declare user accounts
~~~puppet
accounts::user { 'bob':
uid => '4001',
gid => '4001',
group => 'staff',
shell => '/bin/bash',
password => '!!',
locked => false,
}
~~~
### Customize the home directory
A simple bashrc and bash\_profile rc file is managed by Puppet for each account. These rc files add some simple aliases, update the prompt, add ~/bin to the path, and source the following files (which are not managed by this module) in the following order:
1. `/etc/bashrc`
2. `/etc/bashrc.puppet`
3. `~/.bashrc.custom`
Account holders can customize their shells by managing their bashrc.custom files. In addition, the system administrator can make profile changes that affect all accounts with a bash shell by managing the '/etc/bashrc.puppet' file.
To install an email foward, configure the `.forward` file by using the `forward_content` or `forward_source` parameters.
### Lock accounts
Lock accounts by setting the `locked` parameter of an account to true.
For example:
~~~puppet
accounts::user { 'villain':
comment => 'Bad Person',
locked => true
}
~~~
The accounts module sets the account to an invalid shell appropriate for the system Puppet is managing and displays the following message if a user tries to access the account:
~~~
$ ssh villain@centos56
This account is currently not available.
Connection to 172.16.214.129 closed.
~~~
### Manage SSH keys
Manage SSH keys with the `sshkeys` attribute of the `accounts::user` defined type. This parameter accepts an array of public key contents as strings.
Example:
~~~puppet
accounts::user { 'jeff':
comment => 'Jeff McCune',
groups => [
'admin',
'sudonopw',
],
uid => '1112',
gid => '1112',
sshkeys => [
'ssh-rsa AAAAB3Nza...== jeff@puppetlabs.com',
'ssh-dss AAAAB3Nza...== jeff@metamachine.net',
],
}
~~~
The module supports placing sshkeys in a custom location. If you specify a value
for the `sshkey_custom_path` attribute of the `accounts::user` defined type, the
module will place the keys in the specified file. The module will only manage
the specified file and not the full path. If you set `purge_sshkeys` to true, and
you have also set a custom path, it will only purge the ssh keys in the custom path.
Example:
~~~puppet
accounts::user { 'gerrard':
sshkey_custom_path => '/var/lib/ssh/gerrard/authorized_keys',
sshkey_group => 'root',
sshkey_owner => 'root',
shell => '/bin/zsh',
comment => 'Gerrard Geldenhuis',
groups => [
'engineering',
'automation',
],
uid => '1117',
gid => '1117',
sshkeys => [
'ssh-rsa AAAAB9Aza...== gerrard@dirtyfruit.co.uk',
'ssh-dss AAAAB9Aza...== gerrard@dojo.training',
],
password => '!!',
}
~~~
Setting `sshkey_custom_path` is typically associated with setting `AuthorizedKeysFile /var/lib/ssh/%u/authorized_keys` in your sshd config file.
<a id="data-in-hiera"></a>
### Data in Hiera
The accounts module supports storing all account data in Hiera.
Example:
~~~yaml
accounts::group_defaults:
system: true
accounts::group_list:
admins: {}
users: {}
accounts::user_defaults:
groups: [ 'users' ]
managehome: true
system: false
accounts::user_list:
admin:
groups: ['admins', 'users']
joe:
sshkeys:
- &joe_sshkey 'ssh-rsa ... joe@corp.com'
sally:
sshkeys:
- &sally_sshkey 'ssh-rsa ... sally@corp.com'
dba:
sshkeys:
- *joe_sshkey
- *sally_sshkey
system: true
~~~
~~~puppet
include ::accounts
~~~
## Reference
See [REFERENCE.md](https://github.com/puppetlabs/puppetlabs-accounts/blob/main/REFERENCE.md)
<a id="data-types"></a>
### Data types
#### `Accounts::Group::Hash`
A hash of [`group`](https://puppet.com/docs/puppet/latesttypes/group.html#group) data suitable for passing as the second parameter to [`ensure_resources`](https://github.com/puppetlabs/puppetlabs-stdlib#ensure_resources).
#### `Accounts::Group::Provider`
The allowed values for the [`provider`](https://puppet.com/docs/puppet/latest/types/group.html#group-attribute-provider) attribute. Currently, this is:
* `aix`
* `directoryservice`
* `groupadd`
* `ldap`
* `pw`
* `windows_adsi`
#### `Accounts::Group::Resource`
A struct of [`group` attributes](https://puppet.com/docs/puppet/latest/types/group.html#group-attributes) suitable for passing as the third parameter to [`ensure_resource`](https://github.com/puppetlabs/puppetlabs-stdlib#ensure_resource).
#### `Accounts::User::Expiry`
Allows either `'absent'` or a `YYY-MM-DD` datestring.
#### `Accounts::User::Hash`
A hash of [`user`](https://puppet.com/docs/puppet/latest/types/user.html#user) data suitable for passing as the second parameter to [`ensure_resources`](https://github.com/puppetlabs/puppetlabs-stdlib#ensure_resources).
#### `Accounts::User::Iterations`
The [`iterations`](https://puppet.com/docs/puppet/latest/types/user.html#user-attribute-iterations) attribute allows any positive integer, optionally expressed as a string.
#### `Accounts::User::Name`
Allows strings up to 32 characters long that begin with a lower case letter or underscore, followed by lower case letters, digits, underscores, or dashes, and optionally ending in a dollar sign. See [`useradd(8)`](http://manpages.ubuntu.com/manpages/precise/man8/useradd.8.html#caveats)
#### `Accounts::User::PasswordMaxAge`
Maximum number of days a password may be used before it must be changed. Allows any integer from `0` to `99999`. See [`user`](https://puppet.com/docs/puppet/latest/types/user.html#user-attribute-password_max_age) resource.
#### `Accounts::User::Resource`
A struct of [`user` attributes](https://puppet.com/docs/puppet/latest/types/user.html#user-attributes) suitable for passing as the third parameter to [`ensure_resource`](https://github.com/puppetlabs/puppetlabs-stdlib#ensure_resource).
#### `Accounts::User::Uid`
Allows any integer from `0` to `4294967295` (2<sup>32</sup> - 1), optionally expressed as a string.
## Limitations
For an extensive list of supported operating systems, see [metadata.json](https://github.com/puppetlabs/puppetlabs-accounts/blob/main/metadata.json)
### Changes from pe\_accounts
The accounts module is designed to take the place of the pe\_accounts module that shipped with PE versions 2015.2 and earlier. Some of the changes include the removal of the base class, improving the validation, and allowing more flexibility regarding which files should or should not be managed in a user's home directory.
For example, the .bashrc and .bash\_profile files are not managed by default but allow custom content to be passed in using the `bashrc_content` and `bash_profile_content` parameters. The content for these two files as managed by pe\_accounts can continue to be used by passing `bashrc_content => file('accounts/shell/bashrc')` and `bash_profile_content => file('accounts/shell/bash_profile')` to the `accounts::user` defined type.
## Development
Acceptance tests for this module leverage [puppet_litmus](https://github.com/puppetlabs/puppet_litmus).
To run the acceptance tests follow the instructions [here](https://github.com/puppetlabs/puppet_litmus/wiki/Tutorial:-use-Litmus-to-execute-acceptance-tests-with-a-sample-module-(MoTD)#install-the-necessary-gems-for-the-module).
You can also find a tutorial and walkthrough of using Litmus and the PDK on [YouTube](https://www.youtube.com/watch?v=FYfR7ZEGHoE).
If you run into an issue with this module, or if you would like to request a feature, please [file a ticket](https://tickets.puppetlabs.com/browse/MODULES/).
Every Monday the Puppet IA Content Team has [office hours](https://puppet.com/community/office-hours) in the [Puppet Community Slack](http://slack.puppet.com/), alternating between an EMEA friendly time (1300 UTC) and an Americas friendly time (0900 Pacific, 1700 UTC).
If you have problems getting this module up and running, please [contact Support](http://puppetlabs.com/services/customer-support).
If you submit a change to this module, be sure to regenerate the reference documentation as follows:
```bash
puppet strings generate --format markdown --out REFERENCE.md
```

View File

@@ -0,0 +1,800 @@
# Reference
<!-- DO NOT EDIT: This document was generated by Puppet Strings -->
## Table of Contents
### Classes
* [`accounts`](#accounts): This class auto-creates user and group resources from hiera data.
* [`accounts::user::defaults`](#accountsuserdefaults): Load some user defaults from hiera data.
### Defined types
#### Public Defined types
* [`accounts::user`](#accountsuser): This resource manages the user, group, vim/, .ssh/, .bash_profile, .bashrc,
homedir, .ssh/authorized_keys files, and directories.
#### Private Defined types
* `accounts::home_dir`: This resource specifies how home directories are managed.
* `accounts::key_management`: This resource specifies where ssh keys are managed.
* `accounts::manage_keys`: This resource manages ssh keys for a user.
### Functions
* [`accounts_ssh_authorized_keys_line_parser`](#accounts_ssh_authorized_keys_line_parser): Parse an ssh authorized_keys line string into an array using its expected pattern by using a combination of regex matching and extracting the
* [`accounts_ssh_options_parser`](#accounts_ssh_options_parser): Parse an ssh authorized_keys option string into an array using its expected pattern which matches a crazy regex slightly modified from shell
### Data types
* [`Accounts::Group::Hash`](#accountsgrouphash): A hash of group resources, keyed by group name.
* [`Accounts::Group::Provider`](#accountsgroupprovider): The specific backend to use for this group resource.
* [`Accounts::Group::Resource`](#accountsgroupresource): A hash of group attributes.
* [`Accounts::User::Expiry`](#accountsuserexpiry): Account access will be denied after this date.
* [`Accounts::User::Hash`](#accountsuserhash): A hash of user resources, keyed by user name.
* [`Accounts::User::Iterations`](#accountsuseriterations): Chained computation iterations for the PBKDF2 password hash.
* [`Accounts::User::Name`](#accountsusername): Each user or group should have a unique alphanumeric name.
* [`Accounts::User::PasswordMaxAge`](#accountsuserpasswordmaxage): Maximum days between password changes.
* [`Accounts::User::Resource`](#accountsuserresource): A hash of user attributes.
* [`Accounts::User::Uid`](#accountsuseruid): Each user on a system should have a unique numeric uid.
## Classes
### <a name="accounts"></a>`accounts`
This class auto-creates user and group resources from hiera data.
#### Parameters
The following parameters are available in the `accounts` class:
* [`group_defaults`](#group_defaults)
* [`group_list`](#group_list)
* [`user_defaults`](#user_defaults)
* [`user_list`](#user_list)
##### <a name="group_defaults"></a>`group_defaults`
Data type: `Accounts::Group::Resource`
Hash of default attributes for group resources managed by this class.
Default value: `{}`
##### <a name="group_list"></a>`group_list`
Data type: `Accounts::Group::Hash`
Hash of group resources for this class to manage. The hash is keyed by
group name.
Default value: `{}`
##### <a name="user_defaults"></a>`user_defaults`
Data type: `Accounts::User::Resource`
Hash of default attributes for accounts::user resources managed by this
class.
Default value: `{}`
##### <a name="user_list"></a>`user_list`
Data type: `Accounts::User::Hash`
Hash of accounts::user resources for this class to manage. The hash is
keyed by user name.
Default value: `{}`
### <a name="accountsuserdefaults"></a>`accounts::user::defaults`
Load some user defaults from hiera data.
#### Parameters
The following parameters are available in the `accounts::user::defaults` class:
* [`home_template`](#home_template)
* [`locked_shell`](#locked_shell)
* [`root_home`](#root_home)
##### <a name="home_template"></a>`home_template`
Data type: `Stdlib::AbsolutePath`
The sprintf template used to determine a user's home directory.
Default value: `'/home/%s'`
##### <a name="locked_shell"></a>`locked_shell`
Data type: `Stdlib::AbsolutePath`
The shell assigned to locked user accounts.
Default value: `'/sbin/nologin'`
##### <a name="root_home"></a>`root_home`
Data type: `Stdlib::AbsolutePath`
The home directory of the root user.
Default value: `'/root'`
## Defined types
### <a name="accountsuser"></a>`accounts::user`
This resource manages the user, group, vim/, .ssh/, .bash_profile, .bashrc,
homedir, .ssh/authorized_keys files, and directories.
#### Examples
##### Basic usage
```puppet
accounts::user { 'bob':
uid => '4001',
gid => '4001',
group => 'staff',
shell => '/bin/bash',
password => '!!',
locked => false,
}
```
#### Parameters
The following parameters are available in the `accounts::user` defined type:
* [`ensure`](#ensure)
* [`allowdupe`](#allowdupe)
* [`bash_profile_content`](#bash_profile_content)
* [`bash_profile_source`](#bash_profile_source)
* [`bashrc_content`](#bashrc_content)
* [`bashrc_source`](#bashrc_source)
* [`comment`](#comment)
* [`create_group`](#create_group)
* [`expiry`](#expiry)
* [`forcelocal`](#forcelocal)
* [`forward_content`](#forward_content)
* [`forward_source`](#forward_source)
* [`gid`](#gid)
* [`group`](#group)
* [`groups`](#groups)
* [`home`](#home)
* [`home_mode`](#home_mode)
* [`ignore_password_if_empty`](#ignore_password_if_empty)
* [`iterations`](#iterations)
* [`locked`](#locked)
* [`managehome`](#managehome)
* [`managevim`](#managevim)
* [`membership`](#membership)
* [`name`](#name)
* [`password`](#password)
* [`password_max_age`](#password_max_age)
* [`purge_sshkeys`](#purge_sshkeys)
* [`purge_user_home`](#purge_user_home)
* [`salt`](#salt)
* [`shell`](#shell)
* [`sshkey_custom_path`](#sshkey_custom_path)
* [`sshkey_group`](#sshkey_group)
* [`sshkey_owner`](#sshkey_owner)
* [`sshkey_mode`](#sshkey_mode)
* [`sshkeys`](#sshkeys)
* [`system`](#system)
* [`uid`](#uid)
##### <a name="ensure"></a>`ensure`
Data type: `Enum['absent','present']`
Specifies whether the user, its primary group, homedir, and ssh keys should
exist. Valid values are 'present' and 'absent'. Note that when a user is
created, a group with the same name as the user is also created.
Default value: `'present'`
##### <a name="allowdupe"></a>`allowdupe`
Data type: `Boolean`
Whether to allow duplicate UIDs. By default false
Default value: ``false``
##### <a name="bash_profile_content"></a>`bash_profile_content`
Data type: `Optional[String]`
The content to place in the user's ~/.bash_profile file. Mutually exclusive
to bash_profile_source.
Default value: ``undef``
##### <a name="bash_profile_source"></a>`bash_profile_source`
Data type: `Optional[Stdlib::Filesource]`
A source file containing the content to place in the user's ~/.bash_profile
file. Mutually exclusive to bash_profile_content.
Default value: ``undef``
##### <a name="bashrc_content"></a>`bashrc_content`
Data type: `Optional[String]`
The content to place in the user's ~/.bashrc file. Mutually exclusive to
bashrc_source.
Default value: ``undef``
##### <a name="bashrc_source"></a>`bashrc_source`
Data type: `Optional[Stdlib::Filesource]`
A source file containing the content to place in the user's ~/.bashrc file.
Mutually exclusive to bashrc_content.
Default value: ``undef``
##### <a name="comment"></a>`comment`
Data type: `String`
A comment describing or regarding the user.
Default value: `$name`
##### <a name="create_group"></a>`create_group`
Data type: `Boolean`
Specifies if you want to create a group with the user's name.
Default value: ``true``
##### <a name="expiry"></a>`expiry`
Data type: `Optional[Accounts::User::Expiry]`
Specifies the date the user account expires on. Valid values: YYYY-MM-DD
date format, or 'absent' to remove expiry date.
Default value: ``undef``
##### <a name="forcelocal"></a>`forcelocal`
Data type: `Optional[Boolean]`
Specifies whether you want to manage a local user/group that is also managed
by a network name service.
Default value: ``undef``
##### <a name="forward_content"></a>`forward_content`
Data type: `Optional[String]`
The content to place in the user's ~/.forward file. Mutually exclusive to
forward_source.
Default value: ``undef``
##### <a name="forward_source"></a>`forward_source`
Data type: `Optional[Stdlib::Filesource]`
A source file containing the content to place in the user's ~/.forward file.
Mutually exclusive to forward_content.
Default value: ``undef``
##### <a name="gid"></a>`gid`
Data type: `Optional[Accounts::User::Uid]`
Specifies the gid of the user's primary group. Must be specified
numerically.
Default value: ``undef``
##### <a name="group"></a>`group`
Data type: `Accounts::User::Name`
Specifies the name of the user's primary group. By default, this uses a
group named the same as user name
Default value: `$name`
##### <a name="groups"></a>`groups`
Data type: `Array[Accounts::User::Name]`
Specifies the user's group memberships.
Default value: `[]`
##### <a name="home"></a>`home`
Data type: `Optional[Stdlib::Unixpath]`
Specifies the path to the user's home directory.
- Linux, non-root user: '/home/$name'
- Linux, root user: '/root'
- Solaris, non-root user: '/export/home/$name'
- Solaris, root user: '/'
Default value: ``undef``
##### <a name="home_mode"></a>`home_mode`
Data type: `Optional[Stdlib::Filemode]`
Manages the user's home directory permission mode. Valid values are in octal
notation, specified as a string. Defaults to undef, which creates a home
directory with 0700 permissions. It does not touch them if the directory
already exists. Keeping it undef also allows a user to manage their own
permissions. If home_mode is set, Puppet enforces the permissions on every
run.
Default value: ``undef``
##### <a name="ignore_password_if_empty"></a>`ignore_password_if_empty`
Data type: `Boolean`
Specifies whether an empty password attribute should be ignored. If set to true,
a password attribute that is defined but set to the empty string is ignored,
allowing the password to be managed outside of this Puppet module. If set to false,
it sets the password to an empty value.
Default value: ``false``
##### <a name="iterations"></a>`iterations`
Data type: `Optional[Accounts::User::Iterations]`
This is the number of iterations of a chained computation of the PBKDF2
password hash. This field is required for managing passwords on OS X >=
10.8.
Default value: ``undef``
##### <a name="locked"></a>`locked`
Data type: `Boolean`
Specifies whether the account should be locked and the user prevented from
logging in. Set to true for users whose login privileges have been revoked.
Default value: ``false``
##### <a name="managehome"></a>`managehome`
Data type: `Boolean`
Specifies whether the user's home directory should be created when adding a
user.
Default value: ``true``
##### <a name="managevim"></a>`managevim`
Data type: `Boolean`
Specifies whether or not the .vim folder should be created within the
managed accounts home directory.
Default value: ``true``
##### <a name="membership"></a>`membership`
Data type: `Enum['inclusive','minimum']`
Establishes whether specified groups should be considered the complete list
(inclusive) or the minimum list (minimum) of groups to which the user
belongs. Valid values: 'inclusive', 'minimum'.
Default value: `'minimum'`
##### <a name="name"></a>`name`
Name of the user.
##### <a name="password"></a>`password`
Data type: `Variant[String, Sensitive[String]]`
The user's password, in whatever encrypted format the local machine
requires. Default: '!!', which prevents the user from logging in with a
password.
Default value: `'!!'`
##### <a name="password_max_age"></a>`password_max_age`
Data type: `Optional[Accounts::User::PasswordMaxAge]`
Maximum number of days a password may be used before it must be changed.
Allows any integer from `0` to `99999`. See the
[`user`](https://puppet.com/docs/puppet/latest/types/user.html#user-attribute-password_max_age)
resource.
Default value: ``undef``
##### <a name="purge_sshkeys"></a>`purge_sshkeys`
Data type: `Boolean`
Whether keys not included in sshkeys should be removed from the user. If
purge_sshkeys is true and sshkeys is an empty array, all SSH keys will be
removed from the user.
Default value: ``false``
##### <a name="purge_user_home"></a>`purge_user_home`
Data type: `Boolean`
Whether to force recurse remove user home directories when removing a user.
Defaults to false.
Default value: ``false``
##### <a name="salt"></a>`salt`
Data type: `Optional[String]`
This is the 32-byte salt used to generate the PBKDF2 password used in OS X.
This field is required for managing passwords on OS X >= 10.8.
Default value: ``undef``
##### <a name="shell"></a>`shell`
Data type: `Optional[Stdlib::Unixpath]`
Manages the user shell.
Default value: `'/bin/bash'`
##### <a name="sshkey_custom_path"></a>`sshkey_custom_path`
Data type: `Optional[Stdlib::Unixpath]`
Custom location for ssh public key file.
Default value: ``undef``
##### <a name="sshkey_group"></a>`sshkey_group`
Data type: `Optional[Accounts::User::Name]`
Specifies the group of the sshkey file
Default value: `$group`
##### <a name="sshkey_owner"></a>`sshkey_owner`
Data type: `Optional[Accounts::User::Name]`
Specifies the owner of the sshkey file
Default value: `$name`
##### <a name="sshkey_mode"></a>`sshkey_mode`
Data type: `Variant[Integer[0],String]`
Specifies the mode of the sshkey file .ssh/authorized_keys.
Default value: `'0600'`
##### <a name="sshkeys"></a>`sshkeys`
Data type: `Array[String]`
An array of SSH public keys associated with the user. These should be
complete public key strings that include the type, content and name of the
key, exactly as it would appear in its id_*.pub file, or with an optional
options string preceding the other components, as it would appear as an
entry in an authorized_keys file. Must be an array.
Examples:
- ssh-rsa AAAAB3NzaC1y... bob@example.com
- from="myhost.example.com,192.168.1.1" ssh-rsa AAAAQ4ng... bob2@example.com
Note that for multiple keys, the name component (the last) must be unique.
Default value: `[]`
##### <a name="system"></a>`system`
Data type: `Boolean`
Specifies if you want to create a system account.
Default value: ``false``
##### <a name="uid"></a>`uid`
Data type: `Optional[Accounts::User::Uid]`
Specifies the user's uid number. Must be specified numerically.
Default value: ``undef``
## Functions
### <a name="accounts_ssh_authorized_keys_line_parser"></a>`accounts_ssh_authorized_keys_line_parser`
Type: Ruby 4.x API
Parse an ssh authorized_keys line string into an array using its expected
pattern by using a combination of regex matching and extracting the substring
before the match as ssh-options. This allows whitespaces inside the options
and inside the comment and is consistent with the behavior of openssh.
The returned options element can by an empty string.
#### Examples
##### Calling the function
```puppet
accounts_ssh_authorized_keys_line_parser_string('options ssh-rsa AAAA... comment)
```
#### `accounts_ssh_authorized_keys_line_parser(String $str)`
Parse an ssh authorized_keys line string into an array using its expected
pattern by using a combination of regex matching and extracting the substring
before the match as ssh-options. This allows whitespaces inside the options
and inside the comment and is consistent with the behavior of openssh.
The returned options element can by an empty string.
Returns: `Array` of authroized_keys_line components:
['options','keytype','key','comment']
##### Examples
###### Calling the function
```puppet
accounts_ssh_authorized_keys_line_parser_string('options ssh-rsa AAAA... comment)
```
##### `str`
Data type: `String`
ssh authorized_keys line string
### <a name="accounts_ssh_options_parser"></a>`accounts_ssh_options_parser`
Type: Ruby 4.x API
Parse an ssh authorized_keys option string into an array using its expected pattern which matches a crazy regex slightly modified
from shell words. The pattern should be a string.
#### Examples
##### Calling the function
```puppet
accounts_ssh_option_parser_string()
```
#### `accounts_ssh_options_parser(String $str)`
Parse an ssh authorized_keys option string into an array using its expected pattern which matches a crazy regex slightly modified
from shell words. The pattern should be a string.
Returns: `Array` Separated components of the string
##### Examples
###### Calling the function
```puppet
accounts_ssh_option_parser_string()
```
##### `str`
Data type: `String`
ssh authorized_keys option string
## Data types
### <a name="accountsgrouphash"></a>`Accounts::Group::Hash`
Group resoureces hash.
Passed as the second parameter of the ensure_resources function.
Alias of
```puppet
Hash[Accounts::User::Name, Accounts::Group::Resource]
```
### <a name="accountsgroupprovider"></a>`Accounts::Group::Provider`
Group provider.
You will seldom need to specify this -- Puppet will usually discover the
appropriate provider for your platform.
Alias of
```puppet
Enum['aix', 'directoryservice', 'groupadd', 'ldap', 'pw', 'windows_adsi']
```
### <a name="accountsgroupresource"></a>`Accounts::Group::Resource`
Group attributes hash.
Passed as the third parameter of the ensure_resources function.
Alias of
```puppet
Struct[{ Optional[ensure] => Enum['absent', 'present'],
Optional[allowdupe] => Boolean,
Optional[auth_membership] => Boolean,
Optional[forcelocal] => Boolean,
Optional[gid] => Accounts::User::Uid,
Optional[members] => Array[Accounts::User::Name],
Optional[name] => Accounts::User::Name,
Optional[provider] => Accounts::Group::Provider,
Optional[system] => Boolean,
}]
```
### <a name="accountsuserexpiry"></a>`Accounts::User::Expiry`
Account expiration date.
Either 'absent' or a YYYY-MM-DD datestring.
Alias of
```puppet
Variant[Enum['absent'], Pattern[/\A(19|[2-9]\d)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])\z/]]
```
### <a name="accountsuserhash"></a>`Accounts::User::Hash`
User resources hash.
Passed as the second parameter of the ensure_resources function.
Alias of
```puppet
Hash[Accounts::User::Name, Accounts::User::Resource]
```
### <a name="accountsuseriterations"></a>`Accounts::User::Iterations`
Password hash iterations.
This parameter is used in OS X, and is required for managing passwords
on OS X 10.8 and newer.
Alias of
```puppet
Variant[Integer[1,], Pattern[/\A[1-9]\d*\z/]]
```
### <a name="accountsusername"></a>`Accounts::User::Name`
Account (user or group) name.
From useradd(8): It is usually recommended to only use usernames
that begin with a lower case letter or an underscore, followed by lower case
letters, digits, underscores, or dashes. They can end with a dollar sign.
Usernames may only be up to 32 characters long.
Many installations also allow capitals or periods, for example to separate first and
last names.
Alias of
```puppet
Pattern[/\A[a-zA-Z0-9_]([a-zA-Z.0-9_-]{0,30}[a-zA-Z0-9_$-])?\z/]
```
### <a name="accountsuserpasswordmaxage"></a>`Accounts::User::PasswordMaxAge`
Max password age.
On most systems, the default value of 99999 is about 274 years, which
effectively disables password aging.
Alias of
```puppet
Integer[1, 99999]
```
### <a name="accountsuserresource"></a>`Accounts::User::Resource`
User attributes hash.
Passed as the third parameter of the ensure_resources function.
Alias of
```puppet
Struct[{ Optional[ensure] => Enum['absent','present'],
Optional[allowdupe] => Boolean,
Optional[bash_profile_content] => String,
Optional[bash_profile_source] => Stdlib::Filesource,
Optional[bashrc_content] => String,
Optional[bashrc_source] => Stdlib::Filesource,
Optional[comment] => String,
Optional[create_group] => Boolean,
Optional[expiry] => Accounts::User::Expiry,
Optional[forcelocal] => Boolean,
Optional[forward_content] => String,
Optional[forward_source] => Stdlib::Filesource,
Optional[gid] => Accounts::User::Uid,
Optional[group] => Accounts::User::Name,
Optional[groups] => Array[Accounts::User::Name],
Optional[name] => Accounts::User::Name,
Optional[home] => Stdlib::Unixpath,
Optional[home_mode] => Stdlib::Filemode,
Optional[ignore_password_if_empty] => Boolean,
Optional[iterations] => Accounts::User::Iterations,
Optional[locked] => Boolean,
Optional[managehome] => Boolean,
Optional[managevim] => Boolean,
Optional[membership] => Enum['inclusive','minimum'],
Optional[name] => Accounts::User::Name,
Optional[password] => String,
Optional[password_max_age] => Accounts::User::PasswordMaxAge,
Optional[purge_sshkeys] => Boolean,
Optional[purge_user_home] => Boolean,
Optional[salt] => String,
Optional[shell] => Stdlib::Unixpath,
Optional[sshkey_custom_path] => Stdlib::Unixpath,
Optional[sshkey_owner] => Accounts::User::Name,
Optional[sshkey_group] => Accounts::User::Name,
Optional[sshkeys] => Array[String],
Optional[system] => Boolean,
Optional[uid] => Accounts::User::Uid,
}]
```
### <a name="accountsuseruid"></a>`Accounts::User::Uid`
Numeric user ID.
On most Unix systems, the highest uid is 2^32 - 1, or 4294967295.
Alias of
```puppet
Variant[Integer[0,4294967295], Pattern[/\A0\z/,
/\A[1-3]\d{0,9}\z/,
/\A[4-9]\d{0,8}\z/,
/\A4[0-1]\d{8}\z/,
/\A42[0-8]\d{7}\z/,
/\A429[0-3]\d{6}\z/,
/\A4294[0-8]\d{5}\z/,
/\A42949[0-5]\d{4}\z/,
/\A429496[0-6]\d{3}\z/,
/\A4294967[0-1]\d{2}\z/,
/\A42949672[0-8]\d\z/,
/\A429496729[0-5]\z/,
]]
```

View File

@@ -0,0 +1,89 @@
# frozen_string_literal: true
require 'bundler'
require 'puppet_litmus/rake_tasks' if Bundler.rubygems.find_name('puppet_litmus').any?
require 'puppetlabs_spec_helper/rake_tasks'
require 'puppet-syntax/tasks/puppet-syntax'
require 'puppet_blacksmith/rake_tasks' if Bundler.rubygems.find_name('puppet-blacksmith').any?
require 'github_changelog_generator/task' if Bundler.rubygems.find_name('github_changelog_generator').any?
require 'puppet-strings/tasks' if Bundler.rubygems.find_name('puppet-strings').any?
def changelog_user
return unless Rake.application.top_level_tasks.include? "changelog"
returnVal = nil || JSON.load(File.read('metadata.json'))['author']
raise "unable to find the changelog_user in .sync.yml, or the author in metadata.json" if returnVal.nil?
puts "GitHubChangelogGenerator user:#{returnVal}"
returnVal
end
def changelog_project
return unless Rake.application.top_level_tasks.include? "changelog"
returnVal = nil
returnVal ||= begin
metadata_source = JSON.load(File.read('metadata.json'))['source']
metadata_source_match = metadata_source && metadata_source.match(%r{.*\/([^\/]*?)(?:\.git)?\Z})
metadata_source_match && metadata_source_match[1]
end
raise "unable to find the changelog_project in .sync.yml or calculate it from the source in metadata.json" if returnVal.nil?
puts "GitHubChangelogGenerator project:#{returnVal}"
returnVal
end
def changelog_future_release
return unless Rake.application.top_level_tasks.include? "changelog"
returnVal = "v%s" % JSON.load(File.read('metadata.json'))['version']
raise "unable to find the future_release (version) in metadata.json" if returnVal.nil?
puts "GitHubChangelogGenerator future_release:#{returnVal}"
returnVal
end
PuppetLint.configuration.send('disable_relative')
if Bundler.rubygems.find_name('github_changelog_generator').any?
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
raise "Set CHANGELOG_GITHUB_TOKEN environment variable eg 'export CHANGELOG_GITHUB_TOKEN=valid_token_here'" if Rake.application.top_level_tasks.include? "changelog" and ENV['CHANGELOG_GITHUB_TOKEN'].nil?
config.user = "#{changelog_user}"
config.project = "#{changelog_project}"
config.future_release = "#{changelog_future_release}"
config.exclude_labels = ['maintenance']
config.header = "# Change log\n\nAll notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org)."
config.add_pr_wo_labels = true
config.issues = false
config.merge_prefix = "### UNCATEGORIZED PRS; LABEL THEM ON GITHUB"
config.configure_sections = {
"Changed" => {
"prefix" => "### Changed",
"labels" => ["backwards-incompatible"],
},
"Added" => {
"prefix" => "### Added",
"labels" => ["enhancement", "feature"],
},
"Fixed" => {
"prefix" => "### Fixed",
"labels" => ["bug", "documentation", "bugfix"],
},
}
end
else
desc 'Generate a Changelog from GitHub'
task :changelog do
raise <<EOM
The changelog tasks depends on recent features of the github_changelog_generator gem.
Please manually add it to your .sync.yml for now, and run `pdk update`:
---
Gemfile:
optional:
':development':
- gem: 'github_changelog_generator'
version: '~> 1.15'
condition: "Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0')"
EOM
end
end

View File

@@ -0,0 +1,14 @@
# just install puppet module for other modules to use
# example use:
# accounts::user { 'user':
# uid => '4001',
# gid => '4001',
# shell => '/bin/bash',
# name => 'user',
# # password = password
# password => '$6$$bLTg4cpho8PIUrjfsE7qlU08Qx2UEfw..xOc6I1wpGVtyVYToGrr7BzRdAAnEr5lYFr1Z9WcCf1xNZ1HG9qFW1',
#
# # sshkeys => "ssh-rsa AAAA...",
# # locked => false,
# }

View File

@@ -0,0 +1,5 @@
---
accounts::user::defaults::home_template: '/home/%s'
accounts::user::defaults::locked_shell: '/usr/sbin/nologin'
accounts::user::defaults::root_home: '/root'

View File

@@ -0,0 +1,5 @@
---
accounts::user::defaults::home_template: '/export/home/%s'
accounts::user::defaults::locked_shell: '/usr/bin/false'
accounts::user::defaults::root_home: '/'

View File

@@ -0,0 +1 @@
--- {}

View File

@@ -0,0 +1,46 @@
group { 'admin':
gid => 3000,
}
group { 'sudo':
gid => 3001,
}
group { 'sudonopw':
gid => 3002,
}
group { 'developer':
gid => 3003,
}
group { 'ops':
gid => 3004,
}
file { '/var/lib/ssh/jeff':
ensure => directory,
owner => 'jeff',
group => 'jeff',
}
accounts::user { 'jeff':
sshkey_custom_path => '/var/lib/ssh/jeff/authorized_keys',
sshkey_group => 'root',
sshkey_owner => 'root',
shell => '/bin/zsh',
comment => 'Jeff McCune',
groups => [
'admin',
'sudonopw',
],
uid => '1112',
gid => '1112',
locked => true,
sshkeys => [
'ssh-rsa AAAAB3Nza...== jeff@puppetlabs.com',
'ssh-dss AAAAB3Nza...== jeff@metamachine.net',
],
password => '!!',
}
accounts::user { 'dan':
comment => 'Dan Bode',
uid => '1109',
gid => '1109',
}

View File

@@ -0,0 +1,40 @@
group { 'admin':
gid => 3000,
}
group { 'sudo':
gid => 3001,
}
group { 'sudonopw':
gid => 3002,
}
group { 'developer':
gid => 3003,
}
group { 'ops':
gid => 3004,
}
file { '/var/lib/ssh/jeff':
ensure => directory,
owner => 'jeff',
group => 'jeff',
}
accounts::user { 'jeff':
sshkey_custom_path => '/var/lib/ssh/jeff/authorized_keys',
shell => '/bin/zsh',
comment => 'Jeff McCune',
purge_sshkeys => true,
groups => [
'admin',
'sudonopw',
],
uid => '1112',
gid => '1112',
locked => true,
sshkeys => [
'ssh-rsa BBBBB3Nza...== jeff@puppetlabs.com',
'ssh-dss BBBBB3Nza...== jeff@metamachine.net',
],
password => '!!',
}

View File

@@ -0,0 +1,23 @@
# Use a variable OR with hiera_hash():
# This example uses a common group name for both users
$users_hash = {
'jblow' => {
'comment' => 'Joe Blow',
'groups' => [wheel],
'uid' => '1115',
'gid' => '1115',
'group' => 'mrblow',
'sshkeys' => [
'ssh-rsa AAAAB3Nza...== jblow@puppetlabs.com',
'ssh-dss AAAAB3Nza...== jblow@googler.net',
],
'password' => '!!',
},
'kblow' => {
'comment' => 'Ken Blow',
'group' => 'mrblow',
'password' => '!!',
},
}
create_resources('accounts::user', $users_hash)

View File

@@ -0,0 +1,37 @@
group { 'admin':
gid => 3000,
}
group { 'sudo':
gid => 3001,
}
group { 'sudonopw':
gid => 3002,
}
group { 'developer':
gid => 3003,
}
group { 'ops':
gid => 3004,
}
accounts::user { 'jeff':
shell => '/bin/zsh',
comment => 'Jeff McCune',
groups => [
'admin',
'sudonopw',
],
uid => '1112',
gid => '1112',
locked => true,
sshkeys => [
'ssh-rsa AAAAB3Nza...== jeff@puppetlabs.com',
'ssh-dss AAAAB3Nza...== jeff@metamachine.net',
],
password => '!!',
}
accounts::user { 'dan':
comment => 'Dan Bode',
uid => '1109',
gid => '1109',
}

View File

@@ -0,0 +1,31 @@
# Use a variable OR with hiera_hash():
$groups_hash = {
'admin' => { gid => '3000' },
'sudo' => { gid => '3001' },
'sudonopw' => { gid => '3002' },
'developer' => { gid => '3003' },
'ops' => { gid => '3004' },
}
create_resources('group', $groups_hash)
$users_hash = {
'jeff' => {
'shell' => '/bin/zsh',
'comment' => 'Jeff McCune',
'groups' => [admin, sudonopw,],
'uid' => '1112',
'gid' => '1112',
'locked' => true,
'sshkeys' => [
'ssh-rsa AAAAB3Nza...== jeff@puppetlabs.com',
'ssh-dss AAAAB3Nza...== jeff@metamachine.net',
],
'password' => '!!',
},
'dan' => {
'comment' => 'Dan Bode',
'uid' => '1109',
'gid' => '1109',
},
}
create_resources('accounts::user', $users_hash)

View File

@@ -0,0 +1,13 @@
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
unset USERNAME

View File

@@ -0,0 +1,27 @@
# .bashrc
# This file is managed by Puppet. Changes will be overwritten.
# Please edit ~/.bashrc.custom instead of this file!
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Set the prompt
PS1='\u@\h:\w\$ '
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# Puppet specific definitions
if [ -f /etc/bashrc.puppet ]; then
. /etc/bashrc.puppet
fi
# Account holder definitions
if [ -f ~/.bashrc.custom ]; then
. ~/.bashrc.custom
fi

View File

@@ -0,0 +1,11 @@
---
version: 5
defaults:
data_hash: 'yaml_data'
datadir: 'data'
hierarchy:
- name: 'os.family'
path: '%{facts.os.family}.yaml'

View File

@@ -0,0 +1,24 @@
# frozen_string_literal: true
# Parse an ssh authorized_keys line string into an array using its expected
# pattern by using a combination of regex matching and extracting the substring
# before the match as ssh-options. This allows whitespaces inside the options
# and inside the comment and is consistent with the behavior of openssh.
# The returned options element can by an empty string.
Puppet::Functions.create_function(:accounts_ssh_authorized_keys_line_parser) do
# @param str ssh authorized_keys line string
# @return [Array] of authroized_keys_line components:
# ['options','keytype','key','comment']
# @example Calling the function
# accounts_ssh_authorized_keys_line_parser_string('options ssh-rsa AAAA... comment)
dispatch :accounts_ssh_authorized_keys_line_parser_string do
param 'String', :str
end
def accounts_ssh_authorized_keys_line_parser_string(str)
matched = str.match(%r{((sk-ssh-ed25519|sk-ecdsa-|ssh-|ecdsa-)[^\s]+)\s+([^\s]+)\s+(.*)$})
raise ArgumentError, 'Wrong Keyline format!' unless matched && matched.length == 5
options = str[0, str.index(matched[0])].rstrip
[options, matched[1], matched[3], matched[4]]
end
end

View File

@@ -0,0 +1,29 @@
# frozen_string_literal: true
# Parse an ssh authorized_keys option string into an array using its expected pattern which matches a crazy regex slightly modified
# from shell words. The pattern should be a string.
Puppet::Functions.create_function(:accounts_ssh_options_parser) do
# @param str ssh authorized_keys option string
# @return [Array] Separated components of the string
# @example Calling the function
# accounts_ssh_option_parser_string()
dispatch :accounts_ssh_options_parser_string do
param 'String', :str
end
def accounts_ssh_options_parser_string(str)
words = []
field = ''
str.scan(%r{\G\,*(?>([^\,\\\'\"]+)|'([^\']*)'|("(?:[^\"\\]|\\.)*")|(\\.?)|(\S))(\,|\z)?}m) do |word, sq, dq, esc, garbage, sep|
raise ArgumentError, _('Unmatched double quote: %{str_inspect}') % { str_inspect: str.inspect } if garbage
field += (word || sq || dq || esc.gsub(%r{\\(.)}, '\\1'))
field.gsub(%r{\\=}, '\\=\"')
if sep
words << field
field = ''
end
end
words
end
end

View File

@@ -0,0 +1,146 @@
# @summary
# This resource specifies how home directories are managed.
#
# @param ensure
# Specifies whether the user, its primary group, homedir, and ssh keys should
# exist. Valid values are 'present' and 'absent'. Note that when a user is
# created, a group with the same name as the user is also created.
#
# @param bash_profile_content
# The content to place in the user's ~/.bash_profile file. Mutually exclusive
# to bash_profile_source.
#
# @param bash_profile_source
# A source file containing the content to place in the user's ~/.bash_profile
# file. Mutually exclusive to bash_profile_content.
#
# @param bashrc_content
# The content to place in the user's ~/.bashrc file. Mutually exclusive to
# bashrc_source.
#
# @param bashrc_source
# A source file containing the content to place in the user's ~/.bashrc file.
# Mutually exclusive to bashrc_content.
#
# @param forward_content
# The content to place in the user's ~/.forward file. Mutually exclusive to
# forward_source.
#
# @param forward_source
# A source file containing the content to place in the user's ~/.forward file.
# Mutually exclusive to forward_content.
#
# @param group
# Name of the user's primary group.
#
# @param managevim
# Specifies whether or not the .vim folder should be created within the
# managed account's home directory.
#
# @param mode
# Manages the user's home directory permission mode. Valid values are in octal
# notation.
#
# @param name
# Path of the home directory that is being managed.
#
# @param user
# Name of the user that owns all of the files being created.
#
# @api private
#
define accounts::home_dir (
Enum['absent','present'] $ensure = 'present',
Optional[String] $bash_profile_content = undef,
Optional[Stdlib::Filesource] $bash_profile_source = undef,
Optional[String] $bashrc_content = undef,
Optional[Stdlib::Filesource] $bashrc_source = undef,
Optional[String] $forward_content = undef,
Optional[Stdlib::Filesource] $forward_source = undef,
Optional[Accounts::User::Name] $group = undef,
Boolean $managevim = true,
Optional[Stdlib::Filemode] $mode = undef,
Optional[Accounts::User::Name] $user = undef,
) {
assert_type(Stdlib::Unixpath, $name)
if $ensure == 'absent' {
fail('To remove home directories, use the `file` resource.')
} else {
assert_type(Accounts::User::Name, $group)
assert_type(Accounts::User::Name, $user)
# Solaris homedirs are managed in zfs by `useradd -m`. If the directory
# does not yet exist then we can't predict how it should be created, but we
# should still manage the user/group/mode
file { $name:
ensure => directory,
owner => $user,
group => $group,
mode => $mode,
}
if $managevim {
file { "${name}/.vim":
ensure => directory,
owner => $user,
group => $group,
mode => '0700',
}
}
if $bashrc_content or $bashrc_source {
file { "${name}/.bashrc":
ensure => file,
owner => $user,
group => $group,
mode => '0644',
}
if $bashrc_content {
File["${name}/.bashrc"] {
content => $bashrc_content,
}
}
if $bashrc_source {
File["${name}/.bashrc"] {
source => $bashrc_source,
}
}
}
if $bash_profile_content or $bash_profile_source {
file { "${name}/.bash_profile":
ensure => file,
owner => $user,
group => $group,
mode => '0644',
}
if $bash_profile_content {
File["${name}/.bash_profile"] {
content => $bash_profile_content,
}
}
if $bash_profile_source {
File["${name}/.bash_profile"] {
source => $bash_profile_source,
}
}
}
if $forward_content or $forward_source {
file { "${name}/.forward":
ensure => file,
owner => $user,
group => $group,
mode => '0644',
}
if $forward_content {
File["${name}/.forward"] {
content => $forward_content,
}
}
if $forward_source {
File["${name}/.forward"] {
source => $forward_source,
}
}
}
}
}

View File

@@ -0,0 +1,27 @@
# @summary
# This class auto-creates user and group resources from hiera data.
#
# @param group_defaults
# Hash of default attributes for group resources managed by this class.
#
# @param group_list
# Hash of group resources for this class to manage. The hash is keyed by
# group name.
#
# @param user_defaults
# Hash of default attributes for accounts::user resources managed by this
# class.
#
# @param user_list
# Hash of accounts::user resources for this class to manage. The hash is
# keyed by user name.
#
class accounts (
Accounts::Group::Resource $group_defaults = {},
Accounts::Group::Hash $group_list = {},
Accounts::User::Resource $user_defaults = {},
Accounts::User::Hash $user_list = {},
) {
ensure_resources('group', $group_list, $group_defaults)
ensure_resources('accounts::user', $user_list, $user_defaults)
}

View File

@@ -0,0 +1,113 @@
# @summary
# This resource specifies where ssh keys are managed.
#
# @param user
# User that owns all of the files being created.
#
# @param ensure
# Specifies whether the key will be added ('present') or removed ('absent').
#
# @param group
# Name of the user's primary group.
#
# @param purge_user_home
# Whether to force recurse remove user home directories when removing a user.
#
# @param sshkey_custom_path
# Path to custom file for ssh key management.
#
# @param sshkey_group
# Specifies the group of the ssh key file.
#
# @param sshkey_owner
# Specifies the owner of the ssh key file.
#
# @param sshkey_mode
# Specifies the mode of the ssh key file.
#
# @param sshkeys
# List of ssh keys to be added for this user in this directory.
#
# @param user_home
# Specifies the path to the user's home directory.
#
# @api private
#
define accounts::key_management (
Accounts::User::Name $user,
Enum['absent','present'] $ensure = 'present',
Optional[Accounts::User::Name] $group = undef,
Boolean $purge_user_home = false,
Optional[Stdlib::Unixpath] $sshkey_custom_path = undef,
Accounts::User::Name $sshkey_group = $group,
Accounts::User::Name $sshkey_owner = $user,
Variant[Integer[0],String] $sshkey_mode = '0600',
Array[String] $sshkeys = [],
Optional[Stdlib::Unixpath] $user_home = undef,
) {
if $user_home {
$sshkey_dotdir = "${user_home}/.ssh"
}
if $sshkey_custom_path != undef {
$key_file = $sshkey_custom_path.sprintf($user)
} elsif $user_home {
$key_file = "${sshkey_dotdir}/authorized_keys"
} else {
err('Either user_home or sshkey_custom_path must be specified')
}
if $ensure == 'present' {
file { $key_file:
ensure => 'file',
owner => $sshkey_owner,
group => $sshkey_group,
mode => $sshkey_mode,
}
if $user_home {
file { $sshkey_dotdir:
ensure => 'directory',
owner => $user,
group => $group,
mode => '0700',
}
}
if $sshkey_custom_path != undef {
$sshkey_require = File[$key_file]
} else {
$sshkey_require = File[$sshkey_dotdir]
}
$sshkey_before = undef
} else {
if $purge_user_home and $user_home {
file { $sshkey_dotdir:
ensure => 'absent',
before => User[$user],
recurse => true,
force => true,
}
$sshkey_before = [File[$key_file], File[$sshkey_dotdir]]
} else {
$sshkey_before = File[$key_file]
}
file { $key_file:
ensure => 'absent',
before => User[$user],
}
$sshkey_require = undef
}
if $sshkeys != [] {
$sshkeys.each |$sshkey| {
accounts::manage_keys { "${sshkey} for ${user}":
ensure => $ensure,
keyspec => $sshkey,
user => $user,
key_owner => $sshkey_owner,
key_file => $key_file,
require => $sshkey_require,
before => $sshkey_before,
}
}
}
}

View File

@@ -0,0 +1,58 @@
# @summary
# This resource manages ssh keys for a user.
#
# @param key_file
# Specifies the path of the ssh key file.
#
# @param keyspec
# Specifies the content of the ssh key file.
#
# @param user
# Specifies the ssh login username.
#
# @param ensure
# Specifies whether the keys will be added ('present') or removed ('absent').
#
# @param key_owner
# Specifies the owner of the ssh key file.
#
# @api private
#
define accounts::manage_keys (
Stdlib::Unixpath $key_file,
String $keyspec,
Accounts::User::Name $user,
Enum['absent','present'] $ensure = 'present',
Accounts::User::Name $key_owner = $user,
) {
$key_def = accounts_ssh_authorized_keys_line_parser($keyspec)
if (! $key_def) {
err("Could not interpret SSH key definition: '${keyspec}'")
}
else {
if (! empty($key_def[0])) {
$key_options = accounts_ssh_options_parser($key_def[0])
} else {
$key_options = undef
}
$key_type = $key_def[1]
$key_content = $key_def[2]
$key_md5 = md5($key_def[2])
$key_name = "${key_def[3]}_${key_md5}"
$key_title = "${user}_${key_type}_${key_name}"
if $ensure == 'absent' {
Ssh_authorized_key[$key_title] -> User[$user]
}
ssh_authorized_key { $key_title:
ensure => $ensure,
user => $key_owner,
key => $key_content,
type => $key_type,
options => $key_options,
target => $key_file,
}
}
}

View File

@@ -0,0 +1,368 @@
# @summary
# This resource manages the user, group, vim/, .ssh/, .bash_profile, .bashrc,
# homedir, .ssh/authorized_keys files, and directories.
#
# @example Basic usage
# accounts::user { 'bob':
# uid => '4001',
# gid => '4001',
# group => 'staff',
# shell => '/bin/bash',
# password => '!!',
# locked => false,
# }
#
# @param ensure
# Specifies whether the user, its primary group, homedir, and ssh keys should
# exist. Valid values are 'present' and 'absent'. Note that when a user is
# created, a group with the same name as the user is also created.
#
# @param allowdupe
# Whether to allow duplicate UIDs. By default false
#
# @param bash_profile_content
# The content to place in the user's ~/.bash_profile file. Mutually exclusive
# to bash_profile_source.
#
# @param bash_profile_source
# A source file containing the content to place in the user's ~/.bash_profile
# file. Mutually exclusive to bash_profile_content.
#
# @param bashrc_content
# The content to place in the user's ~/.bashrc file. Mutually exclusive to
# bashrc_source.
#
# @param bashrc_source
# A source file containing the content to place in the user's ~/.bashrc file.
# Mutually exclusive to bashrc_content.
#
# @param comment
# A comment describing or regarding the user.
#
# @param create_group
# Specifies if you want to create a group with the user's name.
#
# @param expiry
# Specifies the date the user account expires on. Valid values: YYYY-MM-DD
# date format, or 'absent' to remove expiry date.
#
# @param forcelocal
# Specifies whether you want to manage a local user/group that is also managed
# by a network name service.
#
# @param forward_content
# The content to place in the user's ~/.forward file. Mutually exclusive to
# forward_source.
#
# @param forward_source
# A source file containing the content to place in the user's ~/.forward file.
# Mutually exclusive to forward_content.
#
# @param gid
# Specifies the gid of the user's primary group. Must be specified
# numerically.
#
# @param group
# Specifies the name of the user's primary group. By default, this uses a
# group named the same as user name
#
# @param groups
# Specifies the user's group memberships.
#
# @param home
# Specifies the path to the user's home directory.
#
# - Linux, non-root user: '/home/$name'
#
# - Linux, root user: '/root'
#
# - Solaris, non-root user: '/export/home/$name'
#
# - Solaris, root user: '/'
#
# @param home_mode
# Manages the user's home directory permission mode. Valid values are in octal
# notation, specified as a string. Defaults to undef, which creates a home
# directory with 0700 permissions. It does not touch them if the directory
# already exists. Keeping it undef also allows a user to manage their own
# permissions. If home_mode is set, Puppet enforces the permissions on every
# run.
#
# @param ignore_password_if_empty
# Specifies whether an empty password attribute should be ignored. If set to true,
# a password attribute that is defined but set to the empty string is ignored,
# allowing the password to be managed outside of this Puppet module. If set to false,
# it sets the password to an empty value.
#
# @param iterations
# This is the number of iterations of a chained computation of the PBKDF2
# password hash. This field is required for managing passwords on OS X >=
# 10.8.
#
# @param locked
# Specifies whether the account should be locked and the user prevented from
# logging in. Set to true for users whose login privileges have been revoked.
#
# @param managehome
# Specifies whether the user's home directory should be created when adding a
# user.
#
# @param managevim
# Specifies whether or not the .vim folder should be created within the
# managed accounts home directory.
#
# @param membership
# Establishes whether specified groups should be considered the complete list
# (inclusive) or the minimum list (minimum) of groups to which the user
# belongs. Valid values: 'inclusive', 'minimum'.
#
# @param name
# Name of the user.
#
# @param password
# The user's password, in whatever encrypted format the local machine
# requires. Default: '!!', which prevents the user from logging in with a
# password.
#
# @param password_max_age
# Maximum number of days a password may be used before it must be changed.
# Allows any integer from `0` to `99999`. See the
# [`user`](https://puppet.com/docs/puppet/latest/types/user.html#user-attribute-password_max_age)
# resource.
#
# @param purge_sshkeys
# Whether keys not included in sshkeys should be removed from the user. If
# purge_sshkeys is true and sshkeys is an empty array, all SSH keys will be
# removed from the user.
#
# @param purge_user_home
# Whether to force recurse remove user home directories when removing a user.
# Defaults to false.
#
# @param salt
# This is the 32-byte salt used to generate the PBKDF2 password used in OS X.
# This field is required for managing passwords on OS X >= 10.8.
#
# @param shell
# Manages the user shell.
#
# @param sshkey_custom_path
# Custom location for ssh public key file.
#
# @param sshkey_group
# Specifies the group of the sshkey file
#
# @param sshkey_owner
# Specifies the owner of the sshkey file
#
# @param sshkey_mode
# Specifies the mode of the sshkey file .ssh/authorized_keys.
#
# @param sshkeys
# An array of SSH public keys associated with the user. These should be
# complete public key strings that include the type, content and name of the
# key, exactly as it would appear in its id_*.pub file, or with an optional
# options string preceding the other components, as it would appear as an
# entry in an authorized_keys file. Must be an array.
#
# Examples:
#
# - ssh-rsa AAAAB3NzaC1y... bob@example.com
#
# - from="myhost.example.com,192.168.1.1" ssh-rsa AAAAQ4ng... bob2@example.com
#
# Note that for multiple keys, the name component (the last) must be unique.
#
# @param system
# Specifies if you want to create a system account.
#
# @param uid
# Specifies the user's uid number. Must be specified numerically.
#
define accounts::user (
Enum['absent','present'] $ensure = 'present',
Boolean $allowdupe = false,
Optional[String] $bash_profile_content = undef,
Optional[Stdlib::Filesource] $bash_profile_source = undef,
Optional[String] $bashrc_content = undef,
Optional[Stdlib::Filesource] $bashrc_source = undef,
String $comment = $name,
Boolean $create_group = true,
Optional[Accounts::User::Expiry] $expiry = undef,
Optional[Boolean] $forcelocal = undef,
Optional[String] $forward_content = undef,
Optional[Stdlib::Filesource] $forward_source = undef,
Optional[Accounts::User::Uid] $gid = undef,
Accounts::User::Name $group = $name,
Array[Accounts::User::Name] $groups = [],
Optional[Stdlib::Unixpath] $home = undef,
Optional[Stdlib::Filemode] $home_mode = undef,
Boolean $ignore_password_if_empty = false,
Optional[Accounts::User::Iterations] $iterations = undef,
Boolean $locked = false,
Boolean $managehome = true,
Boolean $managevim = true,
Enum['inclusive','minimum'] $membership = 'minimum',
Variant[String, Sensitive[String]] $password = '!!',
Optional[Accounts::User::PasswordMaxAge] $password_max_age = undef,
Boolean $purge_sshkeys = false,
Boolean $purge_user_home = false,
Optional[String] $salt = undef,
Stdlib::Unixpath $shell = '/bin/bash',
Optional[Stdlib::Unixpath] $sshkey_custom_path = undef,
Optional[Accounts::User::Name] $sshkey_group = $group,
Optional[Accounts::User::Name] $sshkey_owner = $name,
Variant[Integer[0],String] $sshkey_mode = '0600',
Array[String] $sshkeys = [],
Boolean $system = false,
Optional[Accounts::User::Uid] $uid = undef,
) {
assert_type(Accounts::User::Name, $name)
include accounts::user::defaults
$_home = $home ? {
undef => $name ? {
'root' => $accounts::user::defaults::root_home,
default => $accounts::user::defaults::home_template.sprintf($name),
},
default => $home,
}
if $ensure == 'absent' {
user { $name:
ensure => 'absent',
forcelocal => $forcelocal,
home => $_home,
managehome => false, # Workaround for PUP-9706; see below.
}
# The core `user` resource will fail when removing users on Solaris if
# `ensure => 'absent', managhome => true` and the homedir does not exist.
# We therefore force `managehome => false` when `ensure => 'absent'`, and
# remove the homedir as a separate operation.
# See https://tickets.puppetlabs.com/browse/PUP-9706
if $purge_user_home {
file { $_home:
ensure => 'absent',
recurse => true,
force => true,
}
}
# End workaround.
User[$name] -> Group <| ensure == 'absent' |>
if $create_group {
# Only remove the group if it is the same as user name as it may be shared.
if $name == $group {
ensure_resource(
'group',
$group,
{ 'ensure' => 'absent',
'forcelocal' => $forcelocal,
}
)
}
}
accounts::key_management { "${name}_key_management":
ensure => 'absent',
user => $name,
user_home => $_home,
sshkeys => $sshkeys,
sshkey_custom_path => $sshkey_custom_path,
sshkey_owner => $sshkey_owner,
sshkey_group => $sshkey_group,
purge_user_home => $purge_user_home,
}
} else {
# Check if user wants to create the group
if $create_group and ! defined(Group[$group]) {
Group[$group] -> User[$name]
ensure_resource(
'group',
$group,
{ ensure => 'present',
gid => $gid,
system => $system,
forcelocal => $forcelocal,
}
)
}
$_password = (($password =~ String and $password == '') and $ignore_password_if_empty) ? {
true => undef,
default => $password,
}
$_purge_sshkeys = ($purge_sshkeys and $sshkey_custom_path != undef) ? {
true => [String($sshkey_custom_path)],
default => $purge_sshkeys,
}
$_shell = $locked ? {
true => $accounts::user::defaults::locked_shell,
default => $shell,
}
user { $name:
ensure => 'present',
allowdupe => $allowdupe,
comment => String($comment),
expiry => $expiry,
forcelocal => $forcelocal,
gid => $group,
groups => $groups,
home => $_home,
iterations => $iterations,
managehome => $managehome,
membership => $membership,
password => $_password,
password_max_age => $password_max_age,
purge_ssh_keys => $_purge_sshkeys,
salt => $salt,
shell => $_shell,
system => $system,
uid => $uid,
}
if $managehome {
accounts::home_dir { $_home:
ensure => 'present',
mode => $home_mode,
managevim => $managevim,
bashrc_content => $bashrc_content,
bashrc_source => $bashrc_source,
bash_profile_content => $bash_profile_content,
bash_profile_source => $bash_profile_source,
forward_content => $forward_content,
forward_source => $forward_source,
user => $name,
group => $group,
require => [User[$name]],
}
accounts::key_management { "${name}_key_management":
ensure => 'present',
user => $name,
group => $group,
user_home => $_home,
sshkeys => $sshkeys,
sshkey_custom_path => $sshkey_custom_path,
sshkey_owner => $sshkey_owner,
sshkey_group => $sshkey_group,
sshkey_mode => $sshkey_mode,
purge_user_home => $purge_user_home,
require => Accounts::Home_dir[$_home],
}
} elsif $sshkeys != [] {
# We are not managing the user's home directory but we have specified a
# custom, non-home directory for the ssh keys.
if (($sshkey_custom_path != undef) and ($ensure == 'present')) {
accounts::key_management { "${name}_key_management":
ensure => 'present',
user => $name,
group => $group,
sshkeys => $sshkeys,
sshkey_owner => $sshkey_owner,
sshkey_group => $sshkey_group,
sshkey_mode => $sshkey_mode,
sshkey_custom_path => $sshkey_custom_path,
}
} else {
warning("ssh keys were passed for user ${name} but managehome is set to false; not managing user ssh keys")
}
}
}
}

View File

@@ -0,0 +1,19 @@
# @summary
# Load some user defaults from hiera data.
#
# @param home_template
# The sprintf template used to determine a user's home directory.
#
# @param locked_shell
# The shell assigned to locked user accounts.
#
# @param root_home
# The home directory of the root user.
#
class accounts::user::defaults (
Stdlib::AbsolutePath $home_template = '/home/%s',
Stdlib::AbsolutePath $locked_shell = '/sbin/nologin',
Stdlib::AbsolutePath $root_home = '/root',
) {
# Nothing to see here; move along.
}

View File

@@ -0,0 +1,96 @@
{
"name": "puppetlabs-accounts",
"version": "7.2.0",
"author": "puppetlabs",
"summary": "Account management module.",
"license": "Apache-2.0",
"source": "https://github.com/puppetlabs/puppetlabs-accounts",
"project_page": "https://github.com/puppetlabs/puppetlabs-accounts",
"issues_url": "https://tickets.puppetlabs.com/browse/MODULES",
"dependencies": [
{
"name": "puppetlabs/stdlib",
"version_requirement": ">= 5.0.0 < 9.0.0"
}
],
"operatingsystem_support": [
{
"operatingsystem": "RedHat",
"operatingsystemrelease": [
"6",
"7",
"8",
"9"
]
},
{
"operatingsystem": "CentOS",
"operatingsystemrelease": [
"7",
"8"
]
},
{
"operatingsystem": "OracleLinux",
"operatingsystemrelease": [
"6",
"7"
]
},
{
"operatingsystem": "Scientific",
"operatingsystemrelease": [
"6",
"7"
]
},
{
"operatingsystem": "Debian",
"operatingsystemrelease": [
"9",
"10",
"11"
]
},
{
"operatingsystem": "SLES",
"operatingsystemrelease": [
"15"
]
},
{
"operatingsystem": "Ubuntu",
"operatingsystemrelease": [
"18.04",
"20.04"
]
},
{
"operatingsystem": "Solaris",
"operatingsystemrelease": [
"11"
]
},
{
"operatingsystem": "Rocky",
"operatingsystemrelease": [
"8"
]
},
{
"operatingsystem": "AlmaLinux",
"operatingsystemrelease": [
"8"
]
}
],
"requirements": [
{
"name": "puppet",
"version_requirement": ">= 6.0.0 < 8.0.0"
}
],
"template-url": "https://github.com/puppetlabs/pdk-templates.git#main",
"template-ref": "heads/main-0-g806810b",
"pdk-version": "2.3.0"
}

View File

@@ -0,0 +1,68 @@
---
default:
provisioner: docker
images:
- litmusimage/centos:7
vagrant:
provisioner: vagrant
images:
- centos/7
- generic/ubuntu1804
travis_deb:
provisioner: docker
images:
- litmusimage/debian:8
- litmusimage/debian:9
- litmusimage/debian:10
travis_ub_6:
provisioner: docker
images:
- litmusimage/ubuntu:14.04
- litmusimage/ubuntu:16.04
- litmusimage/ubuntu:18.04
- litmusimage/ubuntu:20.04
travis_el7:
provisioner: docker
images:
- litmusimage/centos:7
- litmusimage/oraclelinux:7
- litmusimage/scientificlinux:7
travis_el8:
provisioner: docker
images:
- litmusimage/centos:8
release_checks_6:
provisioner: abs
images:
- redhat-6-x86_64
- redhat-7-x86_64
- redhat-8-x86_64
- centos-6-x86_64
- centos-7-x86_64
- centos-8-x86_64
- oracle-6-x86_64
- oracle-7-x86_64
- scientific-6-x86_64
- scientific-7-x86_64
- debian-8-x86_64
- debian-9-x86_64
- debian-10-x86_64
- sles-15-x86_64
- ubuntu-1404-x86_64
- ubuntu-1604-x86_64
- ubuntu-1804-x86_64
- ubuntu-2004-x86_64
release_checks_7:
provisioner: abs
images:
- redhat-7-x86_64
- redhat-8-x86_64
- centos-7-x86_64
- centos-8-x86_64
- oracle-7-x86_64
- debian-9-x86_64
- debian-10-x86_64
- scientific-7-x86_64
- sles-15-x86_64
- ubuntu-1804-x86_64
- ubuntu-2004-x86_64

View File

@@ -0,0 +1,151 @@
# アカウント
#### 目次
1. [説明](#description)
2. [セットアップ - アカウントを開始するにあたっての基本設定](#setup)
3. [使用方法 - 設定オプションと追加機能](#usage)
* [ユーザアカウントの宣言](#declare-user-accounts)
* [ホームディレクトリのカスタマイズ](#customize-the-home-directory)
* [アカウントのロック](#lock-accounts)
* [SSHキーの管理](#manage-ssh-keys)
4. [参考 - モジュールの機能と動作について](#reference)
5. [制約事項 - OSの互換性など](#limitations)
6. [開発 - モジュール貢献についてのガイド](#development)
## 説明
アカウントモジュールは、ログインアカウントとサービスアカウントに関連するリソースを管理します。
このモジュールは、多くのUNIX/Linuxオペレーティングシステムで動作します。Microsoft Windowsプラットフォームでのアカウントの設定はサポートされていません。
## セットアップ
### アカウントの使用開始
Puppetで管理されているードのマニフェストで`accounts`クラスを宣言します。
~~~puppet
node default {
accounts::user { 'dan': }
accounts::user { 'morgan': }
}
~~~
上記の例では、DanとMorganのアカウント、ホームディレクトリ、グループを作成しています。
## 使用方法
### ユーザアカウントの宣言
~~~puppet
accounts::user { 'bob':
uid => '4001',
gid => '4001',
group => 'staff',
shell => '/bin/bash',
password => '!!',
locked => false,
}
~~~
### ホームディレクトリのカスタマイズ
単純なbashrcおよびbash\ _profile rcファイルは、各アカウントのPuppetによって管理されます。これらのrcファイルは単純なエイリアスの追加、プロンプトの更新、パスへの~/binの追加を行い、(このモジュールでは管理されていない)次のファイルを以下の順序でソースします。
1. `/etc/bashrc`
2. `/etc/bashrc.puppet`
3. `~/.bashrc.custom`
アカウント所有者は、bashrc.customファイルを管理することでシェルをカスタマイズできます。さらに、システム管理者は、 '/etc/bashrc.puppet'ファイルを管理することで、bashシェルを持つすべてのアカウントに影響を与えるプロファイルの変更を行うことができます。
電子メールフォワードをインストールするには、 `forward_content`または` forward_source`パラメータを使って `.forward`ファイルを設定します。
### アカウントのロック
アカウントの`locked`パラメータをtrueに設定して、アカウントをロックします。
例: 
~~~puppet
accounts::user { 'villain':
comment => 'Bad Person',
locked => true
}
~~~
アカウントモジュールは、Puppetが管理しているシステムに適した無効なシェルにアカウントを設定し、ユーザがそのアカウントにアクセスしようとすると次のメッセージを表示します。
~~~
$ ssh villain@centos56
This account is currently not available.
Connection to 172.16.214.129 closed.
~~~
### SSHキーの管理
`accounts::user`定義型の`sshkeys`属性でSSHキーを管理します。このパラメータは、パブリックキーコンテンツの配列を文字列として受け取ります。
例:
~~~puppet
accounts::user { 'jeff':
comment => 'Jeff McCune',
groups => [
'admin',
'sudonopw',
],
uid => '1112',
gid => '1112',
sshkeys => [
'ssh-rsa AAAAB3Nza...== jeff@puppetlabs.com',
'ssh-dss AAAAB3Nza...== jeff@metamachine.net',
],
}
~~~
このモジュールは、カスタムロケーションでのSSHキーの配置をサポートしています。`accounts::user` 定義型の`sshkey_custom_path`属性の値を指定すると、モジュールは指定されたファイルにキーを配置します。このモジュールはフルパスではなく、指定されたファイルのみを管理します。`purge_sshkeys`をtrueに設定してカスタムパスを設定した場合、カスタムパスのSSHキーのみがパージされます。
例:
~~~puppet
accounts::user { 'gerrard':
sshkey_custom_path => '/var/lib/ssh/gerrard/authorized_keys',
shell => '/bin/zsh',
comment => 'Gerrard Geldenhuis',
groups => [
'engineering',
'automation',
],
uid => '1117',
gid => '1117',
sshkeys => [
'ssh-rsa AAAAB9Aza...== gerrard@dirtyfruit.co.uk',
'ssh-dss AAAAB9Aza...== gerrard@dojo.training',
],
password => '!!',
}
~~~
`sshkey_custom_path`の設定は、通常、sshd設定ファイルの`AuthorizedKeysFile /var/lib/ssh/%u/authorized_keys`の設定に関連します。
## リファレンス
[REFERENCE.md](https://github.com/puppetlabs/puppetlabs-accounts/blob/main/REFERENCE.md)を参照してください。
## 制約事項
サポートされているオペレーティングシステムの一覧については、[metadata.json](https://github.com/puppetlabs/puppetlabs-accounts/blob/main/metadata.json)を参照してください。
### pe\_accountsからの変更
アカウントモジュールは、PEバージョン2015.2以前に同梱されているpe\_accountsモジュールの置き換えとして設計されています。変更の一部には、基本クラスの削除、検証の改善、ユーザのホームディレクトリで管理すべきファイルと管理すべきではないファイルに関する柔軟性の強化が含まれます。
例えば、.bashrcと.bash\_profileの各ファイルはデフォルトでは管理されませんが、`bashrc_content`パラメータと`bash_profile_content`パラメータを使ってカスタムコンテンツを渡すことができます。pe\_accountsで管理されているこれらの2つのファイルのコンテンツは、`bashrc_content => file('accounts/shell/bashrc')``bash_profile_content => file('accounts/shell/bash_profile')``accounts::user`定義型に渡すことで引き続き使用できます.
## 開発
本モジュールで問題が発生した場合、またはリクエストしたい機能がある場合、[チケットを送信](https://tickets.puppetlabs.com/browse/MODULES/)してください。
本モジュールの導入時に問題がある場合は、[サポートにお問い合わせ](http://puppetlabs.com/services/customer-support)ください。

View File

@@ -0,0 +1,26 @@
<?xml version="1.0"?>
<utility xmlns="http://www.github/cliffe/SecGen/utility"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.github/cliffe/SecGen/utility">
<name>User account service</name>
<author>Puppet Labs</author>
<author>Jason Keighley</author>
<module_license>Apache v2</module_license>
<description>User account creation and modification</description>
<type>system</type>
<type>puppet_import</type>
<platform>linux</platform>
<!--optional details-->
<reference>https://forge.puppet.com/puppetlabs/accounts</reference>
<conflict>
<module_path>.*/bases/.*wheezy.*</name>
</conflict>
<conflict>
<module_path>.*/bases/.*stretch.*</name>
</conflict>
</utility>

View File

@@ -0,0 +1,519 @@
# frozen_string_literal: true
require 'spec_helper_acceptance'
test_key = 'AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz'\
'4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKL'\
'v6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7P'\
'tixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJ'\
'nAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96h'\
'rucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ=='
hd_defaults = {
'accounts::user_defaults' => {
'home_mode' => '0700',
},
}
hd_group = {
'accounts::group_defaults' => {
'ensure' => 'present',
'system' => true,
},
'accounts::group_list' => {
'staff' => {
'gid' => 1234,
},
},
}
hd_group_change = hd_group.merge(
'accounts::group_list' => {
'staff' => {
'gid' => 1235,
},
},
)
hd_accounts_define = hd_defaults.merge(
'accounts::user_list' => {
'hunner' => {
'groups' => ['root'],
'password' => 'hi',
'password_max_age' => 60,
'shell' => '/bin/true',
'home' => '/test/hunner',
'managevim' => false,
'bashrc_source' => 'puppet:///modules/accounts/shell/bashrc',
'bash_profile_source' => 'puppet:///modules/accounts/shell/bash_profile',
'sshkeys' => [
"ssh-rsa #{test_key} vagrant",
'command="/bin/echo Hello",from="myhost.exapmle.com,192.168.1.1" '\
"ssh-rsa #{test_key} vagrant2",
],
},
},
)
hd_accounts_with_custom_key_path_define = hd_defaults.merge(
'accounts::user_list' => {
'hunner' => {
'sshkey_custom_path' => '/test/sshkeys/hunner',
'sshkey_owner' => 'root',
'sshkey_group' => 'root',
'groups' => ['root'],
'password' => 'hi',
'password_max_age' => 60,
'shell' => '/bin/true',
'home' => '/test/hunner',
'managevim' => false,
'bashrc_source' => 'puppet:///modules/accounts/shell/bashrc',
'bash_profile_source' => 'puppet:///modules/accounts/shell/bash_profile',
'sshkeys' => [
"ssh-rsa #{test_key} vagrant",
'command="/bin/echo Hello",from="myhost.exapmle.com,192.168.1.1" '\
"ssh-rsa #{test_key} vagrant2",
],
},
},
)
hd_without_managehome = hd_defaults.merge(
'accounts::user_list' => {
'hunner' => {
'managehome' => false,
'sshkeys' => [
"ssh-rsa #{test_key} vagrant",
],
},
},
)
hd_with_managevim = hd_defaults.merge(
'accounts::user_list' => {
'hunner' => {
'groups' => ['root'],
'password' => 'hi',
'shell' => '/bin/true',
'home' => '/test/hunner',
'home_mode' => '0700',
'managevim' => true,
'bashrc_source' => 'puppet:///modules/accounts/shell/bashrc',
'bash_profile_source' => 'puppet:///modules/accounts/shell/bash_profile',
'sshkeys' => [
"ssh-rsa #{test_key} vagrant",
'from="myhost.example.com,192.168.1.1" '\
"ssh-rsa #{test_key} vagrant2",
],
},
},
)
hd_locked_user = hd_defaults.merge(
'accounts::user_list' => {
'hunner' => {
'locked' => true,
},
},
)
hd_custom_group_name = hd_defaults.merge(
'accounts::user_list' => {
'first.last' => {
'group' => 'staff',
'password' => '!!',
'home' => '/test/first.last',
},
},
)
hd_create_group_false = hd_defaults.merge(
'accounts::user_list' => {
'grp_flse' => {
'group' => 'newgrp_1',
'create_group' => false,
'home' => '/test/grp_flse',
},
},
)
hd_create_group_true = hd_defaults.merge(
'accounts::user_list' => {
'grp_true' => {
'group' => 'newgrp_2',
'create_group' => true,
'home' => '/test/grp_true',
},
},
)
hd_ignore_user_first_run = hd_defaults.merge(
'accounts::user_list' => {
'ignore_user' => {
'group' => 'staff',
'password' => 'foo',
},
},
)
hd_ignore_user_second_run = hd_defaults.merge(
'accounts::user_list' => {
'ignore_user' => {
'group' => 'staff',
'password' => '',
'ignore_password_if_empty' => true,
},
},
)
hd_no_ignore_user_first_run = hd_defaults.merge(
'accounts::user_list' => {
'no_ignore_user' => {
'group' => 'staff',
'password' => 'foo',
},
},
)
hd_no_ignore_user_second_run = hd_defaults.merge(
'accounts::user_list' => {
'no_ignore_user' => {
'group' => 'staff',
'password' => '',
'ignore_password_if_empty' => false,
},
},
)
hd_specd_user_first_run = hd_defaults.merge(
'accounts::user_list' => {
'specd_user' => {
'group' => 'staff',
'password' => 'foo',
},
},
)
hd_specd_user_second_run = hd_defaults.merge(
'accounts::user_list' => {
'specd_user' => {
'group' => 'staff',
'password' => 'bar',
'ignore_password_if_empty' => true,
},
},
)
hd_user_with_duplicate_id = hd_defaults.merge(
'accounts::user_list' => {
'duplicate_user1' => {
'allowdupe' => true,
'uid' => '1234',
'sshkey_owner' => 'duplicate_user1',
},
'duplicate_user2' => {
'allowdupe' => true,
'uid' => 1234,
'sshkey_owner' => 'duplicate_user1',
},
},
)
hd_delete_accounts = {
'accounts::group_defaults' => {
'ensure' => 'absent',
},
'accounts::group_list' => {
'newgrp_1' => {},
'newgrp_2' => {},
'staff' => {},
},
'accounts::user_defaults' => {
'ensure' => 'absent',
'create_group' => true,
'purge_user_home' => true,
},
'accounts::user_list' => {
'hunner' => {
'home' => '/test/hunner',
'sshkey_custom_path' => '/test/sshkeys/hunner',
'sshkey_owner' => 'root',
'sshkey_group' => 'root',
'sshkeys' => [
"ssh-rsa #{test_key} vagrant",
"ssh-rsa #{test_key} vagrant2",
],
},
'first.last' => {
'home' => '/test/first.last',
},
'grp_flse' => {
'home' => '/test/grp_flse',
},
'grp_true' => {
'home' => '/test/grp_true',
},
'ignore_user' => {},
'no_ignore_user' => {},
'specd_user' => {},
'duplicate_user1' => {},
'duplicate_user2' => {},
},
}
pp_manifest = <<-PUPPETCODE
file { '/test':
ensure => 'directory',
before => Class['accounts'],
}
include ::accounts
PUPPETCODE
pp_manifest_custom_sshkey = <<-PUPPETCODE
file { '/test':
ensure => 'directory',
before => Class['accounts'],
}
file { '/test/sshkeys':
ensure => 'directory',
before => Class['accounts'],
}
include ::accounts
PUPPETCODE
pp_cleanup = <<-PUPPETCODE
include ::accounts
file { '/test':
ensure => 'absent',
force => true,
}
PUPPETCODE
describe 'accounts invoke', unless: UNSUPPORTED_PLATFORMS.include?(os[:family]) do
describe 'group test' do
it 'creates group with specified gid' do
set_hieradata(hd_group)
apply_manifest(pp_manifest, catch_failures: true)
expect(group('staff')).to exist
expect(group('staff')).to have_gid 1234
end
it 'changes existing group id' do
set_hieradata(hd_group)
apply_manifest(pp_manifest, catch_failures: true)
set_hieradata(hd_group_change)
apply_manifest(pp_manifest, catch_failures: true)
expect(group('staff')).to exist
expect(group('staff')).to have_gid 1235
end
end
describe 'main tests' do
it 'creates groups of matching names, assigns non-matching group, '\
'manages homedir, manages other properties, gives key, '\
'makes dotfiles, managevim false' do
set_hieradata(hd_accounts_define)
apply_manifest(pp_manifest, catch_failures: true)
expect(user('hunner')).to exist
expect(user('hunner')).to belong_to_group 'hunner'
expect(user('hunner')).to belong_to_group 'root'
expect(user('hunner')).to have_login_shell '/bin/true'
expect(user('hunner')).to have_home_directory '/test/hunner'
expect(user('hunner')).to contain_password 'hi' unless os[:family] == 'solaris'
expect(user('hunner').maximum_days_between_password_change).to match 60
expect(file('/test/hunner')).to be_directory
expect(file('/test/hunner')).to be_mode 700
expect(file('/test/hunner')).to be_owned_by 'hunner'
expect(file('/test/hunner')).to be_grouped_into 'hunner'
expect(file('/test/hunner/.bashrc')).to be_file
expect(file('/test/hunner/.bashrc').content).to match %r{managed by Puppet}
expect(file('/test/hunner/.bash_profile')).to be_file
expect(file('/test/hunner/.bash_profile').content).to match %r{Get the aliases and functions}
expect(file('/test/hunner/.vim')).not_to exist
end
end
describe 'main tests with custom key path' do
it 'manages ssh key in a separate directory' do
set_hieradata(hd_accounts_with_custom_key_path_define)
apply_manifest(pp_manifest_custom_sshkey, catch_failures: true)
expect(user('hunner')).to exist
expect(file('/test/hunner')).to be_directory
expect(file('/test/hunner')).to be_mode 700
expect(file('/test/hunner')).to be_owned_by 'hunner'
expect(file('/test/hunner')).to be_grouped_into 'hunner'
expect(file('/test/hunner/.ssh/authorized_key')).not_to exist
expect(file('/test/sshkeys/hunner')).to be_file
expect(file('/test/sshkeys/hunner')).to be_owned_by 'root'
end
end
describe 'warn for sshkeys without managehome' do
it 'creates groups of matching names, assigns non-matching group, '\
'manages homedir, manages other properties, gives key, '\
'makes dotfiles' do
set_hieradata(hd_without_managehome)
apply_manifest(pp_manifest, catch_failures: true) do |r|
expect(r.stderr).to match(%r{Warning:.*ssh keys were passed for user hunner})
end
end
end
describe 'managevim set to true' do
it 'creates .vim file' do
set_hieradata(hd_with_managevim)
apply_manifest(pp_manifest, catch_failures: true)
expect(file('/test/hunner/.vim')).to be_directory
end
end
describe 'locking users' do
let(:login_shell) do
case os[:family]
when %r{debian|ubuntu}
'/usr/sbin/nologin'
when 'solaris'
'/usr/bin/false'
else
'/sbin/nologin'
end
end
it 'locks a user' do
set_hieradata(hd_locked_user)
apply_manifest(pp_manifest, catch_failures: true)
expect(user('hunner')).to have_login_shell login_shell
end
end
describe 'create user with custom group name' do
it 'creates group of matching names, assigns non-matching group, '\
'manages homedir' do
set_hieradata(hd_custom_group_name)
apply_manifest(pp_manifest, catch_failures: true)
expect(user('first.last')).to exist
expect(user('first.last')).to belong_to_group 'staff'
expect(user('first.last')).to have_home_directory '/test/first.last'
expect(file('/test/first.last')).to be_directory
expect(file('/test/first.last')).to be_mode 700
expect(file('/test/first.last')).to be_owned_by 'first.last'
expect(file('/test/first.last')).to be_grouped_into 'staff'
end
end
describe 'group set to false does not create group' do
it 'does not create group' do
set_hieradata(hd_create_group_false)
apply_manifest(pp_manifest, expect_failures: true) do |r|
expect(r.stderr).to match(%r{(.*group '?newgrp_1'? does not exist.*|.*Unknown group `?newgrp_1'?.*)})
end
expect(user('grp_flse')).not_to exist
expect(user('grp_flse')).not_to belong_to_group 'new_group_1'
end
end
describe 'group set to true creates group' do
it 'creates group' do
set_hieradata(hd_create_group_true)
apply_manifest(pp_manifest, catch_failures: true)
expect(user('grp_true')).to exist
expect(user('grp_true')).to belong_to_group 'newgrp_2'
end
end
# Solaris does not offer a means of testing the password
describe 'ignore password if ignore set to true', unless: os[:family] == 'solaris' do
it 'creates group of matching names, assigns non-matching group,'\
'empty password, ignore true, ignores password' do
set_hieradata(hd_ignore_user_first_run)
apply_manifest(pp_manifest, catch_failures: true)
set_hieradata(hd_ignore_user_second_run)
apply_manifest(pp_manifest, catch_failures: true)
expect(user('ignore_user')).to exist
expect(user('ignore_user')).to contain_password 'foo'
end
end
# Solaris does not offer a means of testing the password
describe 'do not ignore password if ignore set to false', unless: os[:family] == 'solaris' do
it 'creates group of matching names, assigns non-matching group,'\
'empty password, ignore false, should not ignore password' do
set_hieradata(hd_no_ignore_user_first_run)
apply_manifest(pp_manifest, catch_failures: true)
set_hieradata(hd_no_ignore_user_second_run)
apply_manifest(pp_manifest, catch_failures: true)
expect(user('no_ignore_user')).to exist
expect(user('no_ignore_user')).to contain_password ''
end
end
describe 'do not ignore password if set and ignore set to true', unless: os[:family] == 'solaris' do
it 'creates group of matching names, assigns non-matching group, '\
'specify password, ignore, should not ignore password' do
set_hieradata(hd_specd_user_first_run)
apply_manifest(pp_manifest, catch_failures: true)
set_hieradata(hd_specd_user_second_run)
apply_manifest(pp_manifest, catch_failures: true)
expect(user('specd_user')).to exist
expect(user('specd_user')).to contain_password 'bar'
end
end
describe 'create duplicate users with same uid' do
it 'runs with no errors' do
set_hieradata(hd_user_with_duplicate_id)
apply_manifest(pp_manifest, catch_failures: true)
expect(user('duplicate_user1')).to exist
expect(user('duplicate_user1')).to have_uid 1234
expect(user('duplicate_user2')).to exist
expect(user('duplicate_user2')).to have_uid 1234
end
end
describe 'delete accounts' do
it 'removes users and groups' do
set_hieradata(hd_delete_accounts)
apply_manifest(pp_cleanup, catch_failures: true)
expect(file('/test')).not_to exist
expect(file('/home/ignore_user')).not_to exist
expect(file('/home/no_ignore_user')).not_to exist
expect(file('/home/specd_user')).not_to exist
expect(file('/home/duplicate_user1')).not_to exist
expect(file('/home/duplicate_user2')).not_to exist
expect(file('/test/sshkeys/hunner')).not_to exist
expect(user('hunner')).not_to exist
expect(user('first.last')).not_to exist
expect(user('grp_flse')).not_to exist
expect(user('grp_true')).not_to exist
expect(user('ignore_user')).not_to exist
expect(user('no_ignore_user')).not_to exist
expect(user('specd_user')).not_to exist
expect(user('duplicate_user1')).not_to exist
expect(user('duplicate_user2')).not_to exist
expect(group('staff')).not_to exist
expect(group('hunner')).not_to exist
expect(group('newgrp_1')).not_to exist
expect(group('newgrp_2')).not_to exist
expect(group('duplicate_user1')).not_to exist
expect(group('duplicate_user2')).not_to exist
end
end
end

View File

@@ -0,0 +1,405 @@
# frozen_string_literal: true
require 'spec_helper_acceptance'
test_key = 'AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8Hfd'\
'OV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9W'\
'hQ=='
ecdsa_test_key = 'AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNlpEm6+RwCiQXgQAb0P1asEAxCJDVtm/YYyUbdSifCbri98fjs1C/03pm9yLRQ0W/S70S8AhDCMjVFA07WzjOQ='
ecdsa_sk_test_key = 'AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBAjkGvdKC05udQc82xGWWSKHbmJyBoa/oCq+2FiU6udqQyx0uOEC3YZAjvygBSdIo5vCpDELqJxaNQGQEkeUyYYAAAAEc3NoOg=='
pp_accounts_define = <<-PUPPETCODE
file { '/test':
ensure => directory,
before => Accounts::User['hunner'],
}
if $facts['puppetversion'][0] == '6' {
$key_test = [
'ssh-rsa #{test_key} vagrant',
'command="/bin/echo Hello",from="myhost.example.com,192.168.1.1" ssh-rsa #{test_key} vagrant2'
]
}
else {
$key_test = [#{' '}
'ssh-rsa #{test_key} vagrant',
'command="/bin/echo Hello",from="myhost.example.com,192.168.1.1" ssh-rsa #{test_key} vagrant2',
'ecdsa-sha2-nistp256 #{ecdsa_test_key} vagrant3',
'sk-ecdsa-sha2-nistp256@openssh.com #{ecdsa_sk_test_key} vagrant4'
]
}
accounts::user { 'hunner':
groups => ['root'],
password => 'hi',
shell => '/bin/true',
home => '/test/hunner',
home_mode => '0700',
managevim => false,
bashrc_content => file('accounts/shell/bashrc'),
bash_profile_content => file('accounts/shell/bash_profile'),
sshkeys => $key_test,
}
PUPPETCODE
pp_without_managehome = <<-PUPPETCODE
accounts::user { 'hunner':
managehome => false,
sshkeys => [
'ssh-rsa #{test_key} vagrant',
],
}
PUPPETCODE
pp_with_managevim = <<-PUPPETCODE
file { '/test':
ensure => directory,
before => Accounts::User['hunner'],
}
if $facts['puppetversion'][0] == '6' {
$key_test = [
'ssh-rsa #{test_key} vagrant',
'command="/bin/echo Hello",from="myhost.example.com,192.168.1.1" ssh-rsa #{test_key} vagrant2'
]
}
else {
$key_test = [#{' '}
'ssh-rsa #{test_key} vagrant',
'command="/bin/echo Hello",from="myhost.example.com,192.168.1.1" ssh-rsa #{test_key} vagrant2',
'ecdsa-sha2-nistp256 #{ecdsa_test_key} vagrant3',
'sk-ecdsa-sha2-nistp256@openssh.com #{ecdsa_sk_test_key} vagrant4'
]
}
accounts::user { 'hunner':
groups => ['root'],
password => 'hi',
shell => '/bin/true',
home => '/test/hunner',
home_mode => '0700',
managevim => true,
bashrc_content => file('accounts/shell/bashrc'),
bash_profile_content => file('accounts/shell/bash_profile'),
sshkeys => $key_test,
}
PUPPETCODE
pp_locked_user = <<-PUPPETCODE
accounts::user { 'hunner':
locked => true,
}
PUPPETCODE
pp_custom_group_name = <<-PUPPETCODE
file { '/test':
ensure => directory,
before => Accounts::User['first.last'],
}
accounts::user { 'first.last':
group => 'staff',
password => '!!',
home => '/test/first.last',
home_mode => '0700',
}
PUPPETCODE
pp_create_group_false = <<-PUPPETCODE
accounts::user { 'grp_flse':
group => 'newgrp_1',
create_group => false,
home => '/test/grp_flse',
}
PUPPETCODE
pp_create_group_true = <<-PUPPETCODE
file { '/test':
ensure => directory,
before => Accounts::User['grp_true'],
}
accounts::user { 'grp_true':
group => 'newgrp_2',
create_group => true,
home => '/test/grp_true',
}
PUPPETCODE
pp_ignore_user_first_run = <<-PUPPETCODE
file { '/test':
ensure => directory,
before => Accounts::User['ignore_user'],
}
accounts::user { 'ignore_user':
group => 'staff',
password => 'foo',
}
PUPPETCODE
pp_ignore_user_second_run = <<-PUPPETCODE
file { '/test':
ensure => directory,
before => Accounts::User['ignore_user'],
}
accounts::user { 'ignore_user':
group => 'staff',
password => '',
ignore_password_if_empty => true,
}
PUPPETCODE
pp_no_ignore_user_first_run = <<-PUPPETCODE
file { '/test':
ensure => directory,
before => Accounts::User['no_ignore_user'],
}
accounts::user { 'no_ignore_user':
group => 'staff',
password => 'foo',
}
PUPPETCODE
pp_no_ignore_user_second_run = <<-PUPPETCODE
file { '/test':
ensure => directory,
before => Accounts::User['no_ignore_user'],
}
accounts::user { 'no_ignore_user':
group => 'staff',
password => '',
ignore_password_if_empty => false,
}
PUPPETCODE
pp_specd_user_first_run = <<-PUPPETCODE
file { '/test':
ensure => directory,
before => Accounts::User['specd_user'],
}
accounts::user { 'specd_user':
group => 'staff',
password => 'foo',
}
PUPPETCODE
pp_specd_user_second_run = <<-PUPPETCODE
file { '/test':
ensure => directory,
before => Accounts::User['specd_user'],
}
accounts::user { 'specd_user':
group => 'staff',
password => 'bar',
ignore_password_if_empty => true,
}
PUPPETCODE
pp_archive_homedir_before_user_deletion = <<-PUPPETCODE
file { '/test/archives':
ensure => 'directory',
group => 'archiver',
mode => '0700',
owner => 'archiver',
}
exec { 'backup homedir of specd_user':
command => 'tar -czf /test/archives/specd_user.tar.gz specd_user',
creates => '/test/specd_user.tar.gz',
cwd => '/home',
path => '/bin',
require => File['/test/archives'],
}
accounts::user { 'specd_user':
ensure => 'absent',
purge_user_home => true,
require => Exec['backup homedir of specd_user'],
}
accounts::user { 'archiver':
ensure => 'present',
}
PUPPETCODE
pp_user_with_duplicate_uid = <<-PUPPETCODE
accounts::user { 'duplicate_user1':
allowdupe => true,
uid => '1234',
sshkey_owner => 'duplicate_user1',
}
accounts::user { 'duplicate_user2':
allowdupe => true,
uid => '1234',
sshkey_owner => 'duplicate_user1',
}
PUPPETCODE
pp_user_with_sensitive_password = <<-PUPPETCODE
accounts::user { 'sensitive_user':
password => Sensitive('bar'),
}
PUPPETCODE
pp_cleanup = <<-PUPPETCODE
file { '/test':
ensure => 'absent',
force => true,
}
PUPPETCODE
describe 'accounts::user define', unless: UNSUPPORTED_PLATFORMS.include?(os[:family]) do
after(:all) do
# Cleanup any files created to ensure tests can be ran multiple times
apply_manifest(pp_cleanup, catch_failures: true)
end
describe 'main tests' do
it 'creates groups of matching names, assigns non-matching group, manages homedir, manages other properties, gives key, makes dotfiles, managevim false' do
apply_manifest(pp_accounts_define, catch_failures: true)
expect(user('hunner')).to exist
expect(user('hunner')).to belong_to_group 'hunner'
expect(user('hunner')).to belong_to_group 'root'
expect(user('hunner')).to have_login_shell '/bin/true'
expect(user('hunner')).to have_home_directory '/test/hunner'
expect(user('hunner')).to contain_password 'hi' unless os[:family] == 'solaris'
expect(file('/test/hunner')).to be_directory
expect(file('/test/hunner')).to be_mode 700
expect(file('/test/hunner')).to be_owned_by 'hunner'
expect(file('/test/hunner')).to be_grouped_into 'hunner'
expect(file('/test/hunner/.bashrc')).to be_file
expect(file('/test/hunner/.bashrc').content).to match %r{managed by Puppet}
expect(file('/test/hunner/.bash_profile')).to be_file
expect(file('/test/hunner/.bash_profile').content).to match %r{Get the aliases and functions}
expect(file('/test/hunner/.vim')).not_to exist
end
end
describe 'warn for sshkeys without managehome' do
it 'creates groups of matching names, assigns non-matching group, manages homedir, manages other properties, gives key, makes dotfiles' do
apply_manifest(pp_without_managehome, catch_failures: true) do |r|
expect(r.stderr).to match(%r{Warning:.*ssh keys were passed for user hunner})
end
end
end
describe 'managevim set to true' do
it '.vim file will be created' do
apply_manifest(pp_with_managevim, catch_failures: true)
expect(file('/test/hunner/.vim')).to be_directory
end
end
describe 'locking users' do
let(:login_shell) do
case os[:family]
when %r{debian|ubuntu} # Are there Debian-related distros besides Ubuntu?
'/usr/sbin/nologin'
when 'solaris'
'/usr/bin/false'
else
'/sbin/nologin'
end
end
it 'locks a user' do
apply_manifest(pp_locked_user, catch_failures: true)
expect(user('hunner')).to have_login_shell login_shell
end
end
describe 'create user with custom group name' do
it 'creates group of matching names, assigns non-matching group, manages homedir' do
apply_manifest(pp_custom_group_name, catch_failures: true)
expect(user('first.last')).to exist
expect(user('first.last')).to belong_to_group 'staff'
expect(user('first.last')).to have_home_directory '/test/first.last'
expect(file('/test/first.last')).to be_directory
expect(file('/test/first.last')).to be_mode 700
expect(file('/test/first.last')).to be_owned_by 'first.last'
expect(file('/test/first.last')).to be_grouped_into 'staff'
end
end
describe 'group set to false does not create group' do
it 'does not create group' do
apply_manifest(pp_create_group_false, expect_failures: true) do |r|
expect(r.stderr).to match(%r{(.*group '?newgrp_1'? does not exist.*|.*Unknown group `?newgrp_1'?.*)})
end
expect(user('grp_flse')).not_to exist
expect(user('grp_flse')).not_to belong_to_group 'new_group_1'
end
end
describe 'group set to true creates group' do
it 'creates group' do
apply_manifest(pp_create_group_true, catch_failures: true)
expect(user('grp_true')).to exist
expect(user('grp_true')).to belong_to_group 'newgrp_2'
end
end
# Solaris does not offer a means of testing the password
describe 'ignore password if ignore set to true', unless: os[:family] == 'solaris' do
it 'creates group of matching names, assigns non-matching group, empty password, ignore true, ignores password' do
apply_manifest(pp_ignore_user_first_run, catch_failures: true)
apply_manifest(pp_ignore_user_second_run, catch_failures: true)
expect(user('ignore_user')).to exist
expect(user('ignore_user')).to contain_password 'foo'
end
end
# Solaris does not offer a means of testing the password
describe 'do not ignore password if ignore set to false', unless: os[:family] == 'solaris' do
it 'creates group of matching names, assigns non-matching group, empty password, ignore false, should not ignore password' do
apply_manifest(pp_no_ignore_user_first_run, catch_failures: true)
apply_manifest(pp_no_ignore_user_second_run, catch_failures: true)
expect(user('no_ignore_user')).to exist
expect(user('no_ignore_user')).to contain_password ''
end
end
describe 'do not ignore password if set and ignore set to true', unless: os[:family] == 'solaris' do
it 'creates group of matching names, assigns non-matching group, specify password, ignore, should not ignore password' do
apply_manifest(pp_specd_user_first_run, catch_failures: true)
apply_manifest(pp_specd_user_second_run, catch_failures: true)
expect(user('specd_user')).to exist
expect(user('specd_user')).to contain_password 'bar'
end
end
describe 'allow homedir archival before user deletion' do
it 'allows creating one user before deleting another' do
apply_manifest(pp_archive_homedir_before_user_deletion, catch_failures: true)
expect(user('archiver')).to exist
expect(user('specd_user')).not_to exist
expect(file('/home/specd_user')).not_to exist
end
end
describe 'create duplicate users with same uid' do
it 'runs with no errors' do
apply_manifest(pp_user_with_duplicate_uid, catch_failures: true)
expect(user('duplicate_user1')).to exist
expect(user('duplicate_user1')).to have_uid 1234
expect(user('duplicate_user2')).to exist
expect(user('duplicate_user2')).to have_uid 1234
end
end
describe 'allow password to be a Sentitive type' do
it 'runs with no errors' do
apply_manifest(pp_user_with_sensitive_password, catch_failures: true)
expect(user('sensitive_user')).to exist
expect(user('sensitive_user')).to contain_password 'bar'
end
end
end

View File

@@ -0,0 +1,8 @@
# Use default_module_facts.yml for module specific facts.
#
# Facts specified here will override the values provided by rspec-puppet-facts.
---
ipaddress: "172.16.254.254"
ipaddress6: "FE80:0000:0000:0000:AAAA:AAAA:AAAA"
is_pe: false
macaddress: "AA:AA:AA:AA:AA:AA"

View File

@@ -0,0 +1,323 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'accounts::user' do
on_supported_os.each do |os, facts|
context "on #{os}" do
let(:facts) { facts }
let(:user_vars) do
case facts[:os]['family']
when 'Debian'
{ dan_home: '/home/dan',
locked_shell: '/usr/sbin/nologin',
root_home: '/root' }
when 'Solaris'
{ dan_home: '/export/home/dan',
locked_shell: '/usr/bin/false',
root_home: '/' }
else
{ dan_home: '/home/dan',
locked_shell: '/sbin/nologin',
root_home: '/root' }
end
end
context "for user dan on #{facts[:os]['family']}" do
let(:title) { 'dan' }
describe 'expected defaults' do
let(:params) { {} }
it do
is_expected.to contain_user(title).with('shell' => '/bin/bash')
is_expected.to contain_user(title).with('home' => user_vars[:dan_home])
is_expected.to contain_user(title).with('ensure' => 'present')
is_expected.to contain_user(title).with('comment' => title)
is_expected.to contain_user(title).with('gid' => title)
is_expected.to contain_user(title).with('groups' => [])
is_expected.to contain_user(title).with('allowdupe' => false)
is_expected.to contain_user(title).with('managehome' => true)
end
it do
is_expected.to contain_group(title).with('ensure' => 'present')
is_expected.to contain_group(title).with('gid' => nil)
end
end
describe 'when setting user parameters' do
let(:params) do
{
ensure: 'present',
allowdupe: true,
comment: 'comment',
expiry: '2018-06-22',
gid: 456,
group: 'dan',
groups: ['admin'],
home: '/var/home/dan',
home_mode: '0755',
membership: 'inclusive',
password: 'foo',
password_max_age: 60,
shell: '/bin/csh',
sshkey_owner: 'dan',
sshkeys: ['ssh-rsa AAAAB3Nza...LiPk== dan@example1.net',
'permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-dss AAAAB5...21S== dan key2',
'command="/bin/echo Hello World",from="myhost.exapmle.com,192.168.1.1" ecdsa-sha2-nistp521 test_key vagrant2'],
uid: 123,
}
end
[:ensure, :allowdupe, :comment, :expiry, :groups, :home,
:membership, :password, :password_max_age].each do |param|
it { is_expected.to contain_user(title).with(param.to_s => params[param]) }
end
it do
is_expected.to contain_user(title).with('gid' => params[:group])
is_expected.to contain_group(params[:group]).with('ensure' => params[:ensure],
'gid' => params[:gid])
end
it { is_expected.to contain_group(params[:group]).that_comes_before("User[#{title}]") }
it do
is_expected.to contain_accounts__home_dir(params[:home]).with('user' => title,
'mode' => params[:home_mode])
end
it { is_expected.to contain_accounts__key_management("#{title}_key_management").with('sshkeys' => params[:sshkeys]) }
it { is_expected.to contain_ssh_authorized_key("#{params[:sshkey_owner]}_ssh-rsa_dan@example1.net_1e44b207704970cf4acb3470331b0e5c") }
it { is_expected.to contain_ssh_authorized_key("#{params[:sshkey_owner]}_ssh-dss_dan key2_6e9b8958712502a8b31e1c283b6e6fce") }
it { is_expected.to contain_ssh_authorized_key("#{params[:sshkey_owner]}_ecdsa-sha2-nistp521_vagrant2_8c32d1183251df9828f929b935ae0419") }
it { is_expected.to contain_file("#{params[:home]}/.ssh") }
end
describe 'when locking users' do
let(:params) { { 'locked' => true } }
it { is_expected.to contain_user(title).with('shell' => user_vars[:locked_shell]) }
end
describe 'when setting custom sshkey location' do
let(:params) { { sshkey_custom_path: '/var/lib/ssh/dan/custom_key_file' } }
it { is_expected.to contain_file(params[:sshkey_custom_path]) }
end
describe 'when setting sshkey mode on custom sshkey location' do
let(:params) do
{ sshkey_mode: '0440',
sshkey_custom_path: '/var/lib/ssh/dan/custom_key_file' }
end
it { is_expected.to contain_file(params[:sshkey_custom_path]).with(mode: '0440') }
end
describe 'with create_group set to false' do
let(:params) do
{ group: 'foo',
create_group: false,
ensure: 'present' }
end
it { is_expected.not_to contain_group(params[:group]) }
end
describe 'with create_group set to true' do
let(:params) do
{ group: 'foo',
create_group: true,
ensure: 'present' }
end
it { is_expected.to contain_group(params[:group]) }
end
describe 'with forcelocal set to false' do
let(:params) do
{ forcelocal: false }
end
it { is_expected.to contain_user(title).with('forcelocal' => params[:forcelocal]) }
it { is_expected.to contain_group(title).with('forcelocal' => params[:forcelocal]) }
end
describe 'with forcelocal set to true' do
let(:params) do
{ forcelocal: true }
end
it { is_expected.to contain_user(title).with('forcelocal' => params[:forcelocal]) }
it { is_expected.to contain_group(title).with('forcelocal' => params[:forcelocal]) }
end
describe 'when empty password ignored' do
let(:params) do
{ ignore_password_if_empty: true,
password: '' }
end
it { is_expected.to contain_user(title).without_password }
end
describe 'when empty password not ignored explicitly' do
let(:params) do
{ ignore_password_if_empty: false,
password: '' }
end
it { is_expected.to contain_user(title).with('password' => params[:password]) }
end
describe 'when empty password not ignored by default' do
let(:params) { { password: '' } }
it { is_expected.to contain_user(title).with('password' => params[:password]) }
end
describe 'when non-empty password not ignored' do
let(:params) do
{ ignore_password_if_empty: false,
password: 'foo' }
end
it { is_expected.to contain_user(title).with('password' => params[:password]) }
end
describe 'when non-empty password ignored if empty' do
let(:params) do
{ ignore_password_if_empty: true,
password: 'foo' }
end
it { is_expected.to contain_user(title).with('password' => params[:password]) }
end
describe 'when setting password iterations and salt' do
let(:params) do
{ iterations: 5,
salt: 'bar' }
end
it { is_expected.to contain_user(title).with('iterations' => params[:iterations]) }
it { is_expected.to contain_user(title).with('salt' => params[:salt]) }
end
describe 'when using a sensitive password' do
let(:params) do
{ password: RSpec::Puppet::RawString.new("Sensitive('foo')") }
end
it { is_expected.to contain_user(title).with('password' => sensitive('foo')) }
end
describe 'when supplying resource defaults' do
let(:params) { {} }
let(:pre_condition) { "Accounts::User{ shell => '/bin/zsh' }" }
it { is_expected.to contain_user(title).with('shell' => '/bin/zsh') }
end
describe 'when explicit parameters override defaults' do
let(:params) { { 'shell' => '/bin/csh' } }
let(:pre_condition) { "Accounts::User{ shell => '/bin/zsh' }" }
it { is_expected.to contain_user(title).with('shell' => '/bin/csh') }
end
describe 'when locked overrides defaults and user params' do
let(:params) do
{ 'locked' => true,
'shell' => '/bin/csh' }
end
let(:pre_condition) { "Accounts::User{ shell => '/bin/zsh' }" }
it { is_expected.to contain_user(title).with('shell' => user_vars[:locked_shell]) }
end
context 'when setting the user to absent' do
# when deleting users the home dir is a File resource instead of a accounts::home_dir
let(:contain_home_dir) { contain_file(params[:home]) }
describe 'with default sshkey path' do
let(:params) do
{ ensure: 'absent',
purge_user_home: true }
end
it { is_expected.to contain_user(title).with('ensure' => params[:ensure]) }
it { is_expected.to contain_user(title).that_comes_before("Group[#{title}]") }
it { is_expected.to contain_group(title).with('ensure' => params[:ensure]) }
it { is_expected.not_to contain_accounts__home_dir(user_vars[:dan_home]) }
end
describe 'with custom sshkey location' do
let(:params) do
{ ensure: 'absent',
purge_user_home: true,
sshkey_custom_path: '/var/lib/ssh/dan/custom_key_file' }
end
it { is_expected.to contain_file(params[:sshkey_custom_path]).with('ensure' => params[:ensure]).that_comes_before("User[#{title}]") }
end
describe 'with purge_user_home off' do
let(:params) do
{ ensure: 'absent',
purge_user_home: false }
end
it { is_expected.to contain_user(title).with('ensure' => params[:ensure]) }
it { is_expected.to contain_user(title).with('managehome' => params[:purge_user_home]) }
it { is_expected.not_to contain_accounts__home_dir(user_vars[:dan_home]) }
it { is_expected.not_to contain_file("#{user_vars[:dan_home]}/.ssh") }
end
end
end
context 'for user root' do
let(:title) { 'root' }
let(:params) { {} }
describe 'expected defaults' do
it { is_expected.to contain_user(title).with_home(user_vars[:root_home]) }
end
end
context 'invalid parameter values' do
let(:title) { 'dan' }
describe "only accepts 'absent' and 'present' for ensure" do
let(:params) { { ensure: 'invalid' } }
it { is_expected.to raise_error Puppet::Error }
end
[:home, :shell].each do |param|
describe "should fail if #{param} does not start with '/'" do
let(:params) { { param => 'no_leading_slash' } }
it { is_expected.to raise_error Puppet::Error }
end
end
describe 'does not accept non-date values for expiry' do
let(:params) { { expiry: 'notadate' } }
it { is_expected.to raise_error Puppet::Error }
end
[:gid, :uid].each do |param|
describe "fails if #{param} is not composed of digits" do
let(:params) { { param => 'name' } }
it { is_expected.to raise_error Puppet::Error }
end
end
[:allowdupe, :expiry, :locked, :managehome,
:managevim, :purge_user_home].each do |param|
describe "fails if #{param} is not a boolean" do
let(:params) { { param => 'true' } }
it { is_expected.to raise_error Puppet::Error }
end
end
end
end
end
end

View File

@@ -0,0 +1,37 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'accounts_ssh_authorized_keys_line_parser' do
it {
is_expected.not_to eq(nil)
}
it {
is_expected.to run.with_params('').and_raise_error(ArgumentError, %r{Wrong Keyline format!})
}
it {
is_expected.to run.with_params('options unknown-keytype key comment').and_raise_error(ArgumentError, %r{Wrong Keyline format!})
}
it {
is_expected.to run.with_params('ssh-xyz key name with spaces').and_return( \
['', 'ssh-xyz', 'key', 'name with spaces'],
)
}
it {
is_expected.to run.with_params('"options with arguments",moreoptions,"moreoptions with arguments" ecdsa-xyz key name with spaces').and_return( \
['"options with arguments",moreoptions,"moreoptions with arguments"', 'ecdsa-xyz', 'key', 'name with spaces'],
)
}
it {
is_expected.to run.with_params('tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== jane@example.net').and_return( \
['tunnel="0",command="sh /etc/netstart tun0"', 'ssh-rsa', 'AAAA...==', 'jane@example.net'],
)
}
it {
# rubocop:disable Layout/LineLength
is_expected.to run.with_params('command="rsync --server --sender -vlHogtpr --numeric-ids . /",from="192.168.1.1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ecdsa-sha2-nistp384 AAAA...= rsync backup').and_return( \
['command="rsync --server --sender -vlHogtpr --numeric-ids . /",from="192.168.1.1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding', 'ecdsa-sha2-nistp384', 'AAAA...=', 'rsync backup'],
)
# rubocop:enable Layout/LineLength
}
end

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'accounts_ssh_options_parser' do
it { is_expected.not_to eq(nil) }
it { is_expected.to run.with_params('').and_return([]) }
it { is_expected.to run.with_params('"').and_raise_error(ArgumentError, %r{Unmatched double quote}) }
it { is_expected.to run.with_params('tunnel="0"').and_return(['tunnel="0"']) }
it { is_expected.to run.with_params('restrict,tunnel="0",command="sh /etc/netstart tun0"').and_return(['restrict', 'tunnel="0"', 'command="sh /etc/netstart tun0"']) }
end

View File

@@ -0,0 +1,74 @@
# frozen_string_literal: true
RSpec.configure do |c|
c.mock_with :rspec
end
require 'puppetlabs_spec_helper/module_spec_helper'
require 'rspec-puppet-facts'
require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb'))
include RspecPuppetFacts
default_facts = {
puppetversion: Puppet.version,
facterversion: Facter.version,
}
default_fact_files = [
File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')),
File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')),
]
default_fact_files.each do |f|
next unless File.exist?(f) && File.readable?(f) && File.size?(f)
begin
default_facts.merge!(YAML.safe_load(File.read(f), [], [], true))
rescue => e
RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}"
end
end
# read default_facts and merge them over what is provided by facterdb
default_facts.each do |fact, value|
add_custom_fact fact, value
end
RSpec.configure do |c|
c.default_facts = default_facts
c.before :each do
# set to strictest setting for testing
# by default Puppet runs at warning level
Puppet.settings[:strict] = :warning
Puppet.settings[:strict_variables] = true
end
c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT']
c.after(:suite) do
RSpec::Puppet::Coverage.report!(0)
end
# Filter backtrace noise
backtrace_exclusion_patterns = [
%r{spec_helper},
%r{gems},
]
if c.respond_to?(:backtrace_exclusion_patterns)
c.backtrace_exclusion_patterns = backtrace_exclusion_patterns
elsif c.respond_to?(:backtrace_clean_patterns)
c.backtrace_clean_patterns = backtrace_exclusion_patterns
end
end
# Ensures that a module is defined
# @param module_name Name of the module
def ensure_module_defined(module_name)
module_name.split('::').reduce(Object) do |last_module, next_module|
last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false)
last_module.const_get(next_module, false)
end
end
# 'spec_overrides' from sync.yml will appear below this line

View File

@@ -0,0 +1,6 @@
# frozen_string_literal: true
require 'puppet_litmus'
require 'spec_helper_acceptance_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_acceptance_local.rb'))
PuppetLitmus.configure!

View File

@@ -0,0 +1,128 @@
# frozen_string_literal: true
require 'bolt_spec/run'
require 'puppet_litmus/inventory_manipulation'
UNSUPPORTED_PLATFORMS = ['windows', 'darwin'].freeze
# rubocop:disable all
#####################################################################################
# Partially copied from simp/rubygem-simp-beaker-helpers/lib/simp/beaker_helpers.rb #
# Original copyright therefrom applies. #
#####################################################################################
# A shim to stand in for the now deprecated hiera_datadir function
#
# Note: This may not work if you've shoved data somewhere that is not the
# default and/or are manipulating the default hiera.yaml.
#
# @returns [String] Path to the Hieradata directory on the target system
def hiera_datadir
# This output lets us know where Hiera is configured to look on the system
puppet_lookup_info = run_shell('puppet lookup --explain test__simp__test').stdout.strip.lines
puppet_config_check = run_shell('puppet agent --configprint manifest').stdout
if puppet_config_check.nil? || puppet_config_check.empty?
fail("No output returned from `puppet config print manifest`")
end
puppet_env_path = File.dirname(puppet_config_check)
# We'll just take the first match since Hiera will find things there
puppet_lookup_info = puppet_lookup_info.grep(/Path "/).grep(Regexp.new(puppet_env_path))
# Grep always returns an Array
if puppet_lookup_info.empty?
fail("Could not determine hiera data directory under #{puppet_env_path}")
end
# Snag the actual path without the extra bits
puppet_lookup_info = puppet_lookup_info.first.strip.split('"').last
# Make the parent directories exist
run_shell("mkdir -p #{File.dirname(puppet_lookup_info)}", acceptable_exit_codes: [0])
# We just want the data directory name
datadir_name = puppet_lookup_info.split(puppet_env_path).last
# Grab the file separator to add back later
file_sep = datadir_name[0]
# Snag the first entry (this is the data directory)
datadir_name = datadir_name.split(file_sep)[1]
# Constitute the full path to the data directory
datadir_path = puppet_env_path + file_sep + datadir_name
# Return the path to the data directory
return datadir_path
end
# Write the provided data structure to Hiera's :datadir and configure Hiera to
# use that data exclusively.
#
# @note This is authoritative. It manages both Hiera data and configuration,
# so it may not be used with other Hiera data sources.
#
# @param hieradata [Hash, String] The full hiera data structure to write to
# the system.
#
# @return [Nil]
#
def set_hieradata(hieradata)
@temp_hieradata_dirs ||= []
data_dir = Dir.mktmpdir('hieradata')
@temp_hieradata_dirs << data_dir
fh = File.open(File.join(data_dir, 'common.yaml'), 'w')
if hieradata.is_a?(String)
fh.puts(hieradata)
else
fh.puts(hieradata.to_yaml)
end
fh.close
run_shell("mkdir -p #{File.dirname(data_dir)}", acceptable_exit_codes: [0])
result = upload_file(File.join(data_dir, 'common.yaml'), File.join(@hiera_datadir, 'common.yaml'), ENV['TARGET_HOST'], options: {}, config: nil, inventory: inventory_hash_from_inventory_file)
raise "error uploading hiera file to #{ENV['TARGET_HOST']}" if result[0]["status"] !~ %r{success}
end
# Clean up all temporary hiera data files.
#
# Meant to be called from after(:all)
def clear_temp_hieradata
if @temp_hieradata_dirs && !@temp_hieradata_dirs.empty?
@temp_hieradata_dirs.each do |data_dir|
if File.exists?(data_dir)
FileUtils.rm_r(data_dir)
end
end
end
end
RSpec.configure do |c|
c.before(:all) do
@temp_hieradata_dirs = @temp_hieradata_dirs || []
@hiera_datadir = hiera_datadir
end
c.after(:all) do
clear_temp_hieradata
end
c.formatter = :documentation
end
###########################################################################
# End copying simp/rubygem-simp-beaker-helpers/lib/simp/beaker_helpers.rb #
###########################################################################
# rubocop:enable all
RSpec::Matchers.define :contain_password do |password|
match do |user|
if password == user.encrypted_password
return true
end
end
false
end

View File

@@ -0,0 +1,30 @@
# frozen_string_literal: true
if ENV['COVERAGE'] == 'yes'
require 'simplecov'
require 'simplecov-console'
require 'codecov'
SimpleCov.formatters = [
SimpleCov::Formatter::HTMLFormatter,
SimpleCov::Formatter::Console,
SimpleCov::Formatter::Codecov,
]
SimpleCov.start do
track_files 'lib/**/*.rb'
add_filter '/spec'
# do not track vendored files
add_filter '/vendor'
add_filter '/.vendor'
# do not track gitignored files
# this adds about 4 seconds to the coverage check
# this could definitely be optimized
add_filter do |f|
# system returns true if exit status is 0, which with git-check-ignore means file is ignored
system("git check-ignore --quiet #{f.filename}")
end
end
end

View File

@@ -0,0 +1,34 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Accounts::Group::Hash' do
describe 'Valid group hash values' do
[
{ 'oldusers' => { 'ensure' => 'absent' } },
{ 'sudoers' => { 'system' => true } },
].each do |value|
describe value.inspect do
it { is_expected.to allow_value(value) }
end
end
end
describe 'Invalid group hash values' do
[
{ '$$' => {} },
{ '_a' => { 'ensure' => false } },
{ '_b' => { 'allowdupe' => 'soitenly!' } },
{ '_c' => { 'auth_membership' => [] } },
{ '_d' => { 'forcelocal' => {} } },
{ '_e' => { 'gid' => 'nine' } },
{ '_f' => { 'members' => [-1] } },
{ '_g' => { 'provider' => nil } },
{ '_h' => { 'system' => 'POSIX' } },
].each do |value|
describe value.inspect do
it { is_expected.not_to allow_value(value) }
end
end
end
end

View File

@@ -0,0 +1,36 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Accounts::Group::Provider' do
describe 'Valid group provider values' do
[
'aix',
'directoryservice',
'groupadd',
'ldap',
'pw',
'windows_adsi',
].each do |value|
describe value.inspect do
it { is_expected.to allow_value(value) }
end
end
end
describe 'Invalid group provider values' do
[
0,
false,
'GroupAdd',
'',
{},
[],
nil,
].each do |value|
describe value.inspect do
it { is_expected.not_to allow_value(value) }
end
end
end
end

View File

@@ -0,0 +1,43 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Accounts::Group::Resource' do
describe 'Valid group resource values' do
[
{},
{ 'ensure' => 'absent' },
{ 'allowdupe' => false },
{ 'auth_membership' => true },
{ 'forcelocal' => false },
{ 'gid' => 999 },
{ 'members' => ['root'] },
{ 'name' => 'root' },
{ 'provider' => 'pw' },
{ 'system' => false },
].each do |value|
describe value.inspect do
it { is_expected.to allow_value(value) }
end
end
end
describe 'Invalid group resource values' do
[
{ 'bogus' => true },
{ 'ensure' => false },
{ 'allowdupe' => 'soitenly!' },
{ 'auth_membership' => 'no' },
{ 'forcelocal' => -1 },
{ 'gid' => 'nine' },
{ 'members' => [-1] },
{ 'name' => '$invalid' },
{ 'provider' => 'Custom' },
{ 'system' => 'Linux' },
].each do |value|
describe value.inspect do
it { is_expected.not_to allow_value(value) }
end
end
end
end

Some files were not shown because too many files have changed in this diff Show More