├── .github ├── SECURITY.md ├── dependabot.yml ├── workflows │ ├── release.yml │ ├── main.yml │ └── update.yml └── release.yml ├── modulesync.yml ├── moduleroot ├── .msync.yml.erb ├── .devcontainer │ └── devcontainer.json.erb ├── .github │ ├── labeler.yml.erb │ ├── workflows │ │ ├── labeler.yml.erb │ │ ├── prepare_release.yml.erb │ │ ├── release.yml.erb │ │ └── ci.yml.erb │ ├── PULL_REQUEST_TEMPLATE.md.erb │ ├── ISSUE_TEMPLATE.md.erb │ └── release.yml.erb ├── .puppet-lint.rc.erb ├── .editorconfig.erb ├── .rubocop.yml.erb ├── spec │ ├── spec_helper_acceptance.rb.erb │ └── spec_helper.rb.erb ├── .gitignore.erb ├── .pmtignore.erb ├── Rakefile.erb ├── .overcommit.yml.erb └── Gemfile.erb ├── bin ├── count-unreleased-commits ├── create-pull-requests ├── clean-git-checkouts-nondestructive ├── clean-git-checkouts ├── outdated_modules_and_their_version ├── add_openvox_to_metadata_json ├── bump-dependency-upper-bound ├── merge-prs ├── clean-metadata └── get_all_the_diffs ├── .gitignore ├── Rakefile ├── Gemfile ├── managed_modules.yml ├── config_defaults.yml ├── README.md └── LICENSE /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Vox Pupuli Security Policy 2 | 3 | Our vulnerabilities reporting process is at https://voxpupuli.org/security/ 4 | -------------------------------------------------------------------------------- /modulesync.yml: -------------------------------------------------------------------------------- 1 | --- 2 | git_base: 'git@github.com:' 3 | namespace: voxpupuli 4 | branch: modulesync 5 | message: "Update from voxpupuli modulesync_config" 6 | ... 7 | # vim: syntax=yaml 8 | -------------------------------------------------------------------------------- /moduleroot/.msync.yml.erb: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | modulesync_config_version: '10.4.0' 6 | -------------------------------------------------------------------------------- /moduleroot/.devcontainer/devcontainer.json.erb: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | { 3 | "name": "VoxBox", 4 | "image": "ghcr.io/voxpupuli/voxbox:latest" 5 | } 6 | -------------------------------------------------------------------------------- /moduleroot/.github/labeler.yml.erb: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | skip-changelog: 6 | - head-branch: ['^release-*', 'release'] 7 | -------------------------------------------------------------------------------- /bin/count-unreleased-commits: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | for module in modules/*/* ; do 6 | count=$(git --git-dir "${module}/.git" log "$(git --git-dir "${module}/.git" describe --tags --abbrev=0)"..HEAD --oneline | wc -l) 7 | printf '%-40s %3d\n' "$module" $count 8 | done 9 | -------------------------------------------------------------------------------- /bin/create-pull-requests: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if ! which hub > /dev/null ; then 6 | exit 1 7 | fi 8 | 9 | version=$(git describe) 10 | for module in modules/*/* ; do 11 | (cd "$module" 12 | hub pull-request -m "modulesync ${version}" -l "modulesync" 13 | ) 14 | done 15 | -------------------------------------------------------------------------------- /bin/clean-git-checkouts-nondestructive: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for module in modules/*/* ; do 4 | ( 5 | cd "${module}" || exit 6 | echo "${module}" 7 | git status 8 | git checkout master 9 | git fetch --all --prune 10 | git branch --delete modulesync || true 11 | git pull || true 12 | ) 13 | done 14 | -------------------------------------------------------------------------------- /moduleroot/.puppet-lint.rc.erb: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | 4 | --fail-on-warnings 5 | <% checks = @configs['disabled_lint_checks'] - @configs['enabled_lint_checks'] -%> 6 | <% checks.each do |check| -%> 7 | --no-<%= check.sub(/^disable_/, '') %>-check 8 | <% end -%> 9 | -------------------------------------------------------------------------------- /bin/clean-git-checkouts: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | for module in modules/voxpupuli/* ; do 6 | (cd "$module" 7 | git status 8 | git reset --hard 9 | git clean -dfx 10 | git checkout "$(basename "$(git symbolic-ref refs/remotes/origin/HEAD)")" 11 | git pull --prune --quiet 12 | git branch -D modulesync || true 13 | ) 14 | done 15 | -------------------------------------------------------------------------------- /moduleroot/.editorconfig.erb: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | # Managed by modulesync - DO NOT EDIT 4 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 5 | 6 | root = true 7 | 8 | [*] 9 | charset = utf-8 10 | end_of_line = lf 11 | indent_size = 2 12 | tab_width = 2 13 | indent_style = space 14 | insert_final_newline = true 15 | trim_trailing_whitespace = true 16 | -------------------------------------------------------------------------------- /moduleroot/.rubocop.yml.erb: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | <% if File.exist?(File.join(@metadata[:workdir], '.rubocop_todo.yml')) -%> 6 | inherit_from: .rubocop_todo.yml 7 | <% end -%> 8 | inherit_gem: 9 | voxpupuli-test: rubocop.yml 10 | <% if @configs['extra'] -%> 11 | <%= @configs['extra'].to_yaml.sub(/\A---\n/, '') -%> 12 | <% end -%> 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # raise PRs for gem updates 4 | - package-ecosystem: bundler 5 | directory: "/" 6 | schedule: 7 | interval: daily 8 | time: "13:00" 9 | open-pull-requests-limit: 10 10 | 11 | # Maintain dependencies for GitHub Actions 12 | - package-ecosystem: github-actions 13 | directory: "/" 14 | schedule: 15 | interval: daily 16 | time: "13:00" 17 | open-pull-requests-limit: 10 18 | -------------------------------------------------------------------------------- /moduleroot/spec/spec_helper_acceptance.rb.erb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Managed by modulesync - DO NOT EDIT 4 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 5 | 6 | require 'voxpupuli/acceptance/spec_helper_acceptance' 7 | 8 | <%- unless @configs['configure_beaker'].nil? -%> 9 | configure_beaker(modules: <%= @configs['configure_beaker']['modules'] || ':metadata' %>) 10 | 11 | <%- end -%> 12 | Dir['./spec/support/acceptance/**/*.rb'].sort.each { |f| require f } 13 | -------------------------------------------------------------------------------- /moduleroot/.github/workflows/labeler.yml.erb: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | name: "Pull Request Labeler" 6 | 7 | # yamllint disable-line rule:truthy 8 | on: 9 | pull_request_target: {} 10 | 11 | permissions: 12 | contents: read 13 | pull-requests: write 14 | 15 | jobs: 16 | labeler: 17 | permissions: 18 | contents: read 19 | pull-requests: write 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/labeler@v5 23 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Create github release 3 | 4 | on: 5 | push: 6 | tags: 7 | - '*' 8 | 9 | permissions: 10 | contents: write 11 | 12 | jobs: 13 | release: 14 | runs-on: ubuntu-24.04 15 | name: Create GitHub release 16 | if: ${{ github.repository_owner == 'voxpupuli' }} 17 | steps: 18 | - name: Create Release Page 19 | shell: bash 20 | env: 21 | GH_TOKEN: ${{ github.token }} 22 | run: gh release create --repo ${{ github.repository }} ${{ github.ref_name }} --generate-notes 23 | -------------------------------------------------------------------------------- /moduleroot/.gitignore.erb: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | 4 | /pkg/ 5 | /Gemfile.lock 6 | /Gemfile.local 7 | /vendor/ 8 | /.vendor/ 9 | /spec/fixtures/manifests/ 10 | /spec/fixtures/modules/ 11 | /.vagrant/ 12 | /.bundle/ 13 | /.ruby-version 14 | /coverage/ 15 | /log/ 16 | /.idea/ 17 | /.dependencies/ 18 | /.librarian/ 19 | /Puppetfile.lock 20 | *.iml 21 | .*.sw? 22 | /.yardoc/ 23 | /Guardfile 24 | bolt-debug.log 25 | .rerun.json 26 | <% unless @configs['paths'].nil? -%> 27 | <% @configs['paths'].each do |path| -%> 28 | <%= path %> 29 | <% end -%> 30 | <% end -%> 31 | -------------------------------------------------------------------------------- /moduleroot/.github/PULL_REQUEST_TEMPLATE.md.erb: -------------------------------------------------------------------------------- 1 | 9 | #### Pull Request (PR) description 10 | 13 | 14 | #### This Pull Request (PR) fixes the following issues 15 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | /.config 4 | /coverage/ 5 | /InstalledFiles 6 | /pkg/ 7 | /spec/reports/ 8 | /test/tmp/ 9 | /test/version_tmp/ 10 | /tmp/ 11 | modules/ 12 | 13 | ## Specific to RubyMotion: 14 | .dat* 15 | .repl_history 16 | build/ 17 | 18 | ## Documentation cache and generated files: 19 | /.yardoc/ 20 | /_yardoc/ 21 | /doc/ 22 | /rdoc/ 23 | 24 | ## Environment normalisation: 25 | /.bundle/ 26 | /vendor 27 | /.vendor 28 | /lib/bundler/man/ 29 | 30 | # for a library or gem, you might want to ignore these files since the code is 31 | # intended to run in multiple environments; otherwise, check them in: 32 | Gemfile.lock 33 | # .ruby-version 34 | # .ruby-gemset 35 | 36 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 37 | .rvmrc 38 | -------------------------------------------------------------------------------- /moduleroot/.github/ISSUE_TEMPLATE.md.erb: -------------------------------------------------------------------------------- 1 | 10 | 11 | ## Affected Puppet, Ruby, OS and module versions/distributions 12 | 13 | - Puppet: 14 | - Ruby: 15 | - Distribution: 16 | - Module version: 17 | 18 | ## How to reproduce (e.g Puppet code you use) 19 | 20 | ## What are you seeing 21 | 22 | ## What behaviour did you expect instead 23 | 24 | ## Output log 25 | 26 | ## Any additional information you'd like to impart 27 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'metadata_json_deps' 2 | 3 | desc 'Run metadata-json-deps' 4 | task :metadata_deps do 5 | files = FileList['modules/*/*/metadata.json'] 6 | MetadataJsonDeps.run(files) 7 | end 8 | 9 | begin 10 | require 'github_changelog_generator/task' 11 | require 'yaml' 12 | 13 | GitHubChangelogGenerator::RakeTask.new :changelog do |config| 14 | config.header = "# Changelog\n\nAll notable changes to this project will be documented in this file." 15 | config.exclude_labels = %w{duplicate question invalid wontfix wont-fix skip-changelog github_actions} 16 | config.user = 'voxpupuli' 17 | config.project = 'modulesync_config' 18 | config.future_release = YAML.safe_load(File.read('moduleroot/.msync.yml.erb'))['modulesync_config_version'] 19 | end 20 | rescue LoadError 21 | end 22 | -------------------------------------------------------------------------------- /moduleroot/.pmtignore.erb: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | 4 | /docs/ 5 | /pkg/ 6 | /Gemfile 7 | /Gemfile.lock 8 | /Gemfile.local 9 | /vendor/ 10 | /.vendor/ 11 | /spec/ 12 | /Rakefile 13 | /.vagrant/ 14 | /.bundle/ 15 | /.ruby-version 16 | /coverage/ 17 | /log/ 18 | /.idea/ 19 | /.dependencies/ 20 | /.github/ 21 | /.librarian/ 22 | /Puppetfile.lock 23 | /Puppetfile 24 | *.iml 25 | /.editorconfig 26 | /.fixtures.yml 27 | /.gitignore 28 | /.msync.yml 29 | /.overcommit.yml 30 | /.pmtignore 31 | /.rspec 32 | /.rspec_parallel 33 | /.rubocop.yml 34 | /.sync.yml 35 | .*.sw? 36 | /.yardoc/ 37 | /.yardopts 38 | /Dockerfile 39 | /HISTORY.md 40 | <% if ! @configs['paths'].nil? -%> 41 | <% @configs['paths'].each do |path| -%> 42 | <%= path %> 43 | <% end -%> 44 | <% end -%> 45 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes 3 | 4 | changelog: 5 | exclude: 6 | labels: 7 | - duplicate 8 | - invalid 9 | - modulesync 10 | - question 11 | - skip-changelog 12 | - wont-fix 13 | - wontfix 14 | - github_actions 15 | 16 | categories: 17 | - title: Breaking Changes 🛠 18 | labels: 19 | - backwards-incompatible 20 | 21 | - title: New Features 🎉 22 | labels: 23 | - enhancement 24 | 25 | - title: Bug Fixes 🐛 26 | labels: 27 | - bug 28 | 29 | - title: Documentation Updates 📚 30 | labels: 31 | - documentation 32 | - docs 33 | 34 | - title: Dependency Updates ⬆️ 35 | labels: 36 | - dependencies 37 | 38 | - title: Other Changes 39 | labels: 40 | - "*" 41 | -------------------------------------------------------------------------------- /moduleroot/.github/release.yml.erb: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | # https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes 6 | 7 | changelog: 8 | exclude: 9 | labels: 10 | - duplicate 11 | - invalid 12 | - modulesync 13 | - question 14 | - skip-changelog 15 | - wont-fix 16 | - wontfix 17 | 18 | categories: 19 | - title: Breaking Changes 🛠 20 | labels: 21 | - backwards-incompatible 22 | 23 | - title: New Features 🎉 24 | labels: 25 | - enhancement 26 | 27 | - title: Bug Fixes 🐛 28 | labels: 29 | - bug 30 | 31 | - title: Documentation Updates 📚 32 | labels: 33 | - documentation 34 | - docs 35 | 36 | - title: Dependency Updates ⬆️ 37 | labels: 38 | - dependencies 39 | 40 | - title: Other Changes 41 | labels: 42 | - "*" 43 | -------------------------------------------------------------------------------- /moduleroot/.github/workflows/prepare_release.yml.erb: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | name: 'Prepare Release' 6 | 7 | on: 8 | workflow_dispatch: 9 | inputs: 10 | version: 11 | description: 'Module version to be released. Must be a valid semver string without leading v. (1.2.3)' 12 | required: false 13 | 14 | permissions: 15 | contents: write 16 | pull-requests: write 17 | 18 | jobs: 19 | release_prep: 20 | uses: 'voxpupuli/gha-puppet/.github/workflows/prepare_release.yml@v3' 21 | with: 22 | version: ${{ github.event.inputs.version }} 23 | <%- unless @configs['with']&.has_key?('allowed_owner') -%> 24 | allowed_owner: '<%= @configs['allowed_owner'] || @configs[:namespace] %>' 25 | <%- end -%> 26 | secrets: 27 | # Configure secrets here: 28 | # https://docs.github.com/en/actions/security-guides/encrypted-secrets 29 | github_pat: '${{ secrets.PCCI_PAT_RELEASE_PREP }}' 30 | -------------------------------------------------------------------------------- /moduleroot/.github/workflows/release.yml.erb: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | name: Release 6 | 7 | # yamllint disable-line rule:truthy 8 | on: 9 | push: 10 | tags: 11 | - '*' 12 | 13 | permissions: 14 | contents: write 15 | 16 | jobs: 17 | release: 18 | name: Release 19 | uses: voxpupuli/gha-puppet/.github/workflows/release.yml@v3 20 | with: 21 | <%- if @configs['with'] -%> 22 | <%- @configs['with'].each do |k,v| -%> 23 | <%- if v.is_a?(String) -%> 24 | <%= k %>: '<%= v %>' 25 | <%- else -%> 26 | <%= k %>: <%= v %> 27 | <%- end -%> 28 | <%- end -%> 29 | <%- end -%> 30 | <%- unless @configs['with']&.has_key?('allowed_owner') -%> 31 | allowed_owner: '<%= @configs['allowed_owner'] || @configs[:namespace] %>' 32 | <%- end -%> 33 | secrets: 34 | # Configure secrets here: 35 | # https://docs.github.com/en/actions/security-guides/encrypted-secrets 36 | username: ${{ secrets.PUPPET_FORGE_USERNAME }} 37 | api_key: ${{ secrets.PUPPET_FORGE_API_KEY }} 38 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright 2016 Vox Pupuli 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | source ENV['GEM_SOURCE'] || 'https://rubygems.org' 18 | 19 | group :development do 20 | gem 'pry' 21 | end 22 | 23 | group :release do 24 | gem 'faraday-retry', '~> 2.1', require: false 25 | gem 'github_changelog_generator', '~> 1.16.4', require: false 26 | end 27 | 28 | gem 'metadata_json_deps', '>= 0.2.0', '< 3' 29 | gem 'modulesync', '>= 2.6.0' 30 | gem 'octokit', '~> 4.0' 31 | gem 'puppet_forge', '>= 2.2.9' 32 | # vim: syntax=ruby 33 | -------------------------------------------------------------------------------- /moduleroot/.github/workflows/ci.yml.erb: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | name: CI 6 | 7 | # yamllint disable-line rule:truthy 8 | on: 9 | pull_request: {} 10 | push: 11 | branches: 12 | <%- @configs['main_branches'].each do |main_branch| -%> 13 | - <%= main_branch %> 14 | <%- end -%> 15 | 16 | concurrency: 17 | group: ${{ github.ref_name }} 18 | cancel-in-progress: true 19 | 20 | permissions: 21 | contents: read 22 | 23 | jobs: 24 | puppet: 25 | name: Puppet 26 | <%- if @configs['acceptance_tests'] && Dir[File.join(@metadata[:workdir], 'spec', 'acceptance', '**', '*_spec.rb')].any? -%> 27 | uses: voxpupuli/gha-puppet/.github/workflows/beaker.yml@v4 28 | <%- else -%> 29 | uses: voxpupuli/gha-puppet/.github/workflows/basic.yml@v4 30 | <%- end -%> 31 | <%- if @configs['with'] -%> 32 | with: 33 | <%- @configs['with'].each do |k,v| -%> 34 | <%- if v.is_a?(String) -%> 35 | <%= k %>: '<%= v %>' 36 | <%- else -%> 37 | <%= k %>: <%= v %> 38 | <%- end -%> 39 | <%- end -%> 40 | <%- end -%> 41 | -------------------------------------------------------------------------------- /moduleroot/Rakefile.erb: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | 4 | begin 5 | require 'voxpupuli/test/rake' 6 | rescue LoadError 7 | # only available if gem group test is installed 8 | end 9 | 10 | begin 11 | require 'voxpupuli/acceptance/rake' 12 | rescue LoadError 13 | # only available if gem group acceptance is installed 14 | end 15 | 16 | begin 17 | require 'voxpupuli/release/rake_tasks' 18 | rescue LoadError 19 | # only available if gem group releases is installed 20 | else 21 | GCGConfig.user = '<%= @configs['config.user'] || @configs[:namespace] %>' 22 | GCGConfig.project = '<%= @configs['config.project'] || @configs[:puppet_module] %>' 23 | <%- if @configs['config.tag_pattern'] -%> 24 | GCGConfig.tag_pattern = '<%= @configs['config.tag_pattern'] -%>' 25 | <%- end -%> 26 | end 27 | 28 | desc "Run main 'test' task and report merged results to coveralls" 29 | task test_with_coveralls: [:test] do 30 | if Dir.exist?(File.expand_path('../lib', __FILE__)) 31 | require 'coveralls/rake/task' 32 | Coveralls::RakeTask.new 33 | Rake::Task['coveralls:push'].invoke 34 | else 35 | puts 'Skipping reporting to coveralls. Module has no lib dir' 36 | end 37 | end 38 | 39 | # vim: syntax=ruby 40 | -------------------------------------------------------------------------------- /moduleroot/spec/spec_helper.rb.erb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Managed by modulesync - DO NOT EDIT 4 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 5 | 6 | # puppetlabs_spec_helper will set up coverage if the env variable is set. 7 | # We want to do this if lib exists and it hasn't been explicitly set. 8 | ENV['COVERAGE'] ||= 'yes' if Dir.exist?(File.expand_path('../lib', __dir__)) 9 | 10 | require 'voxpupuli/test/spec_helper' 11 | 12 | RSpec.configure do |c| 13 | c.facterdb_string_keys = <%= @configs['facterdb_string_keys'] %> 14 | <%- if @configs['hiera_config'] -%> 15 | c.hiera_config = <%= @configs['hiera_config'] %> 16 | <%- end -%> 17 | <%- if @configs['mock_with'] -%> 18 | c.mock_with <%= @configs['mock_with'] %> 19 | <%- end -%> 20 | end 21 | <%- if @configs['add_mocked_facts'] -%> 22 | 23 | add_mocked_facts! 24 | <%- end -%> 25 | 26 | if File.exist?(File.join(__dir__, 'default_module_facts.yml')) 27 | facts = YAML.safe_load(File.read(File.join(__dir__, 'default_module_facts.yml'))) 28 | facts&.each do |name, value| 29 | add_custom_fact name.to_sym, value 30 | end 31 | end 32 | <%- [@configs['spec_overrides']].flatten.compact.each do |line| -%> 33 | 34 | <%= line %> 35 | <%- end -%> 36 | Dir['./spec/support/spec/**/*.rb'].sort.each { |f| require f } 37 | -------------------------------------------------------------------------------- /bin/outdated_modules_and_their_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'yaml' 4 | require 'erb' 5 | 6 | # the current version in modulesync_config 7 | version = YAML.load(ERB.new(File.read('moduleroot/.msync.yml.erb')).result)['modulesync_config_version'] 8 | 9 | mod_ary = [] 10 | # min width is width of String "Module" 11 | width_modules = 6 12 | # min width is width of String "modulesync_config version" 13 | width_version = 25 14 | Dir.glob('modules/voxpupuli/puppet-*').sort.each do |f| 15 | if File.exists?(f + '/.msync.yml') 16 | version_module = YAML.load_file(f + '/.msync.yml')['modulesync_config_version'] 17 | mod = (f).split('/')[2] 18 | if version != version_module 19 | mod_ary.push([mod, version_module]) 20 | width_modules = [width_modules, mod.length].max 21 | width_version = [width_version, version_module.length].max 22 | end 23 | else 24 | version_module = 'None' 25 | mod = (f).split('/')[2] 26 | mod_ary.push([mod, version_module]) 27 | width_modules = [width_modules, mod.length].max 28 | width_version = [width_version, version_module.length].max 29 | end 30 | end 31 | 32 | total_width = width_modules + width_version + 7 33 | 34 | puts '-' * total_width 35 | puts "current version: #{version}" 36 | puts '-' * total_width 37 | puts "| #{'Module'.ljust(width_modules)} | #{'modulesync_config version'.ljust(width_version)} |" 38 | mod_ary.each do |mod, version_module| 39 | puts "| #{mod.ljust(width_modules)} | #{version_module.ljust(width_version)} |" 40 | end 41 | -------------------------------------------------------------------------------- /bin/add_openvox_to_metadata_json: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'yaml' 4 | require 'json' 5 | 6 | def clone_or_update(repo) 7 | if Dir.exist?(repo) 8 | system("cd #{repo}; git pull; cd ..") 9 | else 10 | system("git clone git@github.com:voxpupuli/#{repo}.git") 11 | end 12 | end 13 | 14 | 15 | clone_or_update('modulesync_config') 16 | 17 | yd = YAML.load_file('modulesync_config/managed_modules.yml') 18 | yd.each do |module_| 19 | clone_or_update(module_) 20 | filepath = "#{module_}/metadata.json" 21 | if !File.exist?(filepath) 22 | puts "#{filepath} doesn't exist, skipping" 23 | next 24 | end 25 | # load whole metadata.json file 26 | metadata = JSON.load_file(filepath) 27 | 28 | # extract the `puppet` requirements 29 | puppet = metadata['requirements'].detect{|requirement| requirement['name'] == 'puppet'} 30 | 31 | # generate `openvox` requirements with same versions as `puppet` 32 | openvox = {'name'=>'openvox', 'version_requirement'=>puppet['version_requirement']} 33 | 34 | # write everything back to the file 35 | File.write(filepath, JSON.pretty_generate(metadata.merge({'requirements'=>[puppet, openvox]})) + "\n") 36 | end 37 | 38 | # Once this runs, all the changes will exist, you'll then want to commit / make PRs with something like: 39 | # gh auth login 40 | # for x in $(ls -d puppet*); do 41 | # pushd $x 42 | # git switch -c add-openvox 43 | # git commit metadata.json -m "Add openvox to metadata.json" 44 | # git push origin add-openvox 45 | # gh repo set-default voxpupuli/$x 46 | # gh pr create --label enhancement --title 'metadata.json: Add OpenVox' --body '' 47 | # popd 48 | # done 49 | -------------------------------------------------------------------------------- /bin/bump-dependency-upper-bound: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'semantic_puppet' 3 | require 'json' 4 | 5 | def normalize_name(name) 6 | name.tr('-', '/') 7 | end 8 | 9 | def bump_dependency(filename, module_name, upper_bound) 10 | metadata = JSON.load(File.read(filename)) 11 | 12 | raise Exception.new("Unable to find dependencies") unless metadata['dependencies'].is_a?(Array) 13 | 14 | dependency = metadata['dependencies'].detect { |dep| normalize_name(dep['name']) == module_name } 15 | 16 | raise Exception.new("Dependency #{module_name} not found") unless dependency 17 | 18 | old = dependency['version_requirement'] 19 | 20 | requirement = SemanticPuppet::VersionRange.parse(old) 21 | 22 | return [old, old] if requirement.end == upper_bound 23 | 24 | new = ">= #{requirement.begin} < #{upper_bound}" 25 | 26 | dependency['version_requirement'] = new 27 | File.open(filename, 'w') do 28 | |file| file.write(JSON.pretty_generate(metadata) + "\n") 29 | end 30 | 31 | [old, new] 32 | end 33 | 34 | def main 35 | if ARGV.length < 3 36 | puts "Usage: #{$PROGRAM_NAME} dependency upper_bound metadata_path [metadata_path]" 37 | exit 1 38 | end 39 | 40 | module_name, upper_bound, *paths = ARGV 41 | module_name = normalize_name(module_name) 42 | paths.each do |path| 43 | begin 44 | old, new = bump_dependency(path, module_name, upper_bound) 45 | if old != new 46 | puts "Updated #{path}: '#{old}' to '#{new}'" 47 | else 48 | puts "#{path} already matches #{upper_bound}" 49 | end 50 | rescue Exception => e 51 | puts "Failed to update #{path}: #{e}" 52 | end 53 | end 54 | end 55 | 56 | main 57 | -------------------------------------------------------------------------------- /moduleroot/.overcommit.yml.erb: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | # 4 | # Hooks are only enabled if you take action. 5 | # 6 | # To enable the hooks run: 7 | # 8 | # ``` 9 | # bundle exec overcommit --install 10 | # # ensure .overcommit.yml does not harm to you and then 11 | # bundle exec overcommit --sign 12 | # ``` 13 | # 14 | # (it will manage the .git/hooks directory): 15 | # 16 | # Examples howto skip a test for a commit or push: 17 | # 18 | # ``` 19 | # SKIP=RuboCop git commit 20 | # SKIP=PuppetLint git commit 21 | # SKIP=RakeTask git push 22 | # ``` 23 | # 24 | # Don't invoke overcommit at all: 25 | # 26 | # ``` 27 | # OVERCOMMIT_DISABLE=1 git commit 28 | # ``` 29 | # 30 | # Read more about overcommit: https://github.com/brigade/overcommit 31 | # 32 | # To manage this config yourself in your module add 33 | # 34 | # ``` 35 | # .overcommit.yml: 36 | # unmanaged: true 37 | # ``` 38 | # 39 | # to your modules .sync.yml config 40 | --- 41 | PreCommit: 42 | RuboCop: 43 | enabled: true 44 | description: 'Runs rubocop on modified files only' 45 | command: ['bundle', 'exec', 'rubocop'] 46 | RakeTarget: 47 | enabled: true 48 | description: 'Runs lint on modified files only' 49 | targets: 50 | - 'lint' 51 | command: ['bundle', 'exec', 'rake'] 52 | YamlSyntax: 53 | enabled: true 54 | JsonSyntax: 55 | enabled: true 56 | TrailingWhitespace: 57 | enabled: true 58 | 59 | PrePush: 60 | RakeTarget: 61 | enabled: true 62 | description: 'Run rake targets' 63 | targets: 64 | - 'validate' 65 | - 'test' 66 | - 'rubocop' 67 | command: ['bundle', 'exec', 'rake'] 68 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: noop run 2 | 3 | on: 4 | workflow_dispatch: {} 5 | pull_request: {} 6 | push: 7 | branches: 8 | - master 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | unit: 15 | runs-on: ubuntu-latest 16 | name: Run msync --noop against all modules 17 | steps: 18 | - uses: actions/checkout@v6 19 | - name: Setup ruby 20 | uses: ruby/setup-ruby@v1 21 | with: 22 | ruby-version: 2.7 23 | bundler-cache: true 24 | - name: Run msync --noop 25 | run: bundle exec msync update --noop --git-base=https://github.com/ --branch foobranch 26 | metadata_json_deps: 27 | runs-on: ubuntu-latest 28 | name: Run metadata_json_deps on all modules 29 | steps: 30 | - uses: actions/checkout@v6 31 | - name: Setup ruby 32 | uses: ruby/setup-ruby@v1 33 | with: 34 | ruby-version: 2.7 35 | bundler-cache: true 36 | - name: Run msync --noop 37 | run: bundle exec msync clone --git-base=https://github.com/ 38 | - run: bundle exec rake metadata_deps 39 | outdated_module_summary: 40 | runs-on: ubuntu-latest 41 | name: Prints a list of all modules with outdated modulesync_config version 42 | steps: 43 | - uses: actions/checkout@v6 44 | - name: Setup ruby 45 | uses: ruby/setup-ruby@v1 46 | with: 47 | ruby-version: 2.7 48 | bundler-cache: true 49 | - name: Run msync --noop 50 | run: bundle exec msync clone --git-base=https://github.com/ 51 | - name: Generate summary 52 | run: bundle exec bin/outdated_modules_and_their_version 53 | 54 | tests: 55 | needs: 56 | - unit 57 | - metadata_json_deps 58 | runs-on: ubuntu-latest 59 | name: Test suite 60 | steps: 61 | - run: echo Test suite completed 62 | -------------------------------------------------------------------------------- /moduleroot/Gemfile.erb: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | 4 | source ENV['GEM_SOURCE'] || 'https://rubygems.org' 5 | 6 | <% groups = {} -%> 7 | <% (@configs['required'].keys + ((@configs['optional'] || {}).keys)).uniq.each do |key| -%> 8 | <% groups[key] = (@configs['required'][key] || []) + ((@configs['optional'] || {})[key] || []) -%> 9 | <% end -%> 10 | <% -%> 11 | <% groups.each do |group, gems| -%> 12 | group <%= group %> do 13 | <% maxlen = gems.map! do |gem| -%> 14 | <% gem['platforms'].map!{|a| a.to_sym} unless gem['platforms'].nil? -%> 15 | <% { -%> 16 | <% 'gem' => gem['gem'], -%> 17 | <% 'version' => gem['version'], -%> 18 | <% 'platforms' => gem['platforms'], -%> 19 | <% 'require' => gem['require'], -%> 20 | <% 'git' => gem['git'], -%> 21 | <% 'branch' => gem['branch'], -%> 22 | <% 'ruby-version' => gem['ruby-version'], -%> 23 | <% 'ruby-operator' => gem['ruby-operator'], -%> 24 | <% 'length' => gem['gem'].length + (("', '".length if gem['version']) || 0) + gem['version'].to_s.length -%> 25 | <% } -%> 26 | <% end.map do |gem| -%> 27 | <% gem['length'] -%> 28 | <% end.max -%> 29 | <% gems.each do |gem| -%> 30 | gem '<%= gem['gem'] %>'<%= ", '#{gem['version']}'" if gem['version'] %>, <%= ' ' * (maxlen - gem['length']) %> :require => false<%= ", :git => '#{gem['git']}'" if gem['git'] %><%= ", :branch => '#{gem['branch']}'" if gem['branch'] %><%= ", :platforms => #{gem['platforms']}" if gem['platforms'] %><%= " if RUBY_VERSION #{gem['ruby-operator']} '#{gem['ruby-version']}'" if (gem['ruby-operator'] && gem['ruby-version']) %> 31 | <% end -%> 32 | end 33 | 34 | <% end -%> 35 | gem 'rake', :require => false 36 | 37 | gem 'openvox', ENV.fetch('OPENVOX_GEM_VERSION', <%= @configs['openvox_version'].inspect %>), :require => false, :groups => [:test] 38 | 39 | # vim: syntax=ruby 40 | -------------------------------------------------------------------------------- /bin/merge-prs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | from argparse import ArgumentParser 4 | 5 | from github import Github 6 | 7 | 8 | def verify_pull_request(title, pull_request, required_status, merge): 9 | description = f"{title} ({pull_request.title})" 10 | 11 | if pull_request.merged: 12 | print(f"{description} is merged") 13 | return 14 | 15 | if not pull_request.state == 'open': 16 | print(f"{description} is {pull_request.state}") 17 | return 18 | 19 | if not pull_request.mergeable: 20 | print(f"{description} is not mergeable") 21 | return 22 | 23 | reviews = pull_request.get_reviews() 24 | if not [review for review in reviews if review.state != 'PENDING']: 25 | print(f"{description} has no reviews") 26 | return 27 | 28 | commit = list(pull_request.get_commits())[-1] 29 | combined_status = commit.get_combined_status() 30 | if combined_status.state != 'success': 31 | print(f"{description} CI status is {combined_status.state}") 32 | return 33 | 34 | if required_status: 35 | # Travis can not a required status on GH because that blocks other workflows 36 | if not any(status.context == required_status for status in combined_status.statuses): 37 | print(f"{description} does not have a status from {required_status}") 38 | return 39 | 40 | approved = all(review.state in ('APPROVED', 'PENDING') for review in reviews) 41 | if not approved: 42 | print(f"{description} is not approved") 43 | return 44 | 45 | if merge: 46 | print(f"Merging {description}") 47 | pull_request.merge() 48 | else: 49 | print(f"{description} can be merged") 50 | 51 | 52 | def main(): 53 | parser = ArgumentParser() 54 | parser.add_argument('pull_request', nargs='+', help="Pass in PRs as user/repo#pr") 55 | parser.add_argument('--required-status', help='Require this status context', 56 | default='continuous-integration/travis-ci/pr') 57 | parser.add_argument('--merge', help='Actually merge', action='store_true') 58 | 59 | args = parser.parse_args() 60 | 61 | github = Github(os.environ.get('GITHUB_TOKEN')) 62 | 63 | for pull_request in args.pull_request: 64 | name, number = pull_request.split('#', 1) 65 | repo = github.get_repo(name) 66 | pull = repo.get_pull(int(number)) 67 | verify_pull_request(pull_request, pull, args.required_status, args.merge) 68 | 69 | 70 | if __name__ == '__main__': 71 | main() 72 | -------------------------------------------------------------------------------- /.github/workflows/update.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Update all Puppet modules 3 | 4 | on: 5 | workflow_dispatch: {} 6 | push: 7 | tags: 8 | - '*' 9 | 10 | permissions: 11 | contents: read 12 | 13 | env: 14 | GIT_AUTHOR_NAME: pccibot 15 | GIT_AUTHOR_EMAIL: 12855858+pccibot@users.noreply.github.com 16 | GIT_COMMITTER_NAME: pccibot 17 | GIT_COMMITTER_EMAIL: 12855858+pccibot@users.noreply.github.com 18 | SSH_AUTH_SOCK: /tmp/ssh_agent.sock 19 | GITHUB_BASE_URL: https://api.github.com 20 | 21 | jobs: 22 | msync: 23 | runs-on: ubuntu-latest 24 | name: Run msync against all modules 25 | if: ${{ github.repository_owner == 'voxpupuli' }} 26 | steps: 27 | - name: checkout code 28 | # the action has a ssh-key option. 29 | # when provided, it configures the ssh/git config to authenticate automatically with that key to the source repo 30 | # the authentication won't be used for other repos (which we need for msync), so we cannot use the option 31 | # that's the reason for the 'Add SSH key' step 32 | # 33 | # the "ref: github.ref" is required for the tag to be properly checked out, as a workaround 34 | # for https://github.com/actions/checkout/issues/1638 35 | uses: actions/checkout@v6 36 | with: 37 | fetch-depth: 0 38 | fetch-tags: true 39 | ref: ${{ github.ref }} 40 | - name: Setup ruby 41 | uses: ruby/setup-ruby@v1 42 | with: 43 | ruby-version: 3.4 44 | bundler-cache: true 45 | - name: Add SSH key 46 | run: | 47 | mkdir -p ~/.ssh 48 | echo "${{ secrets.PCCI_SSH_PRIVATE_KEY }}" > ~/.ssh/github_actions 49 | chmod 600 ~/.ssh/github_actions 50 | ssh-agent -a $SSH_AUTH_SOCK > /dev/null 51 | ssh-add ~/.ssh/github_actions 52 | - name: set git user & email & commit signing 53 | run: | 54 | git config --global user.email "$GIT_AUTHOR_EMAIL" 55 | git config --global user.name "$GIT_AUTHOR_NAME" 56 | git config --global gpg.format ssh 57 | git config --global user.signingkey ~/.ssh/github_actions 58 | git config --global commit.gpgsign true 59 | - name: Run msync 60 | env: 61 | # https://github.com/voxpupuli/modulesync?tab=readme-ov-file#submitting-prsmrs-to-github-or-gitlab 62 | GITHUB_TOKEN: '${{ secrets.PCCI_PAT_MODULESYNC_PR }}' 63 | run: | 64 | bundle exec msync update --verbose \ 65 | --pr \ 66 | --pr-labels modulesync \ 67 | --pr-title "modulesync $(git describe)" \ 68 | --message "modulesync $(git describe)" 69 | -------------------------------------------------------------------------------- /bin/clean-metadata: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import glob 3 | import json 4 | import os 5 | from posixpath import dirname 6 | import argparse 7 | 8 | # Note range is exclusive so the last number is not in the list 9 | OPENVOX_VERSION = '>= 8.19.0 < 9.0.0' 10 | UNSUPPORTED_EL = {str(i) for i in range(3, 7)} 11 | UNSUPPORTED = { 12 | 'CentOS': UNSUPPORTED_EL, 13 | 'Debian': {str(i) for i in range(3, 9)}, 14 | 'Fedora': {str(i) for i in range(3, 33)}, 15 | 'OracleLinux': UNSUPPORTED_EL, 16 | 'RedHat': UNSUPPORTED_EL, 17 | 'SLED': {'9', '10'}, 18 | 'SLES': {'9', '10'}, 19 | 'Scientific': UNSUPPORTED_EL, 20 | 'Ubuntu': {str(i) + m for i in range(4, 18) for m in ('.04', '.10')}, 21 | } 22 | CHANGED_MODULES_PATH='tmp/changed_modules.txt' 23 | 24 | parser = argparse.ArgumentParser(description='Manage metadata updates for requirements or operatingsystem_support.') 25 | parser.add_argument('--no-requirements', action='store_true', help='Do not update the requirements section.') 26 | parser.add_argument('--no-os', action='store_true', help='Do not update the operatingsystem_support section.') 27 | args = parser.parse_args() 28 | 29 | if not os.path.exists('tmp'): 30 | os.makedirs('tmp') 31 | if os.path.exists(CHANGED_MODULES_PATH): 32 | os.remove(CHANGED_MODULES_PATH) 33 | changed_modules = open(CHANGED_MODULES_PATH, 'a+') 34 | 35 | for filename in glob.glob('modules/*/*/metadata.json'): 36 | print('Reading {}'.format(filename)) 37 | 38 | with open(filename) as fp: 39 | metadata = json.load(fp) 40 | 41 | updated = False 42 | 43 | if not args.no_requirements: 44 | updated_requirements = [] 45 | for req in metadata.get('requirements', []): 46 | if req['name'] == 'openvox' and req['version_requirement'] != OPENVOX_VERSION: 47 | print('Updating openvox version requirement from {} to {}'.format(req['version_requirement'], OPENVOX_VERSION)) 48 | req['version_requirement'] = OPENVOX_VERSION 49 | updated = True 50 | if req['name'] != 'puppet': 51 | updated_requirements.append(req) 52 | else: 53 | updated = True 54 | metadata['requirements'] = updated_requirements 55 | 56 | if not args.no_os: 57 | for operatingsystem in metadata.get('operatingsystem_support', []): 58 | releases = set(operatingsystem.get('operatingsystemrelease', [])) 59 | for release in releases & UNSUPPORTED.get(operatingsystem['operatingsystem'], set()): 60 | print('Removing {}-{}'.format(operatingsystem['operatingsystem'], release)) 61 | operatingsystem['operatingsystemrelease'].remove(release) 62 | updated = True 63 | 64 | if operatingsystem.get('operatingsystemrelease') == []: 65 | print('Removing {}'.format(operatingsystem['operatingsystem'])) 66 | metadata['operatingsystem_support'].remove(operatingsystem) 67 | updated = True 68 | 69 | if updated: 70 | print('Writing {}'.format(filename)) 71 | with open(filename, 'w') as fp: 72 | fp.write(json.dumps(metadata, indent=2) + "\n") 73 | changed_modules.write(dirname(filename) + "\n") 74 | 75 | changed_modules.close() 76 | -------------------------------------------------------------------------------- /managed_modules.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - puppet-allknowingdns 3 | - puppet-alternatives 4 | - puppet-amanda 5 | - puppet-appd_db_agent 6 | - puppet-aptly 7 | - puppet-archive 8 | - puppet-artifactory 9 | - puppet-augeas 10 | - puppet-augeasproviders 11 | - puppet-augeasproviders_apache 12 | - puppet-augeasproviders_base 13 | - puppet-augeasproviders_core 14 | - puppet-augeasproviders_grub 15 | - puppet-augeasproviders_mounttab 16 | - puppet-augeasproviders_nagios 17 | - puppet-augeasproviders_pam 18 | - puppet-augeasproviders_postgresql 19 | - puppet-augeasproviders_puppet 20 | - puppet-augeasproviders_shellvar 21 | - puppet-augeasproviders_ssh 22 | - puppet-augeasproviders_sysctl 23 | - puppet-augeasproviders_syslog 24 | - puppet-authselect 25 | - puppet-autofs 26 | - puppet-autosign 27 | - puppet-bacula 28 | - puppet-bareos 29 | - puppet-bird 30 | - puppet-bolt 31 | - puppet-borg 32 | - puppet-ca_cert 33 | - puppet-caddy 34 | - puppet-cassandra 35 | - puppet-catalog_diff 36 | - puppet-check_mk 37 | - puppet-chrony 38 | - puppet-clevis 39 | - puppet-collectd 40 | - puppet-collections 41 | - puppet-confluence 42 | - puppet-conntrackd 43 | - puppet-consul 44 | - puppet-corosync 45 | - puppet-cpanm 46 | - puppet-cron 47 | - puppet-cups 48 | - puppet-cvmfs 49 | - puppet-dbbackup 50 | - puppet-dhcp 51 | - puppet-dnsquery 52 | - puppet-dotnet 53 | - puppet-drbd 54 | - puppet-earlyoom 55 | - puppet-elastic_stack 56 | - puppet-elasticsearch 57 | - puppet-epel 58 | - puppet-erlang 59 | - puppet-etcd 60 | - puppet-example 61 | - puppet-extlib 62 | - puppet-fail2ban 63 | - puppet-falco 64 | - puppet-ferm 65 | - puppet-fetchcrl 66 | - puppet-filemapper 67 | - puppet-firewalld 68 | - puppet-format 69 | - puppet-gerrit 70 | - puppet-github_actions_runner 71 | - puppet-gitlab 72 | - puppet-gitlab_ci_runner 73 | - puppet-gluster 74 | - puppet-googleauthenticator 75 | - puppet-grafana 76 | - puppet-grafana_alloy 77 | - puppet-graphite_powershell 78 | - puppet-graylog_api 79 | - puppet-groupmembership 80 | - puppet-hashi_stack 81 | - puppet-hdm 82 | - puppet-healthcheck 83 | - puppet-hiera 84 | - puppet-hiera_vault 85 | - puppet-homeassistant 86 | - puppet-hosts 87 | - puppet-hyperglass 88 | - puppet-icinga 89 | - puppet-icinga2 90 | - puppet-icingadb 91 | - puppet-icingaweb2 92 | - puppet-ipset 93 | - puppet-jail 94 | - puppet-jenkins 95 | - puppet-jira 96 | - puppet-jolokia 97 | - puppet-k8s 98 | - puppet-kafka 99 | - puppet-keepalived 100 | - puppet-kibana 101 | - puppet-kmod 102 | - puppet-ldapquery 103 | - puppet-letsencrypt 104 | - puppet-lldpd 105 | - puppet-logrotate 106 | - puppet-logstash 107 | - puppet-make 108 | - puppet-minecraft 109 | - puppet-misp 110 | - puppet-mlocate 111 | - puppet-mongodb 112 | - puppet-monit 113 | - puppet-mosquitto 114 | - puppet-mrepo 115 | - puppet-mumble 116 | - puppet-mysql_java_connector 117 | - puppet-network 118 | - puppet-nfs 119 | - puppet-nftables 120 | - puppet-nginx 121 | - puppet-nodejs 122 | - puppet-nomad 123 | - puppet-nrpe 124 | - puppet-nscd 125 | - puppet-nsclient 126 | - puppet-nsd 127 | - puppet-nsswitch 128 | - puppet-openldap 129 | - puppet-opensearch 130 | - puppet-opensearch_dashboards 131 | - puppet-openssl 132 | - puppet-openvmtools 133 | - puppet-openvoxdb 134 | - puppet-openvox_bootstrap 135 | - puppet-openvoxview 136 | - puppet-openvpn 137 | - puppet-os_patching 138 | - puppet-otelcol 139 | - puppet-patching_as_code 140 | - puppet-patroni 141 | - puppet-pbuilder 142 | - puppet-php 143 | - puppet-pkgng 144 | - puppet-posix_acl 145 | - puppet-postfix 146 | - puppet-poudriere 147 | - puppet-powerdns 148 | - puppet-prometheus 149 | - puppet-prometheus_reporter 150 | - puppet-prosody 151 | - puppet-proxysql 152 | - puppet-puppet_certificate 153 | - puppet-puppet_run_scheduler 154 | - puppet-puppetboard 155 | - puppet-python 156 | - puppet-quadlets 157 | - puppet-r10k 158 | - puppet-rabbitmq 159 | - puppet-rclocal 160 | - puppet-redis 161 | - puppet-rhsm 162 | - puppet-rkhunter 163 | - puppet-rsyslog 164 | - puppet-rundeck 165 | - puppet-rvm 166 | - puppet-selinux 167 | - puppet-sftp_jail 168 | - puppet-smokeping 169 | - puppet-snmp 170 | - puppet-spiped 171 | - puppet-splunk 172 | - puppet-squid 173 | - puppet-ssh_keygen 174 | - puppet-sssd 175 | - puppet-stackify 176 | - puppet-strongswan 177 | - puppet-swap_file 178 | - puppet-systemd 179 | - puppet-tang 180 | - puppet-telegraf 181 | - puppet-trusted_ca 182 | - puppet-tuned 183 | - puppet-unattended_upgrades 184 | - puppet-unbound 185 | - puppet-usbguard 186 | - puppet-varnish 187 | - puppet-vault 188 | - puppet-vault_lookup 189 | - puppet-virtualbox 190 | - puppet-wildfly 191 | - puppet-windows_firewall 192 | - puppet-windowsfeature 193 | - puppet-winlogbeat 194 | - puppet-wireguard 195 | - puppet-xmlfile 196 | - puppet-yum 197 | - puppet-zabbix 198 | - puppet-zram_generator 199 | - puppet-zypprepo 200 | ... 201 | # vim: syntax=yaml 202 | -------------------------------------------------------------------------------- /config_defaults.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # yamllint disable rule:line-length 3 | .github/workflows/ci.yml: 4 | excludes: [] 5 | acceptance_tests: true 6 | main_branches: ['main', 'master'] 7 | # PDK creates this 8 | .github/workflows/puppet-lint.yml: 9 | delete: true 10 | # Perforce used those 11 | .github/workflows/release_without.yml: 12 | delete: true 13 | .github/workflows/release_prep.yml: 14 | delete: true 15 | .github/workflows/nightly.yml: 16 | delete: true 17 | .github/workflows/mend.yml: 18 | delete: true 19 | .travis.yml: 20 | delete: true 21 | Jenkinsfile: 22 | delete: true 23 | Gemfile: 24 | openvox_version: ['>= 7', '< 9'] 25 | required: 26 | ':test': 27 | - gem: voxpupuli-test 28 | version: '~> 13.0' 29 | - gem: puppet_metadata 30 | version: '~> 5.0' 31 | ':development': 32 | - gem: guard-rake 33 | - gem: overcommit 34 | version: '>= 0.39.1' 35 | ':system_tests': 36 | - gem: voxpupuli-acceptance 37 | version: '~> 4.0' 38 | ':release': 39 | - gem: voxpupuli-release 40 | version: '~> 5.0' 41 | Rakefile: 42 | # config.user: USER 43 | # config.project: PROJECT 44 | # config.tag_pattern: 'v%s' 45 | .puppet-lint.rc: 46 | disabled_lint_checks: 47 | - parameter_documentation 48 | - parameter_types 49 | enabled_lint_checks: [] 50 | spec/default_facts.yml: 51 | delete: true 52 | spec/classes/coverage_spec.rb: 53 | delete: true 54 | spec/acceptance/nodesets/default.yml: 55 | delete: true 56 | spec/acceptance/nodesets/archlinux-2-x64.yml: 57 | delete: true 58 | spec/acceptance/nodesets/centos-511-x64.yml: 59 | delete: true 60 | spec/acceptance/nodesets/centos-6-x64.yml: 61 | delete: true 62 | spec/acceptance/nodesets/centos-66-x64.yml: 63 | delete: true 64 | spec/acceptance/nodesets/centos-66-x64-pe.yml: 65 | delete: true 66 | spec/acceptance/nodesets/centos-7-x64.yml: 67 | delete: true 68 | spec/acceptance/nodesets/centos-7.yml: 69 | delete: true 70 | spec/acceptance/nodesets/centos-72-x64.yml: 71 | delete: true 72 | spec/acceptance/nodesets/debian-78-x64.yml: 73 | delete: true 74 | spec/acceptance/nodesets/debian-82-x64.yml: 75 | delete: true 76 | spec/acceptance/nodesets/fedora-20-x64.yml: 77 | delete: true 78 | spec/acceptance/nodesets/fedora-24-x64.yml: 79 | delete: true 80 | spec/acceptance/nodesets/fedora-25-x64.yml: 81 | delete: true 82 | spec/acceptance/nodesets/fedora-26-x64.yml: 83 | delete: true 84 | spec/acceptance/nodesets/fedora-27-x64.yml: 85 | delete: true 86 | spec/acceptance/nodesets/debian-7-x64.yml: 87 | delete: true 88 | spec/acceptance/nodesets/debian-8-x64.yml: 89 | delete: true 90 | spec/acceptance/nodesets/sles-11-x64.yml: 91 | delete: true 92 | spec/acceptance/nodesets/sles-12-x64.yml: 93 | delete: true 94 | spec/acceptance/nodesets/ubuntu-1604-x64.yml: 95 | delete: true 96 | spec/acceptance/nodesets/ubuntu-server-1204-x64.yml: 97 | delete: true 98 | spec/acceptance/nodesets/ubuntu-server-1404-x64.yml: 99 | delete: true 100 | spec/acceptance/nodesets/ubuntu-server-1604-x64.yml: 101 | delete: true 102 | spec/acceptance/nodesets/windows-2008R2-serverstandard-x64.yml: 103 | delete: true 104 | spec/acceptance/nodesets/windows-2012-serverstandard-x64.yml: 105 | delete: true 106 | spec/acceptance/nodesets/windows-2012R2-serverstandard-x64.yml: 107 | delete: true 108 | spec/acceptance/nodesets/ec2/amazonlinux-2016091.yml: 109 | delete: true 110 | spec/acceptance/nodesets/ec2/image_templates.yaml: 111 | delete: true 112 | spec/acceptance/nodesets/ec2/rhel-73-x64.yml: 113 | delete: true 114 | spec/acceptance/nodesets/ec2/sles-12sp2-x64.yml: 115 | delete: true 116 | spec/acceptance/nodesets/ec2/ubuntu-1604-x64.yml: 117 | delete: true 118 | spec/acceptance/nodesets/ec2/windows-2016-base-x64.yml: 119 | delete: true 120 | spec/spec_helper.rb: 121 | add_mocked_facts: true 122 | facterdb_string_keys: false 123 | mock_with: false 124 | spec/spec_helper_acceptance.rb: 125 | unmanaged: true 126 | configure_beaker: 127 | modules: ':metadata' 128 | spec/spec.opts: 129 | delete: true 130 | CONTRIBUTING.md: 131 | delete: true 132 | .github/CONTRIBUTING.md: 133 | delete: true 134 | .yardopts: 135 | delete: true 136 | .gitlab-ci.yml: 137 | delete: true 138 | .pdkignore: 139 | delete: true 140 | appveyor.yml: 141 | delete: true 142 | pdk.yaml: 143 | delete: true 144 | .ruby-version: 145 | delete: true 146 | .tool-versions: 147 | delete: true 148 | CODE_OF_CONDUCT.md: 149 | delete: true 150 | .github/CODE_OF_CONDUCT.md: 151 | delete: true 152 | SECURITY.md: 153 | delete: true 154 | .github/SECURITY.md: 155 | delete: true 156 | .github/stale.yml: 157 | delete: true 158 | Modulefile: 159 | delete: true 160 | Makefile: 161 | delete: true 162 | Dockerfile: 163 | delete: true 164 | .pcci.yml: 165 | delete: true 166 | .rspec_parallel: 167 | delete: true 168 | .rspec: 169 | delete: true 170 | .devcontainer/Dockerfile: 171 | delete: true 172 | .devcontainer/README.md: 173 | delete: true 174 | .vscode/extensions.json: 175 | delete: true 176 | .nodeset.yml: 177 | delete: true 178 | .kitchen.yml: 179 | delete: true 180 | ... 181 | # vim: syntax=yaml 182 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ModuleSync Configs 2 | 3 | [![noop run](https://github.com/voxpupuli/modulesync_config/actions/workflows/main.yml/badge.svg)](https://github.com/voxpupuli/modulesync_config/actions/workflows/main.yml) 4 | 5 | Module sync configurations for Vox Pupuli Modules 6 | 7 | ## How to use it 8 | 9 | ```bash 10 | git clone https://github.com/voxpupuli/modulesync_config.git 11 | cd modulesync_config 12 | git checkout $(git tag --list | sort -V | tail -n1) # checkout latest tag 13 | bundle config set --local path '.vendor' 14 | bundle install 15 | bundle exec msync help update 16 | ``` 17 | 18 | ## Examples 19 | 20 | ### Clone all modules 21 | 22 | This will clone all modules into `modules/$namespace`. 23 | The namespace is set in modulesync.yml and defaults to `voxpupuli`. 24 | 25 | ```bash 26 | bundle exec msync clone --verbose 27 | ``` 28 | 29 | ### module sync one specific module 30 | 31 | ```bash 32 | bundle exec msync update -f {module_name} --message "modulesync $(git describe)" 33 | ``` 34 | 35 | ### module sync one module and review changes before submitting changes 36 | 37 | ```bash 38 | bundle exec msync update -f {module_name} --noop 39 | cd modules/{module_name} 40 | # edit then git commit/push 41 | ``` 42 | 43 | ### Syncing all modules 44 | 45 | This will sync everything in the `managed_modules.yml`. 46 | 47 | ```bash 48 | bundle exec msync update --message "modulesync $(git describe)" 49 | ``` 50 | 51 | Now you can use [hub](https://github.com/github/hub) to create pull requests. 52 | 53 | ```bash 54 | ./bin/create-pull-requests 55 | ``` 56 | 57 | You can now also create pull requests with modulesync directly: 58 | 59 | ```bash 60 | export GITHUB_TOKEN=token 61 | bundle exec msync update --message "modulesync $(git describe)" --pr --pr-labels modulesync --pr-title "modulesync $(git describe)" 62 | ``` 63 | 64 | ### Create a new module 65 | 66 | It is possible to create a new module using msync. 67 | First add it to the list of modules in `managed_modules.yml`. 68 | If it's not in the voxpupuli namespace, be sure to include yours by using `mynamespace/puppet-module`. 69 | Then use an offline update to create the structure: 70 | 71 | ```bash 72 | bundle exec msync update --offline -f puppet-mymodule 73 | ``` 74 | 75 | Now a new directory `modules/mynamespace/puppet-mymodule` will be created. 76 | 77 | Initialize git and push it to your location: 78 | 79 | ```bash 80 | cd modules/mynamespace/puppet-mymodule 81 | git init 82 | git add . 83 | git commit -m 'Add module skeleton' 84 | git remote add origin git@github.com:mynamespace/puppet-mymodule 85 | git push origin HEAD -u 86 | ``` 87 | 88 | Now proceed with the regular module work, such as creating `metadata.json` and your manifests. 89 | 90 | ### Clean up old mess before syncing 91 | 92 | ```bash 93 | ./bin/clean-git-checkouts 94 | ``` 95 | 96 | ### Get a list of open todos 97 | 98 | We have a nice script to detect a bunch of maintenance jobs in our modules. For 99 | example wrong puppet version constraints or missing support for new operating 100 | systems: 101 | 102 | ```bash 103 | bundle install --path --without development 104 | export GITHUB_TOKEN=token 105 | bundle exec bin/get_all_the_diffs 106 | ``` 107 | 108 | You can also pass `DEBUG=true` as an environment variable to the script. to get 109 | a bit more output. 110 | 111 | ### Checking all module dependencies against the forge 112 | 113 | Ideally speaking all modules are compatible with the latest forge releases. To 114 | do this manually is tedious so tools have been written. 115 | 116 | First off all, make sure all modules are checked out and up to date. For 117 | example: 118 | 119 | ```bash 120 | bundle exec msync update --noop -b update-dependencies 121 | ``` 122 | 123 | If you already have all checkouts, `./bin/clean-git-checkouts` can also be 124 | used. 125 | 126 | Now it's time to get a list 127 | ```bash 128 | bundle exec rake metadata_deps 129 | ``` 130 | 131 | If you see `puppetlabs/stdlib` has made a new major release (we'll use 7.x in 132 | this example), you need to set the upper bound to 8.0.0: 133 | 134 | ```bash 135 | ./bin/bump-dependency-upper-bound puppetlabs/stdlib 8.0.0 modules/*/*/metadata.json 136 | ``` 137 | 138 | You can verify it worked by running `rake metadata_deps` again. 139 | 140 | Of course this means nothing until you actually submit the change. To do this 141 | in bulk: 142 | ```bash 143 | for module in modules/*/* ; do 144 | ( 145 | cd $module 146 | if git diff --exit-code metadata.json ; then 147 | git commit -m 'Mark compatible with puppetlabs/stdlib 7.x' metadata.json 148 | fi 149 | ) 150 | done 151 | ``` 152 | 153 | Of course you can expand the loop with commands like `git push origin HEAD -u` 154 | and `hub pull-request --no-edit` to create bulk pull requests. 155 | 156 | ## Tips for External Contributors 157 | 158 | If you are used to a traditional GitHub Fork and PR model, then you may run into 159 | a couple of issues when using this repository. 160 | 161 | ### Using Your Personal Repos 162 | 163 | You may have a case where you work with different communities where they all 164 | name their modules `puppet-`. Obviously, forking all of these and 165 | keeping track of them is extremely difficult, particularly when GitHub does not 166 | have the concept of subgroups. 167 | 168 | In this case, we are going to assume that you have named your module 169 | `/pupmod--`. 170 | 171 | If your username is `gituser` and the author of the module is `voxpupuli`, and 172 | the module name is `firewalld` then the full name would be 173 | `gituser/pupmod-voxpupuli-firewalld`. 174 | 175 | **NOTE:** This is NOT required, but may be useful in the situation noted above. 176 | 177 | To work with the forked module, you will need to do the following: 178 | 179 | 1. Add your forked module name to the `managed_modules.yml` file 180 | 2. Tell `msync` explicitly where to find your module 181 | * `bundle exec msync -n -f pupmod-- --noop` 182 | 183 | ## Contribution 184 | 185 | We currently require all commits to be signed with GPG, so please configure 186 | your git client properly. Let us know if you need some help. We're also 187 | reachable via IRC, email, and Slack, as documented at [connect with us](https://voxpupuli.org/connect/). 188 | 189 | If you provide a patch that effects our modules, please test it on a single 190 | module and link the pull request from that specific module to the PR on 191 | the `modulesync_config` repository. 192 | 193 | ## Do a new release 194 | 195 | * Update the version in `moduleroot/.msync.yml.erb` 196 | * `CHANGELOG_GITHUB_TOKEN='*your token*' bundle exec rake changelog` 197 | 198 | -------------------------------------------------------------------------------- /bin/get_all_the_diffs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'json' 4 | require 'open-uri' 5 | require 'yaml' 6 | require 'puppet_forge' 7 | require 'octokit' 8 | 9 | # we removed the following modules from our modulesync_config / hide it because they are not Puppet modules but match the puppet- pattern 10 | # The modules in the list are broken, unfinished or got migrated (yes, that really happens from time to time) 11 | # ToDo: extend this list with repos that are archived on github 12 | # ToDo: Archive repos that we migrate away 13 | LEGACY_OR_BROKEN_NOBODY_KNOWS = ['puppet-bacula', 'puppet-nagios_providers', 'puppet-iis', 'puppet-syntax', 'puppet-blacksmith', 'puppet-mode'] 14 | 15 | # define some versions that we want to match against 16 | PUPPET_SUPPORT_RANGE = '>= 5.5.8 < 7.0.0' 17 | # Ubuntu 18.04 got released, but Puppet doesn't work yet on it 18 | # https://tickets.puppetlabs.com/browse/PA-1869 19 | # https://github.com/camptocamp/facterdb/pull/82#event-1600066178 20 | UBUNTU_SUPPORT_RANGE = ['16.04', '18.04'] 21 | DEBIAN_SUPPORT_RANGE = ['8', '9', '10'] 22 | CENTOS_SUPPORT_RANGE = ['6', '7'] 23 | 24 | # Do you want debug output? 25 | DEBUG = ENV['DEBUG'] ||= false 26 | 27 | # get all modules we own from github 28 | # use poor mans pagination solution 29 | puts "get data from the github API" if DEBUG 30 | client = Octokit::Client.new 31 | client.auto_paginate = true 32 | gh_repos = client.repos('voxpupuli') 33 | repos = [] 34 | gh_repos.each{|repo| repos << repo[:name] if repo[:name] =~ /^puppet-(?!lint)/} 35 | repos -= LEGACY_OR_BROKEN_NOBODY_KNOWS 36 | 37 | # get all managed modules from our modulesync_config 38 | puts "get all manged modules" if DEBUG 39 | modulesync_repos = YAML.load(File.read('managed_modules.yml')) 40 | 41 | # get all modules that we have on github but are currently not managed by modulesync_config 42 | not_synced_repos = repos.select{|repo| !modulesync_repos.include?(repo)} 43 | 44 | # get all forge releases 45 | puts "get data from the forge API" if DEBUG 46 | PuppetForge.user_agent = "VoxPupuli/0.1 get_all_diffs script" 47 | vp = PuppetForge::User.find('puppet') 48 | forge_releases = vp.modules.unpaginated.map(&:slug) 49 | 50 | # get all modules that are in modulesync_config but not released 51 | unreleased_modules = modulesync_repos.reject{|repo| forge_releases.include?(repo)} 52 | 53 | # get all modules we own but are unreleased 54 | really_unreleased_modules = repos.reject{|repo| forge_releases.include?(repo)} 55 | 56 | # get all modules that require a modulesync 57 | really_need_an_initial_modulesync = not_synced_repos.reject{|repo| LEGACY_OR_BROKEN_NOBODY_KNOWS.include?(repo)} 58 | 59 | # get all modules that really need an initial release 60 | really_need_an_inital_release = really_unreleased_modules.reject{|repo| LEGACY_OR_BROKEN_NOBODY_KNOWS.include?(repo)} 61 | 62 | # update git and get the latest release 63 | `git fetch --all --prune` 64 | tags = `git tag -l` 65 | latest_release = tags.lines.last.strip 66 | 67 | # get all the content of all .msync.yml, .sync.yml and metadata.json files 68 | modules_that_were_added_but_never_synced = [] 69 | modules_that_have_missing_secrets = [] 70 | msyncs = {} 71 | syncs = {} 72 | metadatas = {} 73 | modulesync_repos.each do |repo| 74 | begin 75 | response = URI.open("https://raw.githubusercontent.com/voxpupuli/#{repo}/master/.msync.yml") 76 | rescue OpenURI::HTTPError 77 | puts "something is broken with #{repo} and https://raw.githubusercontent.com/voxpupuli/#{repo}/master/.msync.yml" if DEBUG 78 | modules_that_were_added_but_never_synced << repo 79 | next 80 | end 81 | msyncs[repo] = YAML.load(response) 82 | begin 83 | response = URI.open("https://raw.githubusercontent.com/voxpupuli/#{repo}/master/.sync.yml") 84 | rescue OpenURI::HTTPError 85 | puts "something is broken with #{repo} and https://raw.githubusercontent.com/voxpupuli/#{repo}/master/.sync.yml" if DEBUG 86 | modules_that_have_missing_secrets << repo 87 | next 88 | end 89 | syncs[repo] = YAML.load(response) 90 | begin 91 | response = URI.open("https://raw.githubusercontent.com/voxpupuli/#{repo}/master/metadata.json") 92 | rescue OpenURI::HTTPError 93 | puts "something is broken with #{repo} and https://raw.githubusercontent.com/voxpupuli/#{repo}/master/metadata.json" 94 | next 95 | end 96 | metadatas[repo] = JSON.load(response) 97 | end 98 | 99 | # get the current modulesync version for all repos 100 | versions = {} 101 | msyncs.each do |repo, msync| 102 | versions[repo] = msync['modulesync_config_version'] 103 | end 104 | 105 | # ToDo: get all modules that dont have a secret in .sync.yml 106 | 107 | # ToDo: get all modules with outdated Puppet versions 108 | modules_without_puppet_version_range = [] 109 | modules_with_incorrect_puppet_version_range = [] 110 | modules_without_operatingsystems_support = [] 111 | supports_eol_ubuntu = [] 112 | supports_eol_debian = [] 113 | supports_eol_centos = [] 114 | doesnt_support_latest_ubuntu = [] 115 | doesnt_support_latest_debian = [] 116 | doesnt_support_latest_centos = [] 117 | 118 | metadatas.each do |repo, metadata| 119 | # check if Puppet version range is correct 120 | begin 121 | version_requirement = metadata['requirements'][0]['version_requirement'] 122 | if PUPPET_SUPPORT_RANGE != version_requirement 123 | puts "repo #{repo} has version requirement #{version_requirement}, but it should be #{PUPPET_SUPPORT_RANGE}" if DEBUG 124 | modules_with_incorrect_puppet_version_range << repo 125 | end 126 | # it's possible that the version range isn't present at all in the metadata.json 127 | rescue NoMethodError 128 | modules_without_puppet_version_range << repo 129 | end 130 | 131 | # check Ubuntu range 132 | begin 133 | metadata['operatingsystem_support'].each do |os| 134 | case os['operatingsystem'] 135 | when 'Ubuntu' 136 | supports_eol_ubuntu << repo if os['operatingsystemrelease'].min < UBUNTU_SUPPORT_RANGE.min 137 | doesnt_support_latest_ubuntu << repo if os['operatingsystemrelease'].max < UBUNTU_SUPPORT_RANGE.max 138 | when 'Debian' 139 | supports_eol_debian << repo if os['operatingsystemrelease'].min < DEBIAN_SUPPORT_RANGE.min 140 | doesnt_support_latest_debian << repo if os['operatingsystemrelease'].max < DEBIAN_SUPPORT_RANGE.max 141 | when 'CentOS', 'RedHat' 142 | supports_eol_centos << repo if os['operatingsystemrelease'].min < CENTOS_SUPPORT_RANGE.min 143 | doesnt_support_latest_centos << repo if os['operatingsystemrelease'].max < CENTOS_SUPPORT_RANGE.max 144 | end 145 | end 146 | rescue NoMethodError 147 | modules_without_operatingsystems_support << repo 148 | end 149 | end 150 | # we have a list of CentOS and RedHat in this array, we need to clean it up 151 | supports_eol_centos.sort!.uniq! 152 | doesnt_support_latest_centos.sort!.uniq! 153 | 154 | # get all repos that are on an outdated version of modulesync_config 155 | need_another_sync = [] 156 | versions.each do |repo| 157 | # index 0 is the module name, index 1 is the used modulesync_config version 158 | need_another_sync << repo[0] if Gem::Version.new(latest_release) > Gem::Version.new(repo[1]) 159 | end 160 | 161 | # generate some output 162 | puts '==============================================================================================================================================================' 163 | puts "We got #{repos.count} modules in our github org" 164 | puts "We got #{modulesync_repos.count} in our modulesync config" 165 | puts "We released #{forge_releases.count} modules to forge.puppet.com" 166 | puts '==============================================================================================================================================================' 167 | puts "The following modules are missing in our modulesync config: #{not_synced_repos.join(', ')}" if not_synced_repos.count > 0 168 | puts "The following modules are in modulesync config but not released to the forge: #{unreleased_modules.join(', ')}" if unreleased_modules.count > 0 169 | puts "The following modules are in our github org but unreleased: #{really_unreleased_modules.join(', ')}" if really_unreleased_modules.count > 0 170 | puts "the following modules got added to our modulesync config but were never synced: #{modules_that_were_added_but_never_synced.join(', ')}" if modules_that_were_added_but_never_synced.count > 0 171 | puts '==============================================================================================================================================================' if LEGACY_OR_BROKEN_NOBODY_KNOWS.count > 0 172 | puts "We don't care about #{LEGACY_OR_BROKEN_NOBODY_KNOWS.join(', ')}" if LEGACY_OR_BROKEN_NOBODY_KNOWS.count > 0 173 | puts '==============================================================================================================================================================' 174 | puts "We need to do an initial modulesync on: #{really_need_an_initial_modulesync.join(', ')}" if really_need_an_initial_modulesync.count > 0 175 | puts "we need to do a normal modulesync on: #{need_another_sync.join(', ')}" if need_another_sync.count > 0 176 | puts "We need to check Puppets version_requirement on these modules because it is not equal to #{PUPPET_SUPPORT_RANGE}: #{modules_with_incorrect_puppet_version_range.join(', ')}" if modules_with_incorrect_puppet_version_range.count > 0 177 | puts "We need to add Puppets version_requirement to: #{modules_without_puppet_version_range.join(', ')}" if modules_without_puppet_version_range.count > 0 178 | puts "We need to remove EOL Debian on: #{supports_eol_debian.join(', ')}" if supports_eol_debian.count > 0 179 | puts "We need to remove EOL Ubuntu on: #{supports_eol_ubuntu.join(', ')}" if supports_eol_ubuntu.count > 0 180 | puts "We need to remove EOL CentOS on: #{supports_eol_centos.join(', ')}" if supports_eol_centos.count > 0 181 | puts "We need to add support for Ubuntu #{UBUNTU_SUPPORT_RANGE.max} to: #{doesnt_support_latest_debian.join(', ')}" if doesnt_support_latest_debian.count > 0 182 | puts "We need to add support for Debian #{DEBIAN_SUPPORT_RANGE.max} to: #{doesnt_support_latest_ubuntu.join(', ')}" if doesnt_support_latest_ubuntu.count > 0 183 | puts "We need to add support for CentOS #{CENTOS_SUPPORT_RANGE.max} to: #{doesnt_support_latest_centos.join(', ')}" if doesnt_support_latest_centos.count > 0 184 | puts "Afterwards we really need to release: #{really_need_an_inital_release.join(', ')}" if really_need_an_inital_release.count > 0 185 | puts '==============================================================================================================================================================' 186 | puts 'Note: You can cleanup EOL operating systems with our ./bin/clean-metadata script' 187 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------