├── .codacy.yaml ├── .editorconfig ├── .fixtures.yml ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .gitlab-ci.yml ├── .gitpod.Dockerfile ├── .gitpod.yml ├── .pdkignore ├── .rspec ├── .rubocop.yml ├── .ruby-version ├── .travis.yml ├── .travis.yml.nopdk ├── .vscode ├── settings.json └── tasks.json ├── .yardopts ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dangerfile ├── Gemfile ├── Gemfile.disable ├── Jenkinsfile ├── LICENSE ├── Puppetfile ├── README.md ├── Rakefile ├── appveyor.yml ├── bin ├── Rakefile_blacksmith ├── aws_presetup.sh ├── aws_setup.sh ├── aws_status.sh ├── bootstrap │ ├── cloud_init.sh │ └── tp_cli.sh ├── codemanager_check_deploy.sh ├── codemanager_reset.sh ├── config │ ├── defaults │ ├── gitlab-r10k.yaml │ ├── jenkins-r10k.yaml │ └── proxysetup ├── config_script.sh ├── docker_purge.sh ├── docker_rocker_build_role.sh ├── docker_run.sh ├── docker_setup.sh ├── docker_status.sh ├── docker_test_role.sh ├── docker_tp_build_role.sh ├── docs_classlistgenerate.sh ├── ec2_userdata │ ├── linux.sh │ └── windows.ps1 ├── enc_cat.sh ├── enc_cat │ ├── default.yaml │ └── testos.local.yaml ├── facter_db.rb ├── functions ├── git_checkout_master.sh ├── git_install_hooks.sh ├── git_setup_new_repo.sh ├── git_status.sh ├── gitlab_accept_merge_request.rb ├── gitlab_after.sh ├── gitlab_before.sh ├── gitlab_catalog_diff.sh ├── gitlab_catalog_preview.sh ├── gitlab_create_merge_request.rb ├── gitlab_create_merge_request.sh ├── gitlab_danger.sh ├── gitlab_populate.conf ├── gitlab_populate.sh ├── gitlab_tp_test.sh ├── jenkins_before.sh ├── massfindandreplace.sh ├── massfindandreplace_macspurious.sh ├── papply.sh ├── papply_local.sh ├── puppet_check_beaker.sh ├── puppet_check_rake.sh ├── puppet_check_syntax.sh ├── puppet_check_syntax_fast.sh ├── puppet_ci.sh ├── puppet_code_deploy.sh ├── puppet_deploy_controlrepo.sh ├── puppet_deploy_environment.sh ├── puppet_flush_environment_cache.sh ├── puppet_info.sh ├── puppet_install.ps1 ├── puppet_install.sh ├── puppet_install4.sh ├── puppet_install_puppetfile.sh ├── puppet_job_run.sh ├── puppet_lint.sh ├── puppet_migrate.sh ├── puppet_module_generate.sh ├── puppet_module_publish.sh ├── puppet_remote_setup.sh ├── puppet_set_env_facts.sh ├── puppet_set_external_facts.sh ├── puppet_set_trusted_facts.sh ├── puppet_setup.sh ├── puppet_status.sh ├── puppetdb_env_query.sh ├── puppetdb_query.sh ├── rotate_root_passwords.rb ├── rundeck_job_run.sh ├── setup.sh ├── tp_install.sh ├── tp_setup.sh ├── tp_test.sh ├── travis_check.sh ├── vagrant_node_test.sh ├── vagrant_setup.sh └── vagrant_tptest.sh ├── bolt-project.yaml ├── docker ├── config ├── env │ ├── alpine3 │ ├── centos6 │ ├── centos7 │ ├── debian7 │ ├── debian8 │ ├── redhat6 │ ├── redhat7 │ ├── ubuntu1204 │ ├── ubuntu1404 │ └── ubuntu1604 └── hiera.yaml ├── docs ├── FOSS_puppet_server.md ├── README.md ├── aws.md ├── change_impact.md ├── change_process.md ├── change_process_integration.md ├── compile_masters.md ├── docker.md ├── example42.md ├── external_facts.md ├── git.md ├── hiera.md ├── hiera_eyaml.md ├── modules_list │ ├── example42modules.txt │ ├── list_3rd.txt │ ├── list_deprecated.txt │ ├── list_deprecated2.txt │ ├── list_ex42.txt │ ├── list_extra.txt │ ├── list_maintained.txt │ └── list_puppet4.txt ├── noop_mode.md ├── pe_console.md ├── pe_gitlab.md ├── prerequisites.md ├── puppet.md ├── structure.md ├── toc-modules.txt ├── toc-process.txt ├── toc-puppet.txt ├── toc-use.txt ├── toc.txt ├── tp.md ├── trusted_facts.md ├── use.md ├── vagrant.md └── workflow.md ├── environment.conf ├── gitlab ├── .gitlab-ci.yml-integration ├── .gitlab-ci.yml-pe ├── .gitlab-ci.yml-public └── .gitlab-ci.yml-with-fakes ├── hiera.yaml ├── html ├── _site │ ├── images │ │ ├── bg_hr.png │ │ ├── blacktocat.png │ │ ├── icon_download.png │ │ └── sprite_download.png │ ├── index.html │ ├── javascripts │ │ ├── angular-wizard.js │ │ ├── angular.js │ │ └── main.js │ └── stylesheets │ │ ├── angular-wizard.css │ │ ├── pygment_trac.css │ │ └── stylesheet.css ├── images │ ├── PSICK-logo-200x200.png │ ├── bg_hr.png │ ├── blacktocat.png │ ├── icon_download.png │ └── sprite_download.png ├── index.html ├── javascripts │ ├── angular-wizard.js │ ├── angular.js │ └── main.js └── stylesheets │ ├── angular-wizard.css │ ├── pygment_trac.css │ └── stylesheet.css ├── inventory.yaml ├── keys ├── manifests └── site.pp ├── metadata.json ├── packer └── docker │ └── tiny-puppet.pkr.hcl ├── psick ├── public └── Guide-Puppet.md ├── spec ├── acceptance │ ├── nodesets │ │ ├── default.yml │ │ ├── docker.yml │ │ └── vagrant.yml │ ├── psick_spec.rb │ └── puppetmaster_spec.rb ├── default_facts.yml ├── factsets │ └── README.md ├── hiera.yaml ├── hosts │ ├── build.lab.psick.io_spec.rb │ ├── jenkins.lab.psick.io_spec.rb │ ├── puppet.lab.psick.io_spec.rb │ └── windows2012.lab.psick.io_spec.rb ├── onceover.yaml ├── pre_conditions │ └── README.md ├── resources │ └── base_resources.yaml ├── spec.yaml ├── spec_helper.rb ├── spec_helper_acceptance.rb └── support │ └── os_facts.rb ├── terraform ├── main.tf ├── modules │ ├── aws │ │ ├── aws.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── azure │ │ ├── azure.tf │ │ ├── outputs.tf │ │ └── variables.tf │ └── hetzner │ │ ├── README.md │ │ ├── hcloud.tf │ │ ├── output.tf │ │ ├── terraform.tf │ │ └── variables.tf ├── outputs.tf ├── providers.tf └── variables.tf └── vagrant ├── Vagrantfile ├── bin ├── pagent.sh ├── papply.cmd ├── papply.ps1 ├── papply.sh ├── vagrant-install-puppet.sh ├── vagrant-linkcontrolrepo.sh ├── vagrant-network.sh ├── vagrant-sethostname.sh ├── vagrant-sethosts.sh ├── vagrant-setup_papply.sh ├── vagrant-setup_puppetserver.sh └── vm.sh ├── boxes.yaml └── environments ├── bare ├── README.md ├── Vagrantfile └── config.yaml ├── demo ├── README.md ├── Vagrantfile ├── answers │ └── sample.txt ├── config.yaml └── output.md ├── docker ├── Vagrantfile └── config.yaml ├── foss ├── README.md ├── Vagrantfile └── config.yaml ├── lab ├── README.md ├── Vagrantfile ├── answers │ └── sample.txt ├── config.yaml └── install.ps1 ├── multiuser ├── README.md ├── Vagrantfile └── config.yaml ├── ostest ├── README.md ├── Vagrantfile └── config.yaml └── pe ├── README.md ├── Vagrantfile ├── answers └── sample.txt └── config.yaml /.codacy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | exclude_paths: 3 | - html/**/* 4 | - spec/support/os_facts.rb 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org/ 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_style = space 9 | indent_size = 2 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = off 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.fixtures.yml: -------------------------------------------------------------------------------- 1 | fixtures: 2 | symlinks: 3 | site: "#{source_dir}/site" 4 | r10k: "#{source_dir}/modules" 5 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Really want to contribute to PSICK?!? 2 | 3 | ### Supply your own profile 4 | 5 | One of the main components of PSICK is the collection of profiles, and the framework to easily switch from one to another. 6 | 7 | We encourage the existence of multiple profiles to manage applications ussing different patterns and modules, we think it would be nice to have a good library of profiles to choose from and customise when needed. 8 | 9 | So if you have written a good profile, which may adapt to common use cases, both for new or existing applications, you're welcomed to share it: 10 | 11 | * the profile class 12 | * some hiera examples 13 | * enventual modules to add to Puppetfile 14 | * possibly spec test for the profile 15 | 16 | ### Submit your bug or feature request 17 | 18 | We are not suprised. There are so many combinations of OS, applications and use cases, that it's hard to test them all. 19 | 20 | We still welcome bug fix or feature requests, even better relevant PR, we want to make PSICK as good and useful as possible, 21 | 22 | ### Contribution guideline 23 | 24 | * Open a new GitHub pull request with the patch. 25 | 1. Fork this project 26 | 1. Create your feature branch: `git checkout -b my-new-feature` 27 | 1. Commit your changes: `git commit -am 'Add some feature'` 28 | 1. Push to the branch: `git push origin my-new-feature` 29 | 1. Submit a pull request via GitHub's web interface 30 | * Ensure the PR description clearly describes the problem and its solution. Include the relevant issue number if applicable. 31 | 32 | ### Commercial support 33 | 34 | If you need an enterprise level support on your Puppet infrastructure and may be interested in using some of all the PSICK features, you can contribute to this project by subscribing to example42 Puppet support services and, possibily, allowing us to share here the shareable work we do with you. 35 | 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Expected Behavior 2 | 3 | 4 | ## Actual Behavior 5 | 6 | 7 | ## Steps to Reproduce the Problem 8 | 9 | 1. 10 | 1. 11 | 1. 12 | 13 | ## Specifications 14 | 15 | Please add this info: 16 | 17 | 1. Output of ```facter -p``` on the failing node (at least the OS related facts) 18 | 1. Version of Puppet and of the module 19 | 1. The relevant Puppet code and eventually Hiera data 20 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Before submitting your PR 2 | 3 | 1. Open an **issue** and refer to its number in your PR title 4 | 1. If it's a bug and you have the solution, go on with the PR! 5 | 1. If it's a new profile got with the PR (possibly with docs, samples and tests) 6 | 7 | ## After submitting your PR 8 | 9 | 1. Verify Travis checks and fix the errors if needed 10 | 1. Feel free to ping us if we don't reply promptly 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .*.sw[op] 3 | .metadata 4 | .yardoc 5 | .yardwarns 6 | *.iml 7 | /.bundle/ 8 | .idea/ 9 | .vagrant/ 10 | .onceover/ 11 | .pe_build/ 12 | /coverage/ 13 | /doc/ 14 | /Gemfile.local 15 | /Gemfile.lock 16 | /junit/ 17 | /log/ 18 | /pkg/ 19 | /spec/fixtures/manifests/ 20 | /spec/fixtures/modules/ 21 | /tmp/ 22 | /vendor/ 23 | /convert_report.txt 24 | /update_report.txt 25 | .DS_Store 26 | /keys/ 27 | /modules/ 28 | /vagrant/environments/*/*-console.log 29 | ##terraform 30 | #Secrets and vars go here 31 | **/*.auto.tfvars 32 | **/*.auto.tfvars.json 33 | **/terraform.tfvars 34 | **/terraform.tfvars.json 35 | # Local .terraform directories 36 | **/.terraform/* 37 | # .tfstate files 38 | *.tfstate 39 | *.tfstate.* 40 | # Crash log files 41 | crash.log 42 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 43 | # .tfvars files are managed as part of configuration and so should be included in 44 | # version control. 45 | # 46 | # example.tfvars 47 | # Ignore override files as they are usually used to override resources locally and so 48 | # are not checked in 49 | override.tf 50 | override.tf.json 51 | *_override.tf 52 | *_override.tf.json 53 | # Include override files you do wish to add to version control using negated pattern 54 | # 55 | # !example_override.tf 56 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 57 | # example: *tfplan* 58 | # Ignore CLI configuration files 59 | .terraformrc 60 | terraform.rc 61 | .terraform.lock.hcl 62 | bolt-debug.log 63 | .resource_types/ 64 | *VBoxHeadless*.log -------------------------------------------------------------------------------- /.gitpod.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gitpod/workspace-full 2 | RUN sudo wget https://apt.puppet.com/puppet-tools-release-bionic.deb && \ 3 | wget https://apt.puppetlabs.com/puppet6-release-bionic.deb && \ 4 | sudo dpkg -i puppet6-release-bionic.deb && \ 5 | sudo dpkg -i puppet-tools-release-bionic.deb && \ 6 | sudo apt-get update && sudo apt-get install -y pdk zsh puppet-agent 7 | RUN sudo usermod -s $(which zsh) gitpod && \ 8 | sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" && \ 9 | echo "plugins=(git gitignore github gem pip bundler python ruby docker docker-compose)" >> /home/gitpod/.zshrc && \ 10 | 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 && \ 11 | sudo /opt/puppetlabs/puppet/bin/gem install puppet-debugger hub -N && \ 12 | mkdir -p /home/gitpod/.config/puppet && \ 13 | /opt/puppetlabs/puppet/bin/ruby -r yaml -e "puts ({'disabled' => true}).to_yaml" > /home/gitpod/.config/puppet/analytics.yml 14 | RUN rm -f puppet6-release-bionic.deb puppet-tools-release-bionic.deb 15 | ENTRYPOINT /usr/bin/zsh 16 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: 2 | file: .gitpod.Dockerfile 3 | 4 | tasks: 5 | - init: pdk bundle install 6 | 7 | vscode: 8 | extensions: 9 | - puppet.puppet-vscode@0.28.0:g5CT+jlJywUtP9HoX4DIZg== 10 | -------------------------------------------------------------------------------- /.pdkignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .*.sw[op] 3 | .metadata 4 | .yardoc 5 | .yardwarns 6 | *.iml 7 | /.bundle/ 8 | /.idea/ 9 | /.vagrant/ 10 | /coverage/ 11 | /bin/ 12 | /doc/ 13 | /Gemfile.local 14 | /Gemfile.lock 15 | /junit/ 16 | /log/ 17 | /pkg/ 18 | /spec/fixtures/manifests/ 19 | /spec/fixtures/modules/ 20 | /tmp/ 21 | /vendor/ 22 | /convert_report.txt 23 | /update_report.txt 24 | .DS_Store 25 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.5.8 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: ruby 3 | install: 4 | - wget 'https://pm.puppetlabs.com/cgi-bin/pdk_download.cgi?dist=ubuntu&rel=16.04&arch=amd64&ver=latest' -q -O pdk.deb && sudo dpkg -i pdk.deb && rm pdk.deb 5 | - gem install r10k 6 | - r10k puppetfile install -v 7 | stages: 8 | - validate 9 | - unit 10 | jobs: 11 | include: 12 | - stage: validate 13 | script: 14 | - pdk validate metadata 15 | - pdk validate puppet site/ manifests/ 16 | 17 | - stage: unit 18 | script: pdk test unit 19 | notifications: 20 | email: false 21 | -------------------------------------------------------------------------------- /.travis.yml.nopdk: -------------------------------------------------------------------------------- 1 | --- 2 | sudo: false 3 | language: ruby 4 | cache: bundler 5 | script: 6 | - "bin/travis_check.sh" 7 | - "bundle exec danger" 8 | before_install: 9 | - gem update bundler 10 | - gem install r10k 11 | - r10k puppetfile install -v 12 | matrix: 13 | fast_finish: true 14 | include: 15 | - rvm: 2.1.9 16 | env: PUPPET_GEM_VERSION="~> 4.6.0" 17 | - rvm: 2.1.9 18 | env: PUPPET_GEM_VERSION="~> 4.10.0" 19 | - rvm: 2.4.1 20 | env: PUPPET_GEM_VERSION="~> 5.0.0" STDLIB_LOG_DEPRECATIONS="false" 21 | - rvm: 2.4.1 22 | env: PUPPET_GEM_VERSION="~> 5.1.0" STDLIB_LOG_DEPRECATIONS="false" 23 | - rvm: 2.1.9 24 | env: PUPPET_GEM_VERSION="~> 4" 25 | - rvm: 2.4.1 26 | env: PUPPET_GEM_VERSION="~> 5" STDLIB_LOG_DEPRECATIONS="false" 27 | allow_failures: 28 | - rvm: 2.1.9 29 | env: PUPPET_GEM_VERSION="~> 4.6.0" 30 | 31 | notifications: 32 | email: false 33 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "Sample settings for Visual Studio Code", 3 | "editor.tabSize": 2, 4 | "editor.insertSpaces": true 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/example42/psick/e94f09e8c2a1cc1a0310e572e5cb2c986c1f877c/.vscode/tasks.json -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --markup markdown 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at info@example42.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## How to Contribute to This Project 2 | 3 | #### **Did You Find a Bug?** 4 | 5 | * **Ensure the bug was not already reported** by searching on GitHub under **Issues**. 6 | * If you're unable to find an open issue addressing the problem, **open a new one**. Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. 7 | 8 | #### **Did You Write a Patch That Fixes a Bug?** 9 | 10 | * Open a new GitHub pull request with the patch. 11 | 1. Fork this project 12 | 1. Create your feature branch: `git checkout -b my-new-feature` 13 | 1. Commit your changes: `git commit -am 'Add some feature'` 14 | 1. Push to the branch: `git push origin my-new-feature` 15 | 1. Submit a pull request via GitHub's web interface 16 | * Ensure the PR description clearly describes the problem and its solution. Include the relevant issue number if applicable. 17 | 18 | #### **Do You Intend to Add a New Feature or Change an Existing One?** 19 | 20 | * Suggest your change as a **new issue** using the label `enhancement` 21 | 22 | #### **Do you like PSICK?!?** 23 | 24 | * Use it, improve it, share it 25 | * Link, comment, post, talk about it :-) 26 | 27 | Thanks for contributing! :heart: 28 | 29 | -------------------------------------------------------------------------------- /Dangerfile: -------------------------------------------------------------------------------- 1 | # set the number of lines that must be changed before this classifies as a 'Big PR' 2 | @SDM_DANGER_BIG_PR_LINES = 50 3 | 4 | # Identify changes type 5 | has_danger_changes = !git.modified_files.grep(/^manifests\/.pp$|^hieradata\/common.yaml$|^data\/common.yaml$/).empty? 6 | has_puppet_changes = !git.modified_files.grep(/.pp$/).empty? 7 | has_hiera_changes = !git.modified_files.grep(/^hieradata\/.yaml$|^data\/.yaml$|.pp$/).empty? 8 | has_spec_changes = !git.modified_files.grep(/spec/).empty? 9 | is_version_bump = git.modified_files.sort == ["metadata.json", "lib/danger/version.rb"].sort 10 | 11 | # Puppet code changes without test changes 12 | if has_puppet_changes && !has_spec_changes 13 | warn("There're changes in manifests, but not tests. That's OK as long as you're refactoring existing code.", sticky: false) 14 | end 15 | 16 | # Tests changes without code changes 17 | if !has_puppet_changes && has_spec_changes 18 | message('Changes in tests but not in manifests. Unless you are improving your tests, this should not happen.', sticky: false) 19 | end 20 | 21 | # Hiera changes 22 | if has_hiera_changes 23 | message('There are changes on Hiera files. They will probably affect one or more nodes.', sticky: false) 24 | end 25 | 26 | # hiera.yaml change 27 | if git.modified_files.include?('hiera.yaml') 28 | message('Oh, you are changing the environment hiera.yaml! Be careful if you are changing hierarchies') 29 | end 30 | 31 | # environment.conf change 32 | if git.modified_files.include?('environment.conf') 33 | message('Changing environment.conf settings? That is not something you do every day :-)') 34 | end 35 | 36 | # Changelog plugin 37 | changelog.have_you_updated_changelog? 38 | 39 | # Add a CHANGELOG entry for puppet changes 40 | if !git.modified_files.include?("CHANGELOG.md") && has_puppet_changes && is_version_bump 41 | warn("Please include a CHANGELOG entry when changing version).") 42 | message "Note, we hard-wrap at 80 chars and use 2 spaces after the last line." 43 | end 44 | 45 | # Changes in files with large impact 46 | if has_danger_changes 47 | warn("This change may impact many systems. Double check what you are doing.", sticky: false) 48 | end 49 | 50 | 51 | # Ensure a clean commits history 52 | if git.commits.any? { |c| c.message =~ /^Merge branch/ } 53 | warn('Please rebase to get rid of the merge commits in this PR') 54 | end 55 | 56 | # Large PR 57 | warn('Big PR! Big changes, big things may happen! Check them.') if git.lines_of_code > @SDM_DANGER_BIG_PR_LINES 58 | 59 | 60 | # GitHub 61 | warn "PR is classed as Work in Progress" if github.pr_title.include? "[WIP]" 62 | 63 | if github.pr_body.length < 5 64 | warn "Please provide a summary in the Pull Request description" 65 | end 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /Gemfile.disable: -------------------------------------------------------------------------------- 1 | # Derived from puppetlabs-ntp 2 | 3 | source ENV['GEM_SOURCE'] || "https://rubygems.org" 4 | 5 | gem 'puppet-lint-absolute_classname-check' 6 | gem 'puppet-lint-absolute_template_path' 7 | gem 'puppet-lint-alias-check' 8 | gem 'puppet-lint-anchor-check' 9 | gem 'puppet-lint-appends-check' 10 | gem 'puppet-lint-class_parameter-check' 11 | gem 'puppet-lint-classes_and_types_beginning_with_digits--check' 12 | gem 'puppet-lint-classes_and_types_beginning_with_digits-check' 13 | gem 'puppet-lint-concatenated_template_files-check' 14 | gem 'puppet-lint-duplicate_class_parameters-check' 15 | gem 'puppet-lint-ec2_facts-check' 16 | gem 'puppet-lint-empty_string-check' 17 | gem 'puppet-lint-explicit_hiera_class_param_lookup-check' 18 | gem 'puppet-lint-extended' 19 | gem 'puppet-lint-file_ensure-check' 20 | gem 'puppet-lint-file_line_match-check' 21 | gem 'puppet-lint-file_source_rights-check' 22 | gem 'puppet-lint-fileserver-check' 23 | gem 'puppet-lint-global_resource-check' 24 | gem 'puppet-lint-halyard' 25 | gem 'puppet-lint-i18n' 26 | gem 'puppet-lint-indent-check' 27 | gem 'puppet-lint-leading_zero-check' 28 | gem 'puppet-lint-legacy_facts-check' 29 | gem 'puppet-lint-metrics-check' 30 | gem 'puppet-lint-no_chaining_arrows-check' 31 | gem 'puppet-lint-no_cron_resources-check' 32 | gem 'puppet-lint-no_erb_template-check' 33 | gem 'puppet-lint-no_file_path_attribute-check' 34 | gem 'puppet-lint-no_symbolic_file_modes-check' 35 | gem 'puppet-lint-non_erb_template_filename-check' 36 | gem 'puppet-lint-numericvariable' 37 | gem 'puppet-lint-package_ensure-check' 38 | gem 'puppet-lint-param-docs' 39 | gem 'puppet-lint-reference_on_declaration_outside_of_class-check' 40 | gem 'puppet-lint-resource_outside_class-check' 41 | gem 'puppet-lint-resource_reference_syntax' 42 | gem 'puppet-lint-roles_and_profiles-check' 43 | gem 'puppet-lint-security-plugins' 44 | gem 'puppet-lint-space_after_comma-check' 45 | gem 'puppet-lint-spaceship_operator_without_tag-check' 46 | gem 'puppet-lint-strict_indent-check' 47 | gem 'puppet-lint-template_file_extension-check' 48 | gem 'puppet-lint-top_scope_facts-check' 49 | gem 'puppet-lint-trailing_comma-check' 50 | gem 'puppet-lint-trailing_newline-check' 51 | gem 'puppet-lint-undef_in_function-check' 52 | gem 'puppet-lint-unquoted_string-check' 53 | gem 'puppet-lint-usascii_format-check' 54 | gem 'puppet-lint-use_ensure_packages-check' 55 | gem 'puppet-lint-variable_contains_upcase' 56 | gem 'puppet-lint-version_comparison-check' 57 | gem 'puppet-lint-vim_modeline-check' 58 | gem 'puppet-lint-wmf_styleguide-check' 59 | gem 'puppet-lint-world_writable_files-check' 60 | gem 'puppet-lint-yumrepo_gpgcheck_enabled-check' 61 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent any 3 | stages { 4 | stage('Setup') { 5 | steps { 6 | sh "bin/jenkins_before.sh ${env.BRANCH_NAME}" 7 | sh '/opt/puppetlabs/puppet/bin/bundle --path=vendor' 8 | } 9 | } 10 | stage('Syntax') { 11 | steps { 12 | sh 'bin/puppet_check_syntax_fast.sh all_but_chars' 13 | sh 'bin/puppet_lint.sh' 14 | sh 'bin/puppet_check_syntax_fast.sh chars' 15 | } 16 | } 17 | stage('Unit') { 18 | steps { 19 | sh 'bin/puppet_check_rake.sh site' 20 | sh 'bin/puppet_check_rake.sh controlrepo' 21 | } 22 | } 23 | stage('Diff') { 24 | steps { 25 | sh 'bin/puppet_ci.sh catalog_preview || true' 26 | } 27 | } 28 | stage('Integration') { 29 | steps { 30 | sh 'bin/puppet_check_beaker.sh || true' 31 | } 32 | } 33 | 34 | stage('Integration Rollout') { 35 | when { 36 | branch 'integration' 37 | } 38 | steps { 39 | sh 'bin/puppet_ci.sh r10k_deploy --env integration --ssh jenkins@puppet --sudo' 40 | sh 'bin/puppet_ci.sh task_run psick::puppet_agent --env integration' 41 | sh 'bin/puppet_ci.sh db_query --env integration' 42 | } 43 | } 44 | 45 | stage('Production Rollout') { 46 | when { 47 | branch 'production' 48 | } 49 | steps { 50 | sh 'bin/puppet_ci.sh r10k_deploy --env production --ssh jenkins@puppet --sudo' 51 | sh 'bin/puppet_ci.sh task_run psick::puppet_agent --env production' 52 | sh 'bin/puppet_ci.sh db_query --env production' 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'onceover/rake_tasks' 2 | require 'puppetlabs_spec_helper/rake_tasks' 3 | require 'puppet-syntax/tasks/puppet-syntax' 4 | require 'puppet_blacksmith/rake_tasks' if Bundler.rubygems.find_name('puppet-blacksmith').any? 5 | require 'github_changelog_generator/task' if Bundler.rubygems.find_name('github_changelog_generator').any? 6 | 7 | def changelog_user 8 | return unless Rake.application.top_level_tasks.include? "changelog" 9 | returnVal = nil || JSON.load(File.read('metadata.json'))['author'] 10 | raise "unable to find the changelog_user in .sync.yml, or the author in metadata.json" if returnVal.nil? 11 | puts "GitHubChangelogGenerator user:#{returnVal}" 12 | returnVal 13 | end 14 | 15 | def changelog_project 16 | return unless Rake.application.top_level_tasks.include? "changelog" 17 | returnVal = nil || JSON.load(File.read('metadata.json'))['name'] 18 | raise "unable to find the changelog_project in .sync.yml or the name in metadata.json" if returnVal.nil? 19 | puts "GitHubChangelogGenerator project:#{returnVal}" 20 | returnVal 21 | end 22 | 23 | def changelog_future_release 24 | return unless Rake.application.top_level_tasks.include? "changelog" 25 | returnVal = JSON.load(File.read('metadata.json'))['version'] 26 | raise "unable to find the future_release (version) in metadata.json" if returnVal.nil? 27 | puts "GitHubChangelogGenerator future_release:#{returnVal}" 28 | returnVal 29 | end 30 | 31 | PuppetLint.configuration.send('disable_relative') 32 | 33 | if Bundler.rubygems.find_name('github_changelog_generator').any? 34 | GitHubChangelogGenerator::RakeTask.new :changelog do |config| 35 | 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? 36 | config.user = "#{changelog_user}" 37 | config.project = "#{changelog_project}" 38 | config.future_release = "#{changelog_future_release}" 39 | config.exclude_labels = ['maintenance'] 40 | 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)." 41 | config.add_pr_wo_labels = true 42 | config.issues = false 43 | config.merge_prefix = "### UNCATEGORIZED PRS; GO LABEL THEM" 44 | config.configure_sections = { 45 | "Changed" => { 46 | "prefix" => "### Changed", 47 | "labels" => ["backwards-incompatible"], 48 | }, 49 | "Added" => { 50 | "prefix" => "### Added", 51 | "labels" => ["feature", "enhancement"], 52 | }, 53 | "Fixed" => { 54 | "prefix" => "### Fixed", 55 | "labels" => ["bugfix"], 56 | }, 57 | } 58 | end 59 | else 60 | desc 'Generate a Changelog from GitHub' 61 | task :changelog do 62 | raise <= Gem::Version.new('2.2.2')" 73 | EOM 74 | end 75 | end 76 | 77 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.x.{build} 3 | skip_commits: 4 | message: /^\(?doc\)?.*/ 5 | clone_depth: 10 6 | init: 7 | - SET 8 | - 'mkdir C:\ProgramData\PuppetLabs\code && exit 0' 9 | - 'mkdir C:\ProgramData\PuppetLabs\facter && exit 0' 10 | - 'mkdir C:\ProgramData\PuppetLabs\hiera && exit 0' 11 | - 'mkdir C:\ProgramData\PuppetLabs\puppet\var && exit 0' 12 | environment: 13 | matrix: 14 | - 15 | RUBY_VERSION: 24-x64 16 | CHECK: syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop 17 | - 18 | PUPPET_GEM_VERSION: ~> 4.0 19 | RUBY_VERSION: 21 20 | CHECK: parallel_spec 21 | - 22 | PUPPET_GEM_VERSION: ~> 4.0 23 | RUBY_VERSION: 21-x64 24 | CHECK: parallel_spec 25 | - 26 | PUPPET_GEM_VERSION: ~> 5.0 27 | RUBY_VERSION: 24 28 | CHECK: parallel_spec 29 | - 30 | PUPPET_GEM_VERSION: ~> 5.0 31 | RUBY_VERSION: 24-x64 32 | CHECK: parallel_spec 33 | matrix: 34 | fast_finish: true 35 | install: 36 | - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH% 37 | - bundle install --jobs 4 --retry 2 --without system_tests 38 | - type Gemfile.lock 39 | build: off 40 | test_script: 41 | - bundle exec puppet -V 42 | - ruby -v 43 | - gem -v 44 | - bundle -v 45 | - bundle exec rake %CHECK% 46 | notifications: 47 | - provider: Email 48 | to: 49 | - nobody@nowhere.com 50 | on_build_success: false 51 | on_build_failure: false 52 | on_build_status_changed: false 53 | -------------------------------------------------------------------------------- /bin/Rakefile_blacksmith: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'puppetlabs_spec_helper/rake_tasks' 3 | require 'puppet-lint' 4 | PuppetLint.configuration.send("disable_80chars") 5 | PuppetLint.configuration.send('disable_class_parameter_defaults') 6 | 7 | # Blacksmith 8 | begin 9 | require 'puppet_blacksmith/rake_tasks' 10 | rescue LoadError 11 | puts "Blacksmith needed only to push to the Forge" 12 | end 13 | -------------------------------------------------------------------------------- /bin/aws_presetup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | 5 | echo_title "Going to install awscli and dependencies" 6 | puppet resource package awscli provider=pip ensure=present 7 | puppet resource package aws-sdk-core provider=gem ensure=present 8 | puppet resource package retries provider=gem ensure=present 9 | 10 | echo_title "Running aws configure" 11 | aws configure 12 | 13 | -------------------------------------------------------------------------------- /bin/aws_setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | 5 | puppet_options="--modulepath ${repo_dir}/site:${repo_dir}/modules --environmentpath ${repo_dir}" 6 | 7 | echo_title "Going to install awscli and dependencies" 8 | puppet apply $puppet_options -e 'include psick::aws' 9 | 10 | echo_title "Running aws configure" 11 | aws configure 12 | 13 | -------------------------------------------------------------------------------- /bin/aws_status.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | 5 | if [ ! -z $1 ]; then 6 | region=$1 7 | else 8 | region='us-east-1 us-west-1 us-west-2 eu-west-1 eu-central-1 ap-south-1 ap-northeast-1 ap-northeast-2 ap-southeast-1 ap-southeast-2 sa-east-1' 9 | fi 10 | 11 | echo_title "Showing puppet recognised resources in regions: ${region}" 12 | ask_interactive "It may take some time with multiple regions" 13 | 14 | for reg in $region; do 15 | 16 | export AWS_REGION=$reg 17 | 18 | resources="ec2_autoscalinggroup ec2_elastic_ip ec2_instance ec2_launchconfiguration ec2_scalingpolicy ec2_securitygroup ec2_vpc ec2_vpc_customer_gateway ec2_vpc_dhcp_options ec2_vpc_internet_gateway ec2_vpc_routetable ec2_vpc_subnet ec2_vpc_vpn ec2_vpc_vpn_gateway elb_loadbalancer rds_instance rds_db_securitygroup rds_db_parameter_group sqs_queue cloudwatch_alarm" 19 | global_resources="route53_a_record route53_aaaa_record route53_cname_record route53_mx_record route53_ns_record route53_ptr_record route53_spf_record route53_srv_record route53_txt_record route53_zone" 20 | 21 | echo 22 | echo_title "Current region: $reg" 23 | echo 24 | 25 | for res in $resources; do 26 | echo_subtitle "puppet resource $res" 27 | puppet resource $res 28 | echo 29 | done 30 | 31 | done 32 | 33 | echo_title "Global resources" 34 | for res in $global_resources; do 35 | echo_subtitle "puppet resource $res" 36 | puppet resource $res 37 | echo 38 | done 39 | -------------------------------------------------------------------------------- /bin/bootstrap/cloud_init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | puppet_version=$1 4 | puppet_role=$2 5 | control_repo=$3 6 | 7 | echo "### Installing git" 8 | git --version &>/dev/null 9 | GIT_IS_AVAILABLE=$? 10 | 11 | if [[ ! $GIT_IS_AVAILABLE -eq 0 ]]; then 12 | if [ -f /etc/debian_version ]; then 13 | apt update &>/dev/null 14 | apt install -y git &>/dev/null 15 | fi 16 | 17 | if [ -f /etc/redhat-release ]; then 18 | yum install -y git &>/dev/null 19 | fi 20 | fi 21 | 22 | echo "### Cloning PSICK" 23 | git clone $control_repo /tmp/psick &>/dev/null 24 | pushd /tmp/psick 25 | 26 | echo "### Set external facts" 27 | bin/puppet_set_external_facts.sh --role $puppet_role --env 'host' --zone 'foss' --datacenter 'vagrant' --application 'puppetinfra' 28 | 29 | echo "### Set trusted facts" 30 | bin/puppet_set_trusted_facts.sh --role $puppet_role --env 'host' --zone 'foss' --datacenter 'vagrant' --application 'puppetinfra' 31 | 32 | echo "### Installing Puppet" 33 | bin/puppet_install.sh $puppet_version 34 | popd 35 | 36 | if [ $puppet_role == 'puppet' ]; then 37 | pushd /tmp/psick 38 | 39 | echo "### Installing puppetserver" 40 | puppet resource package puppetserver ensure=present &>/dev/null 41 | 42 | echo "### Installing puppet agent gems" 43 | puppet resource package r10k ensure=present provider=puppet_gem &>/dev/null 44 | 45 | echo "### Deploy control-repository" 46 | mkdir -p /etc/puppetlabs/code/environments/ 47 | mkdir -p /etc/puppetlabs/r10k/ 48 | cat > /etc/puppetlabs/r10k/r10k.yaml << EOF 49 | --- 50 | :postrun: [] 51 | :cachedir: /opt/puppetlabs/puppet/cache/r10k 52 | :sources: 53 | puppet: 54 | basedir: /etc/puppetlabs/code/environments 55 | remote: $control_repo 56 | EOF 57 | 58 | echo "### Running r10k deploy environment -v" 59 | /opt/puppetlabs/puppet/bin/r10k deploy environment -p &>/dev/null 60 | 61 | echo "### Starting Puppet Server" 62 | /opt/puppetlabs/bin/puppet resource service puppetserver ensure=running enable=true &>/dev/null 63 | popd 64 | fi 65 | 66 | rm -fr /tmp/psick 67 | -------------------------------------------------------------------------------- /bin/bootstrap/tp_cli.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | PATH=/opt/puppetlabs/puppet/bin:$PATH 3 | 4 | if [ $USER == 'root' ]; then 5 | sudo_command='' 6 | else 7 | sudo_command='sudo ' 8 | fi 9 | 10 | $sudo_command puppet module install example42-tp 11 | 12 | os=$(facter os.name) 13 | local_user=$(whoami) 14 | case $os in 15 | Darwin*) 16 | $sudo_command puppet module install thekevjames-homebrew 17 | $sudo_command puppet apply -e "class { homebrew: user => $local_user }" 18 | ;; 19 | Windows*) 20 | $sudo_command puppet module install puppetlabs-chocolatey 21 | $sudo_command puppet apply -e "include chocolately" 22 | ;; 23 | esac 24 | 25 | $sudo_command puppet tp setup 26 | 27 | -------------------------------------------------------------------------------- /bin/codemanager_check_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | 5 | env=$1 6 | maxrun=${2:-6} 7 | sleeptime=${3:-10} 8 | numrun=1 9 | echo_title "Display of /etc/puppetlabs/code/environments/$env/.r10k-deploy.json" 10 | sudo cat /etc/puppetlabs/code/environments/$env/.r10k-deploy.json 2>/dev/null 11 | echo_title "Deployment status on ${env} - doing maximum ${maxrun} try every ${sleeptime} sec." 12 | while [ $numrun -le $maxrun ]; 13 | do 14 | echo_title "Running check ${numrun}/${maxrun}" 15 | deployed_commit=$(sudo cat /etc/puppetlabs/code/environments/$env/.r10k-deploy.json | grep signature | awk '{ print $2}' | sed -e 's/"//g' | sed -e 's/,//') 16 | local_commit=$(git rev-parse HEAD) 17 | echo_title "Deployed commit on Puppet Server: ${deployed_commit}" 18 | git show --no-abbrev-commit -s ${deployed_commit} 19 | echo_title "Latest commit on local runner repo: ${local_commit}" 20 | git show --no-abbrev-commit -s ${local_commit} 21 | 22 | echo_title "----------------------------------------------------------------------------------" 23 | if [[ "${deployed_commit}" == "${local_commit}" ]]; then 24 | echo_success "Code correctly deployed to Puppet Server" 25 | exit 0 26 | fi 27 | sleep $sleeptime 28 | (( numrun ++ )) 29 | done 30 | echo_failure "Code not correctly deployed to Puppet Server !!!" 31 | exit 1 32 | -------------------------------------------------------------------------------- /bin/codemanager_reset.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | PATH=$PATH:/opt/puppetlabs/puppet/bin 3 | 4 | if [[ $(id -u) -ne 0 ]] ; then echo "Please run as root" ; exit 1 ; fi 5 | 6 | # This script is used to reset to clean state Code Manager on Puppet Enterprise. 7 | # It's going to remove files and dirs from caches of the git repos used during 8 | # deployments. After this script has been run, you will have to run a puppet-code deploy --all 9 | # to redeploy environments. 10 | 11 | # Some of the following commands should be executed an all servers (primary, replace, compilers). 12 | # This script is OK as is in a standalone PE setup. 13 | 14 | # All PE servers 15 | puppet resource service pe-puppetserver ensure=stopped 16 | 17 | # Primary server 18 | puppet resource service pe-orchestration-services ensure=stopped 19 | 20 | # All PE servers 21 | find /etc/puppetlabs/code -mindepth 1 -delete 22 | mkdir -p /etc/puppetlabs/code/environments/production 23 | chown -R pe-puppet:pe-puppet /etc/puppetlabs/code 24 | chmod 755 /etc/puppetlabs/code/environments 25 | chmod 750 /etc/puppetlabs/code/environments/production 26 | 27 | # Primary server 28 | mv /etc/puppetlabs/code-staging /etc/puppetlabs/code-staging.old 29 | mkdir /etc/puppetlabs/code-staging 30 | chown pe-puppet:pe-puppet /etc/puppetlabs/code-staging 31 | chmod 750 /etc/puppetlabs/code-staging 32 | 33 | # All PE servers 34 | rm -rf /opt/puppetlabs/server/data/code-manager/git/ 35 | rm -rf /opt/puppetlabs/server/data/code-manager/worker-caches/ 36 | rm -rf /opt/puppetlabs/server/data/orchestration-services/data-dir 37 | rm -rf /opt/puppetlabs/server/data/orchestration-services/code 38 | rm -rf /opt/puppetlabs/server/data/puppetserver/filesync 39 | 40 | # PostgreSQL server (primary) 41 | sudo su - pe-postgres -s /bin/bash -c "/opt/puppetlabs/server/bin/psql -d 'pe-classifier' -c \"UPDATE environments SET deleted = 'f' WHERE deleted = 't';\"" 42 | 43 | # Primary server 44 | puppet apply -e "pe_hocon_setting { 'cache': ensure => present, path => '/etc/puppetlabs/puppetserver/conf.d/pe-puppet-server.conf', setting => 'jruby-puppet.environment-class-cache-enabled', value => false }" 45 | 46 | puppet resource service pe-puppetserver ensure=running 47 | puppet resource service pe-orchestration-services ensure=running -------------------------------------------------------------------------------- /bin/config/defaults: -------------------------------------------------------------------------------- 1 | vagrant_env="prod" 2 | vagrant_dc="docker" 3 | vagrant_zone="testzone" 4 | vagrant_app="puppet" 5 | vagrant_role="test" 6 | vagrant_host_env='ostest' 7 | 8 | docker_env="prod" 9 | docker_dc="docker" 10 | docker_zone="testzone" 11 | docker_app="puppet" 12 | docker_role="test" 13 | 14 | -------------------------------------------------------------------------------- /bin/config/gitlab-r10k.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cachedir: /home/gitlab-runner/.r10k 3 | -------------------------------------------------------------------------------- /bin/config/jenkins-r10k.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cachedir: /var/lib/jenkins/.r10k 3 | -------------------------------------------------------------------------------- /bin/config/proxysetup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #export http_proxy="http://proxy.domain.com:80" 3 | #export https_proxy="http://proxy.domain.com:80" 4 | #export no_proxy="domain.com,127.0.0.1,localhost" 5 | -------------------------------------------------------------------------------- /bin/config_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ENVDIR='/etc/puppetlabs/code/environments' 3 | ENVSTAGEDIR='/etc/puppetlabs/code-developers' # Custom dir used for developers environments 4 | if [ -x /usr/bin/git ]; then 5 | if [ -d "${ENVSTAGEDIR}/$1/.git" ]; then 6 | ENVGITDIR="${ENVSTAGEDIR}/$1/.git" 7 | else 8 | ENVGITDIR="${ENVDIR}/$1/.git" 9 | fi 10 | /usr/bin/git --git-dir "${ENVGITDIR}" log --pretty=format:"%h - %an, %ad : %s" -1 11 | else 12 | echo "no git - environment ${1}" 13 | fi 14 | exit 0 15 | -------------------------------------------------------------------------------- /bin/docker_purge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | 5 | if [ "$1" = "auto" ]; then 6 | auto=true 7 | fi 8 | 9 | echo_title "Removing Docker images" 10 | [ "$auto" = "true" ] || ask_warning "Are you sure you want to remove all local docker images?" 11 | [ "$?" = 0 ] || exit 1 12 | docker rmi $(docker images -q) 13 | 14 | echo_title "Removing Docker containers" 15 | [ "$auto" = "true" ] || ask_warning "Are you sure you want to remove all local docker containers?" 16 | [ "$?" = 0 ] || exit 1 17 | docker rm $(docker ps -a -q) 18 | 19 | -------------------------------------------------------------------------------- /bin/docker_rocker_build_role.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | role=${1:-docker_sample_role} 5 | image=${2:-'*'} 6 | 7 | dockerize() { 8 | r=$1 9 | i=${2:-'*'} 10 | 11 | . "${repo_dir}/docker/config" 12 | . "${repo_dir}/docker/env/${i}" 13 | 14 | export FACTER_role=$r 15 | echo_title "Building role ${r} on image ${i}" 16 | echo_subtitle "Running puppet apply on ::psick_profile::docker::rocker_builder" 17 | puppet apply -t --basemodulepath "${repo_dir}/site::${repo_dir}/modules" \ 18 | --environmentpath $repo_dir \ 19 | -e "\$role = ${r} ; include psick" 20 | } 21 | 22 | cd "${repo_dir}/docker" 23 | for os in $(ls -1 env/$image | sed 's/env\///g'); do 24 | dockerize $role $os 25 | done 26 | -------------------------------------------------------------------------------- /bin/docker_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @!parse [text] 3 | # @!parse [text] 4 | repo_dir=$(git rev-parse --show-toplevel) 5 | . "${repo_dir}/bin/functions" 6 | . "${repo_dir}/bin/config/defaults" 7 | 8 | # Customise here the default registry (can be 9 | # defined via the --registry argument). Default 10 | # hub.docker.com is used with example42 puppet-agent 11 | # registry="docker.example.com:5000/puppet" 12 | registry="hub.docker.com:5000/example42" 13 | image="puppet-agent" 14 | version="centos-7" 15 | 16 | env=$docker_env 17 | datacenter=$docker_dc 18 | zone=$docker_zone 19 | application=$docker_app 20 | role=$docker_role 21 | runcommand="bash -c " 22 | args="/etc/puppetlabs/code/environments/production/bin/papply.sh --detailed-exitcodes" 23 | custom="" 24 | tags="" 25 | options="--sysctl net.ipv6.conf.all.disable_ipv6=1" 26 | while [ $# -gt 0 ]; do 27 | CMD=$1 28 | shift 29 | if [ "${1}" != "" ] && [ "${1:0:2}" != "--" ]; then 30 | PARAM="$1" 31 | shift 32 | else 33 | PARAM="" 34 | fi 35 | case "$CMD" in 36 | --tags) 37 | tags="--tags=${PARAM}" 38 | ;; 39 | --registry) 40 | registry=${PARAM:-$registry} 41 | ;; 42 | --image) 43 | image=${PARAM:-$image} 44 | ;; 45 | --version) 46 | version=${PARAM:-$version} 47 | ;; 48 | --shell) 49 | runcommand=${PARAM:-bash} 50 | args="" 51 | options="$options -it" 52 | ;; 53 | --role) 54 | role=$PARAM 55 | ;; 56 | --zone) 57 | zone=$PARAM 58 | ;; 59 | --env) 60 | env=$PARAM 61 | ;; 62 | --datacenter) 63 | datacenter=$PARAM 64 | ;; 65 | --application) 66 | application=$PARAM 67 | ;; 68 | --fact) 69 | custom="$custom -e FACTER_${PARAM}" 70 | ;; 71 | *) 72 | echo "Invalid paramete $CMD" 73 | exit 1 74 | ;; 75 | esac 76 | done 77 | 78 | if [ ! -z "{$args}" ] && [ ! -z "${tags}" ]; then 79 | args="${args} ${tags}" 80 | fi 81 | params="-e FACTER_pp_environment=${env} -e FACTER_pp_role=${role} -e FACTER_pp_datacenter=${datacenter} -e FACTER_pp_application=${application} -e FACTER_pp_zone=${zone} $custom" 82 | name="${image}_${version}-${role}-$(date +'%H%M%S')" 83 | container="${registry}/${image}:${version}" 84 | PATH=$PATH:/opt/puppetlabs/bin 85 | echo_title "## Running $runcommand on image ${image}:${version} from ${repo_dir}" 86 | echo_subtitle "Defined facts: $params" 87 | docker pull "${registry}${image}:${version}" 88 | docker run $options -v "${repo_dir}:/etc/puppetlabs/code/environments/production" --name="${name}" $params "${container}" $runcommand "${args}" 89 | exitstatus=$? 90 | docker rm -f "${name}" 91 | 92 | if [ "x${exitstatus}" == "x0" ] || [ "x${exitstatus}" == "x2" ]; then 93 | exit 0 94 | else 95 | exit 1 96 | fi 97 | -------------------------------------------------------------------------------- /bin/docker_setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | 5 | puppet_options="--modulepath ${repo_dir}/site:${repo_dir}/modules:/etc/puppet/modules --environmentpath ${repo_dir} --hiera_config ${repo_dir}/hiera.yaml" 6 | 7 | echo_title "Going to install Docker" 8 | echo_subtitle "You need sudo powers. Executing: sudo -E puppet apply -e 'include psick_profile::docker'" 9 | sudo -E puppet apply $puppet_options -e 'include psick ; include psick_profile::docker' 10 | 11 | -------------------------------------------------------------------------------- /bin/docker_status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | 5 | echo_title "Docker version" 6 | echo_subtitle "Executing: docker version" 7 | docker version 8 | 9 | echo_title "Latest Docker containers" 10 | echo_subtitle "Executing: docker ps --all --last 10" 11 | docker ps --all --last 10 12 | 13 | echo_title "Docker images" 14 | echo_subtitle "Executing: docker images" 15 | docker images 16 | -------------------------------------------------------------------------------- /bin/docker_test_role.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | role=$1 5 | image=${2:-'*'} 6 | 7 | PATH=$PATH:/opt/puppetlabs/bin 8 | echo_title "## Running Puppet apply on image example42/puppet-agent:${image} with role ${role} from ${repo_dir}" 9 | docker run -v "${repo_dir}:/etc/puppetlabs/code/environments/production" --name="${image}-${role}-$(date +'%H%M%S')" -e "FACTER_role=${role}" "example42/puppet-agent:${image}" bash -c /etc/puppetlabs/code/environments/production/bin/papply.sh --detailed-exitcodes 10 | 11 | if [ "x$?" == "x0" ] || [ "x$?" == "x2" ]; then 12 | exit 0 13 | else 14 | exit 1 15 | fi 16 | -------------------------------------------------------------------------------- /bin/docker_tp_build_role.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | env_dir=$(dirname $repo_dir) 5 | role=${1:-docker_tp_build} 6 | image=${2:-'*'} 7 | 8 | dockerize() { 9 | r=${1} 10 | i=${2:-'*'} 11 | 12 | . "${repo_dir}/docker/config" 13 | . "${repo_dir}/docker/env/${i}" 14 | 15 | export FACTER_role=$role 16 | 17 | echo_title "Building role ${r} on image ${i}" 18 | echo_subtitle "Running puppet using data in hieradata/role/${r}.yaml" 19 | puppet apply --test \ 20 | --environment="${env_name}" \ 21 | --environmentpath="${env_dir}" \ 22 | --modulepath="${repo_dir}/modules:${repo_dir}/site" \ 23 | --hiera_config "${repo_dir}/docker/hiera.yaml" \ 24 | --execute "include psick" 25 | 26 | } 27 | 28 | cd "${repo_dir}/docker" 29 | for os in $(ls -1 env/$image | sed 's/env\///g'); do 30 | dockerize $role $os 31 | done 32 | -------------------------------------------------------------------------------- /bin/docs_classlistgenerate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | 5 | source_dir=${1:-'modules/psick'} 6 | target_file=${2:-'docs/classes.md'} 7 | [ -f $target_file ] && rm -f $target_file 8 | 9 | echo >> $target_file 10 | echo "## List of psick classes" >> $target_file 11 | echo >> $target_file 12 | echo "This is an automatically generated list of the psick classes in this control-repo" >> $target_file 13 | echo >> $target_file 14 | for f in $(find $source_dir -name *.pp | grep manifests | grep -v fixtures); do 15 | a=$(grep ^class ${f} | sed 's/(//g' | sed 's/{//g' | sed 's/)//g' | sed 's/ *$//g' | sed 's/^class //g') 16 | b=$(grep @summary ${f} | sed 's/^# *@summary/ -/g') 17 | echo " - **${a}**${b}" >> $target_file 18 | done 19 | echo >> $target_file 20 | -------------------------------------------------------------------------------- /bin/ec2_userdata/linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Sample ec2_userdata script for installation of Puppet Enterprise agents 3 | # on Linux instances on AWS 4 | # Change URL of the Puppet Server (here: puppet.aws.psick.io) 5 | # Default client certname is $instanceID.aws.psick.io, adapt as needed. 6 | 7 | role=${1:-norole} 8 | environment=${2:-production} 9 | preshared_key='t0b3definED!' 10 | instance_id=$(curl -s --insecure http://169.254.169.254/latest/meta-data/instance-id) 11 | mkdir -p /etc/puppetlabs/puppet 12 | echo --- > /etc/puppetlabs/puppet/csr_attributes.yaml 13 | echo 'extension_requests:' >> /etc/puppetlabs/puppet/csr_attributes.yaml 14 | echo " pp_role: ${role}" >> /etc/puppetlabs/puppet/csr_attributes.yaml 15 | echo " pp_environment: ${environment}" >> /etc/puppetlabs/puppet/csr_attributes.yaml 16 | echo " pp_preshared_key: ${preshared_key}" >> /etc/puppetlabs/puppet/csr_attributes.yaml 17 | chmod 640 /etc/puppetlabs/puppet/csr_attributes.yaml 18 | curl -k https://puppet.aws.psick.io:8140/packages/current/install.bash | bash -s agent:certname=$instance_id.aws.psick.io 19 | 20 | -------------------------------------------------------------------------------- /bin/ec2_userdata/windows.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | Sample ec2_userdata script for installation of Puppet Enterprise agent 4 | on Windows instances on AWS 5 | Change URL of the Puppet Server (here: puppet.aws.psick.io) 6 | Default client certname is $instanceID.aws.psick.io, adapt as needed. 7 | #> 8 | 9 | Set-ExecutionPolicy Unrestricted 10 | $id = (Invoke-WebRequest -Uri http://169.254.169.254/latest/meta-data/instance-id).content 11 | [Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}; 12 | $webClient = New-Object System.Net.WebClient; 13 | $webClient.DownloadFile('https://puppet.aws.psick.io:8140/packages/2017.1.1/install.ps1', 'install.ps1'); 14 | powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -File .\install.ps1 agent:certname=$id.aws.psick.io extension_requests:pp_role=norole extension_requests:pp_environment=production extension_requests:pp_preshared_key= 15 | 16 | 17 | -------------------------------------------------------------------------------- /bin/enc_cat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir="$(dirname $0)/.." 3 | script_dir="$(dirname $0)" 4 | . "${script_dir}/functions" 5 | 6 | host=$1 7 | if [ -f "${repo_dir}/bin/enc_cat/${host}.yaml" ]; then 8 | cat "${repo_dir}/bin/enc_cat/${host}.yaml" 9 | else 10 | cat "${repo_dir}/bin/enc_cat/default.yaml" 11 | fi 12 | -------------------------------------------------------------------------------- /bin/enc_cat/default.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | environment: production 3 | classes: 4 | - psick 5 | parameters: 6 | env: development 7 | role: default 8 | -------------------------------------------------------------------------------- /bin/enc_cat/testos.local.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | environment: production 3 | classes: 4 | - psick::git 5 | parameters: 6 | env: development 7 | role: ostest 8 | 9 | -------------------------------------------------------------------------------- /bin/facter_db.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'facterdb/bin' 4 | #FacterDB::Bin.new(ARGV).run 5 | 6 | #osfamily='RedHat' 7 | FacterDB.get_facts([{:osfamily => osfamily}]) 8 | -------------------------------------------------------------------------------- /bin/functions: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # General functions for shell scripts in this directory 3 | 4 | if tty -s 5 | then 6 | SETCOLOR_SUCCESS=$(tput setaf 2) 7 | SETCOLOR_FAILURE=$(tput setaf 1) 8 | SETCOLOR_WARNING=$(tput setaf 3) 9 | SETCOLOR_ASK=$(tput setaf 13) 10 | SETCOLOR_NORMAL=$(tput sgr0) 11 | SETCOLOR_TITLE=$(tput setaf 6) 12 | SETCOLOR_SUBTITLE=$(tput setaf 14) 13 | SETCOLOR_BOLD=$(tput setaf 15) 14 | else 15 | SETCOLOR_SUCCESS="-" 16 | SETCOLOR_FAILURE="-" 17 | SETCOLOR_WARNING="-" 18 | SETCOLOR_ASK="-" 19 | SETCOLOR_NORMAL="-" 20 | SETCOLOR_TITLE="-" 21 | SETCOLOR_SUBTITLE="-" 22 | SETCOLOR_BOLD="-" 23 | fi 24 | echo_success() { 25 | echo "${SETCOLOR_SUCCESS}${1}${SETCOLOR_NORMAL}" 26 | } 27 | 28 | echo_failure() { 29 | echo "${SETCOLOR_FAILURE}${1}${SETCOLOR_NORMAL}" 30 | return 1 31 | } 32 | 33 | echo_warning() { 34 | echo "${SETCOLOR_WARNING}${1}${SETCOLOR_NORMAL}" 35 | return 1 36 | } 37 | 38 | echo_title () { 39 | echo 40 | echo "${SETCOLOR_BOLD}###${SETCOLOR_NORMAL} ${SETCOLOR_TITLE}${1}${SETCOLOR_NORMAL} ${SETCOLOR_BOLD}###${SETCOLOR_NORMAL}" 41 | } 42 | echo_subtitle () { 43 | echo "${SETCOLOR_BOLD}# ${SETCOLOR_NORMAL}${SETCOLOR_SUBTITLE}${1}${SETCOLOR_NORMAL}" 44 | } 45 | 46 | ask_interactive () { 47 | echo "${SETCOLOR_ASK}${1}${SETCOLOR_NORMAL}" 48 | echo "Press 'x' to skip or just return to go on" 49 | read press 50 | case $press in 51 | x) return 2 ;; 52 | *) return 53 | esac 54 | } 55 | 56 | ask_warning () { 57 | echo "${SETCOLOR_WARNING}${1}${SETCOLOR_NORMAL}" 58 | echo "Press 'y' to continue or anything else to skip." 59 | read press 60 | case $press in 61 | y) return ;; 62 | *) return 2 63 | esac 64 | } 65 | 66 | # Shows or executes a command 67 | show_command () { 68 | echo 69 | $SETCOLOR_BOLD ; echo "$HOSTNAME: $*" ; $SETCOLOR_NORMAL 70 | 71 | bash -c "$*" 72 | } 73 | 74 | # Filtering out only: $ ; ` | < > 75 | shell_filter () { 76 | echo $1 | sed 's/\$//g' | sed 's/;//g' | sed 's/`//g' | sed 's/|//g' | sed 's///g' 77 | } 78 | 79 | shell_filter_strict () { 80 | # Filtering out: $ ; ` | < > = ! { } [ ] / \ # & 81 | echo $1 | sed 's/\$//g' | sed 's/;//g' | sed 's/`//g' | sed 's/|//g' | sed 's///g' | sed 's/=//g' | sed 's/!//g' | sed 's/{//g' | sed 's/}//g' | sed 's/\[//g' | sed 's/\]//g' | sed 's/\///g' | sed 's/\\//g' | sed 's/#//g' | sed 's/&//g' 82 | 83 | # Filtering out: all but accepted chars 84 | # echo $1 | sed "s/[^a-Z0-9_\-]//Ig" 85 | } 86 | 87 | if [ $USER == 'root' ]; then 88 | sudo_command='' 89 | else 90 | sudo_command='sudo ' 91 | fi 92 | -------------------------------------------------------------------------------- /bin/git_checkout_master.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | 5 | cd $repo_dir 6 | for mod in $(ls -1 modules); do 7 | cd "${repo_dir}/modules/${mod}" 8 | if [ -d '.git' ]; then 9 | echo 10 | echo_title "modules/${mod}" 11 | git checkout master 12 | fi 13 | cd ../../ 14 | done 15 | 16 | -------------------------------------------------------------------------------- /bin/git_install_hooks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | 5 | hooks_repo='https://github.com/drwahl/puppet-git-hooks' 6 | if [ $1 ]; then 7 | hooks_repo=$1 8 | fi 9 | 10 | main_dir=$(git rev-parse --show-toplevel) 11 | 12 | echo_title "Executing: git clone ${hooks_repo} /var/tmp/" 13 | git clone ${hooks_repo} /var/tmp/puppet-git-hooks 14 | 15 | echo_title "Copying /var/tmp/puppet-git-hooks/commit_hooks in ${main_dir}/.git/hooks" 16 | cp -rvpn /var/tmp/puppet-git-hooks/commit_hooks "${main_dir}/.git/hooks" 17 | 18 | echo_title "Copying /var/tmp/puppet-git-hooks/pre-commit in ${main_dir}/.git/hooks" 19 | cp -rvpn /var/tmp/puppet-git-hooks/pre-commit "${main_dir}/.git/hooks" 20 | 21 | echo 22 | echo_subtitle "Installed hooks from ${hooks_repo} to ${main_dir}/.git/hooks" 23 | echo 24 | echo "They will be used on git operations. Mostly in the pre-commit phase" 25 | 26 | echo_title "Configure the tests to run hooks by editing ${main_dir}/.git/hooks/commit_hooks/config.cfg" 27 | echo "You may prefer to set CHECK_PUPPET_LINT='permissive' to avoid commit block on Puppet lint errors" 28 | 29 | -------------------------------------------------------------------------------- /bin/git_setup_new_repo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | git_remote=$(git remote -v | grep origin) 5 | parent_dir=$(cd $repo_dir ; cd .. ; pwd) 6 | 7 | echo_title "PSICK is going to create a brand new control-repo" 8 | echo 9 | echo_subtitle "Specify the path where you want to create it" 10 | if [ -z $1 ]; then 11 | echo "Provide the full absolute path or the name of a dir that will be created under ${parent_dir}" 12 | echo "Press [ENTER] when done." 13 | read new_repo_name 14 | else 15 | new_repo_name=$1 16 | fi 17 | echo $new_repo_name | grep "^/" 18 | if [ $? == 0 ]; then 19 | new_repo_dir=$new_repo_name 20 | else 21 | new_repo_dir="${parent_dir}/${new_repo_name}" 22 | fi 23 | 24 | ask_choice () { 25 | echo_subtitle "Choose how you want to start with your new control-repo" 26 | echo "1- Create a full featured control-repo based on current PSICK" 27 | echo "2- Clone the Puppet default one: https://github.com/puppetlabs/control-repo" 28 | echo "Note that you will be able to add or remove components later." 29 | echo "Make your choice:" 30 | read which_controlrepo 31 | 32 | case $which_controlrepo in 33 | 1) setup_psick ;; 34 | 2) setup_default ;; 35 | *) ask_choice ;; 36 | esac 37 | } 38 | 39 | setup_psick () { 40 | echo_subtitle "Copying all files from psick to ${new_repo_dir}" 41 | mkdir -p $new_repo_dir 42 | rsync -a --exclude='.git' --exclude='.vagrant' --exclude='.pe_build' $repo_dir/ $new_repo_dir/ 43 | 44 | git_init 45 | end_message 46 | } 47 | setup_default () { 48 | echo_subtitle "Cloning https://github.com/puppetlabs/control-repo into ${new_repo_dir}" 49 | git clone https://github.com/puppetlabs/control-repo $new_repo_dir 50 | end_message 51 | } 52 | 53 | git_init () { 54 | echo_subtitle "Initialising git in the new directory" 55 | cd $new_repo_dir 56 | git init 57 | git checkout -b production 2>/dev/null 58 | git branch -d master 2>/dev/null 59 | echo_subtitle "Showing current status of the new git repo" 60 | git status 61 | 62 | echo_subtitle "NOTE: master branch has been renamed to production for Puppet compliance" 63 | echo 64 | echo_subtitle "Do you want to make a first commit on the new repo?" 65 | echo "Press 'y' to commit all the existing files so to have a snapshot of the current repo" 66 | echo "Press anything else to skip this and take your time to review and cleanup files before your first commit" 67 | read press 68 | case $press in 69 | y) git add . ; git commit -m "First commit: Snapshot of ${git_remote}" ;; 70 | *) echo_subtitle "Nothing has been committed now" 71 | esac 72 | } 73 | 74 | end_message () { 75 | echo_title "Congratulations! Setup of the new control-repo finished" 76 | echo_subtitle "To start to work on it:" 77 | echo_subtitle "cd ${new_repo_dir}" 78 | } 79 | 80 | ask_choice 81 | -------------------------------------------------------------------------------- /bin/git_status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | 5 | echo_title "Showing git status of external modules" 6 | cd $repo_dir 7 | for mod in $(ls -1 modules); do 8 | cd "${repo_dir}/modules/${mod}" 9 | if [ -d '.git' ]; then 10 | echo 11 | echo_title "modules/${mod}" 12 | git status 13 | git branch 14 | fi 15 | cd ../../ 16 | done 17 | 18 | echo_title "This Puppet control-repo" 19 | git status 20 | 21 | -------------------------------------------------------------------------------- /bin/gitlab_accept_merge_request.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'gitlab' 3 | GITLAB_CONFIG='/etc/gitlab-cli.conf' 4 | config = {} 5 | File.foreach GITLAB_CONFIG do |line| 6 | k = line.split("=")[0].gsub("\n",'') if line =~/=/ 7 | v = line.split("=")[1].gsub("\n",'') if line =~/=/ 8 | config.store(k,v) 9 | end 10 | last_commit=`git log -1 --oneline` 11 | source_branch = ARGV[0] ? ARGV[0] : 'integration' 12 | destination_branch = ARGV[1] ? ARGV[1] : 'production' 13 | mr_title = ARGV[2] ? ARGV[2] : "Merged: #{last_commit} from #{source_branch} to #{destination_branch}" 14 | 15 | project_id = config['GITLAB_API_PROJECT_ID'] 16 | endpoint = config['GITLAB_API_ENDPOINT'] 17 | private_token = config['GITLAB_API_PRIVATE_TOKEN'] 18 | httparty = config['GITLAB_API_HTTPARTY_OPTIONS'].gsub("'",'') 19 | 20 | Gitlab.endpoint = endpoint 21 | Gitlab.private_token = private_token 22 | Gitlab.httparty = eval(httparty) 23 | 24 | merge_requests = Gitlab.merge_requests(project_id) 25 | merge_requests.auto_paginate do |merge_request| 26 | req=merge_request.to_h 27 | if req["state"] == "opened" 28 | mr_id=req["iid"] 29 | sb=req["source_branch"] 30 | db=req["target_branch"] 31 | if source_branch == sb and destination_branch == db 32 | print "Merging id #{project_id}/#{mr_id}: #{mr_title}\n" 33 | Gitlab.accept_merge_request(project_id,mr_id, { merge_when_pipeline_succeeds: true, merge_commit_message: "#{mr_title}", should_remove_source_branch: false }) 34 | exit 0 35 | end 36 | end 37 | end 38 | 39 | print "Error: Merge Request NOT Found: #{mr_title}\n" 40 | exit 1 41 | 42 | -------------------------------------------------------------------------------- /bin/gitlab_after.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir="$(dirname $0)/.." 3 | 4 | echo "Cleanup keys" 5 | rm -f ${repo_dir}/keys/* 6 | echo 7 | -------------------------------------------------------------------------------- /bin/gitlab_before.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir="$(dirname $0)/.." 3 | script_dir="$(dirname $0)" 4 | # repo_dir=$(git rev-parse --show-toplevel) 5 | . "${script_dir}/functions" 6 | PATH=/opt/puppetlabs/puppet/bin:$PATH 7 | git_branch=${1:-integration} 8 | default_branch="production" 9 | ci=$(echo $0 | sed 's/_before\.sh//g' | sed 's/^bin\///g') 10 | r10k_configfile="bin/config/${ci}-r10k.yaml" 11 | # Location of keys to copy into the local repository (removed from_after.sh 12 | eyamlkeyloc=$2 13 | 14 | if [ -f "$eyamlkeyloc" ]; then 15 | echo "Setup keys" 16 | mkdir -p ${repo_dir}/keys 17 | cp -f ${eyamlkeyloc}/* ${repo_dir}/keys/ 18 | fi 19 | 20 | if [ -f "$r10k_configfile" ]; then 21 | config="-c ${r10k_configfile}" 22 | fi 23 | echo 24 | 25 | cd $repo_dir 26 | git config --add remote.origin.fetch +refs/heads/$default_branch:refs/remotes/origin/$default_branch 27 | git fetch --no-tags 28 | diff_commits_number=$(git log origin/$default_branch..HEAD --pretty=oneline | wc -l) 29 | echo "Deploying modules via r10k if Puppetfile has changed in the last ${diff_commits_number} commits" 30 | commits=$(git diff HEAD~$diff_commits_number --name-only | wc -l) 31 | if [ $commits -gt 0 ]; then 32 | changedfiles=$(git diff HEAD~$diff_commits_number --name-only | grep Puppetfile); 33 | if [ "x$changedfiles" == "xPuppetfile" ] || [ ! -d "${repo_dir}/modules/stdlib" ] ; then 34 | echo_title "Installing modules defined in Puppetfile via r10k" 35 | r10k puppetfile install -v ${config} 36 | fi 37 | fi 38 | -------------------------------------------------------------------------------- /bin/gitlab_catalog_diff.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | test -f /etc/gitlab-ci.conf && . /etc/gitlab-ci.conf 3 | 4 | default_nodes=$catalag_diff_default_nodes 5 | always_nodes=$catalag_diff_always_nodes 6 | default_branch='production' 7 | 8 | diff_commits_number=1 9 | 10 | if [[ "x$1" != "x" ]]; then 11 | git checkout $1 12 | git pull 13 | fi 14 | diff_commits_number=$(git log origin/$default_branch..$1 --pretty=oneline | wc -l) 15 | echo "Checking for files in the last $diff_commits_number commits" 16 | for changedfile in $(git diff HEAD~$diff_commits_number --name-only); do 17 | node='' 18 | if [[ $(echo "$changedfile" | grep -q 'hieradata/nodes'; echo $?) -eq 0 ]]; then 19 | node=$(echo $changedfile | sed -e "s/^hieradata\/nodes\///" -e "s/\.yaml//") 20 | fi 21 | if [[ $(echo "$changedfile" | grep -q 'hieradata/role'; echo $?) -eq 0 ]]; then 22 | role=$(echo $changedfile | sed -e "s/^hieradata\/role\///" -e "s/\.yaml//") 23 | fi 24 | 25 | if [[ "x$node" != "x" ]]; then 26 | echo 27 | echo "Catalog diff on ${node} - Check based on commits" 28 | octocatalog-diff -n $node 29 | fi 30 | 31 | if [[ "x$role" != "x" ]]; then 32 | echo 33 | echo "Catalog diff on role ${role} - Check based on commits" 34 | octocatalog-diff -n $role.$(facter domain) 35 | fi 36 | done 37 | 38 | for node in $default_nodes; do 39 | echo 40 | echo "Catalog diff on ${node} - Default check" 41 | octocatalog-diff -n $node 42 | done 43 | 44 | for node in $always_nodes; do 45 | echo 46 | echo "Catalog diff on ${node} - Check always done" 47 | octocatalog-diff -n $node 48 | done 49 | -------------------------------------------------------------------------------- /bin/gitlab_catalog_preview.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | test -f /etc/gitlab-ci.conf && . /etc/gitlab-ci.conf 3 | 4 | default_nodes=$catalog_preview_default_nodes 5 | always_nodes=$catalog_preview_always_nodes 6 | 7 | # Default number of commits to check for changed files 8 | diff_commits_number=1 9 | global_exit=0 10 | nodes=0 11 | 12 | env=$1 13 | 14 | if [[ "x$env" != "x" ]]; then 15 | git checkout $env 16 | git pull 17 | fi 18 | diff_commits_number=$(git log origin/production..$env --pretty=oneline | wc -l) 19 | echo "Checking for files in the last $diff_commits_number commits" 20 | for changedfile in $(git diff origin/production..$env --name-only); do 21 | node='' 22 | if [[ $(echo "$changedfile" | grep -q 'hieradata/nodes'; echo $?) -eq 0 ]]; then 23 | node=$(echo $changedfile | sed -e "s/^hieradata\/nodes\///" -e "s/\.yaml//") 24 | fi 25 | 26 | if [[ "x$node" != "x" ]]; then 27 | echo 28 | echo "Puppet preview diff on ${node} - Check based on commits" 29 | sudo /opt/puppetlabs/bin/puppet preview --view overview --assert equal --baseline_environment production --preview_environment $env $node 30 | global_exit=$(($global_exit + $?)) 31 | nodes=$nodes+1 32 | fi 33 | done 34 | 35 | if [[ $nodes == 0 ]]; then 36 | for node in ${default_nodes//,/ }; do 37 | echo 38 | echo "Catalog preview on ${node} - Default check" 39 | sudo /opt/puppetlabs/bin/puppet preview --view overview --assert equal --baseline_environment production --preview_environment $env $node 40 | global_exit=$(($global_exit + $?)) 41 | done 42 | fi 43 | 44 | for node in ${always_nodes//,/ }; do 45 | echo 46 | echo "Catalog preview on ${node} - Check always done" 47 | sudo /opt/puppetlabs/bin/puppet preview --view overview --assert equal --baseline_environment production --preview_environment $env $node 48 | global_exit=$(($global_exit + $?)) 49 | done 50 | exit $global_exit 51 | -------------------------------------------------------------------------------- /bin/gitlab_create_merge_request.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'gitlab' 3 | GITLAB_CONFIG='/etc/gitlab-cli.conf' 4 | config = {} 5 | File.foreach GITLAB_CONFIG do |line| 6 | k = line.split("=")[0].gsub("\n",'') if line =~/=/ 7 | v = line.split("=")[1].gsub("\n",'') if line =~/=/ 8 | config.store(k,v) 9 | end 10 | last_commit=`git log -1 --oneline` 11 | #last_commit="-numero ultima commit-" 12 | source_branch = ARGV[0] ? ARGV[0] : 'integration' 13 | destination_branch = ARGV[1] ? ARGV[1] : 'production' 14 | mr_title = ARGV[2] ? ARGV[2] : "MR: #{last_commit} #{source_branch} to #{destination_branch}" 15 | 16 | project_id = config['GITLAB_API_PROJECT_ID'] 17 | endpoint = config['GITLAB_API_ENDPOINT'] 18 | private_token = config['GITLAB_API_PRIVATE_TOKEN'] 19 | httparty = config['GITLAB_API_HTTPARTY_OPTIONS'].gsub("'",'') 20 | 21 | gitlab_user = config['GITLAB_USER'] 22 | gitlab_milestone = config['GITLAB_MILESTONE'] 23 | gitlab_labels = config['GITLAB_LABELS'] 24 | autoadd_target = config['GITLAB_TARGET_LABEL'] 25 | autoadd_source = config['GITLAB_SOURCE_LABEL'] 26 | default_target = config['GITLAB_DEFAULT_TARGET_LABEL'] 27 | default_source = config['GITLAB_DEFAULT_SOURCE_LABEL'] 28 | 29 | if autoadd_target.to_s == "true" 30 | gitlab_labels=gitlab_labels.to_s+default_target.to_s+destination_branch 31 | end 32 | 33 | if autoadd_source.to_s == "true" 34 | gitlab_labels=gitlab_labels.to_s+default_source.to_s+source_branch 35 | end 36 | 37 | gitlab_labels=gitlab_labels.to_s.split(",").compact.reject(&:empty?).join(",") 38 | 39 | if gitlab_labels == "''" 40 | gitlab_labels="" 41 | end 42 | 43 | Gitlab.endpoint = endpoint 44 | Gitlab.private_token = private_token 45 | Gitlab.httparty = eval(httparty) 46 | 47 | assignee_id="" 48 | user_list=Gitlab.team_members(project_id) 49 | user_list.auto_paginate do |user| 50 | u=user.to_h 51 | if u["name"] == gitlab_user or u["username"] == gitlab_user 52 | assignee_id= u["id"] 53 | end 54 | end 55 | 56 | milestone_id="" 57 | milestone_list=Gitlab.milestones(project_id) 58 | milestone_list.auto_paginate do |milestone| 59 | m=milestone.to_h 60 | if m["title"] == gitlab_milestone 61 | milestone_id= m["id"] 62 | end 63 | end 64 | 65 | merge_requests = Gitlab.merge_requests(project_id) 66 | merge_requests.auto_paginate do |merge_request| 67 | req=merge_request.to_h 68 | if req["state"] == "opened" 69 | id=req["iid"] 70 | sb=req["source_branch"] 71 | db=req["target_branch"] 72 | if source_branch == sb and destination_branch == db 73 | print "#{mr_title}: already exist with ID Number #{id}.\n" 74 | print "You only need to merge it.\n" 75 | exit 0 76 | end 77 | end 78 | end 79 | 80 | print "Creating #{mr_title}\n Assignee: Name=#{gitlab_user} - Id=#{assignee_id}\n Milestone: Title=#{gitlab_milestone} - Id=#{milestone_id}\n Labels: #{gitlab_labels}\n\n" 81 | 82 | Gitlab.create_merge_request(project_id,"#{mr_title[0..200]}",{ source_branch: source_branch, target_branch: destination_branch, labels: gitlab_labels, assignee_id: assignee_id, milestone_id: milestone_id } ) 83 | -------------------------------------------------------------------------------- /bin/gitlab_create_merge_request.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | set -o allexport 5 | . /etc/gitlab-cli.conf 6 | set +o allexport 7 | 8 | source_branch=$1 9 | destination_branch=$2 10 | mr_title=${3:-"Puppet CI $*"} 11 | 12 | set -x 13 | gitlab create_merge_request $GITLAB_API_PROJECT_ID "$mr_title" "{ source_branch: $source_branch, target_branch: $destination_branch }" 14 | -------------------------------------------------------------------------------- /bin/gitlab_danger.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH=/opt/puppetlabs/puppet/bin:$PATH 3 | echo "Run Danger" 4 | cli_vars=$(cat /etc/gitlab-cli.conf|grep -v "^#"|grep -v "^$") 5 | for v in $cli_vars; do 6 | export $v 7 | done 8 | danger --verbose 9 | -------------------------------------------------------------------------------- /bin/gitlab_populate.conf: -------------------------------------------------------------------------------- 1 | # Configuration file for script gitlab_populate.sh 2 | # The script will recreate on destination_giturl the groups and projects 3 | # present in the puppetfile_file and the controlrepo_path 4 | # It also takes care of syncing the gir repos. 5 | 6 | # Prerequisites: 7 | # - Valid token for a user on target GitLab with permissions to create groups and projects 8 | # - Access via https or ssh to source_giturl or destination_giturl 9 | # - If ssh is used Valid ssh-keys to access git repos on source_giturl and destination_giturl 10 | # - Git command 11 | # - gitlab Ruby gem (the cli to access to gitlab) 12 | 13 | # Configure here hostname / IP of your GitLab server 14 | GITLAB_API_ENDPOINT=https://10.42.100.26/api/v4 15 | 16 | # Configure with the access token of a user which has powers to create groups and projects 17 | # The access token has to be setup from user Settings, with API access privileges 18 | GITLAB_API_PRIVATE_TOKEN=UGZZcx1JN8ugY89nzquV 19 | 20 | # We ignore self signed certs on GitLab 21 | GITLAB_API_HTTPARTY_OPTIONS="{verify: false}" 22 | 23 | # Path of the Puppetfile with list of modules to use 24 | puppetfile_file="${BASEDIR}/Puppetfile" 25 | 26 | # Path of control-repo on Git Servers 27 | controlrepo_path="example42/psick" 28 | #controlrepo_path="puppet/dtt-puppet-control-repo" # DTT 29 | 30 | # URL of source git server (from where to clone/pull repos) 31 | # Format: https://github.com/ or git@github.com: 32 | source_giturl="https://github.com/" 33 | #source_giturl="git@git:" # DTT 34 | 35 | # URL of destination git server (to where to push repos) 36 | # Format: https://github.com/ or git@github.com: 37 | destination_giturl="git@10.42.100.26:" 38 | # destination_giturl="git@10.42.100.26:" # DTT 39 | 40 | # Local work dir (where repos are cloned) 41 | workdir="${BASEDIR}/gitrepos" -------------------------------------------------------------------------------- /bin/gitlab_tp_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | test -f /etc/gitlab-ci.conf && . /etc/gitlab-ci.conf 3 | default_nodes=$tp_test_default_nodes 4 | always_nodes=$tp_test_always_nodes 5 | 6 | diff_commits_number=1 7 | 8 | if [[ "x$1" != "x" ]]; then 9 | git checkout $1 10 | git pull 11 | diff_commits_number=$(git log origin/production..$1 --pretty=oneline | wc -l) 12 | fi 13 | echo "Checking for files in the last $diff_commits_number commits" 14 | for changedfile in $(git diff HEAD~$diff_commits_number --name-only); do 15 | node='' 16 | if [[ $(echo "$changedfile" | grep -q 'hieradata/nodes'; echo $?) -eq 0 ]]; then 17 | node=$(echo $changedfile | sed -e "s/^hieradata\/nodes\///" -e "s/\.yaml//") 18 | fi 19 | 20 | # Default nodes to check in common changes 21 | if [[ $(echo "$changedfile" | grep -q 'hieradata/role'; echo $?) -eq 0 ]] \ 22 | || [[ $(echo "$changedfile" | grep -q 'Puppetfile'; echo $?) -eq 0 ]] \ 23 | || [[ $(echo "$changedfile" | grep -q 'site/'; echo $?) -eq 0 ]] \ 24 | || [[ $(echo "$changedfile" | grep -q 'manifests/'; echo $?) -eq 0 ]]; then 25 | for node in $default_nodes; do 26 | echo 27 | echo "Tp test on ${node} - Default check" 28 | vagrant ssh $node -c 'tp test ; exit $?' 29 | done 30 | fi 31 | 32 | if [[ "x$node" != "x" ]]; then 33 | echo 34 | echo "Tp test ${node} - Check based on commits" 35 | vagrant ssh $node -c 'tp test ; exit $?' 36 | fi 37 | done 38 | 39 | for node in $always_nodes; do 40 | echo 41 | echo "Tp test on ${node} - Check always done" 42 | vagrant ssh $node -c 'tp test ; exit $?' 43 | done 44 | -------------------------------------------------------------------------------- /bin/jenkins_before.sh: -------------------------------------------------------------------------------- 1 | gitlab_before.sh -------------------------------------------------------------------------------- /bin/massfindandreplace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | OLDSTRING=$1 3 | NEWSTRING=$2 4 | 5 | if [ ! $1 ] ; then 6 | echo "Usage: $0 oldstring newstring" 7 | exit 1 8 | fi 9 | for file in $( grep -R "$OLDSTRING" . | grep -v ".git" | cut -d ":" -f 1 ) ; do 10 | # Detect OS 11 | if [ -f /System/Library/Accessibility/AccessibilityDefinitions.plist ] ; then 12 | sed -i "" -e "s/$OLDSTRING/$NEWSTRING/g" $file && echo "Changed $file" 13 | else 14 | sed -i "s/$OLDSTRING/$NEWSTRING/g" $file && echo "Changed $file" 15 | fi 16 | done 17 | -------------------------------------------------------------------------------- /bin/massfindandreplace_macspurious.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | OLDSTRING=" " 3 | NEWSTRING=" " 4 | for file in $( grep -R "$OLDSTRING" . | grep -v ".git" | cut -d ":" -f 1 | grep -v 'massfindandreplace_macspurious.sh' | grep -v 'vendor' ) ; do 5 | # Detect OS 6 | if [ -f /System/Library/Accessibility/AccessibilityDefinitions.plist ] ; then 7 | sed -i "" -e "s/$OLDSTRING/$NEWSTRING/g" $file && echo "Changed $file" 8 | else 9 | sed -i "s/$OLDSTRING/$NEWSTRING/g" $file && echo "Changed $file" 10 | fi 11 | done 12 | 13 | -------------------------------------------------------------------------------- /bin/papply.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | PATH=$PATH:/opt/puppetlabs/server/bin 3 | repo_dir="$(dirname $0)/.." 4 | # repo_dir=$(git rev-parse --show-toplevel) 5 | . "${repo_dir}/bin/functions" 6 | 7 | manifest="${repo_dir}/manifests/site.pp" 8 | extra_options=$* 9 | 10 | PATH=$PATH:/opt/puppetlabs/puppet/bin 11 | 12 | echo_title "Running Puppet version $(puppet --version) apply on ${manifest}" 13 | echo_subtitle "Role: ${FACTER_role} - $(facter -p role)" 14 | 15 | which git > /dev/null 16 | if [ "x$?" == "x0" ] && [ -d "${repo_dir}/.git" ]; then 17 | config_version="/usr/bin/git --git-dir ${repo_dir}/.git log --pretty=format:\"%h - %an, %ad : %s\" -1" 18 | else 19 | config_version="echo" 20 | fi 21 | 22 | # Run puppet apply with correct configs 23 | puppet apply --verbose --report --show_diff --summarize \ 24 | --modulepath "${repo_dir}/site:${repo_dir}/modules:/etc/puppetlabs/code/modules" \ 25 | --environmentpath "${repo_dir}/.." \ 26 | --hiera_config="${repo_dir}/hiera.yaml" \ 27 | --config_version="${config_version}" \ 28 | --detailed-exitcodes $extra_options $manifest 29 | 30 | result=$? 31 | # Puppet exit codes 0 and 2 both imply an error less run 32 | if [ "x$result" == "x0" ] || [ "x$result" == "x2" ]; then 33 | echo_success "Puppet run without errors" 34 | exit 0 35 | else 36 | echo_failure "There were errors in the Puppet run" 37 | exit 1 38 | fi 39 | -------------------------------------------------------------------------------- /bin/papply_local.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir="$(dirname $0)/.." 3 | # repo_dir=$(git rev-parse --show-toplevel) 4 | . "${repo_dir}/bin/functions" 5 | 6 | echo_subtitle "Running ${repo_dir}/bin/papply.sh --hiera_config=hiera3.yaml" 7 | "${repo_dir}/bin/papply.sh" --hiera_config="${repo_dir}/hiera.yaml" $* 8 | -------------------------------------------------------------------------------- /bin/puppet_check_beaker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | export PATH=/opt/puppetlabs/puppet/bin:$PATH 5 | 6 | RUBY=$(which ruby) 7 | mods=${1:-site} 8 | role=${2:-none} 9 | 10 | global_exit=0 11 | 12 | if [ ! -z ${RUBY} ] ; then 13 | echo_title "Running bundle install" 14 | bundle install --with=integration --path=vendor 15 | for r in $(ls -1 spec/acceptance/ | grep _spec.rb | sed 's/_spec.rb//g') ; do 16 | echo_title "Running beaker for role ${r}" 17 | bundle exec rake beaker_roles:${r} 18 | done 19 | if [ $? == 0 ]; then 20 | echo_success "OK" 21 | else 22 | echo_failure "ERROR" 23 | echo $err 24 | global_exit=1 25 | fi 26 | else 27 | echo_warning "rake not found." 28 | fi 29 | 30 | exit $global_exit 31 | -------------------------------------------------------------------------------- /bin/puppet_check_rake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | export PATH=/opt/puppetlabs/puppet/bin:$PATH 5 | mods=${1:-site} 6 | run=${2:-none} 7 | 8 | global_exit=0 9 | 10 | if [ "${mods}" != "controlrepo" ]; then 11 | echo_title "Running rspec tests on modules under ${mods} dir" 12 | for i in $(ls -1 "${repo_dir}/${mods}/") 13 | do 14 | echo_title "Running unit tests for $i" 15 | cd "${repo_dir}/${mods}/${i}" 16 | rm -f Gemfile.lock 17 | if [ "${run}" == "bundle" ]; then 18 | bundle --path=vendor 19 | fi 20 | bundle exec rake spec 21 | if [ $? == 0 ]; then 22 | echo_success "OK" 23 | else 24 | echo_failure "ERROR" 25 | global_exit=1 26 | fi 27 | done 28 | else 29 | echo_title "Running control-repo rspec tests" 30 | if [ "${run}" == "bundle" ]; then 31 | bundle --path=vendor 32 | fi 33 | bundle exec rake spec 34 | if [ $? == 0 ]; then 35 | echo_success "OK" 36 | else 37 | echo_failure "ERROR" 38 | global_exit=1 39 | fi 40 | fi 41 | 42 | exit $global_exit 43 | -------------------------------------------------------------------------------- /bin/puppet_check_syntax.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | 5 | PUPPET=$(which puppet) 6 | ERB=$(which erb) 7 | RUBY=$(which ruby) 8 | R10K=$(which r10k) 9 | global_exit=0 10 | filter='grep -v somethingtoskip' 11 | 12 | if [ -n ${PUPPET} ]; then 13 | echo_title "Checking for pesky non printable characters in files." 14 | 15 | grep -I -H -P -n "[\xa0]" --color=yes -r * | $filter |tr '\302\102' 'X' 16 | fi 17 | 18 | if [ ! -z ${PUPPET} ]; then 19 | echo_title "Validating Manifests in site directory" 20 | 21 | for i in $(find site -name '*.pp') 22 | do 23 | echo -ne "$i - " 24 | err=$(${PUPPET} parser validate $i 2>&1) 25 | if [ $? = 0 ]; then 26 | echo_success "OK" 27 | else 28 | echo_failure "ERROR" 29 | echo $err 30 | global_exit=1 31 | fi 32 | done 33 | else 34 | echo_warning "puppet command not found" 35 | fi 36 | 37 | echo 38 | 39 | if [ ! -z ${RUBY} ]; then 40 | echo_title "Validating YAML files in hieradata/" 41 | for i in $(find hieradata -name "*.yaml") 42 | do 43 | echo -ne "$i - " 44 | err=$(${RUBY} -e "require 'yaml'; YAML.parse(File.open('$i'))" 2>&1) 45 | if [ $? = 0 ]; then 46 | echo_success "OK" 47 | else 48 | echo_failure "ERROR" 49 | echo $err 50 | global_exit=1 51 | fi 52 | done 53 | else 54 | echo_warning "ruby not found." 55 | fi 56 | 57 | echo 58 | 59 | if [ ! -z ${ERB} ] && [ ! -z ${RUBY} ]; then 60 | echo_title "Validation ERB files in site/ directory" 61 | for i in $(find site -name '*.erb') 62 | do 63 | echo -ne "$i - " 64 | err=$(${ERB} -P -x -T - "${i}" | ${RUBY} -c 2>&1) 65 | if [ $? = 0 ]; then 66 | echo_success "OK" 67 | else 68 | echo_failure "ERROR" 69 | echo $err 70 | global_exit=1 71 | fi 72 | done 73 | else 74 | echo_warning "erb not found." 75 | fi 76 | 77 | if [ ! -z ${R10K} ]; then 78 | echo_title "Validating Puppetfile syntax" 79 | echo -ne "Puppetfile - " 80 | err=$(${R10K} puppetfile check 2>&1) 81 | if [ $? = 0 ]; then 82 | echo_success "OK" 83 | else 84 | echo_failure "ERROR" 85 | echo $err 86 | global_exit=1 87 | fi 88 | else 89 | echo_warning "r10k not found." 90 | fi 91 | 92 | echo 93 | 94 | exit $global_exit 95 | -------------------------------------------------------------------------------- /bin/puppet_code_deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | 5 | env=$1 6 | 7 | echo_title "Deploying Puppet code on environment ${env}" 8 | puppet code deploy $env --wait 9 | -------------------------------------------------------------------------------- /bin/puppet_deploy_controlrepo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | script_dir="$(dirname $0)" 3 | # . "${script_dir}/functions" 4 | PATH=$PATH:/usr/local/bin 5 | control_repo=${1:-"https://github.com/example42/psick.git"} 6 | 7 | echo "Installing prerequisite packages and gems" 8 | puppet resource package git ensure=present 9 | 10 | puppet resource package deep_merge ensure=present provider=puppet_gem 11 | puppet resource package hiera-eyaml ensure=present provider=puppet_gem 12 | puppet resource package r10k ensure=present provider=puppet_gem 13 | 14 | mkdir -p /etc/puppetlabs/code/environments/ 15 | mkdir -p /etc/puppetlabs/r10k/ 16 | cat > /etc/puppetlabs/r10k/r10k.yaml << EOF 17 | --- 18 | :postrun: [] 19 | :cachedir: /opt/puppetlabs/puppet/cache/r10k 20 | :sources: 21 | puppet: 22 | basedir: /etc/puppetlabs/code/environments 23 | remote: $control_repo 24 | EOF 25 | 26 | echo "Running r10k deploy environment -v" 27 | /opt/puppetlabs/puppet/bin/r10k deploy environment -v 28 | 29 | -------------------------------------------------------------------------------- /bin/puppet_deploy_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | script_dir="$(dirname $0)" 3 | . "${script_dir}/functions" 4 | environment=${1:-production} 5 | PATH=/opt/puppetlabs/puppet/bin:$PATH 6 | 7 | if [ -d "/etc/puppetlabs/code/environments/${environment}/.git" ]; then 8 | cd /etc/puppetlabs/code/environments/$environment 9 | git pull origin $environment 10 | r10k puppetfile install -v 11 | else 12 | cd /etc/puppetlabs/code/environments/ 13 | git clone $origin $environment 14 | r10k puppetfile install -v 15 | fi 16 | -------------------------------------------------------------------------------- /bin/puppet_flush_environment_cache.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ "x$1" != "x" ]]; then 4 | query_params="?environment=${1}" 5 | else 6 | query_params='' 7 | fi 8 | echo "Flushing ${1} environment cache" 9 | curl -i --cert $(puppet config print hostcert) --key $(puppet config print hostprivkey) --cacert $(puppet config print cacert) -X DELETE https://$(puppet config print server):8140/puppet-admin-api/v1/environment-cache${query_params} 10 | -------------------------------------------------------------------------------- /bin/puppet_info.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | 5 | showhelp() { 6 | cat < [--env ] [--ssh ] 10 | Available actions: 11 | resources - Lists the resources managed by Puppet on the local node' 12 | last_run_summary - Show the content of /opt/puppetlabs/puppet/cache/state/last_run_summary.yaml 13 | show_filebucket - Some files in local filebucket 14 | Example: $0 resources --ssh jenkins@web01 15 | HELP 16 | } 17 | 18 | # We want to live in Puppet space 19 | export PATH=/opt/puppetlabs/puppet/bin:$PATH 20 | 21 | # Configuration file of this script (not an official Puppet configuation) 22 | # Managed by psick::puppet::ci 23 | test -f /etc/puppetlabs/ci.conf && . /etc/puppetlabs/ci.conf 24 | 25 | # run_action function runs different commands according to the provided task 26 | run_action () { 27 | a=$1 28 | case "$a" in 29 | resources) 30 | $ssh_command 31 | $sudo_command cat /opt/puppetlabs/puppet/cache/state/state.yaml | grep -v "^ " | grep -v "^---$" | sort | sed 's/:$//g' 32 | $ssh_command_post 33 | ;; 34 | last_run_summary) 35 | $ssh_command 36 | $sudo_command cat /opt/puppetlabs/puppet/cache/state/last_run_summary.yaml 37 | $ssh_command_post 38 | ;; 39 | show_filebucket) 40 | $ssh_command 41 | $sudo_command find /opt/puppetlabs/puppet/cache/clientbucket/ -name paths -exec sh -c 'i="$1"; cat "$i" ; stat -c %y "$i" ' _ {} \; 42 | $ssh_command_post 43 | ;; 44 | *) 45 | echo_failure "Action not supported" 46 | showhelp 47 | exit 1 48 | ;; 49 | esac 50 | } 51 | 52 | # Params parsing 53 | # Check Input 54 | if [ "$#" = "0" ] ; then 55 | showhelp 56 | exit 57 | fi 58 | 59 | ssh_command='' 60 | ssh_command_post='' 61 | sudo_command='' 62 | action='showhelp' 63 | while [ $# -gt 0 ]; do 64 | case "$1" in 65 | resources) 66 | action='resources' 67 | shift 68 | ;; 69 | last_run_summary) 70 | action='last_run_summary' 71 | shift 72 | ;; 73 | show_filebucket) 74 | action='show_filebucket' 75 | shift 76 | ;; 77 | --ssh) 78 | ssh_command="ssh $2 < 25 | param( 26 | [string]$MsiUrl = "https://downloads.puppetlabs.com/windows/puppet-agent-x64-latest.msi" 27 | ,[string]$PuppetVersion = $null 28 | ,[string]$PuppetMaster = "puppet" 29 | ,[string]$PuppetCertname = $null 30 | ) 31 | 32 | if ($PuppetVersion) { 33 | $MsiUrl = "https://downloads.puppetlabs.com/windows/puppet-agent-x64-$($PuppetVersion).msi" 34 | Write-Host "Puppet version $PuppetVersion specified, updated MsiUrl to `"$MsiUrl`"" 35 | } 36 | if ($PuppetCertname) { 37 | $CertnameArg = "PUPPET_AGENT_CERTNAME=$PuppetCertname" 38 | } else { 39 | $CertnameArg = " " 40 | } 41 | 42 | $PuppetInstalled = $false 43 | try { 44 | $ErrorActionPreference = "Stop"; 45 | Get-Command puppet | Out-Null 46 | $PuppetInstalled = $true 47 | $PuppetVersion=&puppet "--version" 48 | Write-Host "Puppet $PuppetVersion is installed. This process does not ensure the exact version or at least version specified, but only that puppet is installed. Exiting..." 49 | Exit 0 50 | } catch { 51 | Write-Host "Puppet is not installed, continuing..." 52 | } 53 | 54 | if (!($PuppetInstalled)) { 55 | $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) 56 | if (! ($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))) { 57 | Write-Host -ForegroundColor Red "You must run this script as an administrator." 58 | Exit 1 59 | } 60 | 61 | # Install it - msiexec will download from the url 62 | $install_args = @("/qn", "/norestart","/i", $MsiUrl, "PUPPET_MASTER_SERVER=$PuppetMaster", $CertnameArg) 63 | Write-Host "Installing Puppet. Running msiexec.exe $install_args" 64 | $process = Start-Process -FilePath msiexec.exe -ArgumentList $install_args -Wait -PassThru 65 | if ($process.ExitCode -ne 0) { 66 | Write-Host "Installer failed." 67 | Exit 1 68 | } 69 | 70 | # Stop the service that it autostarts 71 | Write-Host "Stopping Puppet service that is running by default..." 72 | Start-Sleep -s 5 73 | Stop-Service -Name puppet 74 | 75 | Write-Host "Puppet Agent successfully installed." 76 | } 77 | -------------------------------------------------------------------------------- /bin/puppet_install_puppetfile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | if [ $1 ]; then 5 | ln -s "${repo_dir}/Puppetfile_${1}" "${repo_dir}/Puppetfile" 6 | fi 7 | if [ $PUPPETFILE_ENV ]; then 8 | ln -s "${repo_dir}/Puppetfile_${PUPPETFILE_ENV}" "${repo_dir}/Puppetfile" 9 | fi 10 | if [ ! -f "${repo_dir}/Puppetfile" ]; then 11 | ln -s "${repo_dir}/Puppetfile_public" "${repo_dir}/Puppetfile" 12 | fi 13 | r10k puppetfile install 14 | -------------------------------------------------------------------------------- /bin/puppet_job_run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | 5 | test -f /etc/gitlab-ci.conf && . /etc/gitlab-ci.conf 6 | env=$1 7 | default=${env}_query_default_nodes 8 | always=${env}_query_always_nodes 9 | default_nodes=${!default} 10 | always_nodes=${!always} 11 | nodes=0 12 | global_exit=0 13 | domain=$(facter domain) 14 | 15 | diff_commits_number=$(git log production..$1 --pretty=oneline | wc -l) 16 | 17 | echo "Checking for files in the last $diff_commits_number commits" 18 | for changedfile in $(git diff HEAD~$diff_commits_number --name-only); do 19 | node='' 20 | if [[ $(echo "$changedfile" | grep -q "^hieradata/nodes" | grep $domain ; echo $?) -eq 0 ]]; then 21 | node=$(echo $changedfile | sed -e "s/^hieradata\/nodes\///" -e "s/\.yaml//") 22 | nodes=$nodes+1 23 | fi 24 | 25 | if [[ "x$node" != "x" ]]; then 26 | echo 27 | echo_title "Running Puppet on node ${node} - Check based on commits" 28 | puppet job run --nodes $node 29 | if [ $? != 0 ]; then 30 | global_exit=1 31 | fi 32 | fi 33 | done 34 | 35 | # Default nodes to check if none found from the commit 36 | if [[ $nodes == 0 ]]; then 37 | echo_title "Running Puppet on nodes ${default_nodes} - Default nodes" 38 | puppet job run --nodes $default_nodes 39 | if [ $? != 0 ]; then 40 | global_exit=1 41 | fi 42 | fi 43 | 44 | echo_title "Running Puppet on nodes ${always_nodes} - Node always checked" 45 | puppet job run --nodes $always_nodes 46 | if [ $? != 0 ]; then 47 | global_exit=1 48 | fi 49 | 50 | exit $global_exit 51 | 52 | -------------------------------------------------------------------------------- /bin/puppet_lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | PATH=/opt/puppetlabs/puppet/bin:$PATH 5 | 6 | if [ "x${1}" == "xfix" ]; then 7 | PUPPETLINT='puppet-lint -f' 8 | else 9 | PUPPETLINT='puppet-lint' 10 | fi 11 | global_exit=0 12 | 13 | if [ ! -z $(which puppet-lint) ]; then 14 | echo_title "Puppet linting manifests in site directory" 15 | 16 | for i in $(find site -name '*.pp' | grep -v fixtures) 17 | do 18 | echo -ne "$i - " 19 | $PUPPETLINT $i 20 | if [ $? == 0 ]; then 21 | echo_success "OK" 22 | else 23 | echo_failure "ERROR" 24 | global_exit=1 25 | fi 26 | done 27 | else 28 | echo_warning "puppet-lint command not found" 29 | fi 30 | 31 | exit $global_exit 32 | 33 | 34 | -------------------------------------------------------------------------------- /bin/puppet_module_generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "x$1" == "x" ]; then 4 | echo "Specify the name of the module you want to generate." 5 | read -p "Use author-module format, ie: example42-apache: " fullmodule 6 | else 7 | fullmodule=$1 8 | template=${2:-https://github.com/puppetlabs/pdk-templates} 9 | fi 10 | # author=$(echo $fullmodule | cut -d '-' -f 1) 11 | module=$(echo $fullmodule | cut -d '-' -f 2) 12 | 13 | echo "Generating new module with pdk" 14 | pdk new module $module --template-url=$template 15 | -------------------------------------------------------------------------------- /bin/puppet_remote_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir="$(dirname $0)/.." 3 | script_dir="$(dirname $0)" 4 | # repo_dir=$(git rev-parse --show-toplevel) 5 | . "${script_dir}/functions" 6 | 7 | PATH=$PATH:/usr/local/bin 8 | if [ "$1" = "auto" ]; then 9 | auto=true 10 | fi 11 | 12 | echo_title "This scripts setups the Puppet environment" 13 | echo "It asks to install the required Ruby gems: r10k, hiera-eyaml, deep_merge" 14 | echo "Then it runs: r10k puppetfile install -v" 15 | [ "$auto" = "true" ] || ask_interactive "Install the needed gems and then, via r10k, the modules listed in Puppetfile?" 16 | [ "$?" = 0 ] || exit 1 17 | 18 | echo_title "Installing gems" 19 | puppet resource package rubygems ensure=present 20 | which gem || echo "You need gem support! Install rubygems to continue successfully" 21 | echo 22 | echo_subtitle "Installing with /bin/gem" 23 | gem install deep_merge --no-ri --no-rdoc 24 | gem install hiera-eyaml --no-ri --no-rdoc 25 | gem install r10k --no-ri --no-rdoc 26 | if [ -x /opt/puppetlabs/puppet/bin/gem ]; then 27 | echo_subtitle "Installing with /opt/puppetlabs/puppet/bin/gem" 28 | /opt/puppetlabs/puppet/bin/gem install deep_merge --no-ri --no-rdoc 29 | /opt/puppetlabs/puppet/bin/gem install hiera-eyaml --no-ri --no-rdoc 30 | /opt/puppetlabs/puppet/bin/gem install r10k --no-ri --no-rdoc 31 | fi 32 | if [ -x /opt/puppetlabs/bin/puppetserver ]; then 33 | echo_subtitle "Installing with /opt/puppetlabs/bin/puppetserver" 34 | /opt/puppetlabs/bin/puppetserver gem install deep_merge 35 | /opt/puppetlabs/bin/puppetserver gem install hiera-eyaml 36 | /opt/puppetlabs/bin/puppetserver gem install r10k 37 | fi 38 | 39 | echo_title "Installing rsync" 40 | puppet resource package rsync ensure=present 41 | 42 | echo 43 | cd $repo_dir 44 | echo_title "Installing external modules via r10k" 45 | r10k puppetfile install -v 46 | echo 47 | 48 | progs="puppet vagrant docker" 49 | for prog in $progs; do 50 | echo_subtitle "Checking ${prog} availability" 51 | which $prog || echo_failure "${prog} not found. Installation is recommended." 52 | echo 53 | done 54 | -------------------------------------------------------------------------------- /bin/puppet_set_env_facts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | while [ $# -gt 0 ]; do 3 | case "$1" in 4 | --role) 5 | export FACTER_role=$2 6 | shift 2 7 | ;; 8 | --zone) 9 | export FACTER_zone=$2 10 | shift 2 11 | ;; 12 | --env) 13 | export FACTER_env=$2 14 | shift 2 15 | ;; 16 | --datacenter) 17 | export FACTER_datacenter=$2 18 | shift 2 19 | ;; 20 | --application) 21 | export FACTER_application=$2 22 | shift 2 23 | ;; 24 | *) 25 | exit 26 | ;; 27 | esac 28 | done 29 | echo "### Setting facts in bash env: role=${role} env=${env} zone=${zone} datacenter=${datacenter} application=${application}" 30 | 31 | -------------------------------------------------------------------------------- /bin/puppet_set_external_facts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | facts_dir=/etc/puppetlabs/facter/facts.d 3 | # facts_dir=$(puppet config print pluginfactdest) 4 | [ -d $facts_dir ] || mkdir -p $facts_dir 5 | while [ $# -gt 0 ]; do 6 | case "$1" in 7 | --role) 8 | role=$2 9 | shift 2 10 | ;; 11 | --zone) 12 | zone=$2 13 | shift 2 14 | ;; 15 | --env) 16 | env=$2 17 | shift 2 18 | ;; 19 | --datacenter) 20 | datacenter=$2 21 | shift 2 22 | ;; 23 | --application) 24 | application=$2 25 | shift 2 26 | ;; 27 | *) 28 | exit 29 | ;; 30 | esac 31 | done 32 | 33 | [ -d $facts_dir ] || mkdir -p $facts_dir 34 | echo "### Setting external facts role=${role} env=${env} zone=${zone} datacenter=${datacenter} application=${application}" 35 | [ -z $role ] || echo "role=${role}" > "${facts_dir}/role.txt" 36 | [ -z $zone ] || echo "zone=${zone}" > "${facts_dir}/zone.txt" 37 | [ -z $env ] || echo "env=${env}" > "${facts_dir}/env.txt" 38 | [ -z $application ] || echo "application=${application}" > "${facts_dir}/application.txt" 39 | [ -z $datacenter ] || echo "datacenter=${datacenter}" > "${facts_dir}/datacenter.txt" 40 | 41 | -------------------------------------------------------------------------------- /bin/puppet_set_trusted_facts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | which puppet 2>/dev/null 3 | if [ "x$?" == "x0" ]; then 4 | facts_dir=$(puppet config print pluginfactdest) 5 | confdir=$(puppet config print confdir) 6 | csr_file=$(puppet config print csr_attributes) 7 | else 8 | facts_dir=/opt/puppetlabs/puppet/cache/facts.d 9 | confdir=/etc/puppetlabs/puppet 10 | csr_file=/etc/puppetlabs/puppet/csr_attributes.yaml 11 | fi 12 | 13 | while [ $# -gt 0 ]; do 14 | case "$1" in 15 | --role) 16 | role=$2 17 | shift 2 18 | ;; 19 | --zone) 20 | zone=$2 21 | shift 2 22 | ;; 23 | --env) 24 | env=$2 25 | shift 2 26 | ;; 27 | --datacenter) 28 | datacenter=$2 29 | shift 2 30 | ;; 31 | --application) 32 | application=$2 33 | shift 2 34 | ;; 35 | *) 36 | exit 37 | ;; 38 | esac 39 | done 40 | 41 | [ -d $facts_dir ] || mkdir -p $facts_dir 42 | if [ ! -f $csr_file ]; then 43 | echo "### Setting trusted facts pp_role=${role} pp_environment=${env} pp_zone=${zone} pp_datacenter=${datacenter} pp_application=${application}" 44 | mkdir -p $confdir 45 | echo "---" > $csr_file 46 | echo " extension_requests:" >> $csr_file 47 | [ -z $role ] || echo " pp_role: '${role}'" >> $csr_file 48 | [ -z $zone ] || echo " pp_zone: '${zone}'" >> $csr_file 49 | [ -z $env ] || echo " pp_environment: '${env}'" >> $csr_file 50 | [ -z $datacenter ] || echo " pp_datacenter: '${datacenter}'" >> $csr_file 51 | [ -z $application ] || echo " pp_application: '${application}'" >> $csr_file 52 | fi 53 | 54 | -------------------------------------------------------------------------------- /bin/puppet_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir="$(dirname $0)/.." 3 | script_dir="$(dirname $0)" 4 | # repo_dir=$(git rev-parse --show-toplevel) 5 | . "${script_dir}/functions" 6 | 7 | PATH=/opt/puppetlabs/puppet/bin:$PATH 8 | if [ "$1" = "auto" ]; then 9 | auto=true 10 | fi 11 | 12 | install_gems() { 13 | echo_title "This script setups the Puppet environment" 14 | echo "We need the following Ruby gems: r10k, hiera-eyaml, deep_merge" 15 | [ "$auto" = "true" ] || ask_interactive "Shall we install the needed gems? Skip if you can care of them." 16 | [ "$?" = 0 ] || return 17 | 18 | echo_title "Installing gems" 19 | $sudo_command puppet resource package rubygems ensure=present 20 | which gem || echo "You need gem support! Install rubygems to continue successfully" 21 | echo 22 | echo_subtitle "Installing with gem" 23 | $sudo_command gem install deep_merge --no-ri --no-rdoc 24 | $sudo_command gem install hiera-eyaml --no-ri --no-rdoc 25 | $sudo_command gem install r10k --no-ri --no-rdoc 26 | if [ -x /opt/puppetlabs/puppet/bin/gem ]; then 27 | echo_subtitle "Installing with /opt/puppetlabs/puppet/bin/gem" 28 | $sudo_command /opt/puppetlabs/puppet/bin/gem install deep_merge --no-ri --no-rdoc 29 | $sudo_command /opt/puppetlabs/puppet/bin/gem install hiera-eyaml --no-ri --no-rdoc 30 | $sudo_command /opt/puppetlabs/puppet/bin/gem install r10k --no-ri --no-rdoc 31 | fi 32 | if [ -x /opt/puppetlabs/bin/puppetserver ]; then 33 | echo_subtitle "Installing with /opt/puppetlabs/bin/puppetserver" 34 | $sudo_command /opt/puppetlabs/bin/puppetserver gem install deep_merge 35 | $sudo_command /opt/puppetlabs/bin/puppetserver gem install hiera-eyaml 36 | $sudo_command /opt/puppetlabs/bin/puppetserver gem install r10k 37 | fi 38 | } 39 | 40 | install_rsync() { 41 | echo_title "Installing rsync" 42 | [ "$auto" = "true" ] || ask_interactive "Can we install rsync?" 43 | [ "$?" = 0 ] || return 44 | $sudo_command puppet resource package rsync ensure=present 45 | } 46 | 47 | install_modules() { 48 | cd $repo_dir 49 | echo_title "Installing external modules via r10k" 50 | [ "$auto" = "true" ] || ask_interactive "Shall we run r10k puppetfile install -v to install Puppet modules under modules/ ? We need them! :-)" 51 | [ "$?" = 0 ] || return 52 | r10k puppetfile install -v 53 | echo 54 | } 55 | 56 | install_gems 57 | install_rsync 58 | install_modules 59 | 60 | progs="puppet vagrant docker" 61 | for prog in $progs; do 62 | echo_subtitle "Checking ${prog} availability" 63 | which $prog && echo_success "${prog} found. Good!" || echo_failure "${prog} not found. Installation is recommended." 64 | echo 65 | done 66 | -------------------------------------------------------------------------------- /bin/puppet_status.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | 5 | showhelp() { 6 | cat < [--env ] [--ssh ] 10 | Available actions: 11 | resources - Lists the resources managed by Puppet on the local node 12 | last_run_summary - Show the content of /opt/puppetlabs/puppet/cache/state/last_run_summary.yaml 13 | filebucket - Show filebucketed files under /opt/puppetlabs/puppet/cache/clientbucket/ 14 | Example: $0 resources --ssh jenkins@web01 15 | HELP 16 | } 17 | 18 | # We want to live in Puppet space 19 | export PATH=/opt/puppetlabs/puppet/bin:$PATH 20 | 21 | # Configuration file of this script (not an official Puppet configuation) 22 | # Managed by psick::puppet::ci 23 | test -f /etc/puppetlabs/ci.conf && . /etc/puppetlabs/ci.conf 24 | 25 | # run_action function runs different commands according to the provided task 26 | run_action () { 27 | a=$1 28 | n=$2 29 | case "$a" in 30 | resources) 31 | echo_title "Showing Puppet managed resources on this node" 32 | $ssh_command 33 | $sudo_command cat /opt/puppetlabs/puppet/cache/state/state.yaml | grep -v "^ " | grep -v "^---$" | sort | sed 's/:$//g' 34 | $ssh_command_post 35 | ;; 36 | last_run_summary) 37 | echo_title "Showing Puppet's last run summary" 38 | $ssh_command 39 | $sudo_command cat /opt/puppetlabs/puppet/cache/state/last_run_summary.yaml 40 | $ssh_command_post 41 | ;; 42 | filebucket) 43 | echo_title "Showing files backupped in the filebucket" 44 | $ssh_command 45 | $sudo_command find /opt/puppetlabs/puppet/cache/clientbucket/ -name paths -exec sh -c 'cat "$1" | tr "\n" " " ; stat -c %y "$1" ' _ {} \; 46 | $ssh_command_post 47 | ;; 48 | *) 49 | echo_failure "Action not supported" 50 | showhelp 51 | exit 1 52 | ;; 53 | esac 54 | } 55 | 56 | # Params parsing 57 | # Check Input 58 | if [ "$#" = "0" ] ; then 59 | showhelp 60 | exit 61 | fi 62 | 63 | ssh_command='' 64 | ssh_command_post='' 65 | sudo_command='' 66 | env='production' 67 | action='showhelp' 68 | description='[CI]' 69 | while [ $# -gt 0 ]; do 70 | case "$1" in 71 | resources) 72 | action='resources' 73 | shift 74 | ;; 75 | last_run_summary) 76 | action='last_run_summary' 77 | shift 78 | ;; 79 | filebucket) 80 | action='filebucket' 81 | shift 82 | ;; 83 | --ssh) 84 | ssh_command="ssh $2 < true }" 22 | 23 | 24 | result=$? 25 | # Puppet exit codes 0 and 2 both imply an error less run 26 | if [ "x$result" == "x0" ] || [ "x$result" == "x2" ]; then 27 | echo_success "Puppet run without errors" 28 | exit 0 29 | else 30 | echo_failure "There were errors in the Puppet run" 31 | exit 1 32 | fi 33 | -------------------------------------------------------------------------------- /bin/tp_setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | PATH=$PATH:/opt/puppetlabs/puppet/bin 3 | puppet module install example42-tp 4 | puppet tp setup 5 | -------------------------------------------------------------------------------- /bin/tp_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir="$(dirname $0)/.." 3 | # repo_dir=$(git rev-parse --show-toplevel) 4 | . "${repo_dir}/bin/functions" 5 | 6 | # RegExp for whitelist of programs to not uninstall after test 7 | uninstall_whitelist='ssh|vim|lsb|puppet|mcollective|apt|puppet-agent|epel|openjdk-jdk' 8 | 9 | show_help () { 10 | echo 11 | echo "You must specify the application you want to test and the VM to use:" 12 | echo "$0 [check_mode]" 13 | echo 14 | echo "To test redis on Ubuntu1404:" 15 | echo "$0 redis Ubuntu1404" 16 | echo 17 | echo "To test redis on all running VMs:" 18 | echo "$0 redis all" 19 | echo 20 | echo "To test all apps on Ubuntu1404:" 21 | echo "$0 all Ubuntu1404 " 22 | echo 23 | echo "To test all apps on Ubuntu1404 and save acceptance tests results:" 24 | echo "$0 redis Ubuntu1404 acceptance" 25 | echo 26 | echo "To test all apps on all running VMs:" 27 | echo "$0 all all " 28 | } 29 | 30 | if [ "x$2" == "x" ]; then 31 | show_help 32 | exit 1 33 | fi 34 | 35 | app=$1 36 | vm=$2 37 | if [ "x$3" == "x" ]; then 38 | mode='default' 39 | else 40 | mode=$3 41 | fi 42 | 43 | # puppet_options="$PUPPET_OPTIONS --verbose --report --show_diff --pluginsync --summarize --modulepath '/vagrant/modules_local:/vagrant/modules:/etc/puppet/modules' " 44 | # puppet_command="sudo -i $envs puppet apply" 45 | tp_command="sudo -i tp " 46 | 47 | install() { 48 | i_app=$1 49 | i_vm=$2 50 | echo_title "Installing $i_app on $i_vm" 51 | vagrant ssh $i_vm -c "$tp_command install $i_app" 52 | } 53 | 54 | uninstall() { 55 | u_app=$1 56 | u_vm=$2 57 | if [[ "$u_app" =~ $uninstall_whitelist ]]; then 58 | echo_title "Skipping Uninstallation of $u_app on $u_vm" 59 | else 60 | echo_title "Uninstalling $u_app on $u_vm" 61 | vagrant ssh $i_vm -c "$tp_command uninstall $i_app" 62 | fi 63 | } 64 | 65 | default_check() { 66 | echo 67 | } 68 | acceptance_check () { 69 | echo_title "Running acceptance test for $1 on $2" 70 | rm -f $repo_dir/tests/app/$2/success/$1 71 | rm -f $repo_dir/tests/app/$2/failure/$1 72 | rm -f $repo_dir/tests/app/$2/na/$1 73 | vagrant ssh $2 -c "$tp_command test $1" > /tmp/tp_test_$1_$2 74 | res=$? 75 | if [ "x$res" == "x0" ]; then 76 | result='success' 77 | elif [ "x$res" == "x99" ]; then 78 | result='na' 79 | else 80 | result='failure' 81 | fi 82 | mkdir -p $repo_dir/tests/app/$2/$result 83 | mv /tmp/tp_test_$1_$2 tests/app/$2/$result/$1 84 | cat tests/app/$2/$result/$1 85 | echo_$result "## ${result}! ## Output written to tests/app/$2/${result}/$1" 86 | 87 | uninstall $1 $2 88 | } 89 | 90 | if [ "x${app}" == "xall" ]; then 91 | for a in $(ls -1 $repo_dir/modules/tinydata/data | grep -v default.yaml | grep -v test) ; do 92 | if [ "x${vm}" == "xall" ]; then 93 | for v in $(vagrant status | grep running | cut -d ' ' -f1) ; do 94 | install $a $v 95 | ${mode}_check $a $v 96 | done 97 | else 98 | install $a $vm 99 | ${mode}_check $a $vm 100 | fi 101 | done 102 | elif [ "x${vm}" == "xall" ]; then 103 | for v in $(vagrant status | grep running | cut -d ' ' -f1) ; do 104 | install $app $v 105 | ${mode}_check $app $v 106 | done 107 | else 108 | install $app $vm 109 | ${mode}_check $app $vm 110 | fi 111 | 112 | -------------------------------------------------------------------------------- /bin/travis_check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir="$(dirname $0)/.." 3 | . "${repo_dir}/bin/functions" 4 | 5 | global_exit=0 6 | 7 | run_script() { 8 | status=${2:-'required'} 9 | $1 10 | if ([ $? = 0 ] || [ $status != 'required' ]); then 11 | echo_success "OK" 12 | else 13 | echo_failure "ERROR" 14 | global_exit=1 15 | fi 16 | } 17 | 18 | cd $repo_dir 19 | 20 | # Syntax tests 21 | run_script "bundle exec rake validate" 22 | #run_script bin/puppet_check_syntax_fast.sh 23 | 24 | # Lint tests 25 | run_script "bundle exec rake lint" "optional" 26 | #run_script bin/puppet_lint.sh optional 27 | 28 | # Spec tests 29 | if [ "x$SKIP_SPEC_TESTS" == 'xtrue' ]; then 30 | echo "Skipping spec tests" 31 | else 32 | # Control repo nodes spec tests 33 | run_script "bundle exec rake spec" 34 | 35 | # Psick module spec tests 36 | cd "${repo_dir}/modules/psick" 37 | run_script "bundle exec rake spec" 38 | 39 | # Public modules spec tests 40 | # run_script "bin/puppet_check_rake.sh modules" 41 | fi 42 | 43 | if [ $global_exit == 1 ]; then 44 | echo_failure "Some checks have failed" 45 | else 46 | echo_success "All checks successfull!" 47 | fi 48 | 49 | exit $global_exit 50 | 51 | -------------------------------------------------------------------------------- /bin/vagrant_node_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | 5 | results_dir="${repo_dir}/tests/vagrant/$(date +%Y%m%d-%H%M%S)" 6 | mkdir -p $results_dir/failure 7 | mkdir -p $results_dir/success 8 | 9 | testing_branch=$(git name-rev --name-only HEAD) 10 | current_branch='production' 11 | global_exit=0 12 | node=$1 13 | env=$2 14 | action=${3:-all} 15 | exit_manage() { 16 | error=$1 17 | file=$2 18 | if [ "x${error}" != "x0" ]; then 19 | mv $results_dir/$file $results_dir/failure 20 | global_exit=1 21 | echo_failure "Failed ($error)" 22 | echo "For details: $results_dir/failure/$file" 23 | else 24 | mv $results_dir/$file $results_dir/success 25 | echo_success "Success" 26 | echo "For details: $results_dir/success/$file" 27 | echo 28 | fi 29 | } 30 | 31 | run_vagrant() { 32 | echo_title "Running vagrant ${1} on node ${2} in env ${3} - Step ${4}" 33 | output_file="${2}_${3}-$(date +%H%M%S)-${1}-${4}" 34 | 35 | $repo_dir/vagrant/bin/vm.sh "$1" "$2" "$3" | tee "${results_dir}/${output_file}" 36 | exit_manage $PIPESTATUS $output_file 37 | } 38 | 39 | # Testing sequence 40 | if [ $action == 'destroy' ]; then 41 | run_vagrant "destroy -f" $node $env "0-destroy" 42 | elif [ $action == 'halt' ]; then 43 | run_vagrant "halt -f" $node $env "0-halt" 44 | else 45 | if [ $action == 'setup' ] || [ $action == 'all' ]; then 46 | git checkout -f $current_branch 47 | git pull 48 | run_vagrant up $node $env "1-setup" 49 | run_vagrant provision $node $env "2-run-current" 50 | fi 51 | 52 | if [ $action == 'drift' ] || [ $action == 'all' ]; then 53 | git checkout -f $testing_branch 54 | run_vagrant provision $node $env "3-run-testing" 55 | fi 56 | fi 57 | exit $global_exit 58 | 59 | -------------------------------------------------------------------------------- /bin/vagrant_setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | repo_dir=$(git rev-parse --show-toplevel) 3 | . "${repo_dir}/bin/functions" 4 | 5 | puppet_options="--modulepath ${repo_dir}/site:${repo_dir}/modules:/etc/puppet/modules --environmentpath ${repo_dir}" 6 | 7 | echo_title "Going to install vagrant and the needed plugins" 8 | echo_subtitle "Executing: sudo -E puppet apply -e 'include psick_profile::vagrant'" 9 | sudo -E puppet apply $puppet_options -e 'include psick_profile::vagrant' 10 | 11 | -------------------------------------------------------------------------------- /bin/vagrant_tptest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for vm in $(vagrant status | grep running | cut -f 1 -d ' '); do 4 | echo "### ${vm} ###" 5 | vagrant ssh $vm -c '/etc/tp/test/* ; exit $?' 6 | done 7 | -------------------------------------------------------------------------------- /bolt-project.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: psick 3 | analytics: true 4 | apply-settings: 5 | evaltrace: true 6 | log_level: debug 7 | show_diff: true 8 | trace: true 9 | modules: 10 | - git: https://github.com/example42/psick-hieradata 11 | ref: production 12 | - 'example42/tp' 13 | - 'example42/tinydata' 14 | - 'example42/psick' 15 | - 'example42/psick_profile' 16 | - 'puppetlabs/concat' 17 | - 'puppetlabs/stdlib' 18 | - 'puppetlabs/vcsrepo' 19 | - 'puppetlabs/firewall' 20 | - 'puppetlabs/inifile' 21 | - 'puppetlabs/catalog_preview' 22 | - 'jdowning/rbenv' 23 | - 'trlinkin/noop' 24 | - 'puppet/archive' 25 | 26 | format: human 27 | hiera-config: "hiera.yaml" 28 | modulepath: 29 | - "site" 30 | - "modules" 31 | 32 | tasks: 33 | - tp::test 34 | - psick::puppet_* 35 | 36 | puppetdb: 37 | server_urls: ["https://puppet.lab.psick.io:8081"] 38 | cacert: /etc/puppetlabs/puppet/ssl/certs/ca.pem 39 | token: ~/.puppetlabs/token 40 | 41 | -------------------------------------------------------------------------------- /docker/config: -------------------------------------------------------------------------------- 1 | # Configurations here are done setting Puppet facts via environment variables: 2 | 3 | # Working directory (where dockerfiles are generated) 4 | export FACTER_docker_workdir="$(pwd)/dockerfiles" 5 | 6 | # Docker config dir 7 | export FACTER_docker_config="${HOME}/.docker" 8 | -------------------------------------------------------------------------------- /docker/env/alpine3: -------------------------------------------------------------------------------- 1 | # Alpine3 facts 2 | export FACTER_docker_os=alpine 3 | export FACTER_docker_osversion=3.3 4 | export FACTER_osfamily=Linux 5 | export FACTER_operatingsystem=Alpine 6 | export FACTER_operatingsystemmajrelease=3.3 7 | 8 | -------------------------------------------------------------------------------- /docker/env/centos6: -------------------------------------------------------------------------------- 1 | # Centos6 facts 2 | export FACTER_docker_os=centos 3 | export FACTER_docker_osversion=6 4 | export FACTER_osfamily=RedHat 5 | export FACTER_operatingsystem=CentOS 6 | export FACTER_operatingsystemmajrelease=6 7 | 8 | -------------------------------------------------------------------------------- /docker/env/centos7: -------------------------------------------------------------------------------- 1 | # Centos7 facts 2 | export FACTER_docker_os=centos 3 | export FACTER_docker_osversion=7 4 | export FACTER_osfamily=RedHat 5 | export FACTER_operatingsystem=CentOS 6 | export FACTER_operatingsystemmajrelease=7 7 | 8 | -------------------------------------------------------------------------------- /docker/env/debian7: -------------------------------------------------------------------------------- 1 | # Debian 7 facts 2 | export FACTER_docker_os=debian 3 | export FACTER_docker_osversion=7 4 | export FACTER_osfamily=Debian 5 | export FACTER_operatingsystem=Debian 6 | export FACTER_operatingsystemmajrelease=7 7 | -------------------------------------------------------------------------------- /docker/env/debian8: -------------------------------------------------------------------------------- 1 | # Debian 8 facts 2 | export FACTER_docker_os=debian 3 | export FACTER_docker_osversion=8 4 | export FACTER_osfamily=Debian 5 | export FACTER_operatingsystem=Debian 6 | export FACTER_operatingsystemmajrelease=8 7 | -------------------------------------------------------------------------------- /docker/env/redhat6: -------------------------------------------------------------------------------- 1 | # RedHat6 facts 2 | export FACTER_docker_os=centos # TODO: find RH image 3 | export FACTER_docker_osversion=6 4 | export FACTER_osfamily=RedHat 5 | export FACTER_operatingsystem=RedHat 6 | export FACTER_operatingsystemmajrelease=6 7 | 8 | -------------------------------------------------------------------------------- /docker/env/redhat7: -------------------------------------------------------------------------------- 1 | # RedHat7 facts 2 | export FACTER_docker_os=centos # TODO 3 | export FACTER_docker_osversion=7 4 | export FACTER_osfamily=RedHat 5 | export FACTER_operatingsystem=RedHat 6 | export FACTER_operatingsystemmajrelease=7 7 | 8 | -------------------------------------------------------------------------------- /docker/env/ubuntu1204: -------------------------------------------------------------------------------- 1 | # Ubuntu 12.04 facts 2 | export FACTER_docker_os=ubuntu 3 | export FACTER_docker_osversion=12.04 4 | export FACTER_osfamily=Debian 5 | export FACTER_operatingsystem=Ubuntu 6 | export FACTER_operatingsystemmajrelease=12.04 7 | 8 | -------------------------------------------------------------------------------- /docker/env/ubuntu1404: -------------------------------------------------------------------------------- 1 | # Ubuntu 14.04 facts 2 | export FACTER_docker_os=ubuntu 3 | export FACTER_docker_osversion=14.04 4 | export FACTER_osfamily=Debian 5 | export FACTER_operatingsystem=Ubuntu 6 | export FACTER_operatingsystemmajrelease=14.04 7 | 8 | -------------------------------------------------------------------------------- /docker/env/ubuntu1604: -------------------------------------------------------------------------------- 1 | # Ubuntu 16.04 facts 2 | export FACTER_docker_os=ubuntu 3 | export FACTER_docker_osversion=16.04 4 | export FACTER_osfamily=Debian 5 | export FACTER_operatingsystem=Ubuntu 6 | export FACTER_operatingsystemmajrelease=16.04 7 | 8 | -------------------------------------------------------------------------------- /docker/hiera.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | :backends: 3 | - yaml 4 | 5 | :hierarchy: 6 | - "role/%{::role}" 7 | # - common 8 | 9 | :yaml: 10 | :datadir: "../hieradata" 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/change_process.md: -------------------------------------------------------------------------------- 1 | ## Puppet change process 2 | 3 | Delivery of `Puppet code` and `data`, from `Puppet Server` and users to production can be done in several different ways. 4 | 5 | They ultimately depend on each site policies and procedures, but it's still possible to summarise the needed steps and procedures. 6 | 7 | From `Puppet` developer workstation to real `puppet run` on managed nodes we can identify at least these steps, more or less mandatory, applicable, desired or needed: 8 | 9 | - [DevStation] Work on `control-repo:` data, local site profile or managed external modules. 10 | - [DevStation] [GitServer] [WebGUI] Manage `Puppet` [hiera] data 11 | - [DevStation] Interactive development and tests on local VMs. 12 | - [DevStation] [CI] Syntax checks 13 | - [DevStation] [CI] Run `unit` and `integration tests`. 14 | - [CI] [WebGUI] Trigger `Puppet runs` on selected nodes 15 | - [CIGUI] [GitServer] Review `CI` tests 16 | - [GitServer] Discuss and review code changes requests 17 | - [WebGUI] Check `Puppet infrastructure` status and reports 18 | - [CI] [GitServer] [WebGUI] Manage code promotion to `production` `environment/branch` 19 | - [CI] [WebGUI] [GitServer] Manage `control-repo` deployment on `Puppet Servers` 20 | 21 | [TODO] Complete 22 | -------------------------------------------------------------------------------- /docs/compile_masters.md: -------------------------------------------------------------------------------- 1 | 2 | Manual 3 | -------------------------------------------------------------------------------- /docs/external_facts.md: -------------------------------------------------------------------------------- 1 | ## Puppet external facts 2 | 3 | There are 3 ways to add our **own facts** in `Puppet`: 4 | 5 | - Writing our **custom facts**, in `Ruby language` and adding them to the ```lib/facter``` directory of a module. [Details here](https://puppet.com/docs/facter/latest/custom_facts.html) 6 | 7 | - Adding **trusted facts** in ```csr_attributes.yaml``` as described in [this document](trusted_facts.md) 8 | 9 | - Adding **external facts**, written in `plain text` or as `executables` in **any language**. Details below: 10 | 11 | External facts are placed in these directories: 12 | 13 | On Linux/*nix: 14 | /opt/puppetlabs/facter/facts.d/ 15 | /etc/puppetlabs/facter/facts.d/ 16 | /etc/facter/facts.d/ 17 | 18 | On Windows: 19 | C:\ProgramData\PuppetLabs\facter\facts.d\ 20 | 21 | They are simple files that can have different formats: 22 | 23 | - Simple `*.txt` files. Facts names and their values are in [.ini file format](https://en.wikipedia.org/wiki/INI_file): 24 | 25 | role=webserver 26 | env=prod 27 | zone=berlin 28 | 29 | - `Yaml` files, with `.yaml` extension: 30 | 31 | --- 32 | role: webserver 33 | env: prod 34 | zone: berlin 35 | 36 | - `Json` files, with `.json` extension: 37 | 38 | { 39 | "role": "webserver", 40 | "env": "prod", 41 | "zone": "berlin", 42 | } 43 | 44 | - Any `command` in any language. On Linux/*nix the file, with whatever extension, just has to be `executable`. On `Windows` it must have `.com`, `.exe`, `.bat`, `.cmd`, `.ps1` extension. The `command` should just output the `fact` **name(s)** and its/their **values**: 45 | 46 | #!/bin/bash 47 | echo "role=webserver" 48 | echo "env=prod" 49 | echo "zone=berlin" 50 | 51 | The files we create on client in the ```facts.d``` directory can provide one or more facts values, and they can have any name. Typically, for data files that provide just one fact, the file name is the name of the fact: 52 | 53 | cat /etc/puppetlabs/facter/facts.d/role.txt 54 | role=webserver 55 | 56 | `External facts` can be deployed during provisioning of the server or can be placed in the ```facts.d``` directory of a module (they are ```pluginsynced``` automatically to the client at the beginning of each `Puppet run`). 57 | 58 | `External facts` are a very easy way to set custom facts on nodes, just consider the following points: 59 | 60 | - They can be potentially changed on the client just by editing the relevant fact. We may prefer to use [trusted facts](trusted_facts.md) when we want their values to be immutable. 61 | 62 | - If we use the ```pluginsync``` functionality to distribute them **note** that they are copied as is, from `Puppet Server` to clients, so we don't have a way to distribute different facts to different clients. For this reason we'll probably find ourselves adding facts to the clients that just contain data (`.txt`, `.yaml`, `.json`) in some alternative way (typically during the node's provisioning) and use [pluginsync](https://puppet.com/docs/puppet/5.3/plugins_in_modules.html#technical-details-of-pluginsync) only for the ones that **compute the result** in some way (as executables ones do). 63 | -------------------------------------------------------------------------------- /docs/modules_list/example42modules.txt: -------------------------------------------------------------------------------- 1 | # Example42 modules conversion list 2 | # + Module data migrated to tp 3 | # - Module won't be migrated and will be removed for Ex42 modules 3.x 4 | # = Module will remain on Ex42 5 | # ! Module deprecated 6 | # (name) maintainer 7 | # (name!) maintainer in own repo 8 | # [FORK] module was a fork on a third party module 9 | 10 | !+activemq (gwarf) 11 | !+=apache (gwarf) 12 | +=apt (sathieu, gwarf) 13 | !-auth (gwarf) 14 | !+autofs (shellfu) 15 | +bacula (netmanagers!) 16 | +bind (netmanagers!) 17 | +bluepill (mburger!) 18 | !-bundler 19 | !+ceilometer 20 | !+ceph 21 | !+cinder 22 | !+clvm 23 | !+collectd 24 | !+corosync 25 | +ddclient (netmanagers!) 26 | !+dhcpd 27 | !-django 28 | +dnsmasq (netmanagers!) 29 | !+dovecot 30 | !+elasticsearch 31 | !+exim 32 | +fail2ban (netmanagers!) 33 | !-firewall 34 | !-foreman (ricciocri) 35 | !+freeradius 36 | !=git 37 | !+glance 38 | !+graylog2 39 | !+haproxy 40 | !+heartbeat 41 | !=hosts 42 | !+icinga 43 | !+icinga2 [FORK] 44 | !=iptables 45 | !=java (gwarf) 46 | !+jboss (gwarf) 47 | !+jenkins 48 | !+keystone 49 | !-kibana 50 | !+libvirt 51 | !+lighttpd 52 | !=limits 53 | !+logrotate (gwarf) 54 | !+logstash 55 | !+lsb 56 | !+mailx 57 | !+mariadb 58 | !-maven [FORK] 59 | !+mcollective (gwarf) 60 | !+memcached 61 | !+mongodb 62 | !+monit (ricciocri) 63 | !-monitor 64 | !+msmtp 65 | !+multipath 66 | !+munin (gwarf) 67 | !+mysql (lermit, gwarf) 68 | !+nagios 69 | =network 70 | !+newrelic 71 | !+nfs 72 | +nginx (netmanagers!) 73 | !+nova 74 | !+nrpe 75 | !+ntp (gwarf) 76 | -nut (netmanagers!) 77 | !+openntpd 78 | !+openssh 79 | !+openvpn 80 | !+openvswitch 81 | !+orientdb 82 | !+pacemaker 83 | !+pam 84 | !-pentaho 85 | !=perl 86 | !+=php (gwarf) 87 | !+postfix (amateo, shellfu) 88 | !+postgresql (gwarf) 89 | !+profile 90 | !+proftpd 91 | !+puppet (gwarf) 92 | !-puppetdashboard (gwarf) 93 | !+puppetdb (gwarf) 94 | !+quagga 95 | !+quantum 96 | !+=rabbitmq 97 | !=rclocal 98 | !+redis 99 | !=resolver 100 | !-rhcs 101 | !+rsync 102 | !-rsyncssh 103 | !+rsyslog 104 | !-ruby 105 | !-rvm 106 | !+samba 107 | !-scmserver 108 | !+sendmail 109 | !+snmpd 110 | !-=solr 111 | !-=splunk 112 | !+ssmtp 113 | !=sudo (gwarf) 114 | !=svn 115 | !=sysctl (gwarf) 116 | !+sysklogd 117 | !+syslogng (renamed to syslog-ng) 118 | +sysstat (bmcclure!) 119 | !-tartarus 120 | -=tcpwrappers (netmanagers!) 121 | !+tftp 122 | !=timezone (gwarf) 123 | !+tinc 124 | !=tomcat (ricciocri) 125 | !-unicorn (shellfu) 126 | !=user 127 | !-vagrant 128 | +varnish (netmanagers!) 129 | !+vim 130 | !+vsftpd (gwarf) 131 | !=wget 132 | !-wordpress 133 | !+xinetd 134 | =yum (shellfu, gwarf) 135 | !+zabbix_agent (renamed to zabbix-agent) (shellfu) 136 | !c-zip 137 | -------------------------------------------------------------------------------- /docs/modules_list/list_3rd.txt: -------------------------------------------------------------------------------- 1 | stdlib 2 | concat 3 | vcsrepo 4 | 5 | -------------------------------------------------------------------------------- /docs/modules_list/list_deprecated.txt: -------------------------------------------------------------------------------- 1 | auth 2 | bacula 3 | bind 4 | bluepill 5 | bundler 6 | ceilometer 7 | ceph 8 | cinder 9 | clvm 10 | collectd 11 | corosync 12 | ddclient 13 | dhcpd 14 | django 15 | dnsmasq 16 | dovecot 17 | elasticsearch 18 | exim 19 | fail2ban 20 | firewall 21 | foreman 22 | freeradius 23 | glance 24 | graylog2 25 | haproxy 26 | heartbeat 27 | icinga 28 | icinga2 29 | jenkins 30 | keystone 31 | kibana 32 | libvirt 33 | lighttpd 34 | logstash 35 | lsb 36 | mailx 37 | maven 38 | mcollective 39 | memcached 40 | mongodb 41 | monitor 42 | monit 43 | msmtp 44 | multipath 45 | munin 46 | nagios 47 | newrelic 48 | nfs 49 | nginx 50 | nova 51 | ntp 52 | nut 53 | openntpd 54 | openssh 55 | openvpn 56 | openvswitch 57 | orientdb 58 | pacemaker 59 | pam 60 | pentaho 61 | proftpd 62 | puppetdashboard 63 | quagga 64 | quantum 65 | redis 66 | rhcs 67 | rsync 68 | rsyncssh 69 | rsyslog 70 | ruby 71 | rvm 72 | samba 73 | scmserver 74 | sendmail 75 | snmpd 76 | solr 77 | splunk 78 | ssmtp 79 | sysklogd 80 | syslogng 81 | tartarus 82 | tcpwrappers 83 | tftp 84 | tinc 85 | unicorn 86 | vagrant 87 | varnish 88 | vim 89 | vsftpd 90 | wget 91 | wordpress 92 | xinetd 93 | zabbix_agent 94 | zip 95 | -------------------------------------------------------------------------------- /docs/modules_list/list_deprecated2.txt: -------------------------------------------------------------------------------- 1 | activemq 2 | apache 3 | autofs 4 | git 5 | hosts 6 | iptables 7 | java 8 | jboss 9 | limits 10 | logrotate 11 | mariadb 12 | mysql 13 | nrpe 14 | perl 15 | php 16 | postfix 17 | postgresql 18 | profile 19 | puppet 20 | puppetdb 21 | puppi 22 | rabbitmq 23 | rclocal 24 | resolver 25 | sudo 26 | svn 27 | sysctl 28 | sysstat 29 | timezone 30 | tomcat 31 | user 32 | -------------------------------------------------------------------------------- /docs/modules_list/list_ex42.txt: -------------------------------------------------------------------------------- 1 | activemq 2 | apache 3 | apt 4 | collectd 5 | dovecot 6 | elasticsearch 7 | exim 8 | foreman 9 | git 10 | haproxy 11 | hosts 12 | icinga 13 | iptables 14 | java 15 | jboss 16 | kibana 17 | logstash 18 | mariadb 19 | mcollective 20 | monit 21 | monitor 22 | mysql 23 | nrpe 24 | ntp 25 | php 26 | postfix 27 | postgresql 28 | puppet 29 | puppetdashboard 30 | puppetdb 31 | puppi 32 | rabbitmq 33 | rsyslog 34 | ruby 35 | snmpd 36 | solr 37 | sudo 38 | sysctl 39 | timezone 40 | tinc 41 | vim 42 | -------------------------------------------------------------------------------- /docs/modules_list/list_extra.txt: -------------------------------------------------------------------------------- 1 | Example42-documentation 2 | Example42-templates 3 | Example42-tools 4 | Example42-tutorials 5 | example42 6 | exported_vars 7 | extlib 8 | module_data 9 | pupmod-concat 10 | puppet-skeleton-standard42 11 | stdmod 12 | 13 | -------------------------------------------------------------------------------- /docs/modules_list/list_maintained.txt: -------------------------------------------------------------------------------- 1 | apt 2 | puppi 3 | tinydata 4 | tp 5 | yum 6 | -------------------------------------------------------------------------------- /docs/modules_list/list_puppet4.txt: -------------------------------------------------------------------------------- 1 | ansible 2 | apache 3 | docker 4 | icinga 5 | puppet 6 | rails 7 | -------------------------------------------------------------------------------- /docs/pe_console.md: -------------------------------------------------------------------------------- 1 | - [Puppet Enterprise Console](#puppet-enterprise-console) 2 | - [Infrastructure awareness](#infrastructure-awareness) 3 | - [Dashboard](#dashboard) 4 | - [Reports](#reports) 5 | - [Nodes](#nodes) 6 | 7 | ## Puppet Enterprise Console 8 | 9 | `Puppet Enterprise` (PE) provides a web console which can be used for different purposes: 10 | 11 | - Classify nodes in the **Node Classifier**, pinning single nodes or setting matching rules to assign a node to a `Node groups` and defining for each `Node Group` the list of classes and parameters to include. Nodes classification via the console is not mandatory, and actually in our base setup it's not used. 12 | 13 | - Check and review the `Puppet run` reports for all our nodes, having insights on what has changed in the infrastructure. 14 | 15 | - Have an overview on the healthiness of the infrastructure and insights on what's failing. 16 | 17 | - Manage `Puppet job tasks`. 18 | 19 | - Have an inventory of the facts of all the managed systems. 20 | 21 | ### Infrastructure awareness 22 | 23 | The `PE console` provides direct access to all the data generated by `Puppet` and stored on `PuppetDB`. 24 | 25 | ### Dashboard 26 | 27 | One of the most useful features of the `PE console` is the `Dashboard`, here we have an immediate overview on the status and the health of the infrastructure. 28 | 29 | We can see the nodes where `Puppet` is running for real, the ones where it's running in **noop mode** (`Puppet runs`, shows the changes it would do, but it doesn't actually perform any modification on the system), and the ones which are **not reporting** (`Puppet` has not run on the node, or has not reported back to the server, for more than one hour (default setting)). 30 | 31 | We have also the list of the latest reports, where we can see the total number of managed resources, the number or resources changed for a change in our code (**intentional changes**), which ones were changed because `Puppet` brought resource back to the desired state, after some local manual modification (**corrective changes**), the resources which failed and the total time spent by the `Puppet Server` to compile the catalog (**configuration retrieval**). 32 | 33 | ### Reports 34 | 35 | Clicking on a report date, it's possible to see the full details of the relevant `Puppet` transaction with all the managed resources and the occurred events, with the possibility to drill down to the specific line of code where the failure occurred. 36 | 37 | ### Nodes 38 | 39 | Clicking on a node name, we can see the detail page for that node, here, on the different tabs, we can access to a lot of information about the node: 40 | 41 | - The full list of the node's facts 42 | - All the saved reports and events for the node 43 | - The list of classes and parameters which are used on the node (**NOTE:** only the ones deriving from the classification on `PE console` are included, classes included in `Puppet code`, on via `Hiera`, are not listed here) 44 | - A graph with al the relationships among the node's resources 45 | -------------------------------------------------------------------------------- /docs/prerequisites.md: -------------------------------------------------------------------------------- 1 | - [Prerequisites](#prerequisites) 2 | - [Single Modules](#single-modules) 3 | - [Control repo](#control-repo) 4 | - [Vagrant](#vagrant) 5 | - [Docker](#docker) 6 | 7 | ## Prerequisites 8 | 9 | To have a fully working environment we might need to locally install some software for specific activities. 10 | 11 | We can simply run ```bin/setup.sh``` to install them via `Puppet` or just can do that manually, as follows. 12 | 13 | ### Single Modules 14 | 15 | All the modules have a ```metadata.json``` file where dependencies are described. 16 | 17 | Most of the modules require `PuppetLabs' stdlib`. 18 | 19 | ### Control repo 20 | 21 | To be able to use the `control-repo` with `Puppet` some gems are needed and modules defined in the ```Puppetfile``` have to be deployed. 22 | 23 | The `hiera-eyaml`, `r10k` and `deep_merge` gems can be installed by the setup script or manually with commands like: 24 | 25 | # Gem installation in system 26 | gem install hiera-eyaml 27 | gem install r10k 28 | gem install deep_merge 29 | 30 | # Gem installation in Puppet environment 31 | /opt/puppetlabs/puppet/bin/gem install hiera-eyaml 32 | /opt/puppetlabs/puppet/bin/gem install r10k 33 | /opt/puppetlabs/puppet/bin/gem install deep_merge 34 | 35 | # Gem installation in Puppet server environment (if present) 36 | /opt/puppetlabs/bin/puppetserver gem install hiera-eyaml 37 | /opt/puppetlabs/bin/puppetserver gem install r10k 38 | /opt/puppetlabs/bin/puppetserver gem install deep_merge 39 | 40 | Population of the ```modules``` directory via ```r10k``` based on ```Puppetfile```: 41 | 42 | r10k puppetfile install -v 43 | 44 | The above steps can be accomplished by simply running ```bin/puppet_setup.sh```. 45 | 46 | 47 | ### Vagrant 48 | 49 | For a correct setup of the `Vagrant` environment we need `Vagrant`, `VirtualBox` and some extra plugins: 50 | 51 | vagrant plugin install vagrant-cachier 52 | vagrant plugin install vagrant-vbguest 53 | vagrant plugin install vagrant-hostmanager 54 | 55 | These plugins, as `Vagrant` itself, can be installed by the ```bin/setup.sh``` script. 56 | 57 | ### Docker 58 | 59 | `Docker` operations via the command line require `Docker` to be locally installed. 60 | 61 | If we use `Mac` or `Windows` we need the newer native client, things won't work when using `Docker` running inside a `Virtualbox VM`. 62 | 63 | You'll need to run ```docker login``` before trying any operation that involves pushing our images to `Docker registry`. 64 | 65 | Also `Docker` can be installed by the ```bin/setup.sh``` script. 66 | -------------------------------------------------------------------------------- /docs/structure.md: -------------------------------------------------------------------------------- 1 | ## Control repo structure 2 | 3 | The common elements of a `control-repo` are: 4 | 5 | - The ```manifests``` directory where are placed the first files that the `Puppet Server` parses when compiling catalogs for clients. Here we typically have the ```site.pp``` file (but other manifests with different names can be seamlessly added) where we can set [Top scope variables](https://docs.puppet.com/puppet/latest/lang_scope.html), [Resource Defaults](https://docs.puppet.com/puppet/latest/lang_defaults.html), and eventually have [Node statements](https://docs.puppet.com/puppet/latest/lang_node_definitions.html) to define what classes should be included in our nodes (nodes classification can be done in several different ways, using the ```node``` statement is just one of them, which, incidentally, is not used here). 6 | - The ```hieradata``` or ```data``` directory which contains [Hiera](https://docs.puppet.com/hiera/latest/) data files. The name of the directory is completely arbitrary and must match what's defined in ```hiera.yaml```. On some `control-repos` we may not have such a directory (in the rare case `Hiera` is not used, or uses external backends or its data is stored in a separated repository). In our case `Hiera` is used with the popular **Eyaml backend**, which allows storage of data in `YAML` files and the possibility to encrypt some key. The `Hiera` data files in `YAML` format are placed in the ```data``` directory. 7 | - The ```modules``` directory contains `Puppet modules`. Typically we don't place themselves directly in our `control-repo` but define them in the ```Puppetfile``` and then deploy them with tools like [r10k](https://github.com/puppetlabs/r10k) or [Librarian Puppet](https://github.com/voxpupuli/librarian-puppet). 8 | - Besides the ones in public modules, we need to create custom classes where we customize resources to fit our needs. In this `control-repo` they are placed in the ```site``` directory, here we have a `profile` module with all our profiles (the `Puppet classes` that actually manage different kind of services and software), and a `tools` module, mostly containing `Puppet` [defines](https://docs.puppet.com/puppet/latest/lang_defined_types.html) used in our profiles. 9 | - The ```environment.conf``` file, which configures our environment: where the modules are placed, the caching timeout and eventually a script that returns a custom configuration version. 10 | 11 | 12 | Besides these common locations, in our `control-repo` we have also: 13 | 14 | - The ```vagrant``` directory contains different `Vagrant` environments with the relevant toolset that can be used to test the same `control-repo`. They are fully customizable by editing the ```config.yaml``` file in each `Vagrant` environment. 15 | - Files for building `Docker images` locally are under the ```docker``` directory. 16 | - Documentation is stored under ```docs``` 17 | - The ```bin``` directory contains several scripts for various purposes. 18 | -------------------------------------------------------------------------------- /docs/toc-modules.txt: -------------------------------------------------------------------------------- 1 | README.md 2 | classes_modules.md 3 | -------------------------------------------------------------------------------- /docs/toc-process.txt: -------------------------------------------------------------------------------- 1 | git.md 2 | change_process.md 3 | change_impact.md 4 | change_process_integration.md 5 | -------------------------------------------------------------------------------- /docs/toc-puppet.txt: -------------------------------------------------------------------------------- 1 | puppet.md 2 | hiera.md 3 | hiera_eyaml.md 4 | trusted_facts.md 5 | external_facts.md 6 | pe_console.md 7 | -------------------------------------------------------------------------------- /docs/toc-use.txt: -------------------------------------------------------------------------------- 1 | README.md 2 | structure.md 3 | use.md 4 | prerequisites.md 5 | noop_mode.md 6 | vagrant.md 7 | docker.md 8 | -------------------------------------------------------------------------------- /docs/toc.txt: -------------------------------------------------------------------------------- 1 | README.md 2 | structure.md 3 | puppet.md 4 | hiera.md 5 | hiera_eyaml.md 6 | trusted_facts.md 7 | external_facts.md 8 | pe_console.md 9 | use.md 10 | prerequisites.md 11 | noop_mode.md 12 | vagrant.md 13 | docker.md 14 | classes.md 15 | git.md 16 | change_process.md 17 | change_impact.md 18 | change_process_integration.md 19 | -------------------------------------------------------------------------------- /docs/trusted_facts.md: -------------------------------------------------------------------------------- 1 | ## Trusted facts 2 | 3 | Extensions to a node certificate can de defined for each `Puppet` managed node in order to define informations that **can't be changed** unless the same node certificate is recreated. 4 | 5 | These settings are defined `trusted facts`, for this reason and are the most secure way to set facts on a node which don't rely of some computation but just define some characteristics of the node itself (as its `role`, operational `environment` or other). 6 | 7 | **Before** the first execution of `Puppet` on the node edit ```/etc/puppetlabs/puppet/csr_attributes.yaml``` with a content like: 8 | 9 | --- 10 | extension_requests: 11 | pp_role: 'fe' 12 | pp_environment: 'devel' 13 | pp_datacenter: 'main' 14 | pp_application: 'voicemail' 15 | 16 | The first `Puppet` run should be done after this file has been generated. 17 | 18 | Once created, `trusted facts` can be accessed in `Puppet code` with a syntax like: 19 | 20 | $trusted['extensions']['pp_role'] 21 | 22 | **NOTE:** that once a `trusted fact` is set, that can't be changed unless the client's certificate is recreated. This means, for example, that before changing the environment of a server (if ever needed) a (eventually manual) client re-certification has to be done. 23 | 24 | In case of SSL errors always usual procedures apply: 25 | 26 | - Check times on client and server are synced 27 | - Eventually clean old certs with same name on client and server 28 | - Google 29 | 30 | For more information: [SSL configuration: CSR attributes and certificate extensions](https://docs.puppet.com/puppet/latest/reference/ssl_attributes_extensions.html) 31 | 32 | **NOTE:** that once a `trusted fact` is set, that can't be changed unless the client's certificate is recreated. This means, for example, that before changing the environment of a server (if ever needed) a (eventually manual) client re-certification has to be done. 33 | 34 | In this `control-repo` if `trusted facts` such facts are defined, they are used to populate `top scope` variables which are then used in ```hiera.yaml``` hierarchy. 35 | 36 | The `top scope` variables are defined in ```manifests/site.pp``` as follows: 37 | 38 | if $trusted['extensions']['pp_role'] { 39 | $role = $trusted['extensions']['pp_role'] 40 | } 41 | if $trusted['extensions']['pp_environment'] { 42 | $env = $trusted['extensions']['pp_environment'] 43 | } 44 | if $trusted['extensions']['pp_datacenter'] { 45 | $zone = $trusted['extensions']['pp_datacenter'] 46 | } 47 | 48 | In ```hiera.yaml``` are then used these variables in the sample hierarchy: 49 | 50 | paths: 51 | - "nodes/%{trusted.certname}.yaml" 52 | - "role/%{::role}-%{::env}.yaml" 53 | - "role/%{::role}.yaml" 54 | - "zone/%{::zone}.yaml" 55 | - "common.yaml" 56 | -------------------------------------------------------------------------------- /docs/use.md: -------------------------------------------------------------------------------- 1 | ## Using and understanding this control-repo 2 | 3 | The default design of this `control-repo` is based on a nodeless classification, driven by `top scope` variables like these: 4 | 5 | - ```$::role``` - Defines the nodes' `role` 6 | - ```$::env``` - Defines the nodes' operational `environment` 7 | - ```$::zone``` - Defines the `datacenter` or `region`, or `segment` of an infrastructure **(optional)** 8 | 9 | Variable names and area of interest can be adapted, according to our hierarchy in ```hiera.yaml``` but in any case such variables **have to be set** in some ways. 10 | 11 | There are different ways to set `top scope` variables: 12 | 13 | - As **[trusted facts](trusted_facts.md)**, set on the client **before** `Puppet` installation 14 | 15 | - As **[external facts](external_facts.md)**, writing the relevant files on the client under ```/etc/puppetlabs/facter/facts.d``` 16 | 17 | - As global parameters set in a [**ENC**](https://puppet.com/docs/puppet/latest/nodes_external.html) (such as [Puppet Enterprise](https://puppet.com/products/puppet-enterprise) or [The Foreman](https://www.theforeman.org/)). 18 | 19 | - On `Puppet Server` in ```manifests/site.pp``` as result of the parsing of the hostname or other facts. 20 | 21 | The latter case is possible when we have hostnames with a fixed pattern which contains information about the `role`, `env`, `zone` or whatever needed for grouping. 22 | 23 | For example if we have nodes with a naming pattern like: ```$role-$id-$env.$::networking['domain']``` (ie: ```fe-01-test.example42.com```) we can have set `top scope` variables in ```manifests/site.pp``` (outside any class or node statement): 24 | 25 | $node_array = split($::networking['hostname'],'-') 26 | $role = $node_array[0] 27 | $id = $node_array[1] 28 | $env = $node_array[2] 29 | 30 | These variables are used in the `Hiera's` hierarchy (check ```hiera.yaml```) and should be enough to classify univocally any node in a averagely complex infrastructure. Here they are set as `external facts` (you'll need to set them when provisioning your nodes, as it's done in the `Vagrant` environment). 31 | 32 | Such an approach can be easily adapted to any other logic and environment, for example, you can use an `External Node Classifier` (ENC) like `Puppet Enterprise` or `The Foreman` and manage there how your nodes are classified. 33 | 34 | The manifests file, ```manifests/site.pp``` sets some resource defaults and just includes the `psick` module, which manages nodes classification and provides profiles for common use cases. 35 | 36 | All the `Hiera data` is in ```hieradata``` , the file ```hiera.yaml``` shows a possible hierarchy design and uses `hiera-eyaml` as backend for keys encryption (no key is currently encrypted, because we are not shipping the generated private key (it's in ```.gitignore```). 37 | 38 | You will have to regenerate your `hiera-eyaml` keys (run, from the main repo dir, ```eyaml createkeys```). 39 | -------------------------------------------------------------------------------- /docs/workflow.md: -------------------------------------------------------------------------------- 1 | - [Setup of the control-repo](#setup-of-the-control-repo) 2 | - [Just playing around](#just-playing-around) 3 | - [Forking example42's control repo](#forking-example42s-control-repo) 4 | - [Starting from scratch](#starting-from-scratch) 5 | - [Testing your code](#testing-your-code) 6 | - [On live servers](#on-live-servers) 7 | - [With Docker](#with-docker) 8 | - [With Vagrant](#with-vagrant) 9 | - [Managing Puppet code deployment and runs](#managing-puppet-code-deployment-and-runs) 10 | 11 | 12 | ### Setup of the control-repo 13 | 14 | You can follow alternative approaches on how to play or work with this `control-repo`, eventually with the intention to customise it for your own use. 15 | 16 | #### Just playing around 17 | 18 | The quickest way to start to play around: 19 | 20 | git clone https://github.com/example42/psick 21 | cd psick 22 | bin/setup.sh 23 | 24 | #### Forking example42's control repo 25 | 26 | You can [fork](https://help.github.com/articles/fork-a-repo/) `PSICK` [control-repo](https://github.com/example42/psick) on `GitHub` and then work on your fork as `origin` and add example42 repo as `upstream`, in order to ease (always welcomed) `Pull Requests` for issues of features: 27 | 28 | git clone https://github.com//psick 29 | cd psick 30 | git remote add upstream https://github.com/example42/psick 31 | 32 | #### Starting from scratch 33 | 34 | If you want to start a `Git repo` from scratch, wiping out the history (and the ability to easily merge back) of `example42 control-repo`, you can: 35 | 36 | git clone https://github.com/example42/psick 37 | 38 | You will be asked the name of the directory where to create the new `Git repository`. It's placed on the same parent dir of the original `control-repo`. 39 | 40 | Once done, you can move into the new directory, with only a branch, called ```production``` and no commits. 41 | 42 | Select the files to keep or remove, then commit them all 43 | 44 | git commit -a -m "Repo based on https://github.com/example42/psick" 45 | 46 | Now you can set the `origin` push your repo to an empty existing repo you have created on `GitHub/Bitbucket/GitLab/...` : 47 | 48 | git remote add origin git@github.com:example42/psick.git 49 | git push -u origin --all 50 | 51 | 52 | #### With Vagrant 53 | 54 | There are different `Vagrant` environment available. You can pick any of them, like the ```lab``` one to test your own different roles. 55 | 56 | First review and edit the configuration file for the `Vagrant` environment 57 | 58 | vi vagrant/environments/lab/config.yaml 59 | 60 | Then either run `vagrant commands` from the relevant repo: 61 | 62 | cd vagrant/environments/lab 63 | vagrant status 64 | vagrant up 65 | vagrant provision 66 | -------------------------------------------------------------------------------- /environment.conf: -------------------------------------------------------------------------------- 1 | # The environment configuration file 2 | 3 | # The main manifest directory or file where Puppet starts to evaluate code 4 | # This is the default value. Works with just a site.pp file or any other .pp 5 | manifest = manifests/ 6 | 7 | # The directories added to the module path, looked in first match first used order: 8 | # site - The local site modules, included in this control-repo 9 | # modules - Directory for external modules, populated by r10k based on Puppetfile 10 | # $basemodulepath - As from: puppet config print basemodulepath 11 | modulepath = site:modules:$basemodulepath 12 | 13 | # Set the cache timeout for this environment 14 | 15 | # Example to always cache catalogs (better perfs in high traffic systems): 16 | # environment_timeout = unlimited 17 | 18 | # Note: unlimited caching requires that whenever changes thePuppet code and data 19 | # to serve to clients, the cache is flushed. This is done by Code Manager on PE 20 | # or any workflow that flushes caches at every deployment. 21 | # This can also be done manually running: bin/puppet_flush_environment_cache.sh 22 | 23 | # Example to completely disable catalog caching (necessary when developing): 24 | environment_timeout = 0 25 | 26 | # The script to run to determine Puppet configuration version 27 | # Here we pass to one in the control repo the Puppet environment (and git branch) 28 | # to get title and essential info of the last git commit 29 | config_version = 'bin/config_script.sh $environment' 30 | 31 | -------------------------------------------------------------------------------- /hiera.yaml: -------------------------------------------------------------------------------- 1 | version: 5 2 | defaults: 3 | datadir: modules/hieradata/data 4 | hierarchy: 5 | - name: Eyaml hierarchy 6 | lookup_key: eyaml_lookup_key 7 | paths: 8 | - "nodes/%{trusted.certname}.yaml" 9 | - "role/%{::role}-%{::env}.yaml" 10 | - "role/%{::role}.yaml" 11 | - "zone/%{::zone}.yaml" 12 | - common.yaml 13 | options: 14 | pkcs7_private_key: /etc/puppetlabs/puppet/keys/private_key.pkcs7.pem 15 | pkcs7_public_key: /etc/puppetlabs/puppet/keys/public_key.pkcs7.pem 16 | -------------------------------------------------------------------------------- /html/_site/images/bg_hr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/example42/psick/e94f09e8c2a1cc1a0310e572e5cb2c986c1f877c/html/_site/images/bg_hr.png -------------------------------------------------------------------------------- /html/_site/images/blacktocat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/example42/psick/e94f09e8c2a1cc1a0310e572e5cb2c986c1f877c/html/_site/images/blacktocat.png -------------------------------------------------------------------------------- /html/_site/images/icon_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/example42/psick/e94f09e8c2a1cc1a0310e572e5cb2c986c1f877c/html/_site/images/icon_download.png -------------------------------------------------------------------------------- /html/_site/images/sprite_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/example42/psick/e94f09e8c2a1cc1a0310e572e5cb2c986c1f877c/html/_site/images/sprite_download.png -------------------------------------------------------------------------------- /html/_site/javascripts/main.js: -------------------------------------------------------------------------------- 1 | angular.module('wizard-sample', ['mgo-angular-wizard']) 2 | .controller('WizardCtrl', function($scope, $q, $timeout, WizardHandler) { 3 | 4 | $scope.canExit = true; 5 | $scope.stepActive = true; 6 | 7 | $scope.finished = function() { 8 | alert("Wizard finished :)"); 9 | }; 10 | $scope.logStep = function() { 11 | console.log("Step continued"); 12 | }; 13 | $scope.goBack = function() { 14 | WizardHandler.wizard('topWizard').goTo(1); 15 | }; 16 | $scope.exitWithAPromise = function() { 17 | var d = $q.defer(); 18 | $timeout(function() { 19 | d.resolve(true); 20 | }, 1000); 21 | return d.promise; 22 | }; 23 | $scope.exitToggle = function() { 24 | $scope.canExit = !$scope.canExit; 25 | }; 26 | $scope.stepToggle = function() { 27 | $scope.stepActive = !$scope.stepActive; 28 | } 29 | $scope.exitValidation = function() { 30 | return $scope.canExit; 31 | }; 32 | 33 | /* Logix for ngRepeat Wizard */ 34 | $scope.wizardSteps = [{ 35 | title: 'Step 1', 36 | content: 'This is content for step 1' 37 | }, { 38 | title: 'Step 2', 39 | content: 'This is content for step 2' 40 | }]; 41 | 42 | $scope.stepToAdd = { 43 | title: '', 44 | content: '' 45 | }; 46 | 47 | $scope.addStep = function() { 48 | $scope.wizardSteps.push(angular.copy($scope.stepToAdd)); 49 | console.log('pushed: ', $scope.wizardSteps, $scope.stepToAdd); 50 | $scope.stepToAdd.title = ''; 51 | $scope.stepToAdd.content = ''; 52 | }; 53 | 54 | $scope.removeStep = function(index) { 55 | $scope.wizardSteps.splice(index, 1); 56 | }; 57 | }); -------------------------------------------------------------------------------- /html/images/PSICK-logo-200x200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/example42/psick/e94f09e8c2a1cc1a0310e572e5cb2c986c1f877c/html/images/PSICK-logo-200x200.png -------------------------------------------------------------------------------- /html/images/bg_hr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/example42/psick/e94f09e8c2a1cc1a0310e572e5cb2c986c1f877c/html/images/bg_hr.png -------------------------------------------------------------------------------- /html/images/blacktocat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/example42/psick/e94f09e8c2a1cc1a0310e572e5cb2c986c1f877c/html/images/blacktocat.png -------------------------------------------------------------------------------- /html/images/icon_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/example42/psick/e94f09e8c2a1cc1a0310e572e5cb2c986c1f877c/html/images/icon_download.png -------------------------------------------------------------------------------- /html/images/sprite_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/example42/psick/e94f09e8c2a1cc1a0310e572e5cb2c986c1f877c/html/images/sprite_download.png -------------------------------------------------------------------------------- /html/javascripts/main.js: -------------------------------------------------------------------------------- 1 | angular.module('wizard-sample', ['mgo-angular-wizard']) 2 | .controller('WizardCtrl', function($scope, $q, $timeout, WizardHandler) { 3 | 4 | $scope.canExit = true; 5 | $scope.stepActive = true; 6 | 7 | $scope.finished = function() { 8 | alert("Wizard finished :)"); 9 | }; 10 | $scope.logStep = function() { 11 | console.log("Step continued"); 12 | }; 13 | $scope.goBack = function() { 14 | WizardHandler.wizard('topWizard').goTo(1); 15 | }; 16 | $scope.exitWithAPromise = function() { 17 | var d = $q.defer(); 18 | $timeout(function() { 19 | d.resolve(true); 20 | }, 1000); 21 | return d.promise; 22 | }; 23 | $scope.exitToggle = function() { 24 | $scope.canExit = !$scope.canExit; 25 | }; 26 | $scope.stepToggle = function() { 27 | $scope.stepActive = !$scope.stepActive; 28 | } 29 | $scope.exitValidation = function() { 30 | return $scope.canExit; 31 | }; 32 | 33 | /* Logix for ngRepeat Wizard */ 34 | $scope.wizardSteps = [{ 35 | title: 'Step 1', 36 | content: 'This is content for step 1' 37 | }, { 38 | title: 'Step 2', 39 | content: 'This is content for step 2' 40 | }]; 41 | 42 | $scope.stepToAdd = { 43 | title: '', 44 | content: '' 45 | }; 46 | 47 | $scope.addStep = function() { 48 | $scope.wizardSteps.push(angular.copy($scope.stepToAdd)); 49 | console.log('pushed: ', $scope.wizardSteps, $scope.stepToAdd); 50 | $scope.stepToAdd.title = ''; 51 | $scope.stepToAdd.content = ''; 52 | }; 53 | 54 | $scope.removeStep = function(index) { 55 | $scope.wizardSteps.splice(index, 1); 56 | }; 57 | }); -------------------------------------------------------------------------------- /inventory.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Groups based on OS. Queries PuppetDB for nodes with the specified OS. 3 | groups: 4 | - name: linux 5 | targets: 6 | - _plugin: puppetdb 7 | query: "inventory[certname] { facts.kernel = 'Linux' }" 8 | - name: windows 9 | targets: 10 | - _plugin: puppetdb 11 | query: "inventory[certname] { facts.kernel = 'windows' }" 12 | transport: winrm 13 | - name: mac 14 | targets: 15 | - _plugin: puppetdb 16 | query: "inventory[certname] { facts.kernel = 'Darwin' }" 17 | 18 | # General configuration for all targets 19 | config: 20 | ssh: 21 | host-key-check: false 22 | winrm: 23 | user: Administrator 24 | ssl: false 25 | transport: 26 | _plugin: env_var 27 | var: BOLT_TRANSPORT 28 | default: ssh 29 | pcp: 30 | cacert: ~/.puppetlabs/puppet/cert.pem 31 | service-url: https://puppet:8143 32 | task-environment: host 33 | token-file: ~/.puppetlabs/puppet/token.pem 34 | 35 | -------------------------------------------------------------------------------- /keys: -------------------------------------------------------------------------------- 1 | /etc/puppetlabs/puppet/keys -------------------------------------------------------------------------------- /metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example42-psick", 3 | "version": "0.9.4", 4 | "author": "Example42", 5 | "summary": "PSICK Control repo.", 6 | "license": "Apache-2.0", 7 | "source": "https://github.com/example42/psick", 8 | "project_page": "https://github.com/example42/psick", 9 | "dependencies": [ 10 | { 11 | "name": "puppetlabs/stdlib", 12 | "version_requirement": ">= 4.0.0 < 7.0.0" 13 | } 14 | ], 15 | "operatingsystem_support": [ 16 | { 17 | "operatingsystem": "RedHat", 18 | "operatingsystemrelease": [ 19 | "6", 20 | "7", 21 | "8" 22 | ] 23 | }, 24 | { 25 | "operatingsystem": "CentOS", 26 | "operatingsystemrelease": [ 27 | "6", 28 | "7", 29 | "8" 30 | ] 31 | }, 32 | { 33 | "operatingsystem": "OracleLinux", 34 | "operatingsystemrelease": [ 35 | "6", 36 | "7", 37 | "8" 38 | ] 39 | }, 40 | { 41 | "operatingsystem": "SLES", 42 | "operatingsystemrelease": [ 43 | "11 SP1", 44 | "12" 45 | ] 46 | }, 47 | { 48 | "operatingsystem": "Debian", 49 | "operatingsystemrelease": [ 50 | "7", 51 | "8", 52 | "9" 53 | ] 54 | }, 55 | { 56 | "operatingsystem": "Ubuntu", 57 | "operatingsystemrelease": [ 58 | "16.04", 59 | "16.10", 60 | "17.04", 61 | "17.10", 62 | "18.04", 63 | "18.10", 64 | "19.04", 65 | "19.10", 66 | "20.04" 67 | ] 68 | } 69 | ], 70 | "requirements": [ 71 | { 72 | "name": "puppet", 73 | "version_requirement": ">= 4.5.0 < 8.0.0" 74 | } 75 | ], 76 | "description": "Puppet Systems Infrastructure Construction Kit control repo.", 77 | "pdk-version": "1.7.0", 78 | "template-url": "file:///opt/puppetlabs/pdk/share/cache/pdk-templates.git", 79 | "template-ref": "1.7.0-0-g57412ed" 80 | } 81 | -------------------------------------------------------------------------------- /psick: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'yaml' 4 | $action = ARGV[0] ? ARGV[0] : 'none' 5 | $subaction = ARGV[1] ? ARGV[1] : 'none' 6 | 7 | PSICK_DIR = File.dirname(__FILE__) 8 | PSICK_SETTINGS = File.exists?(PSICK_DIR + '/Psickfile') ? YAML.load_file(PSICK_DIR + '/Psickfile') : 'none' 9 | 10 | # Trap CTRL+C cleanly (in psick diff) 11 | trap("INT") { puts 'Exiting...'; exit } 12 | 13 | def usage 14 | print < [object] 18 | 19 | Available actions: 20 | create: Create a new Puppet control-repo 21 | add: Add profiles or integrations to control-repo [TODO] 22 | remove: Remove profiles or integrations from control-repo [TODO] 23 | diff: Show diff between current PSICK and your control-repo [TODO] 24 | list: List the files managed by Psickfile [TODO] 25 | EOF 26 | end 27 | 28 | 29 | 30 | case $action 31 | when 'create' 32 | exec ("bin/git_setup_new_repo.sh") 33 | when 'add' 34 | puts 'TODO' 35 | when 'remove' 36 | puts 'TODO' 37 | when 'diff' 38 | #files = [] 39 | #system("diff . " + PSICK_SETTINGS['']) 40 | puts 'TODO' 41 | when 'list' 42 | # files = Dir.entries(TINYDATA_DIR).sort.reject { |f| File.directory?(f) } 43 | puts 'TODO' 44 | 45 | else 46 | usage 47 | 48 | end 49 | -------------------------------------------------------------------------------- /spec/acceptance/nodesets/default.yml: -------------------------------------------------------------------------------- 1 | docker.yml -------------------------------------------------------------------------------- /spec/acceptance/nodesets/docker.yml: -------------------------------------------------------------------------------- 1 | HOSTS: 2 | centos-7-x64: 3 | platform: el-7-x86_64 4 | hypervisor : docker 5 | image: centos:centos7 6 | docker_preserve_image: true 7 | mount_folders: 8 | controlrepo: 9 | host_path: . 10 | container_path: /tmp/production 11 | opts: ro 12 | docker_cmd: '["/usr/sbin/init"]' 13 | docker_image_commands: 14 | - 'yum -y swap -- remove fakesystemd -- install systemd systemd-libs' 15 | - 'yum -y install crontabs tar ss wget openssl sysvinit-tools iproute which initscripts' 16 | - 'yum -y update; yum clean all; yum makecache' 17 | - 'systemctl mask getty@tty1.service' 18 | CONFIG: 19 | type: foss 20 | -------------------------------------------------------------------------------- /spec/acceptance/nodesets/vagrant.yml: -------------------------------------------------------------------------------- 1 | HOSTS: 2 | centos-7-x64.psick.io: 3 | roles: 4 | - default 5 | platform: el-7-x86_64 6 | hypervisor: vagrant 7 | box: puppetlabs/centos-7.2-64-nocm 8 | mount_folders: 9 | controlrepo: 10 | from: ../../../ 11 | to: /etc/puppetlabs/code/environments/production 12 | CONFIG: 13 | type: foss 14 | -------------------------------------------------------------------------------- /spec/acceptance/psick_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper_acceptance' 2 | 3 | describe 'psick' do 4 | let(:facts) do 5 | OS_FACTS.merge(facts).merge( domain: 'lab.psick.io' ) 6 | end 7 | let(:manifest) { 8 | <<-EOS 9 | Tp::Install { 10 | test_enable => lookup('tp::test_enable', Boolean, 'first', false), 11 | puppi_enable => lookup('tp::puppi_enable', Boolean, 'first', false), 12 | debug => lookup('tp::debug', Boolean, 'first', false), 13 | data_module => lookup('tp::data_module', String, 'first', 'tinydata'), 14 | } 15 | Tp::Conf { 16 | config_file_notify => lookup('tp::config_file_notify', Boolean, 'first', true), 17 | config_file_require => lookup('tp::config_file_require', Boolean, 'first', true), 18 | debug => lookup('tp::debug', Boolean, 'first', false), 19 | data_module => lookup('tp::data_module', String, 'first', 'tinydata'), 20 | } 21 | Tp::Dir { 22 | config_dir_notify => lookup('tp::config_dir_notify', Boolean, 'first', true), 23 | config_dir_require => lookup('tp::config_dir_require', Boolean, 'first', true), 24 | debug => lookup('tp::debug', Boolean, 'first', false), 25 | data_module => lookup('tp::data_module', String, 'first', 'tinydata'), 26 | } 27 | Exec { 28 | path => '/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin', 29 | } 30 | include psick 31 | EOS 32 | } 33 | it 'should run without errors or without changes' do 34 | result = apply_manifest(manifest, :catch_failures => true) 35 | expect(@result.exit_code).to eq(2).or(eq(0)) 36 | end 37 | it 'should run a second time without changes' do 38 | result = apply_manifest(manifest, :catch_changes => true) 39 | expect(@result.exit_code).to eq 0 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /spec/acceptance/puppetmaster_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper_acceptance' 2 | 3 | describe 'puppetmaster' do 4 | let(:facts) do 5 | OS_FACTS.merge(facts).merge({ :role => 'puppetmaster' }) 6 | end 7 | 8 | let(:manifest) { 9 | <<-EOS 10 | include psick 11 | EOS 12 | } 13 | it 'should run first time with changes and without errors' do 14 | result = apply_manifest(manifest, :catch_failures => true) 15 | expect(@result.exit_code).to eq 2 16 | end 17 | it 'should run a second time without changes' do 18 | result = apply_manifest(manifest, :catch_changes => true) 19 | expect(@result.exit_code).to eq 0 20 | end 21 | # here one can add more serverspec tests 22 | end 23 | 24 | -------------------------------------------------------------------------------- /spec/default_facts.yml: -------------------------------------------------------------------------------- 1 | # Use default_module_facts.yml for module specific facts. 2 | # 3 | # Facts specified here will override the values provided by rspec-puppet-facts. 4 | --- 5 | concat_basedir: "/tmp" 6 | ipaddress: "172.16.254.254" 7 | is_pe: false 8 | macaddress: "AA:AA:AA:AA:AA:AA" 9 | -------------------------------------------------------------------------------- /spec/factsets/README.md: -------------------------------------------------------------------------------- 1 | # Factsets 2 | 3 | This directory is where we put any custom factsets that we want to use. They can be generated by running `puppet facts` on the target system. 4 | 5 | **Hot tip:** If you already have factsets in here when you run `onceover init` they will be picked up and added to the config file Automatically 6 | 7 | More info: https://github.com/dylanratcliffe/onceover#factsets 8 | -------------------------------------------------------------------------------- /spec/hiera.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 5 3 | 4 | defaults: 5 | datadir: ../modules/hieradata/data # Data in separated module, defined in Puppetfile 6 | # datadir: hieradata # Data in control-repo. Previous psick setting 7 | # datadir: data # Data in control-repo. Default for puppetlabs/control-repo 8 | data_hash: yaml_data 9 | 10 | hierarchy: 11 | - name: "Eyaml hierarchy" 12 | paths: 13 | - "nodes/%{trusted.certname}.yaml" 14 | - "role/%{::role}-%{::env}.yaml" 15 | - "role/%{::role}.yaml" 16 | - "zone/%{::zone}.yaml" 17 | - "common.yaml" 18 | 19 | -------------------------------------------------------------------------------- /spec/hosts/build.lab.psick.io_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | @os_facts 4 | 5 | describe 'build.lab.psick.io' do 6 | on_supported_os.each do |os, facts| 7 | context "on #{os}" do 8 | let(:facts) do 9 | OS_FACTS.merge(facts) 10 | end 11 | let(:environment) { 'production' } 12 | let(:trusted_facts) do 13 | { 14 | 'env' => 'lab', 15 | 'zone' => 'lab', 16 | 'datacenter' => 'lab', 17 | 'role' => 'build' 18 | } 19 | end 20 | it { is_expected.to compile.with_all_deps } 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/hosts/jenkins.lab.psick.io_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | @os_facts 4 | # Jenkins role tested only on an os subset 5 | describe 'jenkins.lab.psick.io' do 6 | on_supported_os.select { |k, _v| k == 'redhat-7-x86_64' || k == 'ubuntu-18.04-x86_64' }.each do |os, facts| 7 | context "on #{os}" do 8 | let(:facts) do 9 | OS_FACTS.merge(facts) 10 | end 11 | let(:environment) { 'production' } 12 | let(:trusted_facts) do 13 | { 14 | 'env' => 'lab', 15 | 'zone' => 'lab', 16 | 'datacenter' => 'lab', 17 | 'role' => 'jenkins' 18 | } 19 | end 20 | it { is_expected.to compile.with_all_deps } 21 | it { is_expected.to contain_service('jenkins').with('ensure' => 'running') } 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/hosts/puppet.lab.psick.io_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | @os_facts 4 | 5 | describe 'puppet.lab.psick.io' do 6 | test_on = { 7 | :supported_os => [ 8 | { 'operatingsystem' => 'RedHat' } 9 | ] 10 | } 11 | on_supported_os(test_on).each do |os, facts| 12 | context "on #{os}" do 13 | let(:facts) do 14 | OS_FACTS.merge(facts).merge({ :servername => 'puppet.example.com' }) 15 | end 16 | let(:environment) { 'production' } 17 | let(:trusted_facts) do 18 | { 19 | 'env' => 'lab', 20 | 'zone' => 'lab', 21 | 'datacenter' => 'lab', 22 | 'role' => 'puppet' 23 | } 24 | end 25 | it { is_expected.to compile.with_all_deps } 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/hosts/windows2012.lab.psick.io_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | @os_facts 4 | 5 | describe 'windows2012.lab.psick.io' do 6 | on_supported_os.each do |os, facts| 7 | context "on #{os}" do 8 | let(:facts) do 9 | OS_FACTS.merge(facts) 10 | end 11 | let(:environment) { 'production' } 12 | let(:trusted_facts) do 13 | { 14 | 'env' => 'lab', 15 | 'zone' => 'lab', 16 | 'datacenter' => 'lab', 17 | 'role' => 'ostest' 18 | } 19 | end 20 | it { is_expected.to compile.with_all_deps } 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/onceover.yaml: -------------------------------------------------------------------------------- 1 | # Classes to be tested 2 | classes: 3 | - /^psick/ 4 | 5 | # Nodes to tests classes on, this refers to a 'factset' or 'nodeset' 6 | # depending on whether you are running 'spec' or 'acceptance' tests 7 | nodes: 8 | - solaris-10_u9-sparc-64 9 | - Ubuntu-12.04-32 10 | - CentOS-6.6-32 11 | - Debian-6.0.10-64 12 | - AIX-6.1-powerpc 13 | - Debian-7.8-64 14 | - CentOS-5.11-64 15 | - Ubuntu-12.04-64 16 | - Windows_Server-2008r2-64 17 | - Ubuntu-14.04-32 18 | - SLES-11.3-64 19 | - SLES-12.1-64 20 | - Debian-7.8-32 21 | - CentOS-7.0-64 22 | - solaris-11.2-sparc-64 23 | - windows-10-64 24 | - CentOS-6.6-64 25 | - AIX-7.1-powerpc 26 | - Debian-6.0.10-32 27 | - Ubuntu-14.04-64 28 | - Windows_Server-2012r2-64 29 | - CentOS-5.11-32 30 | 31 | # You can group classes here to save typing 32 | class_groups: 33 | 34 | # You can group nodes here to save typing 35 | # We have created a 'non_windows_nodes' group because we can't 36 | # give you Windows vagrant boxes to test with because licensing, 37 | # we can give you fact sets though so go crazy with spec testing! 38 | node_groups: 39 | windows_nodes: 40 | - Windows_Server-2008r2-64 41 | - windows-10-64 42 | - Windows_Server-2012r2-64 43 | non_windows_nodes: 44 | include: 'all_nodes' 45 | exclude: 'windows_nodes' 46 | 47 | test_matrix: 48 | - all_nodes: 49 | classes: 'all_classes' 50 | tests: 'spec' 51 | - non_windows_nodes: 52 | classes: 'all_classes' 53 | tests: 'acceptance' 54 | -------------------------------------------------------------------------------- /spec/pre_conditions/README.md: -------------------------------------------------------------------------------- 1 | # Pre Conditions 2 | 3 | This folder should contain any \*.pp files that you want to be included in every test. 4 | 5 | A common use of this is defining resources that may not exist in the catalog when you are running tests. For example, if we are using a resource that tries to restart the `pe-puppetserver` service, unless it is compiled on a Puppet Maser the `pe-puppetserver` service will not exist and the catalog will fail to compile. To get around this we can create a .pp file and define the resource like so: 6 | 7 | ``` puppet 8 | # We are not going to actually have this service anywhere on our servers but 9 | # our code needs to refresh it. This is to trick puppet into doing nothing 10 | service { 'pe-puppetserver': 11 | ensure => 'running', 12 | enable => false, 13 | hasrestart => false, # Force Puppet to use start and stop to restart 14 | start => 'echo "Start"', # This will always exit 0 15 | stop => 'echo "Stop"', # This will also always exit 0 16 | hasstatus => false, # Force puppet to use our command for status 17 | status => 'echo "Status"', # This will always exit 0 and therefore Puppet will think the service is running 18 | provider => 'base', 19 | } 20 | ``` 21 | 22 | This will mean that the `pe-puppetserver` service is in the catalog for spec testing and will even allow you to try to restart it during acceptance tests without the service actually being present. 23 | 24 | More info: https://github.com/dylanratcliffe/onceover#using-workarounds 25 | -------------------------------------------------------------------------------- /spec/resources/base_resources.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | tp__install: 3 | - ntpdate 4 | - openssh 5 | - puppet-agent 6 | - postfix 7 | - rsyslog 8 | -------------------------------------------------------------------------------- /spec/spec.yaml: -------------------------------------------------------------------------------- 1 | networking: 2 | dhcp: 10.0.2.2 3 | domain: lan 4 | fqdn: puppet.lan 5 | hostname: puppet 6 | interfaces: 7 | docker0: 8 | bindings: 9 | - address: 172.17.0.1 10 | netmask: 255.255.0.0 11 | network: 172.17.0.0 12 | ip: 172.17.0.1 13 | mac: "02:42:8e:da:27:96" 14 | mtu: 1500 15 | netmask: 255.255.0.0 16 | network: 172.17.0.0 17 | eth0: 18 | bindings: 19 | - address: 10.0.2.15 20 | netmask: 255.255.255.0 21 | network: 10.0.2.0 22 | dhcp: 10.0.2.2 23 | ip: 10.0.2.15 24 | mac: "52:54:00:22:5b:53" 25 | mtu: 1500 26 | netmask: 255.255.255.0 27 | network: 10.0.2.0 28 | eth1: 29 | bindings: 30 | - address: 10.42.42.101 31 | netmask: 255.255.255.0 32 | network: 10.42.42.0 33 | ip: 10.42.42.101 34 | mac: "08:00:27:e4:c8:bd" 35 | mtu: 1500 36 | netmask: 255.255.255.0 37 | network: 10.42.42.0 38 | lo: 39 | bindings: 40 | - address: 127.0.0.1 41 | netmask: 255.0.0.0 42 | network: 127.0.0.0 43 | ip: 127.0.0.1 44 | mtu: 65536 45 | netmask: 255.0.0.0 46 | network: 127.0.0.0 47 | ip: 10.0.2.15 48 | mac: "52:54:00:22:5b:53" 49 | mtu: 1500 50 | netmask: 255.255.255.0 51 | network: 10.0.2.0 52 | primary: eth0 53 | 54 | 55 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'puppetlabs_spec_helper/module_spec_helper' 2 | require 'rspec-puppet-facts' 3 | 4 | begin 5 | require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) 6 | rescue LoadError => loaderror 7 | warn "Could not require spec_helper_local: #{loaderror.message}" 8 | end 9 | 10 | include RspecPuppetFacts 11 | 12 | # Custom support path 13 | support_path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec/support/*.rb')) 14 | Dir[support_path].each {|f| require f} 15 | 16 | default_facts = { 17 | puppetversion: Puppet.version, 18 | facterversion: Facter.version, 19 | } 20 | 21 | default_facts_path = File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')) 22 | default_module_facts_path = File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')) 23 | 24 | if File.exist?(default_facts_path) && File.readable?(default_facts_path) 25 | default_facts.merge!(YAML.safe_load(File.read(default_facts_path))) 26 | end 27 | 28 | if File.exist?(default_module_facts_path) && File.readable?(default_module_facts_path) 29 | default_facts.merge!(YAML.safe_load(File.read(default_module_facts_path))) 30 | end 31 | 32 | RSpec.configure do |c| 33 | c.default_facts = default_facts 34 | c.before :each do 35 | # set to strictest setting for testing 36 | # by default Puppet runs at warning level 37 | Puppet.settings[:strict] = :warning 38 | end 39 | end 40 | 41 | def ensure_module_defined(module_name) 42 | module_name.split('::').reduce(Object) do |last_module, next_module| 43 | last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module) 44 | last_module.const_get(next_module) 45 | end 46 | end 47 | 48 | # 'spec_overrides' from sync.yml will appear below this line 49 | -------------------------------------------------------------------------------- /spec/spec_helper_acceptance.rb: -------------------------------------------------------------------------------- 1 | require 'beaker-rspec' 2 | require 'beaker-hiera' 3 | require 'beaker/puppet_install_helper' 4 | begin 5 | require 'puppet' 6 | rescue TypeError 7 | end 8 | 9 | hosts.each do |host| 10 | # Install Puppet 11 | # check for puppet version 12 | case Puppet.version.to_i 13 | when 4 14 | version_to_install = '1.' + Puppet.version.split('.')[1..-1]*"." 15 | install_puppet_agent_on(host, {:version => version_to_install}) 16 | when 5 17 | install_puppet_agent_on(host, {:version => Puppet.version,:puppet_collection => 'puppet5'}) 18 | else 19 | puts 'unsupported puppet version' 20 | exit 21 | end 22 | end 23 | 24 | RSpec.configure do |c| 25 | # Project root 26 | proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) 27 | # Readable test descriptions 28 | c.formatter = :documentation 29 | # Configure all nodes in nodeset 30 | c.before :suite do 31 | hosts.each do |host| 32 | on(host, '/usr/bin/test -f /etc/puppetlabs/puppet/hiera.yaml && /bin/rm -f /etc/puppetlabs/puppet/hiera.yaml || echo true') 33 | # remove existing production environment 34 | on(host, '/usr/bin/test -d /etc/puppetlabs/code/environments/production && /bin/rm -fr /etc/puppetlabs/code/environments/production || echo true') 35 | # re-create production environment directory 36 | on(host, '/usr/bin/test ! -d /etc/puppetlabs/code/environments/production && mkdir -p /etc/puppetlabs/code/environments/production || echo true') 37 | # copy control-repo 38 | on(host, 'cp -r /tmp/production /etc/puppetlabs/code/environments/') 39 | 40 | on(host, '/opt/puppetlabs/bin/puppet resource package git ensure=present') 41 | on(host, '/opt/puppetlabs/puppet/bin/gem install r10k') 42 | on(host, 'cd /etc/puppetlabs/code/environments/production && /opt/puppetlabs/puppet/bin/r10k puppetfile install -v') 43 | on(host, '/opt/puppetlabs/puppet/bin/gem install hiera-eyaml') 44 | on(host, 'cd /etc/puppetlabs/puppet/ && /opt/puppetlabs/puppet/bin/eyaml createkeys') 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /terraform/main.tf: -------------------------------------------------------------------------------- 1 | ## AWS 2 | module "aws" { 3 | source = "./modules/aws" 4 | count = var.enable_aws ? 1 : 0 5 | instances = var.instance_count 6 | subnet = var.aws_subnet 7 | } 8 | 9 | ## Azure 10 | module "azure" { 11 | source = "./modules/azure" 12 | count = var.enable_azure ? 1 : 0 13 | instances = var.instance_count 14 | resource_group_name = var.resource_group_name 15 | resource_group_location = var.resource_group_location 16 | } -------------------------------------------------------------------------------- /terraform/modules/aws/aws.tf: -------------------------------------------------------------------------------- 1 | resource "aws_instance" "inst" { 2 | count = var.instances 3 | ami = var.ami_id 4 | instance_type = var.instance_type 5 | subnet_id = var.subnet 6 | 7 | tags = { 8 | Name = "EX42-${count.index}" 9 | } 10 | } -------------------------------------------------------------------------------- /terraform/modules/aws/outputs.tf: -------------------------------------------------------------------------------- 1 | output "instance_name" { 2 | value = aws.inst.*.tags.Name 3 | } -------------------------------------------------------------------------------- /terraform/modules/aws/variables.tf: -------------------------------------------------------------------------------- 1 | variable "instances" {} 2 | 3 | variable "ami_id" { 4 | type = string 5 | default = "ami-0729e439b6769d6ab" 6 | } 7 | 8 | variable "instance_type" { 9 | type = string 10 | default = "t3.micro" 11 | } 12 | 13 | variable "subnet" {} 14 | -------------------------------------------------------------------------------- /terraform/modules/azure/azure.tf: -------------------------------------------------------------------------------- 1 | # Import Resource Group 2 | resource "azurerm_resource_group" "rg" { 3 | name = var.resource_group_name 4 | location = var.resource_group_location 5 | } 6 | 7 | # Create virtual network 8 | resource "azurerm_virtual_network" "vnet" { 9 | name = "Vnet" 10 | address_space = ["10.0.0.0/16"] 11 | location = azurerm_resource_group.rg.location 12 | resource_group_name = azurerm_resource_group.rg.name 13 | } 14 | 15 | # Create subnet 16 | resource "azurerm_subnet" "subnet" { 17 | name = "Subnet" 18 | resource_group_name = azurerm_resource_group.rg.name 19 | virtual_network_name = azurerm_virtual_network.vnet.name 20 | address_prefixes = ["10.0.1.0/24"] 21 | } 22 | 23 | 24 | # Create network interface 25 | resource "azurerm_network_interface" "nic" { 26 | count = var.instances 27 | name = "NIC${count.index}" 28 | location = azurerm_resource_group.rg.location 29 | resource_group_name = azurerm_resource_group.rg.name 30 | 31 | ip_configuration { 32 | name = "NicConfig" 33 | subnet_id = azurerm_subnet.subnet.id 34 | private_ip_address_allocation = "Dynamic" 35 | } 36 | } 37 | 38 | # Create virtual machine 39 | resource "azurerm_linux_virtual_machine" "vm" { 40 | count = var.instances 41 | name = "EX42-${count.index}" 42 | location = azurerm_resource_group.rg.location 43 | resource_group_name = azurerm_resource_group.rg.name 44 | network_interface_ids = [azurerm_network_interface.nic[count.index].id] 45 | size = "Standard_DS1_v2" 46 | 47 | admin_ssh_key { 48 | username = "admin" 49 | public_key = file("~/.ssh/id_rsa.pub") 50 | } 51 | 52 | os_disk { 53 | caching = "ReadWrite" 54 | storage_account_type = "Standard_LRS" 55 | } 56 | 57 | source_image_reference { 58 | publisher = "Canonical" 59 | offer = "UbuntuServer" 60 | sku = "18.04-LTS" 61 | version = "latest" 62 | } 63 | 64 | computer_name = "VM-${count.index}" 65 | admin_username = "admin" 66 | admin_password = "wqe2sdf3" 67 | disable_password_authentication = false 68 | } -------------------------------------------------------------------------------- /terraform/modules/azure/outputs.tf: -------------------------------------------------------------------------------- 1 | output "instance_name" { 2 | value = azurerm_linux_virtual_machine.vm.*.name 3 | } -------------------------------------------------------------------------------- /terraform/modules/azure/variables.tf: -------------------------------------------------------------------------------- 1 | variable "instances" {} 2 | 3 | variable "resource_group_name" {} 4 | 5 | variable "resource_group_location" {} 6 | 7 | -------------------------------------------------------------------------------- /terraform/modules/hetzner/README.md: -------------------------------------------------------------------------------- 1 | # PSICK on Hetzner Cloud using Terraform 2 | 3 | ## Description 4 | 5 | This terraform project generates a Puppet Infrastructure on Hetzner Cloud. 6 | 7 | We usually use this setup for training classes. 8 | 9 | We will always deploy a Puppet Master and a GitLab Server. 10 | Additional Puppet nodes can be specified within the configuration file. 11 | 12 | ## Preparation 13 | 14 | Part 1: Hetzner: 15 | 16 | Log into Hetzner Cloud, create a Project, generate an API token and add your SSH Keys, which you want to distribute onto the cloud servers. 17 | 18 | 19 | Part 2: local: 20 | 21 | Generate an SSH Key without (!) passphrase. This key will be used for provisioning. 22 | Don't add this key to Hetzner Cloud! It will be used locally for provisioning the VMs. 23 | 24 | Generate file `secrets.auto.tfvars` right next to `hcloud.tf` file. 25 | Content: 26 | 27 | hcloud_token = "your_api_token" 28 | hdns_token = "your_dns_token" 29 | internal_subdomain = "internal" 30 | public_subdomain = "public" 31 | sshkey = "/home/example42/.ssh/hetzner_key" 32 | puppet_version = 6 33 | control_repo = "https://github.com/example42/psick.git" 34 | machines = { 35 | "puppet" = { ip = "10.0.1.1", role = 'puppet', server_type = 'cx41', access_level = 'admin_keys', image = "centos-7" } 36 | "gitlab" = { ip = "10.0.1.2", role = 'gitlab', server_type = 'cx21', access_level = 'admin_keys', image = "centos-7" } 37 | "student1" = { ip = "10.0.1.11", role = 'webserver', server_type = 'cx11', access_level = 'all_keys', image = "centos-7" } 38 | "" = { ip = "10.0.1.0/24", role = '', server_type = 'hetzner server type', access_level = '[all_keys, admin_keys]', image = "hetzner image" } 39 | } 40 | 41 | Within `control_repo` you can specify a differente control repository which should be used for any further deployment. 42 | Please take care that you must have a script in your repo (`bin/bootstrap/cloud_init.sh`) which takes three parameters: 43 | 44 | - puppet\_version 45 | - role 46 | - control\_repo 47 | 48 | The `sshkey` setting tells terraform where to find the private ssh key without passphrase used for provisioning. 49 | 50 | The `puppet_version` variable lets you choose which major Puppet version to install. Here we only accept `5` or `6` as valid values. 51 | 52 | Under `machines` you place a hash, which describes the systems in your infrastructure: 53 | 54 | * ip: IPv4 Address from subnet 10.0.10.0/24 - configured in hcloud.tf 55 | * role: The desired puppet role, will be added to trusted and external facts. can be used for e.g. node classification 56 | * server\_type: The required Hetzner server type. 57 | * access\_level: which ssh keys to use. possible values: all\_keys or admin\_keys - configured in hcloud.tf - not used at the moment 58 | 59 | Note: "puppet" and "gitlab" are optional. But if you add them be sure that "puppet" system must have IP 10.0.1.1 and "gitlab" must have 10.0.1.2 !! 60 | 61 | ## Finishing 62 | 63 | After running `terrafrom apply` you will see a list of servernames and IP addresses. 64 | 65 | 66 | -------------------------------------------------------------------------------- /terraform/modules/hetzner/hcloud.tf: -------------------------------------------------------------------------------- 1 | # Set the variable value in *.tfvars file 2 | # or using the -var="hcloud_token=..." CLI option 3 | 4 | # Configure the Hetzner Cloud Provider 5 | provider "hcloud" { 6 | token = var.hcloud_token 7 | } 8 | 9 | # Configure Hetzner DNS Provider 10 | provider "hetznerdns" { 11 | apitoken = var.hdns_token 12 | } 13 | 14 | data "hcloud_ssh_keys" "all_keys" { 15 | } 16 | 17 | data "hcloud_ssh_keys" "admin_keys" { 18 | with_selector = "role=admin" 19 | } 20 | 21 | data "hetznerdns_zone" "dns_zone" { 22 | name = "example42.cloud" 23 | } 24 | 25 | resource "hcloud_network" "workshop" { 26 | name = "workshop" 27 | ip_range = "10.0.0.0/8" 28 | } 29 | 30 | resource "hcloud_network_subnet" "workshop_subnet" { 31 | network_id = hcloud_network.workshop.id 32 | type = "server" 33 | network_zone = "eu-central" 34 | ip_range = "10.0.1.0/24" 35 | } 36 | 37 | resource "hcloud_server_network" "nodes" { 38 | for_each = var.machines 39 | server_id = hcloud_server.client_nodes[each.key].id 40 | network_id = hcloud_network.workshop.id 41 | ip = each.value.ip 42 | } 43 | 44 | resource "hcloud_server" "client_nodes" { 45 | for_each = var.machines 46 | name = each.key 47 | image = each.value.image 48 | server_type = each.value.server_type 49 | ssh_keys = data.hcloud_ssh_keys.all_keys.ssh_keys.*.name 50 | #ssh_keys = format("data.hcloud_ssh_keys.%s.ssh_keys.*.name", each.value.access_level) 51 | location = "fsn1" 52 | labels = { "use" = "schulung" } 53 | connection { 54 | type = "ssh" 55 | user = "root" 56 | private_key = file(var.sshkey) 57 | host = self.ipv4_address 58 | } 59 | provisioner "file" { 60 | source = "../../bin/bootstrap/cloud_init.sh" 61 | destination = "/tmp/cloud_init.sh" 62 | } 63 | 64 | provisioner "remote-exec" { 65 | inline = [ 66 | "sudo hostnamectl set-hostname ${each.key}.private.${data.hetznerdns_zone.dns_zone.name}", 67 | "chmod +x /tmp/cloud_init.sh", 68 | "/tmp/cloud_init.sh ${var.puppet_version} ${each.value.role} ${var.control_repo}", 69 | ] 70 | } 71 | } 72 | 73 | resource "hetznerdns_record" "private_addresses" { 74 | for_each = var.machines 75 | zone_id = data.hetznerdns_zone.dns_zone.id 76 | name = "${each.key}.${var.internal_subdomain}" 77 | value = each.value.ip 78 | type = "A" 79 | ttl= 60 80 | } 81 | 82 | resource "hetznerdns_record" "public_addresses" { 83 | for_each = var.machines 84 | zone_id = data.hetznerdns_zone.dns_zone.id 85 | name = "${each.key}.${var.public_subdomain}" 86 | value = hcloud_server.client_nodes[each.key].ipv4_address 87 | type = "A" 88 | ttl= 60 89 | } 90 | -------------------------------------------------------------------------------- /terraform/modules/hetzner/output.tf: -------------------------------------------------------------------------------- 1 | 2 | output "server_ip_list" { 3 | value = { 4 | for instance, data in hcloud_server.client_nodes: 5 | instance => data.ipv4_address 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /terraform/modules/hetzner/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | hetznerdns = { 4 | source = "timohirt/hetznerdns" 5 | } 6 | hcloud = { 7 | source = "hetznercloud/hcloud" 8 | } 9 | } 10 | required_version = ">= 0.14" 11 | } 12 | -------------------------------------------------------------------------------- /terraform/outputs.tf: -------------------------------------------------------------------------------- 1 | output "aws_instances" { 2 | value = module.aws.*.instance_name 3 | } 4 | 5 | output "azure_instances" { 6 | value = module.azure.*.instance_name 7 | } -------------------------------------------------------------------------------- /terraform/providers.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.14.9" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 4.25" 8 | } 9 | 10 | azurerm = { 11 | source = "hashicorp/azurerm" 12 | version = "~>3.17" 13 | } 14 | } 15 | } 16 | 17 | provider "aws" { 18 | region = "eu-north-1" 19 | profile = "default" 20 | } 21 | 22 | provider "azurerm" { 23 | features {} 24 | 25 | skip_provider_registration = true 26 | } -------------------------------------------------------------------------------- /terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "enable_aws" { 2 | description = "Enable / Disable AWS Deployment" 3 | type = bool 4 | default = true 5 | } 6 | 7 | variable "enable_azure" { 8 | description = "Enable / Disable Azure Deployment" 9 | type = bool 10 | default = false 11 | } 12 | 13 | variable "instance_count" { 14 | description = "Number of Instances" 15 | type = string 16 | default = 2 17 | } 18 | 19 | variable "aws_subnet" { 20 | description = "AWS Subnet" 21 | type = string 22 | default = "subnet-01e0d908d980f33cc" 23 | } 24 | 25 | variable "resource_group_name" { 26 | description = "Resource Group Name" 27 | type = string 28 | default = "1-a46ba6a8-playground-sandbox" 29 | } 30 | 31 | variable "resource_group_location" { 32 | description = "Resource Group Location" 33 | type = string 34 | default = "centralus" 35 | } -------------------------------------------------------------------------------- /vagrant/bin/pagent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | options=$* 3 | PATH=$PATH:/opt/puppetlabs/puppet/bin 4 | 5 | echo "## Running puppet agent -t ${options} --detailed-exitcodes" 6 | puppet agent -t ${options} --detailed-exitcodes 7 | result=$? 8 | if [ "x$result" == "x0" ] || [ "x$result" == "x2" ]; then 9 | exit 0 10 | else 11 | exit 1 12 | fi 13 | -------------------------------------------------------------------------------- /vagrant/bin/papply.cmd: -------------------------------------------------------------------------------- 1 | set base_dir="C:\vagrant_puppet" 2 | set manifest="C:\vagrant_puppet\manifests\site.pp" 3 | 4 | puppet apply -t --environmentpath "C:\" --environment "vagrant_puppet" --detailed-exitcodes %manifest% 5 | 6 | 7 | -------------------------------------------------------------------------------- /vagrant/bin/papply.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .SYNOPSIS 4 | Runs puppet apply from within a Vagrant VM 5 | .DESCRIPTION 6 | Runs puppet apply command using Puppet code and data mounted in c:\vagrant_puppet. 7 | .PARAMETER Manifest 8 | The name of the manifest to apply. 9 | Default is C:\vagrant_puppet\manifests\site.pp 10 | .PARAMETER Options 11 | Optional options to pass to puppet command (ie: --debug). 12 | This defaults to $null. 13 | #> 14 | param( 15 | [string]$Manifest = "C:\vagrant_puppet\manifests\site.pp" 16 | ,[string]$Options = $null 17 | ) 18 | 19 | $BaseDir="C:\vagrant_puppet\" 20 | $env:Path += ";C:\Program Files\Puppet Labs\Puppet\puppet\bin" 21 | 22 | Write-Host "Running Puppet apply on $Manifest." 23 | 24 | $InstallArgs = @("apply", "--test", "--report", "--summarize", "--modulepath", "$BaseDir/site:$BaseDir/modules:/etc/puppet/modules", "--environmentpath", "C:\", "--environment", "vagrant_puppet", "--detailed-exitcodes", "$Options", $Manifest) 25 | 26 | $InstallArg = "apply --test --report --summarize --modulepath $BaseDir/site:$BaseDir/modules:/etc/puppet/modules --environmentpath C:\ --environment vagrant_puppet --detailed-exitcodes $Options $Manifest" 27 | 28 | #$process = Start-Process -FilePath puppet $InstallArg -Wait -PassThru 29 | #$process = Start-Process -FilePath puppet -ArgumentList "$InstallArg" -Wait -PassThru 30 | Start-Process -FilePath puppet -ArgumentList "$InstallArg" -Wait -PassThru 31 | 32 | #if ($process.ExitCode -ne 0 -and $process.ExitCode -ne 2) { 33 | # Write-Host "Errors in the Puppet run." 34 | # Exit 1 35 | #} 36 | 37 | -------------------------------------------------------------------------------- /vagrant/bin/papply.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | environment=${1:-"host"} 4 | base_dir="/etc/puppetlabs/code/environments/${environment}" 5 | manifest=${2:-"${base_dir}/manifests/site.pp"} 6 | 7 | PATH=$PATH:/opt/puppetlabs/bin 8 | 9 | echo "## Running Puppet apply on ${manifest}. Version $(puppet --version)" 10 | 11 | puppet apply --test --report --summarize \ 12 | --modulepath "${base_dir}/site:${base_dir}/modules:/etc/puppet/modules" \ 13 | --environmentpath "${base_dir}/.." \ 14 | --environment $environment \ 15 | --detailed-exitcodes $manifest 16 | 17 | result=$? 18 | if [ "x$result" == "x0" ] || [ "x$result" == "x2" ]; then 19 | exit 0 20 | else 21 | exit 1 22 | fi 23 | 24 | -------------------------------------------------------------------------------- /vagrant/bin/vagrant-install-puppet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | lock_file=/var/tmp/vagrant-setup.lock 3 | 4 | # Run setup only the first time 5 | if [ -f $lock_file ]; then 6 | echo "### Found $lock_file. Skipping installation of Puppet." 7 | echo "## Remove $lock_file on the Vagrant VM to retry Puppet installation" 8 | else 9 | echo "### Installing Puppet 4" 10 | wget -O - https://bit.ly/installpuppet | bash && touch $lock_file 11 | fi 12 | 13 | 14 | -------------------------------------------------------------------------------- /vagrant/bin/vagrant-linkcontrolrepo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | env=${1:-production} 3 | mount_dir=${2:-'/vagrant_puppet'} 4 | 5 | link_controlrepo() { 6 | echo "### Linking Puppet ${env} environment to local development directory." 7 | [ -d /etc/puppetlabs/code/environments ] || mkdir -p /etc/puppetlabs/code/environments 8 | [ -d /etc/puppetlabs/code/environments/$env ] && mv /etc/puppetlabs/code/environments/$env /etc/puppetlabs/code/environments/$env_$(date +%Y%m%d_%H%M%S) 9 | ln -sf $mount_dir /etc/puppetlabs/code/environments/$env 10 | } 11 | 12 | [ -L /etc/puppetlabs/code/environments/$env ] || link_controlrepo $env 13 | 14 | -------------------------------------------------------------------------------- /vagrant/bin/vagrant-network.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "### Workaround for https://github.com/mitchellh/vagrant/issues/8166" 4 | if [ -f /sbin/ifconfig ]; then 5 | /sbin/ifconfig eth1 && restart=yes 6 | else 7 | ip a | grep eth1 && restart=yes 8 | fi 9 | 10 | if [ "x$restart" == "xyes" ]; then 11 | sudo ifup eth1 2>/dev/null 12 | fi 13 | -------------------------------------------------------------------------------- /vagrant/bin/vagrant-sethostname.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | hostn=$1 3 | 4 | echo "### Setting hostname ${hostn}" 5 | hostname $hostn 6 | -------------------------------------------------------------------------------- /vagrant/bin/vagrant-sethosts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | puppet_master_name=$1 3 | puppet_master_ip=$2 4 | 5 | echo "### Setting ${puppet_master_ip} puppet ${puppet_master_name} in /etc/hosts" 6 | grep "${puppet_master_ip} puppet ${puppet_master_name}" /etc/hosts || echo "${puppet_master_ip} puppet ${puppet_master_name}" >> /etc/hosts 7 | -------------------------------------------------------------------------------- /vagrant/bin/vagrant-setup_papply.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | lock_file='/var/tmp/vagrant-setup_papply.lock' 3 | puppet_env=${1:-production} 4 | 5 | setup() { 6 | if [ $(facter osfamily) == 'Debian' ]; then 7 | puppet resource package ruby ensure=present 8 | else 9 | puppet resource package rubygems ensure=present 10 | fi 11 | 12 | echo "### Installing gems with provider gem" 13 | puppet resource package hiera-eyaml provider=gem ensure=present 14 | puppet resource package deep_merge provider=gem ensure=present 15 | echo "### Installing gems with provider puppet_gem" 16 | puppet resource package hiera-eyaml provider=puppet_gem ensure=present 17 | puppet resource package deep_merge provider=puppet_gem ensure=present 18 | } 19 | 20 | # Run setup only the first time 21 | if [ -f $lock_file ]; then 22 | echo "### Found $lock_file. Skipping installation of dependencies needed for puppet apply mode" 23 | echo "## Remove $lock_file on the Vagrant VM to retry their installation" 24 | else 25 | echo "### Installing dependencies needed for puppet apply mode" 26 | setup && touch $lock_file 27 | fi 28 | -------------------------------------------------------------------------------- /vagrant/bin/vagrant-setup_puppetserver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | puppetserver_lock_file='/var/tmp/vagrant-setup_puppetserver.lock' 3 | # puppet_env=${1:-production} 4 | 5 | setup_puppetserver() { 6 | echo "### Installing git" 7 | puppet resource package git ensure=present 8 | echo "### Install puppetserver (onyl if not PE)" 9 | if ! [ -f /usr/lib/systemd/system/pe-puppetserver.service ]; then 10 | puppet resource package puppetserver ensure=present 11 | fi 12 | which puppetserver 2>/dev/null 13 | if [ "x$?" == "x0" ]; then 14 | echo "### Installing gems for puppetserver" 15 | puppetserver gem install hiera-eyaml 16 | puppetserver gem install deep_merge 17 | if [ -f /usr/lib/systemd/system/pe-puppetserver.service ]; then 18 | service pe-puppetserver restart 19 | else 20 | service puppetserver restart 21 | fi 22 | else 23 | return 1 24 | fi 25 | } 26 | 27 | # Run server setup only in Puppet server is installed 28 | if [ -f $puppetserver_lock_file ]; then 29 | echo "### Found $puppetserver_lock_file. Skipping installation of dependencies needed for puppet server" 30 | echo "## Remove $puppetserver_lock_file on the Vagrant VM to retry their installation" 31 | else 32 | echo "### Installing dependencies needed for puppet server" 33 | setup_puppetserver 34 | if [ "x$?" == "x0" ]; then 35 | touch $puppetserver_lock_file 36 | fi 37 | fi 38 | -------------------------------------------------------------------------------- /vagrant/bin/vm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | repo_dir="$(dirname $0)/../.." 3 | . "${repo_dir}/bin/functions" 4 | . "${repo_dir}/bin/config/proxysetup" 5 | . "${repo_dir}/bin/config/defaults" 6 | 7 | action=$1 8 | vm=$2 9 | env=${3-$vagrantenv} 10 | 11 | export VAGRANT_DOTFILE_PATH=$HOME/.vagrant 12 | mkdir -p $VAGRANT_DOTFILE_PATH 13 | 14 | if [ "x${env}" != "" ]; then 15 | cd "${repo_dir}/vagrant/environments/${env}" 16 | vagrant $action $vm 17 | else 18 | cd "${repo_dir}/vagrant/environments" 19 | for v in $(ls); do 20 | echo_title "vagrant/environments/${v}" 21 | cd $v 22 | if [ -d ".vagrant/machines/${vm}" ]; then 23 | echo_subtitle "Running vagrant ${action} ${vm}" 24 | vagrant $action $vm 25 | else 26 | if [ $action == 'status' ]; then 27 | vagrant $action 28 | fi 29 | true 30 | fi 31 | cd ../ 32 | done 33 | fi 34 | 35 | -------------------------------------------------------------------------------- /vagrant/environments/bare/README.md: -------------------------------------------------------------------------------- 1 | # Vagrant environment of bare OS machines 2 | 3 | This Vagrant environment is similar to ostest, in terms of choices of OS, 4 | bust provaide bare installations, without setup of any kind and without mount 5 | of local control-repo directory on the VM guest. 6 | 7 | Edit ```config.yaml``` in this directory to customise the VMs to test. 8 | 9 | To work in this Vagrant environment: 10 | 11 | cd 12 | cd vagrant/environment/bare 13 | 14 | # Show available Vagrant machines 15 | vagrant status 16 | 17 | # Customise them 18 | vi config.yaml 19 | 20 | # Define and parametrise the Puppet classes to test 21 | cd 22 | vi hieradata/role/bare.yaml 23 | 24 | 25 | -------------------------------------------------------------------------------- /vagrant/environments/bare/Vagrantfile: -------------------------------------------------------------------------------- 1 | ../../Vagrantfile -------------------------------------------------------------------------------- /vagrant/environments/bare/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Default settings for vms 3 | vm: 4 | memory: 512 5 | cpu: 1 6 | role: ostest 7 | puppet_apply: false 8 | puppet_agent: false 9 | facter_external_facts: false 10 | facter_trusted_facts: false 11 | synced_folder_type: vboxfs # Sync folders types: nfs, vboxfs 12 | 13 | network: 14 | range: 10.42.40.0/24 15 | ip_start_offset: 101 16 | domain: bare 17 | 18 | # Vagrant settings 19 | vagrant: 20 | # Update host's /etc/hosts if you have the hostmanager plugin. 21 | # Needed for automatic decommissioning of nodes. If false, you've to manage 22 | # manually ssl certs removal of reinstalled nodes. 23 | hostmanager.manage_host: false # If true and you have the hostmanager plugin 24 | 25 | puppet: 26 | version: latest 27 | env: devel 28 | zone: bare 29 | setup: false 30 | 31 | vbguest: 32 | auto_update: false 33 | 34 | # Nodes shown in vagrant status 35 | nodes: 36 | - hostname_base: redhat9 37 | box: rhel9 38 | - hostname_base: redhat8 39 | box: rhel8 40 | - hostname_base: redhat7 41 | box: rhel7 42 | - hostname_base: centos8 43 | box: centos8 44 | - hostname_base: centos7 45 | box: centos7 46 | - hostname_base: centos6 47 | box: centos6 48 | - hostname_base: oracle9 49 | box: oracle9 50 | - hostname_base: oracle8 51 | box: oracle8 52 | - hostname_base: ubuntu2204 53 | box: ubuntu2204 54 | - hostname_base: ubuntu2004 55 | box: ubuntu2004 56 | - hostname_base: ubuntu1804 57 | box: ubuntu1804 58 | - hostname_base: ubuntu1604 59 | box: ubuntu1604 60 | - hostname_base: ubuntu1404 61 | box: ubuntu1404 62 | - hostname_base: ubuntu1204 63 | box: ubuntu1204 64 | - hostname_base: debian10 65 | box: debian10 66 | - hostname_base: debian11 67 | box: debian11 68 | - hostname_base: debian10 69 | box: debian10 70 | - hostname_base: debian9 71 | box: debian9 72 | - hostname_base: debian8 73 | box: debian8 74 | - hostname_base: debian7 75 | box: debian7 76 | - hostname_base: suse15 77 | box: suse15 78 | - hostname_base: suse12 79 | box: suse12 80 | - hostname_base: suse11 81 | box: suse11 82 | - hostname_base: opensuse15 83 | box: opensuse15 84 | - hostname_base: alpine315 85 | box: alpine315 86 | - hostname_base: fedora37 87 | box: fedora37 88 | - hostname_base: fedora36 89 | box: fedora36 90 | - hostname_base: windows2012 91 | fqdn: windows2012-bare 92 | box: windows2012 93 | forwarded_port: 94 | guest: 3389 95 | host: 33891 96 | - hostname_base: windows2008 97 | fqdn: windows2008-bare 98 | box: windows2008 99 | forwarded_port: 100 | guest: 3389 101 | host: 33892 102 | - hostname_base: solaris11 103 | box: solaris11 104 | - hostname_base: solaris10 105 | box: solaris10 106 | - hostname_base: freebsd12 107 | box: freebsd12 108 | - hostname_base: freebsd11 109 | box: freebsd11 110 | - hostname_base: freebsd10 111 | box: freebsd10 112 | - hostname_base: osx1011 113 | box: osx1011 114 | vagrant_mount: false 115 | - hostname_base: osx1010 116 | box: osx1010 117 | vagrant_mount: false 118 | - hostname_base: rocky9 119 | box: rocky9 120 | - hostname_base: rocky8 121 | box: rocky8 122 | -------------------------------------------------------------------------------- /vagrant/environments/demo/Vagrantfile: -------------------------------------------------------------------------------- 1 | ../../Vagrantfile -------------------------------------------------------------------------------- /vagrant/environments/docker/Vagrantfile: -------------------------------------------------------------------------------- 1 | ../../Vagrantfile -------------------------------------------------------------------------------- /vagrant/environments/docker/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Default settings for vms 3 | vm: 4 | memory: 1024 5 | cpu: 1 6 | box: centos7 # From boxes list below 7 | puppet_apply: true 8 | puppet_agent: false 9 | synced_folder_type: vboxfs # Sync folders types: nfs, vboxfs 10 | 11 | network: 12 | range: 10.42.42.0/24 13 | ip_start_offset: 101 14 | domain: docker.psick.io 15 | 16 | vagrant: 17 | hostmanager.enable: false # If to enable hostmanager plugin 18 | hostmanager.manage_host: false # If to manage also the main host's hosts 19 | multi_user: false 20 | vm_provider: docker 21 | docker_image: puppet/puppet-agent-ubuntu 22 | 23 | puppet: 24 | version: latest 25 | env: devel 26 | zone: docker 27 | # master_hostname: dev-local-puppet-01 28 | 29 | # Nodes shown in vagrant status 30 | nodes: 31 | - role: git 32 | count: 1 33 | memory: 2048 34 | - role: ci 35 | count: 1 36 | memory: 2048 37 | - role: compilemaster 38 | count: 1 39 | memory: 2048 40 | - role: puppet_db 41 | hostname_base: puppet-db 42 | count: 1 43 | - role: puppet_mom 44 | hostname_base: puppet-mom 45 | count: 1 46 | memory: 4096 47 | ip_address: 10.42.42.10 48 | puppet_apply: true 49 | aliases: 50 | - puppet 51 | 52 | -------------------------------------------------------------------------------- /vagrant/environments/foss/README.md: -------------------------------------------------------------------------------- 1 | # Vagrant environment based on Puppet Open Source 2 | 3 | In this Vagrant environment machines are provisioned with Puppet Open Source. 4 | 5 | By default you have at disposal the ```puppet``` machine, who has a POS allinone installation, and other VMs for other roles, which use puppet agent on the puppet VM (which compiles catalogs based on code and data on this control-repo). 6 | 7 | Edit ```config.yaml``` in this directory to customise the VMs to test, the Puppet Open Source version to use and how you want your Vagrant environment to be. 8 | You can give a look to [config.yaml documentation here](/docs/vagrant.md#customisations). 9 | 10 | To work in this Vagrant environment: 11 | 12 | cd 13 | 14 | # Download or refresh modules listed in Puppetfile if needed 15 | r10k puppetfile install -v 16 | 17 | # Move to vagrant foss environment 18 | cd vagrant/environment/foss 19 | 20 | # Show available Vagrant machines 21 | vagrant status 22 | 23 | # Customise them, eventually updating the version to use 24 | vi config.yaml 25 | 26 | # Start the puppet VM. It will install Puppet Open Source from Puppet repositories 27 | vagrant up puppet.foss.psick.io 28 | 29 | # You might need to provision multiple times, at the beginning 30 | vagrant provision puppet.foss.psick.io 31 | 32 | # Then start the other VM you want to test. 33 | # They will run puppet agent pointing to the puppet vm 34 | vagrant up [vm] 35 | 36 | Note 1: It's recommended to run this Vagrant environment on hosts that have at least 8 Gb of RAM. Edit ```config.yaml``` to tune the memory to allocate to the VM. 37 | 38 | There is no web frontend for reporting at the moment. We are working on bootstrapping puppetboard onto the POS master. 39 | -------------------------------------------------------------------------------- /vagrant/environments/foss/Vagrantfile: -------------------------------------------------------------------------------- 1 | ../../Vagrantfile -------------------------------------------------------------------------------- /vagrant/environments/lab/Vagrantfile: -------------------------------------------------------------------------------- 1 | ../../Vagrantfile -------------------------------------------------------------------------------- /vagrant/environments/lab/install.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | # Derived from https://github.com/hashicorp/puppet-bootstrap/blob/master/windows.ps1 3 | 4 | .SYNOPSIS 5 | Installs Puppet on this machine. 6 | .DESCRIPTION 7 | Downloads and installs the Puppet-agent MSI package. 8 | This script requires administrative privileges. 9 | You can run this script from an old-style cmd.exe prompt using the 10 | following: 11 | powershell.exe -ExecutionPolicy Unrestricted -NoLogo -NoProfile -Command "& '.\puppet_install.ps1'" 12 | .PARAMETER MsiUrl 13 | This is the URL to the Puppet MSI file you want to install. This defaults 14 | to a version from PuppetLabs. 15 | .PARAMETER PuppetVersion 16 | This is the version of Puppet that you want to install. If you pass this it will override the version in the MsiUrl. 17 | This defaults to $null. 18 | .PARAMETER PuppetMaster 19 | This is the hostname of the Puppet Master to use. 20 | This defaults to puppet. 21 | .PARAMETER PuppetCertname 22 | This is the certname to use for the client. 23 | This defaults to puppet. 24 | #> 25 | param( 26 | [string]$MsiUrl = "https://downloads.puppetlabs.com/windows/puppet-agent-x64-latest.msi" 27 | ,[string]$PuppetVersion = $null 28 | ,[string]$PuppetMaster = "puppet" 29 | ,[string]$PuppetCertname = $null 30 | ) 31 | 32 | if ($PuppetVersion) { 33 | $MsiUrl = "https://downloads.puppetlabs.com/windows/puppet-agent-x64-$($PuppetVersion).msi" 34 | Write-Host "Puppet version $PuppetVersion specified, updated MsiUrl to `"$MsiUrl`"" 35 | } 36 | if ($PuppetCertname) { 37 | $CertnameArg = "PUPPET_AGENT_CERTNAME=$PuppetCertname" 38 | } else { 39 | $CertnameArg = " " 40 | } 41 | 42 | $PuppetInstalled = $false 43 | try { 44 | $ErrorActionPreference = "Stop"; 45 | Get-Command puppet | Out-Null 46 | $PuppetInstalled = $true 47 | $PuppetVersion=&puppet "--version" 48 | Write-Host "Puppet $PuppetVersion is installed. This process does not ensure the exact version or at least version specified, but only that puppet is installed. Exiting..." 49 | Exit 0 50 | } catch { 51 | Write-Host "Puppet is not installed, continuing..." 52 | } 53 | 54 | if (!($PuppetInstalled)) { 55 | $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) 56 | if (! ($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))) { 57 | Write-Host -ForegroundColor Red "You must run this script as an administrator." 58 | Exit 1 59 | } 60 | 61 | # Install it - msiexec will download from the url 62 | $install_args = @("/qn", "/norestart","/i", $MsiUrl, "PUPPET_MASTER_SERVER=$PuppetMaster", $CertnameArg) 63 | Write-Host "Installing Puppet. Running msiexec.exe $install_args" 64 | $process = Start-Process -FilePath msiexec.exe -ArgumentList $install_args -Wait -PassThru 65 | if ($process.ExitCode -ne 0) { 66 | Write-Host "Installer failed." 67 | Exit 1 68 | } 69 | 70 | # Stop the service that it autostarts 71 | Write-Host "Stopping Puppet service that is running by default..." 72 | Start-Sleep -s 5 73 | Stop-Service -Name puppet 74 | 75 | Write-Host "Puppet Agent successfully installed." 76 | } 77 | -------------------------------------------------------------------------------- /vagrant/environments/multiuser/README.md: -------------------------------------------------------------------------------- 1 | # Vagrant environment for multi-user setup 2 | 3 | This Vagrant environment is intended to be used on large Vagrant hosts where different users 4 | test their code on their own vagrant vms. 5 | 6 | A central Puppet server, configured via master_fqdn rant environment. 7 | In order to be able to use the local user Puppet code, the Puppet server ideally should run 8 | on the same Vagrant host where the different vms are running. 9 | 10 | Edit ```config.yaml``` in this directory to customise the VMs to test. 11 | 12 | puppet: 13 | master_vm: '' # Puppetserver is not a local VM 14 | master_fqdn: 'puppet.lab.psick.io' # FQDN of the Puppet server to use with puppet agent 15 | purge_via_ssh: false # Use ssh when purging puppet nodes from master_fqdn Puppet server 16 | 17 | network: 18 | domain: pe.psick.io # Name of DNS domain for the created machines 19 | ports_offset_map: # A map of users and relevant host port forwarding offset 20 | al: 10000 21 | lab: 20000 22 | 23 | 24 | To work in this Vagrant environment: 25 | 26 | cd 27 | cd vagrant/environment/multiuser 28 | 29 | # Show available Vagrant machines 30 | vagrant status 31 | 32 | # Customise them 33 | vi config.yaml 34 | 35 | # Set hiera data to test directly onm your own vm yaml file 36 | cd 37 | vi hieradata/host/-.yaml 38 | 39 | -------------------------------------------------------------------------------- /vagrant/environments/multiuser/Vagrantfile: -------------------------------------------------------------------------------- 1 | ../../Vagrantfile -------------------------------------------------------------------------------- /vagrant/environments/ostest/README.md: -------------------------------------------------------------------------------- 1 | # Vagrant environment for Operating Systems test 2 | 3 | This Vagrant environment allows you to test the code in your local copy of the control-repo 4 | on different Vagrant boxes for different Operating Systems. 5 | 6 | Edit ```config.yaml``` in this directory to customise the VMs to test. 7 | 8 | To work in this Vagrant environment: 9 | 10 | cd 11 | cd vagrant/environment/ostest 12 | 13 | # Show available Vagrant machines 14 | vagrant status 15 | 16 | # Customise them 17 | vi config.yaml 18 | 19 | # Define and parametrise the Puppet classes to test 20 | cd 21 | vi hieradata/role/ostest.yaml 22 | 23 | 24 | -------------------------------------------------------------------------------- /vagrant/environments/ostest/Vagrantfile: -------------------------------------------------------------------------------- 1 | ../../Vagrantfile -------------------------------------------------------------------------------- /vagrant/environments/pe/README.md: -------------------------------------------------------------------------------- 1 | # Vagrant environment based on Puppet Enterprise 2 | 3 | In this Vagrant environment machines are provisioned with Puppet Enterprise, thanks to the wonderful [pe_build](https://github.com/oscar-stack/vagrant-pe_build) plugin. 4 | 5 | By default you have at disposal the ```puppet``` machine, who has a PE allinone installation, and other VMs for other roles, which use puppet agent on the puppet VM (which compiles catalogs based on code and data on this control-repo). 6 | 7 | Edit ```config.yaml``` in this directory to customise the VMs to test, the Puppet Enterprise version to use and how you want your Vagrant environment to be. 8 | 9 | To work in this Vagrant environment: 10 | 11 | # You need the pe_build plugin 12 | vagrant plugin install vagrant-pe_build 13 | # You need the vagrant-vbguest plugin to inject the vbguest extension into the box at runtime 14 | vagrant plugin install vagrant-vbguest 15 | cd 16 | cd vagrant/environment/pe 17 | 18 | # Show available Vagrant machines 19 | vagrant status 20 | 21 | # Customise them, eventually updating the PE version to use 22 | vi config.yaml 23 | 24 | # Start the puppet. It will download PE tarball, install it and run puppet agent 25 | vagrant up puppet.pe.psick.io 26 | vagrant reload puppet.pe.psick.io # In case of errors. See Note 1 27 | vagrant provision puppet.pe.psick.io # See Note 1 28 | 29 | # Then start the other VM you want to test. 30 | # They will run puppet agent pointing to the puppet vm 31 | vagrant up [vm] # See Note 2 32 | 33 | 34 | Note 1: The first time a new PE tarball is downloaded from the net you may have an error as what follows, when provisioning the puppet: 35 | 36 | bash: line 2: /vagrant/.pe_build/puppet-enterprise-2016.2.1-el-7-x86_64/puppet-enterprise-installer: No such file or directory 37 | 38 | It looks like the newly downloaded PE tarball, placed in the ```.pe_build``` directory of this Vagrant environment, is not immediately available on the VM under its ```/vagrant``` directory. 39 | 40 | If the PE installation files are already in place when you vagrant up the puppet VM, you won't have this error, so the quick solution is (the very first time you use a new PE version): 41 | 42 | vagrant up puppet.pe.psick.io # It fails if ```.pe_build``` doesn't contain the installation files for your PE version 43 | vagrant reload puppet.pe.psick.io # Machines reloads and this times mounts ```/vagrant``` with all the expected files 44 | vagrant provision puppet.pe.psick.io # Do the real provisioning: it should install PE and run puppet agent with no errors 45 | 46 | 47 | Note 2: It's recommended to run this Vagrant environment on hosts that have at least 8 Gb of RAM. Edit ```config.yaml``` to tune the memory to allocate to the VM. 48 | 49 | To access the PE console from your host browse to **https://127.0.0.1:1643** 50 | 51 | Login: **admin** 52 | Password: **puppetlabs** 53 | 54 | 55 | -------------------------------------------------------------------------------- /vagrant/environments/pe/Vagrantfile: -------------------------------------------------------------------------------- 1 | ../../Vagrantfile --------------------------------------------------------------------------------