├── .fixtures.yml ├── .gitattributes ├── .gitignore ├── .gitlab-ci.yml ├── .librarian └── puppet │ └── config ├── .pdkignore ├── .puppet-lint.rc ├── .rspec ├── .rubocop.yml ├── .ruby-version ├── .travis.yml ├── .vscode └── extensions.json ├── .yardopts ├── Gemfile ├── LICENSE ├── Puppetfile ├── Puppetfile.lock ├── README.md ├── Rakefile ├── Vagrantfile ├── appveyor.yml ├── examples ├── amazon-linux.pp ├── init.pp ├── params.pp └── vagrant.pp ├── manifests ├── deps.pp ├── deps │ ├── debian.pp │ ├── osx.pp │ └── redhat.pp ├── init.pp ├── params.pp └── profile.pp ├── metadata.json ├── spec ├── classes │ └── awscli_spec.rb ├── default_facts.yml ├── defines │ └── awscli_profile_spec.rb └── spec_helper.rb └── templates ├── config_concat.erb └── credentials_concat.erb /.fixtures.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fixtures: 3 | forge_modules: 4 | epel: 5 | repo: "puppet/epel" 6 | ref: "3.0.1" 7 | concat: 8 | repo: "puppetlabs/concat" 9 | ref: "4.0.0" 10 | stdlib: "puppetlabs/stdlib" 11 | file_concat: 12 | repo: "electrical/file_concat" 13 | ref: "1.0.1" 14 | symlinks: 15 | awscli: "#{source_dir}" 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.rb eol=lf 2 | *.erb eol=lf 3 | *.pp eol=lf 4 | *.sh eol=lf 5 | *.epp eol=lf 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .*.sw[op] 3 | .metadata 4 | .tmp 5 | .yardoc 6 | .yardwarns 7 | *.iml 8 | /.bundle/ 9 | /.idea/ 10 | /.vagrant/ 11 | /coverage/ 12 | /bin/ 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 | .project 27 | .envrc 28 | /inventory.yaml 29 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | stages: 3 | - syntax 4 | - unit 5 | 6 | cache: 7 | paths: 8 | - vendor/bundle 9 | 10 | before_script: 11 | - bundle -v 12 | - rm Gemfile.lock || true 13 | - gem update --system $RUBYGEMS_VERSION 14 | - gem --version 15 | - bundle -v 16 | - bundle install --without system_tests --path vendor/bundle --jobs $(nproc) 17 | 18 | syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop-Ruby 2.5.3-Puppet ~> 6: 19 | stage: syntax 20 | image: ruby:2.5.3 21 | script: 22 | - bundle exec rake syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop 23 | variables: 24 | PUPPET_GEM_VERSION: '~> 6' 25 | 26 | parallel_spec-Ruby 2.5.3-Puppet ~> 6: 27 | stage: unit 28 | image: ruby:2.5.3 29 | script: 30 | - bundle exec rake parallel_spec 31 | variables: 32 | PUPPET_GEM_VERSION: '~> 6' 33 | 34 | parallel_spec-Ruby 2.4.5-Puppet ~> 5: 35 | stage: unit 36 | image: ruby:2.4.5 37 | script: 38 | - bundle exec rake parallel_spec 39 | variables: 40 | PUPPET_GEM_VERSION: '~> 5' 41 | 42 | -------------------------------------------------------------------------------- /.librarian/puppet/config: -------------------------------------------------------------------------------- 1 | --- 2 | LIBRARIAN_PUPPET_DESTRUCTIVE: 'false' 3 | LIBRARIAN_PUPPET_USE_V1_API: '1' 4 | -------------------------------------------------------------------------------- /.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 | .project 26 | .envrc 27 | /inventory.yaml 28 | /appveyor.yml 29 | /.fixtures.yml 30 | /Gemfile 31 | /.gitattributes 32 | /.gitignore 33 | /.gitlab-ci.yml 34 | /.pdkignore 35 | /Rakefile 36 | /rakelib/ 37 | /.rspec 38 | /.rubocop.yml 39 | /.travis.yml 40 | /.yardopts 41 | /spec/ 42 | /.vscode/ 43 | -------------------------------------------------------------------------------- /.puppet-lint.rc: -------------------------------------------------------------------------------- 1 | --relative 2 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | require: 3 | - rubocop-rspec 4 | - rubocop-i18n 5 | AllCops: 6 | DisplayCopNames: true 7 | TargetRubyVersion: '2.1' 8 | Include: 9 | - "./**/*.rb" 10 | Exclude: 11 | - bin/* 12 | - ".vendor/**/*" 13 | - "**/Gemfile" 14 | - "**/Rakefile" 15 | - pkg/**/* 16 | - spec/fixtures/**/* 17 | - vendor/**/* 18 | - "**/Puppetfile" 19 | - "**/Vagrantfile" 20 | - "**/Guardfile" 21 | Metrics/LineLength: 22 | Description: People have wide screens, use them. 23 | Max: 200 24 | GetText: 25 | Enabled: false 26 | GetText/DecorateString: 27 | Description: We don't want to decorate test output. 28 | Exclude: 29 | - spec/**/* 30 | RSpec/BeforeAfterAll: 31 | Description: Beware of using after(:all) as it may cause state to leak between tests. 32 | A necessary evil in acceptance testing. 33 | Exclude: 34 | - spec/acceptance/**/*.rb 35 | RSpec/HookArgument: 36 | Description: Prefer explicit :each argument, matching existing module's style 37 | EnforcedStyle: each 38 | Style/BlockDelimiters: 39 | Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to 40 | be consistent then. 41 | EnforcedStyle: braces_for_chaining 42 | Style/ClassAndModuleChildren: 43 | Description: Compact style reduces the required amount of indentation. 44 | EnforcedStyle: compact 45 | Style/EmptyElse: 46 | Description: Enforce against empty else clauses, but allow `nil` for clarity. 47 | EnforcedStyle: empty 48 | Style/FormatString: 49 | Description: Following the main puppet project's style, prefer the % format format. 50 | EnforcedStyle: percent 51 | Style/FormatStringToken: 52 | Description: Following the main puppet project's style, prefer the simpler template 53 | tokens over annotated ones. 54 | EnforcedStyle: template 55 | Style/Lambda: 56 | Description: Prefer the keyword for easier discoverability. 57 | EnforcedStyle: literal 58 | Style/RegexpLiteral: 59 | Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168 60 | EnforcedStyle: percent_r 61 | Style/TernaryParentheses: 62 | Description: Checks for use of parentheses around ternary conditions. Enforce parentheses 63 | on complex expressions for better readability, but seriously consider breaking 64 | it up. 65 | EnforcedStyle: require_parentheses_when_complex 66 | Style/TrailingCommaInArguments: 67 | Description: Prefer always trailing comma on multiline argument lists. This makes 68 | diffs, and re-ordering nicer. 69 | EnforcedStyleForMultiline: comma 70 | Style/TrailingCommaInLiteral: 71 | Description: Prefer always trailing comma on multiline literals. This makes diffs, 72 | and re-ordering nicer. 73 | EnforcedStyleForMultiline: comma 74 | Style/SymbolArray: 75 | Description: Using percent style obscures symbolic intent of array's contents. 76 | EnforcedStyle: brackets 77 | RSpec/MessageSpies: 78 | EnforcedStyle: receive 79 | Style/Documentation: 80 | Exclude: 81 | - lib/puppet/parser/functions/**/* 82 | - spec/**/* 83 | Style/WordArray: 84 | EnforcedStyle: brackets 85 | Style/CollectionMethods: 86 | Enabled: true 87 | Style/MethodCalledOnDoEndBlock: 88 | Enabled: true 89 | Style/StringMethods: 90 | Enabled: true 91 | Layout/EndOfLine: 92 | Enabled: false 93 | Layout/IndentHeredoc: 94 | Enabled: false 95 | Metrics/AbcSize: 96 | Enabled: false 97 | Metrics/BlockLength: 98 | Enabled: false 99 | Metrics/ClassLength: 100 | Enabled: false 101 | Metrics/CyclomaticComplexity: 102 | Enabled: false 103 | Metrics/MethodLength: 104 | Enabled: false 105 | Metrics/ModuleLength: 106 | Enabled: false 107 | Metrics/ParameterLists: 108 | Enabled: false 109 | Metrics/PerceivedComplexity: 110 | Enabled: false 111 | RSpec/DescribeClass: 112 | Enabled: false 113 | RSpec/ExampleLength: 114 | Enabled: false 115 | RSpec/MessageExpectation: 116 | Enabled: false 117 | RSpec/MultipleExpectations: 118 | Enabled: false 119 | RSpec/NestedGroups: 120 | Enabled: false 121 | Style/AsciiComments: 122 | Enabled: false 123 | Style/IfUnlessModifier: 124 | Enabled: false 125 | Style/SymbolProc: 126 | Enabled: false 127 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.5.7 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dist: xenial 3 | language: ruby 4 | cache: bundler 5 | before_install: 6 | - bundle -v 7 | - rm -f Gemfile.lock 8 | - gem update --system $RUBYGEMS_VERSION 9 | - gem --version 10 | - bundle -v 11 | script: 12 | - 'bundle exec rake $CHECK' 13 | bundler_args: --without system_tests 14 | rvm: 15 | - 2.5.3 16 | stages: 17 | - static 18 | - spec 19 | - acceptance 20 | - 21 | if: tag =~ ^v\d 22 | name: deploy 23 | matrix: 24 | fast_finish: true 25 | include: 26 | - 27 | env: CHECK="check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop syntax lint metadata_lint" 28 | stage: static 29 | - 30 | env: PUPPET_GEM_VERSION="~> 5.0" CHECK=parallel_spec 31 | rvm: 2.4.5 32 | stage: spec 33 | - 34 | env: PUPPET_GEM_VERSION="~> 6.0" CHECK=parallel_spec 35 | rvm: 2.5.3 36 | stage: spec 37 | - 38 | env: DEPLOY_TO_FORGE=yes 39 | stage: deploy 40 | branches: 41 | only: 42 | - master 43 | - /^v\d/ 44 | notifications: 45 | email: false 46 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "jpogran.puppet-vscode", 4 | "rebornix.Ruby" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --markup markdown 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source ENV['GEM_SOURCE'] || 'https://rubygems.org' 2 | 3 | def location_for(place_or_version, fake_version = nil) 4 | git_url_regex = %r{\A(?(https?|git)[:@][^#]*)(#(?.*))?} 5 | file_url_regex = %r{\Afile:\/\/(?.*)} 6 | 7 | if place_or_version && (git_url = place_or_version.match(git_url_regex)) 8 | [fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact 9 | elsif place_or_version && (file_url = place_or_version.match(file_url_regex)) 10 | ['>= 0', { path: File.expand_path(file_url[:path]), require: false }] 11 | else 12 | [place_or_version, { require: false }] 13 | end 14 | end 15 | 16 | ruby_version_segments = Gem::Version.new(RUBY_VERSION.dup).segments 17 | minor_version = ruby_version_segments[0..1].join('.') 18 | 19 | group :development do 20 | gem "fast_gettext", '1.1.0', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.1.0') 21 | gem "fast_gettext", require: false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.1.0') 22 | gem "json_pure", '<= 2.0.1', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') 23 | gem "json", '= 1.8.1', require: false if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('2.1.9') 24 | gem "json", '= 2.0.4', require: false if Gem::Requirement.create('~> 2.4.2').satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 25 | gem "json", '= 2.1.0', require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 26 | gem "rb-readline", '= 0.5.5', require: false, platforms: [:mswin, :mingw, :x64_mingw] 27 | gem "puppet-module-posix-default-r#{minor_version}", '~> 0.3', require: false, platforms: [:ruby] 28 | gem "puppet-module-posix-dev-r#{minor_version}", '~> 0.3', require: false, platforms: [:ruby] 29 | gem "puppet-module-win-default-r#{minor_version}", '~> 0.3', require: false, platforms: [:mswin, :mingw, :x64_mingw] 30 | gem "puppet-module-win-dev-r#{minor_version}", '~> 0.3', require: false, platforms: [:mswin, :mingw, :x64_mingw] 31 | end 32 | 33 | puppet_version = ENV['PUPPET_GEM_VERSION'] 34 | facter_version = ENV['FACTER_GEM_VERSION'] 35 | hiera_version = ENV['HIERA_GEM_VERSION'] 36 | 37 | gems = {} 38 | 39 | gems['puppet'] = location_for(puppet_version) 40 | 41 | # If facter or hiera versions have been specified via the environment 42 | # variables 43 | 44 | gems['facter'] = location_for(facter_version) if facter_version 45 | gems['hiera'] = location_for(hiera_version) if hiera_version 46 | 47 | if Gem.win_platform? && puppet_version =~ %r{^(file:///|git://)} 48 | # If we're using a Puppet gem on Windows which handles its own win32-xxx gem 49 | # dependencies (>= 3.5.0), set the maximum versions (see PUP-6445). 50 | gems['win32-dir'] = ['<= 0.4.9', require: false] 51 | gems['win32-eventlog'] = ['<= 0.6.5', require: false] 52 | gems['win32-process'] = ['<= 0.7.5', require: false] 53 | gems['win32-security'] = ['<= 0.2.5', require: false] 54 | gems['win32-service'] = ['0.8.8', require: false] 55 | end 56 | 57 | gems.each do |gem_name, gem_params| 58 | gem gem_name, *gem_params 59 | end 60 | 61 | # Evaluate Gemfile.local and ~/.gemfile if they exist 62 | extra_gemfiles = [ 63 | "#{__FILE__}.local", 64 | File.join(Dir.home, '.gemfile'), 65 | ] 66 | 67 | extra_gemfiles.each do |gemfile| 68 | if File.file?(gemfile) && File.readable?(gemfile) 69 | eval(File.read(gemfile), binding) 70 | end 71 | end 72 | # vim: syntax=ruby 73 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2015 Justin Downing 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Puppetfile: -------------------------------------------------------------------------------- 1 | forge 'https://forgeapi.puppetlabs.com' 2 | 3 | metadata 4 | -------------------------------------------------------------------------------- /Puppetfile.lock: -------------------------------------------------------------------------------- 1 | FORGE 2 | remote: https://forgeapi.puppetlabs.com 3 | specs: 4 | puppetlabs-concat (2.2.1) 5 | puppetlabs-stdlib (< 5.0.0, >= 4.2.0) 6 | puppetlabs-stdlib (4.16.0) 7 | puppet-epel (3.0.1) 8 | 9 | DEPENDENCIES 10 | puppetlabs-concat (< 5.0.0, >= 2.0.0) 11 | puppetlabs-stdlib (< 5.0.0, >= 4.0.0) 12 | puppet-epel (< 3.99.0, >= 3.0.0) 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # awscli 2 | 3 | [![Build Status](https://travis-ci.org/jdowning/puppet-awscli.png)](https://travis-ci.org/jdowning/puppet-awscli) [![Puppet Forge](https://img.shields.io/puppetforge/v/jdowning/awscli.svg)](https://forge.puppetlabs.com/jdowning/awscli) [![Puppet Forge](https://img.shields.io/puppetforge/dt/jdowning/awscli.svg)](https://forge.puppetlabs.com/jdowning/awscli) 4 | 5 | ## Description 6 | 7 | This Puppet module will install [awscli](https://github.com/aws/aws-cli). It is works with Debian, RedHat and OSX(Tested on Yosemite using boxen) based distros. 8 | 9 | OSX has been tested on Yosemite only and requires: 10 | - boxen https://boxen.github.com 11 | - boxen homebrew https://github.com/boxen/puppet-homebrew. 12 | - Packages python and brew-pip are require to be install using boxen. 13 | 14 | ## Installation 15 | 16 | `puppet module install --modulepath /path/to/puppet/modules jdowning-awscli` 17 | 18 | ## Usage 19 | 20 | `class { 'awscli': }` 21 | 22 | There are some optional class parameters, documentation can be found in [init.pp](manifests/init.pp). 23 | 24 | ### Profiles 25 | 26 | You may want to add a credentials for awscli and can do so using `awscli::profile`. 27 | If you just define access_key_id and secret key, these credentials will work only for the root user: 28 | 29 | ``` 30 | awscli::profile { 'myprofile': 31 | aws_access_key_id => 'MYAWSACCESSKEYID', 32 | aws_secret_access_key => 'MYAWSSECRETACESSKEY' 33 | } 34 | ``` 35 | 36 | You can also define a profile for a custom user: 37 | 38 | ``` 39 | awscli::profile { 'myprofile2': 40 | user => 'ubuntu', 41 | aws_access_key_id => 'MYAWSACCESSKEYID', 42 | aws_secret_access_key => 'MYAWSSECRETACESSKEY' 43 | } 44 | ``` 45 | 46 | If the user has a non-standard `${HOME}` location (`/home/${USER}` on Linux, 47 | `/Users/${USER}` on Mac OS X), you can specify the homedir explicitly: 48 | 49 | ``` 50 | awscli::profile { 'myprofile3': 51 | user => 'ubuntu', 52 | homedir => '/tmp', 53 | aws_access_key_id => 'MYAWSACCESSKEYID', 54 | aws_secret_access_key => 'MYAWSSECRETACESSKEY' 55 | } 56 | ``` 57 | 58 | To remove a profile, simply set `$ensure => 'absent'` 59 | ``` 60 | awscli::profile { 'myprofile3': 61 | ensure => 'absent', 62 | } 63 | ``` 64 | 65 | You can also define the profile's region and output format: 66 | 67 | ``` 68 | awscli::profile { 'myprofile4': 69 | user => 'ubuntu', 70 | aws_access_key_id => 'MYAWSACCESSKEYID', 71 | aws_secret_access_key => 'MYAWSSECRETACESSKEY' 72 | aws_region => 'eu-west-1', 73 | output => 'text', 74 | } 75 | ``` 76 | 77 | Finally, if you'd like to use a different profile name, you can specify profile_name directly as a parameter. You can read more in the [aws-cli docs](http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-multiple-profiles). (Note that this is 78 | a potentially breaking change if you depended on the `$title` for this previously): 79 | 80 | ``` 81 | awscli::profile { 'myprofile5': 82 | profile_name => 'foo', 83 | user => 'ubuntu', 84 | aws_access_key_id => 'MYAWSACCESSKEYID', 85 | aws_secret_access_key => 'MYAWSSECRETACESSKEY' 86 | aws_region => 'eu-west-1', 87 | output => 'text', 88 | } 89 | ``` 90 | 91 | The above will result in a file `~ubuntu/.aws/config` that looks like this: 92 | 93 | ``` 94 | [profile foo] 95 | region=eu-west-1 96 | output=text 97 | ``` 98 | 99 | and a file `~ubuntu/.aws/credentials` that looks like this: 100 | 101 | ``` 102 | [foo] 103 | aws_access_key_id=MYAWSACCESSKEYID 104 | aws_secret_access_key=MYAWSSECRETACESSKEY 105 | ``` 106 | 107 | If you do not provide `aws::profile::aws_access_key_id` and `awscli::profile::aws_secret_access_key`, 108 | then the aws-cli tool can use IAM roles to authenticate a user's request. 109 | 110 | ## Testing 111 | You can test this module with rspec: 112 | 113 | bundle install 114 | bundle exec rake spec 115 | 116 | ## Vagrant 117 | 118 | You can also test this module in a Vagrant box. There are two box definitons included in the 119 | Vagrant file for CentOS and Ubuntu testing. You will need to use `librarian-puppet` to setup dependencies: 120 | 121 | bundle install 122 | bundle exec librarian-puppet install 123 | 124 | To test both boxes: 125 | 126 | vagrant up 127 | 128 | To test one distribution: 129 | 130 | vagrant up [centos|ubuntu] 131 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'puppet_litmus/rake_tasks' if Bundler.rubygems.find_name('puppet_litmus').any? 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 | require 'puppet-strings/tasks' if Bundler.rubygems.find_name('puppet-strings').any? 7 | 8 | def changelog_user 9 | return unless Rake.application.top_level_tasks.include? "changelog" 10 | returnVal = nil || JSON.load(File.read('metadata.json'))['author'] 11 | raise "unable to find the changelog_user in .sync.yml, or the author in metadata.json" if returnVal.nil? 12 | puts "GitHubChangelogGenerator user:#{returnVal}" 13 | returnVal 14 | end 15 | 16 | def changelog_project 17 | return unless Rake.application.top_level_tasks.include? "changelog" 18 | returnVal = nil || JSON.load(File.read('metadata.json'))['source'].match(%r{.*/([^/]*)})[1] 19 | raise "unable to find the changelog_project in .sync.yml or the name in metadata.json" if returnVal.nil? 20 | puts "GitHubChangelogGenerator project:#{returnVal}" 21 | returnVal 22 | end 23 | 24 | def changelog_future_release 25 | return unless Rake.application.top_level_tasks.include? "changelog" 26 | returnVal = "v%s" % JSON.load(File.read('metadata.json'))['version'] 27 | raise "unable to find the future_release (version) in metadata.json" if returnVal.nil? 28 | puts "GitHubChangelogGenerator future_release:#{returnVal}" 29 | returnVal 30 | end 31 | 32 | PuppetLint.configuration.send('disable_relative') 33 | 34 | if Bundler.rubygems.find_name('github_changelog_generator').any? 35 | GitHubChangelogGenerator::RakeTask.new :changelog do |config| 36 | 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? 37 | config.user = "#{changelog_user}" 38 | config.project = "#{changelog_project}" 39 | config.future_release = "#{changelog_future_release}" 40 | config.exclude_labels = ['maintenance'] 41 | 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)." 42 | config.add_pr_wo_labels = true 43 | config.issues = false 44 | config.merge_prefix = "### UNCATEGORIZED PRS; GO LABEL THEM" 45 | config.configure_sections = { 46 | "Changed" => { 47 | "prefix" => "### Changed", 48 | "labels" => ["backwards-incompatible"], 49 | }, 50 | "Added" => { 51 | "prefix" => "### Added", 52 | "labels" => ["feature", "enhancement"], 53 | }, 54 | "Fixed" => { 55 | "prefix" => "### Fixed", 56 | "labels" => ["bugfix"], 57 | }, 58 | } 59 | end 60 | else 61 | desc 'Generate a Changelog from GitHub' 62 | task :changelog do 63 | raise <= Gem::Version.new('2.2.2')" 74 | EOM 75 | end 76 | end 77 | 78 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure("2") do |config| 5 | config.vm.hostname = 'puppet-awscli' 6 | config.vm.synced_folder "modules", "/tmp/puppet-modules", type: "rsync", rsync__exclude: ".git/" 7 | config.vm.synced_folder ".", "/tmp/puppet-modules/awscli", type: "rsync", rsync__exclude: ".git/" 8 | 9 | config.vm.define "centos" do |centos| 10 | centos.vm.box = 'centos64' 11 | centos.vm.box_url = 'http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210.box' 12 | centos.vm.provision :puppet do |puppet| 13 | puppet.manifests_path = "tests" 14 | puppet.manifest_file = "vagrant.pp" 15 | puppet.options = ["--modulepath", "/tmp/puppet-modules"] 16 | end 17 | end 18 | 19 | config.vm.define "ubuntu", primary: true do |ubuntu| 20 | ubuntu.vm.box = 'ubuntu64' 21 | ubuntu.vm.box_url = 'http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210.box' 22 | ubuntu.vm.provision :shell, :inline => 'aptitude update' 23 | ubuntu.vm.provision :puppet do |puppet| 24 | puppet.manifests_path = "tests" 25 | puppet.manifest_file = "vagrant.pp" 26 | puppet.options = ["--modulepath", "/tmp/puppet-modules"] 27 | end 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.x.{build} 3 | branches: 4 | only: 5 | - master 6 | - release 7 | skip_commits: 8 | message: /^\(?doc\)?.*/ 9 | clone_depth: 10 10 | init: 11 | - SET 12 | - 'mkdir C:\ProgramData\PuppetLabs\code && exit 0' 13 | - 'mkdir C:\ProgramData\PuppetLabs\facter && exit 0' 14 | - 'mkdir C:\ProgramData\PuppetLabs\hiera && exit 0' 15 | - 'mkdir C:\ProgramData\PuppetLabs\puppet\var && exit 0' 16 | environment: 17 | matrix: 18 | - 19 | RUBY_VERSION: 24-x64 20 | CHECK: syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop 21 | - 22 | PUPPET_GEM_VERSION: ~> 5.0 23 | RUBY_VERSION: 24 24 | CHECK: parallel_spec 25 | - 26 | PUPPET_GEM_VERSION: ~> 5.0 27 | RUBY_VERSION: 24-x64 28 | CHECK: parallel_spec 29 | - 30 | PUPPET_GEM_VERSION: ~> 6.0 31 | RUBY_VERSION: 25 32 | CHECK: parallel_spec 33 | - 34 | PUPPET_GEM_VERSION: ~> 6.0 35 | RUBY_VERSION: 25-x64 36 | CHECK: parallel_spec 37 | matrix: 38 | fast_finish: true 39 | install: 40 | - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH% 41 | - bundle install --jobs 4 --retry 2 --without system_tests 42 | - type Gemfile.lock 43 | build: off 44 | test_script: 45 | - bundle exec puppet -V 46 | - ruby -v 47 | - gem -v 48 | - bundle -v 49 | - bundle exec rake %CHECK% 50 | notifications: 51 | - provider: Email 52 | to: 53 | - nobody@nowhere.com 54 | on_build_success: false 55 | on_build_failure: false 56 | on_build_status_changed: false 57 | -------------------------------------------------------------------------------- /examples/amazon-linux.pp: -------------------------------------------------------------------------------- 1 | # There is no need to declare `class { 'awscli': }` since the 2 | # awscli package is already installed by default in Amazon Linux 3 | awscli::profile { 'default': 4 | user => 'ec2-user', 5 | aws_access_key_id => 'MYTESTACCESSKEYID', 6 | aws_secret_access_key => 'MYTESTSECRETACCESSKEY' 7 | } 8 | -------------------------------------------------------------------------------- /examples/init.pp: -------------------------------------------------------------------------------- 1 | # The baseline for module testing used by Puppet Labs is that each manifest 2 | # should have a corresponding test manifest that declares that class or defined 3 | # type. 4 | # 5 | # Tests are then run by using puppet apply --noop (to check for compilation 6 | # errors and view a log of events) or by fully applying the test in a virtual 7 | # environment (to compare the resulting system state to the desired state). 8 | # 9 | # Learn more about module testing here: 10 | # http://docs.puppetlabs.com/guides/tests_smoke.html 11 | # 12 | include awscli 13 | -------------------------------------------------------------------------------- /examples/params.pp: -------------------------------------------------------------------------------- 1 | # The baseline for module testing used by Puppet Labs is that each manifest 2 | # should have a corresponding test manifest that declares that class or defined 3 | # type. 4 | # 5 | # Tests are then run by using puppet apply --noop (to check for compilation 6 | # errors and view a log of events) or by fully applying the test in a virtual 7 | # environment (to compare the resulting system state to the desired state). 8 | # 9 | # Learn more about module testing here: 10 | # http://docs.puppetlabs.com/guides/tests_smoke.html 11 | # 12 | class {'awscli': 13 | pkg_dev => 'python', 14 | pkg_pip => 'brew-pip' 15 | } 16 | -------------------------------------------------------------------------------- /examples/vagrant.pp: -------------------------------------------------------------------------------- 1 | class { 'awscli': version => 'latest' } 2 | awscli::profile { 'default': 3 | user => 'vagrant', 4 | aws_access_key_id => 'MYTESTACCESSKEYID', 5 | aws_secret_access_key => 'MYTESTSECRETACCESSKEY' 6 | } 7 | -------------------------------------------------------------------------------- /manifests/deps.pp: -------------------------------------------------------------------------------- 1 | # == Class: awscli::deps 2 | # 3 | # This module manages awscli dependencies and should *not* be called directly. 4 | # 5 | # === Authors 6 | # 7 | # Justin Downing 8 | # 9 | # === Copyright 10 | # 11 | # Copyright 2014 Justin Downing 12 | # 13 | class awscli::deps ( 14 | $proxy = $awscli::params::proxy, 15 | ) inherits awscli::params { 16 | case $::os['family'] { 17 | 'Debian': { 18 | contain awscli::deps::debian 19 | } 20 | 'RedHat': { 21 | class { 'awscli::deps::redhat': 22 | proxy => $proxy, 23 | } 24 | contain awscli::deps::redhat 25 | } 26 | 'Darwin': { 27 | contain awscli::deps::osx 28 | } 29 | default: { fail("The awscli module does not support ${::osfamily}") } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /manifests/deps/debian.pp: -------------------------------------------------------------------------------- 1 | # == Class: awscli::deps::debian 2 | # 3 | # This module manages awscli dependencies for Debian $::os['family']. 4 | # 5 | class awscli::deps::debian { 6 | if $awscli::install_pkgdeps { 7 | if ! defined(Package[ $awscli::pkg_dev ]) { 8 | package { $awscli::pkg_dev: ensure => installed } 9 | } 10 | } 11 | 12 | if $awscli::install_pip { 13 | if ! defined(Package[ $awscli::pkg_pip ]) { 14 | package { $awscli::pkg_pip: ensure => installed } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /manifests/deps/osx.pp: -------------------------------------------------------------------------------- 1 | # == Class: awscli::deps::osx 2 | # 3 | # This module manages awscli dependencies for Darwin $::os['family']. 4 | # 5 | class awscli::deps::osx { 6 | if $awscli::install_pkgdeps { 7 | if ! defined(Package[ $awscli::pkg_dev ]) { 8 | package { $awscli::pkg_dev: ensure => installed, provider => homebrew } 9 | } 10 | } 11 | if $awscli::install_pip { 12 | if ! defined(Package[ $awscli::pkg_pip ]) { 13 | package { $awscli::pkg_pip: ensure => installed, provider => homebrew } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /manifests/deps/redhat.pp: -------------------------------------------------------------------------------- 1 | # == Class: awscli::deps::redhat 2 | # 3 | # This module manages awscli dependencies for redhat $::os['family']. 4 | # 5 | class awscli::deps::redhat ( 6 | $proxy = $awscli::params::proxy, 7 | $manage_epel = $awscli::manage_epel, 8 | ) inherits awscli::params { 9 | # Check if we manage epel repositories 10 | if $manage_epel { 11 | # Check if we have a proxy to setup with EPEL 12 | if $proxy != undef { 13 | class { '::epel': 14 | epel_proxy => $proxy, 15 | } 16 | } 17 | else { 18 | include ::epel 19 | } 20 | 21 | Package { require => Class['epel'] } 22 | } 23 | if $awscli::install_pkgdeps { 24 | if ! defined(Package[ $awscli::pkg_dev ]) { 25 | package { $awscli::pkg_dev: ensure => installed } 26 | } 27 | } 28 | if $awscli::install_pip { 29 | if ! defined(Package[ $awscli::pkg_pip ]) { 30 | package { $awscli::pkg_pip: ensure => installed } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manifests/init.pp: -------------------------------------------------------------------------------- 1 | # == Class: awscli 2 | # 3 | # Install awscli 4 | # 5 | # === Parameters 6 | # 7 | # [$version] 8 | # Provides ability to change the version of awscli being installed. 9 | # Default: 'present' 10 | # This variable is required. 11 | # 12 | # [$pkg_dev] 13 | # Provides ability to install a specific Dev package by name. 14 | # Default: See awscli::params Class 15 | # This variable is optional. 16 | # 17 | # [$pkg_pip] 18 | # Provides ability to install a specific PIP package by name. 19 | # Default: See awscli::params Class 20 | # This variable is optional. 21 | # 22 | # [$manage_epel] 23 | # Boolean flag to install the EPEL repositories. 24 | # Default: true 25 | # This variable is optional. 26 | # 27 | # [$install_pkgdeps] 28 | # Boolean flag to install the package dependencies or not 29 | # Default: true 30 | # 31 | # [$install_pip] 32 | # Boolean flag to install pip or not 33 | # Default: true 34 | # 35 | # [$provider] 36 | # One of "pip" or "apt" 37 | # 38 | # [$proxy] 39 | # String proxy variable for use with EPEL module 40 | # Default: undef 41 | # 42 | # [$install_options] 43 | # Array of install options for the awscli Pip package 44 | # Default: undef 45 | # 46 | # === Examples 47 | # 48 | # class { awscli: } 49 | # 50 | # === Authors 51 | # 52 | # Justin Downing 53 | # 54 | # === Copyright 55 | # 56 | # Copyright 2014 Justin Downing 57 | # 58 | class awscli ( 59 | $version = 'present', 60 | $pkg_dev = $awscli::params::pkg_dev, 61 | $pkg_pip = $awscli::params::pkg_pip, 62 | $manage_epel = true, 63 | $install_pkgdeps = true, 64 | $install_pip = true, 65 | $provider = 'pip', 66 | $proxy = $awscli::params::proxy, 67 | $install_options = $awscli::params::install_options, 68 | ) inherits awscli::params { 69 | 70 | case $provider { 71 | 'pip','pip3': { 72 | class { '::awscli::deps': 73 | proxy => $proxy, 74 | } 75 | 76 | package { 'awscli': 77 | ensure => $version, 78 | provider => $provider, 79 | install_options => $install_options, 80 | require => [ 81 | Package[$pkg_pip], 82 | Class['awscli::deps'], 83 | ], 84 | } 85 | } 86 | 87 | default: { 88 | package { 'awscli': 89 | ensure => $version, 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /manifests/params.pp: -------------------------------------------------------------------------------- 1 | # == Class: awscli::params 2 | # 3 | # This class manages awscli parameters depending on the platform and 4 | # should *not* be called directly. 5 | # 6 | class awscli::params { 7 | 8 | $proxy = undef 9 | $install_options = undef 10 | 11 | case $::os['family'] { 12 | 'Debian': { 13 | $pkg_dev = 'python-dev' 14 | $pkg_pip = 'python-pip' 15 | } 16 | 'RedHat': { 17 | if $::os['name'] == 'Amazon' { 18 | $pkg_dev = 'python27-devel' 19 | } else { 20 | $pkg_dev = 'python-devel' 21 | } 22 | 23 | case $::os['release']['major'] { 24 | '7': { 25 | $pkg_pip = 'python2-pip' 26 | } 27 | default: { 28 | $pkg_pip = 'python-pip' 29 | } 30 | } 31 | } 32 | 'Darwin': { 33 | $pkg_dev = 'python' 34 | $pkg_pip = 'brew-pip' 35 | } 36 | default: { fail("The awscli module does not support ${::os['family']}") } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /manifests/profile.pp: -------------------------------------------------------------------------------- 1 | # == Define: awscli::profile 2 | # 3 | # Configures an aws-cli profile 4 | # 5 | # === Variables 6 | # 7 | # [$ensure] 8 | # Control whether the profile should be present or not 9 | # Default: present 10 | # 11 | # [$user] 12 | # The user for whom the profile will be installed 13 | # 14 | # [$group] 15 | # The group for whom the profile will be installed 16 | # 17 | # [$homedir] 18 | # The home directory where the config and credentials will be placed 19 | # 20 | # [$aws_access_key_id] 21 | # The aws_access_key_id for this profile. If not specified, aws-cli can 22 | # can use IAM roles to authenticate. 23 | # 24 | # [$aws_secret_access_key] 25 | # The aws_secret_access_key for this profile. If not specified, aws-cli can 26 | # can use IAM roles to authenticate. 27 | # 28 | # [$role_arn] 29 | # The ARN for the role to use in this profile. The source_profile must 30 | # be supplied when role_arn is specified 31 | # 32 | # [$source_profile] 33 | # The profile to use for credentials to assume the specified role 34 | # 35 | # [$role_session_name] 36 | # An identifier for the assumed role session 37 | # 38 | # [$aws_region] 39 | # The aws_region for this profile 40 | # Default: us-east-1 41 | # 42 | # [$profile_name] 43 | # The name of the AWS profile 44 | # Default: default 45 | # 46 | # [$output] 47 | # The output format used for this profile 48 | # Default: json 49 | # 50 | # === Example 51 | # 52 | # awscli::profile { 'tsmith-awscli': 53 | # user => 'tsmith', 54 | # aws_access_key_id => 'access_key', 55 | # aws_secret_access_key => 'secret_key', 56 | # aws_region => 'us-west-2', 57 | # role_arn => 'arn:aws:iam::123456789012:role/MyRole', 58 | # source_profile => 'user', 59 | # role_session_name => 'mysession', 60 | # profile_name => 'default', 61 | # output => 'text', 62 | # } 63 | # 64 | define awscli::profile( 65 | $ensure = 'present', 66 | $user = 'root', 67 | $group = undef, 68 | $homedir = undef, 69 | $aws_access_key_id = undef, 70 | $aws_secret_access_key = undef, 71 | $role_arn = undef, 72 | $source_profile = undef, 73 | $role_session_name = undef, 74 | $aws_region = 'us-east-1', 75 | $profile_name = 'default', 76 | $output = 'json', 77 | ) { 78 | if $aws_access_key_id == undef and $aws_secret_access_key == undef { 79 | info ('AWS keys for awscli::profile. Your will need IAM roles configured.') 80 | $skip_credentials = true 81 | } else { 82 | $skip_credentials = false 83 | } 84 | 85 | if $homedir { 86 | $homedir_real = $homedir 87 | } else { 88 | if $user != 'root' { 89 | $homedir_real = $::os['family']? { 90 | 'Darwin' => "/Users/${user}", 91 | default => "/home/${user}" 92 | } 93 | } else { 94 | $homedir_real = '/root' 95 | } 96 | } 97 | 98 | if ($group == undef) { 99 | if $user != 'root' { 100 | $group_real = $::os['family']? { 101 | 'Darwin' => 'staff', 102 | default => $user 103 | } 104 | } else { 105 | $group_real = 'root' 106 | } 107 | } else { 108 | $group_real = $group 109 | } 110 | 111 | # ensure $homedir/.aws is available 112 | if !defined(File["${homedir_real}/.aws"]) { 113 | file { "${homedir_real}/.aws": 114 | ensure => 'directory', 115 | owner => $user, 116 | group => $group_real, 117 | mode => '0700', 118 | } 119 | } 120 | 121 | # setup credentials 122 | if ! $skip_credentials { 123 | if !defined(Concat["${homedir_real}/.aws/credentials"]) { 124 | concat { "${homedir_real}/.aws/credentials": 125 | ensure => 'present', 126 | owner => $user, 127 | group => $group_real, 128 | mode => '0600', 129 | show_diff => false, 130 | require => File["${homedir_real}/.aws"], 131 | } 132 | } 133 | 134 | if ( $ensure == 'present' ) { 135 | concat::fragment { "${title}-credentials": 136 | target => "${homedir_real}/.aws/credentials", 137 | content => template('awscli/credentials_concat.erb'), 138 | } 139 | } 140 | } 141 | 142 | # setup config 143 | if !defined(Concat["${homedir_real}/.aws/config"]) { 144 | concat { "${homedir_real}/.aws/config": 145 | ensure => 'present', 146 | owner => $user, 147 | group => $group_real, 148 | mode => '0600', 149 | require => File["${homedir_real}/.aws"], 150 | } 151 | } 152 | 153 | if ( $ensure == 'present' ) { 154 | concat::fragment { "${title}-config": 155 | target => "${homedir_real}/.aws/config", 156 | content => template('awscli/config_concat.erb'), 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jdowning-awscli", 3 | "version": "2.3.0", 4 | "author": "Justin Downing", 5 | "summary": "Install awscli", 6 | "license": "Apache-2.0", 7 | "source": "https://github.com/jdowning/puppet-awscli.git", 8 | "project_page": "https://github.com/jdowning/puppet-awscli", 9 | "issues_url": "https://github.com/jdowning/puppet-awscli/issues", 10 | "dependencies": [ 11 | { 12 | "name": "puppet/epel", 13 | "version_requirement": ">= 3.0.0 <3.99.0" 14 | }, 15 | { 16 | "name": "puppetlabs/stdlib", 17 | "version_requirement": ">= 4.0.0 <7.0.0" 18 | }, 19 | { 20 | "name": "puppetlabs/concat", 21 | "version_requirement": ">= 2.0.0 <7.0.0" 22 | } 23 | ], 24 | "operatingsystem_support": [ 25 | { 26 | "operatingsystem": "Darwin", 27 | "operatingsystemrelease": [ 28 | "10.8", 29 | "10.9", 30 | "10.10" 31 | ] 32 | }, 33 | { 34 | "operatingsystem": "CentOS", 35 | "operatingsystemrelease": [ 36 | "5", 37 | "6", 38 | "7", 39 | "8" 40 | ] 41 | }, 42 | { 43 | "operatingsystem": "OracleLinux", 44 | "operatingsystemrelease": [ 45 | "5", 46 | "6", 47 | "7" 48 | ] 49 | }, 50 | { 51 | "operatingsystem": "RedHat", 52 | "operatingsystemrelease": [ 53 | "5", 54 | "6", 55 | "7" 56 | ] 57 | }, 58 | { 59 | "operatingsystem": "Scientific", 60 | "operatingsystemrelease": [ 61 | "5", 62 | "6", 63 | "7" 64 | ] 65 | }, 66 | { 67 | "operatingsystem": "Debian", 68 | "operatingsystemrelease": [ 69 | "6", 70 | "7" 71 | ] 72 | }, 73 | { 74 | "operatingsystem": "Ubuntu", 75 | "operatingsystemrelease": [ 76 | "10.04", 77 | "12.04", 78 | "14.04", 79 | "16.04", 80 | "18.04" 81 | ] 82 | } 83 | ], 84 | "requirements": [ 85 | { 86 | "name": "puppet", 87 | "version_requirement": ">= 3.4.3 <= 6.99.0" 88 | } 89 | ], 90 | "description": "Install awscli", 91 | "pdk-version": "1.12.0", 92 | "template-url": "pdk-default#1.12.0", 93 | "template-ref": "1.12.0-0-g55d9ae2" 94 | } 95 | -------------------------------------------------------------------------------- /spec/classes/awscli_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'awscli', type: 'class' do 4 | context 'supported OS' do 5 | ['darwin', 'debian', 'redhat'].each do |osfamily| 6 | describe "#{osfamily} installation" do 7 | let(:facts) do 8 | { 9 | os: { 10 | family: osfamily.to_s, 11 | release: { 12 | major: 6, 13 | }, 14 | }, 15 | } 16 | end 17 | let(:params) do 18 | { 19 | manage_epel: false, 20 | } 21 | end 22 | 23 | it { is_expected.to contain_class('awscli::deps') } 24 | 25 | it do 26 | is_expected.to contain_package('awscli').with( 27 | 'ensure' => 'present', 28 | 'provider' => 'pip', 29 | 'install_options' => nil, 30 | ) 31 | end 32 | end 33 | 34 | describe 'proxy pip setup' do 35 | let(:facts) do 36 | { 37 | os: { 38 | family: osfamily.to_s, 39 | release: { 40 | major: 6, 41 | }, 42 | }, 43 | } 44 | end 45 | let(:params) do 46 | { 47 | install_options: ['--proxy foo'], 48 | manage_epel: false, 49 | } 50 | end 51 | 52 | it do 53 | is_expected.to contain_package('awscli').with( 54 | 'ensure' => 'present', 55 | 'provider' => 'pip', 56 | 'install_options' => ['--proxy foo'], 57 | ) 58 | end 59 | end 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /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 | ipaddress: "172.16.254.254" 6 | is_pe: false 7 | macaddress: "AA:AA:AA:AA:AA:AA" 8 | -------------------------------------------------------------------------------- /spec/defines/awscli_profile_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'awscli::profile', type: :define do 4 | context 'on supported operatingsystems' do 5 | ['darwin', 'debian', 'redhat'].each do |osfamily| 6 | describe "#{osfamily} installation" do 7 | let(:facts) do 8 | { 9 | os: { family: osfamily.to_s }, 10 | concat_basedir: '/var/lib/puppet/concat/', 11 | } 12 | end 13 | let(:title) { 'test_profile' } 14 | let(:params) { {} } 15 | 16 | it 'creates profile for root if no user is given' do 17 | is_expected.to contain_file('/root/.aws').with( 18 | ensure: 'directory', 19 | owner: 'root', 20 | group: 'root', 21 | mode: '0700', 22 | ) 23 | is_expected.to contain_concat('/root/.aws/config').with( 24 | owner: 'root', 25 | group: 'root', 26 | mode: '0600', 27 | ) 28 | is_expected.to contain_concat__fragment('test_profile-config').with( 29 | target: '/root/.aws/config', 30 | ) 31 | end 32 | end 33 | end 34 | end 35 | 36 | context 'on supported Linux distributions' do 37 | ['debian', 'redhat'].each do |osfamily| 38 | describe "#{osfamily} installation" do 39 | let(:facts) do 40 | { 41 | os: { family: osfamily.to_s }, 42 | concat_basedir: '/var/lib/puppet/concat/', 43 | } 44 | end 45 | let(:title) { 'test_profile' } 46 | let(:params) do 47 | { 48 | 'aws_access_key_id' => 'TESTAWSACCESSKEYID', 49 | 'aws_secret_access_key' => 'TESTSECRETACCESSKEY', 50 | } 51 | end 52 | 53 | it 'creates profile for root if no user is given' do 54 | is_expected.to contain_file('/root/.aws').with( 55 | ensure: 'directory', 56 | owner: 'root', 57 | group: 'root', 58 | mode: '0700', 59 | ) 60 | is_expected.to contain_concat('/root/.aws/config').with( 61 | owner: 'root', 62 | group: 'root', 63 | mode: '0600', 64 | ) 65 | is_expected.to contain_concat__fragment('test_profile-config').with( 66 | target: '/root/.aws/config', 67 | ) 68 | is_expected.to contain_concat('/root/.aws/credentials').with( 69 | owner: 'root', 70 | group: 'root', 71 | mode: '0600', 72 | ) 73 | is_expected.to contain_concat__fragment('test_profile-credentials').with( 74 | target: '/root/.aws/credentials', 75 | ) 76 | end 77 | 78 | it 'creates profile for user test' do 79 | params['user'] = 'test' 80 | is_expected.to contain_file('/home/test/.aws').with( 81 | ensure: 'directory', 82 | owner: 'test', 83 | group: 'test', 84 | mode: '0700', 85 | ) 86 | is_expected.to contain_concat('/home/test/.aws/config').with( 87 | owner: 'test', 88 | group: 'test', 89 | mode: '0600', 90 | ) 91 | is_expected.to contain_concat__fragment('test_profile-config').with( 92 | target: '/home/test/.aws/config', 93 | ) 94 | is_expected.to contain_concat('/home/test/.aws/credentials').with( 95 | owner: 'test', 96 | group: 'test', 97 | mode: '0600', 98 | ) 99 | is_expected.to contain_concat__fragment('test_profile-credentials').with( 100 | target: '/home/test/.aws/credentials', 101 | ) 102 | end 103 | 104 | it 'creates profile for user test and group testGroup' do 105 | params.merge!('user' => 'test', 106 | 'group' => 'testGroup') 107 | is_expected.to contain_file('/home/test/.aws').with( 108 | ensure: 'directory', 109 | owner: 'test', 110 | group: 'testGroup', 111 | mode: '0700', 112 | ) 113 | is_expected.to contain_concat('/home/test/.aws/config').with( 114 | owner: 'test', 115 | group: 'testGroup', 116 | mode: '0600', 117 | ) 118 | is_expected.to contain_concat__fragment('test_profile-config').with( 119 | target: '/home/test/.aws/config', 120 | ) 121 | is_expected.to contain_concat('/home/test/.aws/credentials').with( 122 | owner: 'test', 123 | group: 'testGroup', 124 | mode: '0600', 125 | ) 126 | is_expected.to contain_concat__fragment('test_profile-credentials').with( 127 | target: '/home/test/.aws/credentials', 128 | ) 129 | end 130 | 131 | it 'creates profile for user test with homedir /tmp' do 132 | params.merge!('user' => 'test', 133 | 'homedir' => '/tmp') 134 | is_expected.to contain_file('/tmp/.aws').with( 135 | ensure: 'directory', 136 | owner: 'test', 137 | group: 'test', 138 | mode: '0700', 139 | ) 140 | is_expected.to contain_concat('/tmp/.aws/config').with( 141 | owner: 'test', 142 | group: 'test', 143 | mode: '0600', 144 | ) 145 | is_expected.to contain_concat__fragment('test_profile-config').with( 146 | target: '/tmp/.aws/config', 147 | ) 148 | is_expected.to contain_concat('/tmp/.aws/credentials').with( 149 | owner: 'test', 150 | group: 'test', 151 | mode: '0600', 152 | ) 153 | is_expected.to contain_concat__fragment('test_profile-credentials').with( 154 | target: '/tmp/.aws/credentials', 155 | ) 156 | end 157 | 158 | it 'creates profile for user test with group testGroup with homedir /tmp' do 159 | params.merge!('user' => 'test', 160 | 'group' => 'testGroup', 161 | 'homedir' => '/tmp') 162 | is_expected.to contain_file('/tmp/.aws').with( 163 | ensure: 'directory', 164 | owner: 'test', 165 | group: 'testGroup', 166 | mode: '0700', 167 | ) 168 | is_expected.to contain_concat('/tmp/.aws/config').with( 169 | owner: 'test', 170 | group: 'testGroup', 171 | mode: '0600', 172 | ) 173 | is_expected.to contain_concat__fragment('test_profile-config').with( 174 | target: '/tmp/.aws/config', 175 | ) 176 | is_expected.to contain_concat('/tmp/.aws/credentials').with( 177 | owner: 'test', 178 | group: 'testGroup', 179 | mode: '0600', 180 | ) 181 | is_expected.to contain_concat__fragment('test_profile-credentials').with( 182 | target: '/tmp/.aws/credentials', 183 | ) 184 | end 185 | end 186 | end 187 | end 188 | 189 | context 'on Darwin' do 190 | let(:facts) do 191 | { 192 | os: { family: 'Darwin' }, 193 | concat_basedir: '/var/lib/puppet/concat/', 194 | } 195 | end 196 | 197 | let(:title) { 'test_profile' } 198 | 199 | let(:params) do 200 | { 201 | 'user' => 'test', 202 | 'aws_access_key_id' => 'TESTAWSACCESSKEYID', 203 | 'aws_secret_access_key' => 'TESTSECRETACCESSKEY', 204 | } 205 | end 206 | 207 | it 'creates profile for user test' do 208 | is_expected.to contain_file('/Users/test/.aws').with( 209 | ensure: 'directory', 210 | owner: 'test', 211 | group: 'staff', 212 | mode: '0700', 213 | ) 214 | is_expected.to contain_concat('/Users/test/.aws/config').with( 215 | owner: 'test', 216 | group: 'staff', 217 | mode: '0600', 218 | ) 219 | is_expected.to contain_concat__fragment('test_profile-config').with( 220 | target: '/Users/test/.aws/config', 221 | ) 222 | is_expected.to contain_concat('/Users/test/.aws/credentials').with( 223 | owner: 'test', 224 | group: 'staff', 225 | mode: '0600', 226 | ) 227 | is_expected.to contain_concat__fragment('test_profile-credentials').with( 228 | target: '/Users/test/.aws/credentials', 229 | ) 230 | end 231 | 232 | it 'creates profile for user test and group staff' do 233 | params['group'] = 'testGroup' 234 | is_expected.to contain_file('/Users/test/.aws').with( 235 | ensure: 'directory', 236 | owner: 'test', 237 | group: 'testGroup', 238 | mode: '0700', 239 | ) 240 | is_expected.to contain_concat('/Users/test/.aws/config').with( 241 | owner: 'test', 242 | group: 'testGroup', 243 | mode: '0600', 244 | ) 245 | is_expected.to contain_concat__fragment('test_profile-config').with( 246 | target: '/Users/test/.aws/config', 247 | ) 248 | is_expected.to contain_concat('/Users/test/.aws/credentials').with( 249 | owner: 'test', 250 | group: 'testGroup', 251 | mode: '0600', 252 | ) 253 | is_expected.to contain_concat__fragment('test_profile-credentials').with( 254 | target: '/Users/test/.aws/credentials', 255 | ) 256 | end 257 | 258 | it 'creates profile for user test with homedir /tmp' do 259 | params.merge!('user' => 'test', 260 | 'homedir' => '/tmp') 261 | is_expected.to contain_file('/tmp/.aws').with( 262 | ensure: 'directory', 263 | owner: 'test', 264 | group: 'staff', 265 | mode: '0700', 266 | ) 267 | is_expected.to contain_concat('/tmp/.aws/config').with( 268 | owner: 'test', 269 | group: 'staff', 270 | mode: '0600', 271 | ) 272 | is_expected.to contain_concat__fragment('test_profile-config').with( 273 | target: '/tmp/.aws/config', 274 | ) 275 | is_expected.to contain_concat('/tmp/.aws/credentials').with( 276 | owner: 'test', 277 | group: 'staff', 278 | mode: '0600', 279 | ) 280 | is_expected.to contain_concat__fragment('test_profile-credentials').with( 281 | target: '/tmp/.aws/credentials', 282 | ) 283 | end 284 | 285 | it 'creates profile for user test with group staff with homedir /tmp' do 286 | params.merge!('user' => 'test', 287 | 'group' => 'testGroup', 288 | 'homedir' => '/tmp') 289 | is_expected.to contain_file('/tmp/.aws').with( 290 | ensure: 'directory', 291 | owner: 'test', 292 | group: 'testGroup', 293 | mode: '0700', 294 | ) 295 | is_expected.to contain_concat('/tmp/.aws/config').with( 296 | owner: 'test', 297 | group: 'testGroup', 298 | mode: '0600', 299 | ) 300 | is_expected.to contain_concat__fragment('test_profile-config').with( 301 | target: '/tmp/.aws/config', 302 | ) 303 | is_expected.to contain_concat('/tmp/.aws/credentials').with( 304 | owner: 'test', 305 | group: 'testGroup', 306 | mode: '0600', 307 | ) 308 | is_expected.to contain_concat__fragment('test_profile-credentials').with( 309 | target: '/tmp/.aws/credentials', 310 | ) 311 | end 312 | end 313 | end 314 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'puppetlabs_spec_helper/module_spec_helper' 2 | require 'rspec-puppet-facts' 3 | 4 | require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) 5 | 6 | include RspecPuppetFacts 7 | 8 | default_facts = { 9 | puppetversion: Puppet.version, 10 | facterversion: Facter.version, 11 | } 12 | 13 | default_fact_files = [ 14 | File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')), 15 | File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')), 16 | ] 17 | 18 | default_fact_files.each do |f| 19 | next unless File.exist?(f) && File.readable?(f) && File.size?(f) 20 | 21 | begin 22 | default_facts.merge!(YAML.safe_load(File.read(f), [], [], true)) 23 | rescue => e 24 | RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" 25 | end 26 | end 27 | 28 | # read default_facts and merge them over what is provided by facterdb 29 | default_facts.each do |fact, value| 30 | add_custom_fact fact, value 31 | end 32 | 33 | RSpec.configure do |c| 34 | c.default_facts = default_facts 35 | c.before :each do 36 | # set to strictest setting for testing 37 | # by default Puppet runs at warning level 38 | Puppet.settings[:strict] = :warning 39 | end 40 | c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] 41 | c.after(:suite) do 42 | end 43 | end 44 | 45 | # Ensures that a module is defined 46 | # @param module_name Name of the module 47 | def ensure_module_defined(module_name) 48 | module_name.split('::').reduce(Object) do |last_module, next_module| 49 | last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false) 50 | last_module.const_get(next_module, false) 51 | end 52 | end 53 | 54 | # 'spec_overrides' from sync.yml will appear below this line 55 | -------------------------------------------------------------------------------- /templates/config_concat.erb: -------------------------------------------------------------------------------- 1 | <% if @profile_name == 'default' -%> 2 | [<%= @profile_name %>] 3 | <% else -%> 4 | [profile <%= @profile_name %>] 5 | <% end -%> 6 | region=<%= @aws_region %> 7 | output=<%= @output %> 8 | <% if @role_arn -%> 9 | role_arn=<%= @role_arn %> 10 | <% end -%> 11 | <% if @source_profile -%> 12 | source_profile=<%= @source_profile %> 13 | <% end -%> 14 | <% if @role_session_name -%> 15 | role_session_name=<%= @role_session_name %> 16 | <% end -%> 17 | -------------------------------------------------------------------------------- /templates/credentials_concat.erb: -------------------------------------------------------------------------------- 1 | [<%= @profile_name %>] 2 | aws_access_key_id=<%= @aws_access_key_id %> 3 | aws_secret_access_key=<%= @aws_secret_access_key %> 4 | --------------------------------------------------------------------------------