├── .devcontainer ├── Dockerfile ├── README.md └── devcontainer.json ├── .fixtures.yml ├── .gitattributes ├── .github ├── pull_request_template.md └── workflows │ ├── ci.yml │ ├── mend.yml │ ├── nightly.yml │ ├── release.yml │ └── release_prep.yml ├── .gitignore ├── .gitpod.Dockerfile ├── .gitpod.yml ├── .pdkignore ├── .puppet-lint.rc ├── .rspec ├── .rubocop.yml ├── .rubocop_todo.yml ├── .sync.yml ├── .vscode └── extensions.json ├── .yardopts ├── CHANGELOG.md ├── CODEOWNERS ├── CONTRIBUTING.md ├── Gemfile ├── HISTORY.md ├── LICENSE ├── NOTICE ├── README.md ├── REFERENCE.md ├── Rakefile ├── data └── common.yaml ├── hiera.yaml ├── lib └── puppet │ ├── provider │ └── java_ks │ │ └── keytool.rb │ └── type │ └── java_ks.rb ├── manifests └── config.pp ├── metadata.json ├── pdk.yaml ├── provision.yaml └── spec ├── acceptance ├── certs │ ├── ca.der │ ├── ca.pem │ ├── ca2.pem │ ├── chain.pem │ ├── chain2.pem │ ├── leaf.p12 │ ├── leaf.pem │ ├── leaf2.p12 │ ├── leafchain.pem │ ├── leafchain2.pem │ ├── leafkey.pem │ └── privkey.pem ├── chain_key_spec.rb ├── content_spec.rb ├── destkeypass_spec.rb ├── keystore_spec.rb ├── pkcs12_spec.rb ├── private_key_spec.rb └── truststore_spec.rb ├── default_facts.yml ├── spec_helper.rb ├── spec_helper_acceptance.rb ├── spec_helper_acceptance_local.rb ├── spec_helper_local.rb └── unit └── puppet ├── provider └── java_ks │ └── keytool_spec.rb └── type └── java_ks_spec.rb /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM puppet/pdk:latest 2 | 3 | # [Optional] Uncomment this section to install additional packages. 4 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 5 | # && apt-get -y install --no-install-recommends 6 | 7 | -------------------------------------------------------------------------------- /.devcontainer/README.md: -------------------------------------------------------------------------------- 1 | # devcontainer 2 | 3 | 4 | For format details, see https://aka.ms/devcontainer.json. 5 | 6 | For config options, see the README at: 7 | https://github.com/microsoft/vscode-dev-containers/tree/v0.140.1/containers/puppet 8 | 9 | ``` json 10 | { 11 | "name": "Puppet Development Kit (Community)", 12 | "dockerFile": "Dockerfile", 13 | 14 | // Set *default* container specific settings.json values on container create. 15 | "settings": { 16 | "terminal.integrated.profiles.linux": { 17 | "bash": { 18 | "path": "bash", 19 | } 20 | } 21 | }, 22 | 23 | // Add the IDs of extensions you want installed when the container is created. 24 | "extensions": [ 25 | "puppet.puppet-vscode", 26 | "rebornix.Ruby" 27 | ], 28 | 29 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 30 | "forwardPorts": [], 31 | 32 | // Use 'postCreateCommand' to run commands after the container is created. 33 | "postCreateCommand": "pdk --version", 34 | } 35 | ``` 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Puppet Development Kit (Community)", 3 | "dockerFile": "Dockerfile", 4 | 5 | "settings": { 6 | "terminal.integrated.profiles.linux": { 7 | "bash": { 8 | "path": "bash" 9 | } 10 | } 11 | }, 12 | 13 | "extensions": [ 14 | "puppet.puppet-vscode", 15 | "rebornix.Ruby" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.fixtures.yml: -------------------------------------------------------------------------------- 1 | fixtures: 2 | repositories: 3 | facts: 'https://github.com/puppetlabs/puppetlabs-facts.git' 4 | provision: 'https://github.com/puppetlabs/provision.git' 5 | puppet_agent: 6 | repo: 'https://github.com/puppetlabs/puppetlabs-puppet_agent.git' 7 | ref: v4.21.0 8 | forge_modules: 9 | chocolatey: "puppetlabs/chocolatey" 10 | java: "puppetlabs/java" 11 | powershell: "puppetlabs/powershell" 12 | registry: "puppetlabs/registry" 13 | stdlib: "puppetlabs/stdlib" 14 | symlinks: 15 | java_ks: "#{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 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Summary 2 | Provide a detailed description of all the changes present in this pull request. 3 | 4 | ## Additional Context 5 | Add any additional context about the problem here. 6 | - [ ] Root cause and the steps to reproduce. (If applicable) 7 | - [ ] Thought process behind the implementation. 8 | 9 | ## Related Issues (if any) 10 | Mention any related issues or pull requests. 11 | 12 | ## Checklist 13 | - [ ] 🟢 Spec tests. 14 | - [ ] 🟢 Acceptance tests. 15 | - [ ] Manually verified. (For example `puppet apply`) -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: "ci" 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - "main" 7 | workflow_dispatch: 8 | 9 | jobs: 10 | Spec: 11 | uses: "puppetlabs/cat-github-actions/.github/workflows/module_ci.yml@main" 12 | secrets: "inherit" 13 | 14 | Acceptance: 15 | needs: Spec 16 | uses: "puppetlabs/cat-github-actions/.github/workflows/module_acceptance.yml@main" 17 | secrets: "inherit" 18 | with: 19 | runs_on: "ubuntu-24.04" 20 | -------------------------------------------------------------------------------- /.github/workflows/mend.yml: -------------------------------------------------------------------------------- 1 | name: "mend" 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - "main" 7 | schedule: 8 | - cron: "0 0 * * *" 9 | workflow_dispatch: 10 | 11 | jobs: 12 | 13 | mend: 14 | uses: "puppetlabs/cat-github-actions/.github/workflows/mend_ruby.yml@main" 15 | secrets: "inherit" 16 | -------------------------------------------------------------------------------- /.github/workflows/nightly.yml: -------------------------------------------------------------------------------- 1 | name: "nightly" 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | workflow_dispatch: 7 | 8 | jobs: 9 | Spec: 10 | uses: "puppetlabs/cat-github-actions/.github/workflows/module_ci.yml@main" 11 | secrets: "inherit" 12 | 13 | Acceptance: 14 | needs: Spec 15 | uses: "puppetlabs/cat-github-actions/.github/workflows/module_acceptance.yml@main" 16 | secrets: "inherit" 17 | with: 18 | runs_on: "ubuntu-24.04" 19 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "Publish module" 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | release: 8 | uses: "puppetlabs/cat-github-actions/.github/workflows/module_release.yml@main" 9 | secrets: "inherit" 10 | -------------------------------------------------------------------------------- /.github/workflows/release_prep.yml: -------------------------------------------------------------------------------- 1 | name: "Release Prep" 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: "Module version to be released. Must be a valid semver string. (1.2.3)" 8 | required: true 9 | 10 | jobs: 11 | release_prep: 12 | uses: "puppetlabs/cat-github-actions/.github/workflows/module_release_prep.yml@main" 13 | with: 14 | version: "${{ github.event.inputs.version }}" 15 | secrets: "inherit" 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 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 | /.vendor/ 23 | /convert_report.txt 24 | /update_report.txt 25 | .DS_Store 26 | .project 27 | .envrc 28 | /inventory.yaml 29 | /spec/fixtures/litmus_inventory.yaml 30 | .resource_types 31 | .modules 32 | .task_cache.json 33 | .plan_cache.json 34 | .rerun.json 35 | bolt-debug.log 36 | -------------------------------------------------------------------------------- /.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 && \ 7 | sudo apt-get install -y pdk zsh puppet-agent && \ 8 | sudo apt-get clean && \ 9 | sudo rm -rf /var/lib/apt/lists/* 10 | RUN sudo usermod -s $(which zsh) gitpod && \ 11 | sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" && \ 12 | echo "plugins=(git gitignore github gem pip bundler python ruby docker docker-compose)" >> /home/gitpod/.zshrc && \ 13 | 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 && \ 14 | sudo /opt/puppetlabs/puppet/bin/gem install puppet-debugger hub -N && \ 15 | mkdir -p /home/gitpod/.config/puppet && \ 16 | /opt/puppetlabs/puppet/bin/ruby -r yaml -e "puts ({'disabled' => true}).to_yaml" > /home/gitpod/.config/puppet/analytics.yml 17 | RUN rm -f puppet6-release-bionic.deb puppet-tools-release-bionic.deb 18 | ENTRYPOINT /usr/bin/zsh 19 | -------------------------------------------------------------------------------- /.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@1.2.0:f5iEPbmOj6FoFTOV6q8LTg== 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 | /.vendor/ 23 | /convert_report.txt 24 | /update_report.txt 25 | .DS_Store 26 | .project 27 | .envrc 28 | /inventory.yaml 29 | /spec/fixtures/litmus_inventory.yaml 30 | .resource_types 31 | .modules 32 | .task_cache.json 33 | .plan_cache.json 34 | .rerun.json 35 | bolt-debug.log 36 | /.fixtures.yml 37 | /Gemfile 38 | /.gitattributes 39 | /.github/ 40 | /.gitignore 41 | /.pdkignore 42 | /.puppet-lint.rc 43 | /Rakefile 44 | /rakelib/ 45 | /.rspec 46 | /..yml 47 | /.yardopts 48 | /spec/ 49 | /.vscode/ 50 | /.sync.yml 51 | /.devcontainer/ 52 | -------------------------------------------------------------------------------- /.puppet-lint.rc: -------------------------------------------------------------------------------- 1 | --relative 2 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | require: 3 | - rubocop-performance 4 | - rubocop-rspec 5 | AllCops: 6 | NewCops: enable 7 | DisplayCopNames: true 8 | TargetRubyVersion: '2.6' 9 | Include: 10 | - "**/*.rb" 11 | Exclude: 12 | - bin/* 13 | - ".vendor/**/*" 14 | - "**/Gemfile" 15 | - "**/Rakefile" 16 | - pkg/**/* 17 | - spec/fixtures/**/* 18 | - vendor/**/* 19 | - "**/Puppetfile" 20 | - "**/Vagrantfile" 21 | - "**/Guardfile" 22 | inherit_from: ".rubocop_todo.yml" 23 | Layout/LineLength: 24 | Description: People have wide screens, use them. 25 | Max: 200 26 | RSpec/BeforeAfterAll: 27 | Description: Beware of using after(:all) as it may cause state to leak between tests. 28 | A necessary evil in acceptance testing. 29 | Exclude: 30 | - spec/acceptance/**/*.rb 31 | RSpec/HookArgument: 32 | Description: Prefer explicit :each argument, matching existing module's style 33 | EnforcedStyle: each 34 | RSpec/DescribeSymbol: 35 | Exclude: 36 | - spec/unit/facter/**/*.rb 37 | Style/BlockDelimiters: 38 | Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to 39 | be consistent then. 40 | EnforcedStyle: braces_for_chaining 41 | Style/ClassAndModuleChildren: 42 | Description: Compact style reduces the required amount of indentation. 43 | EnforcedStyle: compact 44 | Style/EmptyElse: 45 | Description: Enforce against empty else clauses, but allow `nil` for clarity. 46 | EnforcedStyle: empty 47 | Style/FormatString: 48 | Description: Following the main puppet project's style, prefer the % format format. 49 | EnforcedStyle: percent 50 | Style/FormatStringToken: 51 | Description: Following the main puppet project's style, prefer the simpler template 52 | tokens over annotated ones. 53 | EnforcedStyle: template 54 | Style/Lambda: 55 | Description: Prefer the keyword for easier discoverability. 56 | EnforcedStyle: literal 57 | Style/RegexpLiteral: 58 | Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168 59 | EnforcedStyle: percent_r 60 | Style/TernaryParentheses: 61 | Description: Checks for use of parentheses around ternary conditions. Enforce parentheses 62 | on complex expressions for better readability, but seriously consider breaking 63 | it up. 64 | EnforcedStyle: require_parentheses_when_complex 65 | Style/TrailingCommaInArguments: 66 | Description: Prefer always trailing comma on multiline argument lists. This makes 67 | diffs, and re-ordering nicer. 68 | EnforcedStyleForMultiline: comma 69 | Style/TrailingCommaInArrayLiteral: 70 | Description: Prefer always trailing comma on multiline literals. This makes diffs, 71 | and re-ordering nicer. 72 | EnforcedStyleForMultiline: comma 73 | Style/SymbolArray: 74 | Description: Using percent style obscures symbolic intent of array's contents. 75 | EnforcedStyle: brackets 76 | RSpec/MessageSpies: 77 | EnforcedStyle: receive 78 | Style/Documentation: 79 | Exclude: 80 | - lib/puppet/parser/functions/**/* 81 | - spec/**/* 82 | Style/WordArray: 83 | EnforcedStyle: brackets 84 | Performance/AncestorsInclude: 85 | Enabled: true 86 | Performance/BigDecimalWithNumericArgument: 87 | Enabled: true 88 | Performance/BlockGivenWithExplicitBlock: 89 | Enabled: true 90 | Performance/CaseWhenSplat: 91 | Enabled: true 92 | Performance/ConstantRegexp: 93 | Enabled: true 94 | Performance/MethodObjectAsBlock: 95 | Enabled: true 96 | Performance/RedundantSortBlock: 97 | Enabled: true 98 | Performance/RedundantStringChars: 99 | Enabled: true 100 | Performance/ReverseFirst: 101 | Enabled: true 102 | Performance/SortReverse: 103 | Enabled: true 104 | Performance/Squeeze: 105 | Enabled: true 106 | Performance/StringInclude: 107 | Enabled: true 108 | Performance/Sum: 109 | Enabled: true 110 | Style/CollectionMethods: 111 | Enabled: true 112 | Style/MethodCalledOnDoEndBlock: 113 | Enabled: true 114 | Style/StringMethods: 115 | Enabled: true 116 | Bundler/GemFilename: 117 | Enabled: false 118 | Bundler/InsecureProtocolSource: 119 | Enabled: false 120 | Capybara/CurrentPathExpectation: 121 | Enabled: false 122 | Capybara/VisibilityMatcher: 123 | Enabled: false 124 | Gemspec/DuplicatedAssignment: 125 | Enabled: false 126 | Gemspec/OrderedDependencies: 127 | Enabled: false 128 | Gemspec/RequiredRubyVersion: 129 | Enabled: false 130 | Gemspec/RubyVersionGlobalsUsage: 131 | Enabled: false 132 | Layout/ArgumentAlignment: 133 | Enabled: false 134 | Layout/BeginEndAlignment: 135 | Enabled: false 136 | Layout/ClosingHeredocIndentation: 137 | Enabled: false 138 | Layout/EmptyComment: 139 | Enabled: false 140 | Layout/EmptyLineAfterGuardClause: 141 | Enabled: false 142 | Layout/EmptyLinesAroundArguments: 143 | Enabled: false 144 | Layout/EmptyLinesAroundAttributeAccessor: 145 | Enabled: false 146 | Layout/EndOfLine: 147 | Enabled: false 148 | Layout/FirstArgumentIndentation: 149 | Enabled: false 150 | Layout/HashAlignment: 151 | Enabled: false 152 | Layout/HeredocIndentation: 153 | Enabled: false 154 | Layout/LeadingEmptyLines: 155 | Enabled: false 156 | Layout/SpaceAroundMethodCallOperator: 157 | Enabled: false 158 | Layout/SpaceInsideArrayLiteralBrackets: 159 | Enabled: false 160 | Layout/SpaceInsideReferenceBrackets: 161 | Enabled: false 162 | Lint/BigDecimalNew: 163 | Enabled: false 164 | Lint/BooleanSymbol: 165 | Enabled: false 166 | Lint/ConstantDefinitionInBlock: 167 | Enabled: false 168 | Lint/DeprecatedOpenSSLConstant: 169 | Enabled: false 170 | Lint/DisjunctiveAssignmentInConstructor: 171 | Enabled: false 172 | Lint/DuplicateElsifCondition: 173 | Enabled: false 174 | Lint/DuplicateRequire: 175 | Enabled: false 176 | Lint/DuplicateRescueException: 177 | Enabled: false 178 | Lint/EmptyConditionalBody: 179 | Enabled: false 180 | Lint/EmptyFile: 181 | Enabled: false 182 | Lint/ErbNewArguments: 183 | Enabled: false 184 | Lint/FloatComparison: 185 | Enabled: false 186 | Lint/HashCompareByIdentity: 187 | Enabled: false 188 | Lint/IdentityComparison: 189 | Enabled: false 190 | Lint/InterpolationCheck: 191 | Enabled: false 192 | Lint/MissingCopEnableDirective: 193 | Enabled: false 194 | Lint/MixedRegexpCaptureTypes: 195 | Enabled: false 196 | Lint/NestedPercentLiteral: 197 | Enabled: false 198 | Lint/NonDeterministicRequireOrder: 199 | Enabled: false 200 | Lint/OrderedMagicComments: 201 | Enabled: false 202 | Lint/OutOfRangeRegexpRef: 203 | Enabled: false 204 | Lint/RaiseException: 205 | Enabled: false 206 | Lint/RedundantCopEnableDirective: 207 | Enabled: false 208 | Lint/RedundantRequireStatement: 209 | Enabled: false 210 | Lint/RedundantSafeNavigation: 211 | Enabled: false 212 | Lint/RedundantWithIndex: 213 | Enabled: false 214 | Lint/RedundantWithObject: 215 | Enabled: false 216 | Lint/RegexpAsCondition: 217 | Enabled: false 218 | Lint/ReturnInVoidContext: 219 | Enabled: false 220 | Lint/SafeNavigationConsistency: 221 | Enabled: false 222 | Lint/SafeNavigationWithEmpty: 223 | Enabled: false 224 | Lint/SelfAssignment: 225 | Enabled: false 226 | Lint/SendWithMixinArgument: 227 | Enabled: false 228 | Lint/ShadowedArgument: 229 | Enabled: false 230 | Lint/StructNewOverride: 231 | Enabled: false 232 | Lint/ToJSON: 233 | Enabled: false 234 | Lint/TopLevelReturnWithArgument: 235 | Enabled: false 236 | Lint/TrailingCommaInAttributeDeclaration: 237 | Enabled: false 238 | Lint/UnreachableLoop: 239 | Enabled: false 240 | Lint/UriEscapeUnescape: 241 | Enabled: false 242 | Lint/UriRegexp: 243 | Enabled: false 244 | Lint/UselessMethodDefinition: 245 | Enabled: false 246 | Lint/UselessTimes: 247 | Enabled: false 248 | Metrics/AbcSize: 249 | Enabled: false 250 | Metrics/BlockLength: 251 | Enabled: false 252 | Metrics/BlockNesting: 253 | Enabled: false 254 | Metrics/ClassLength: 255 | Enabled: false 256 | Metrics/CyclomaticComplexity: 257 | Enabled: false 258 | Metrics/MethodLength: 259 | Enabled: false 260 | Metrics/ModuleLength: 261 | Enabled: false 262 | Metrics/ParameterLists: 263 | Enabled: false 264 | Metrics/PerceivedComplexity: 265 | Enabled: false 266 | Migration/DepartmentName: 267 | Enabled: false 268 | Naming/AccessorMethodName: 269 | Enabled: false 270 | Naming/BlockParameterName: 271 | Enabled: false 272 | Naming/HeredocDelimiterCase: 273 | Enabled: false 274 | Naming/HeredocDelimiterNaming: 275 | Enabled: false 276 | Naming/MemoizedInstanceVariableName: 277 | Enabled: false 278 | Naming/MethodParameterName: 279 | Enabled: false 280 | Naming/RescuedExceptionsVariableName: 281 | Enabled: false 282 | Naming/VariableNumber: 283 | Enabled: false 284 | Performance/BindCall: 285 | Enabled: false 286 | Performance/DeletePrefix: 287 | Enabled: false 288 | Performance/DeleteSuffix: 289 | Enabled: false 290 | Performance/InefficientHashSearch: 291 | Enabled: false 292 | Performance/UnfreezeString: 293 | Enabled: false 294 | Performance/UriDefaultParser: 295 | Enabled: false 296 | RSpec/Be: 297 | Enabled: false 298 | RSpec/Capybara/FeatureMethods: 299 | Enabled: false 300 | RSpec/ContainExactly: 301 | Enabled: false 302 | RSpec/ContextMethod: 303 | Enabled: false 304 | RSpec/ContextWording: 305 | Enabled: false 306 | RSpec/DescribeClass: 307 | Enabled: false 308 | RSpec/EmptyHook: 309 | Enabled: false 310 | RSpec/EmptyLineAfterExample: 311 | Enabled: false 312 | RSpec/EmptyLineAfterExampleGroup: 313 | Enabled: false 314 | RSpec/EmptyLineAfterHook: 315 | Enabled: false 316 | RSpec/ExampleLength: 317 | Enabled: false 318 | RSpec/ExampleWithoutDescription: 319 | Enabled: false 320 | RSpec/ExpectChange: 321 | Enabled: false 322 | RSpec/ExpectInHook: 323 | Enabled: false 324 | RSpec/FactoryBot/AttributeDefinedStatically: 325 | Enabled: false 326 | RSpec/FactoryBot/CreateList: 327 | Enabled: false 328 | RSpec/FactoryBot/FactoryClassName: 329 | Enabled: false 330 | RSpec/HooksBeforeExamples: 331 | Enabled: false 332 | RSpec/ImplicitBlockExpectation: 333 | Enabled: false 334 | RSpec/ImplicitSubject: 335 | Enabled: false 336 | RSpec/LeakyConstantDeclaration: 337 | Enabled: false 338 | RSpec/LetBeforeExamples: 339 | Enabled: false 340 | RSpec/MatchArray: 341 | Enabled: false 342 | RSpec/MissingExampleGroupArgument: 343 | Enabled: false 344 | RSpec/MultipleExpectations: 345 | Enabled: false 346 | RSpec/MultipleMemoizedHelpers: 347 | Enabled: false 348 | RSpec/MultipleSubjects: 349 | Enabled: false 350 | RSpec/NestedGroups: 351 | Enabled: false 352 | RSpec/PredicateMatcher: 353 | Enabled: false 354 | RSpec/ReceiveCounts: 355 | Enabled: false 356 | RSpec/ReceiveNever: 357 | Enabled: false 358 | RSpec/RepeatedExampleGroupBody: 359 | Enabled: false 360 | RSpec/RepeatedExampleGroupDescription: 361 | Enabled: false 362 | RSpec/RepeatedIncludeExample: 363 | Enabled: false 364 | RSpec/ReturnFromStub: 365 | Enabled: false 366 | RSpec/SharedExamples: 367 | Enabled: false 368 | RSpec/StubbedMock: 369 | Enabled: false 370 | RSpec/UnspecifiedException: 371 | Enabled: false 372 | RSpec/VariableDefinition: 373 | Enabled: false 374 | RSpec/VoidExpect: 375 | Enabled: false 376 | RSpec/Yield: 377 | Enabled: false 378 | Security/Open: 379 | Enabled: false 380 | Style/AccessModifierDeclarations: 381 | Enabled: false 382 | Style/AccessorGrouping: 383 | Enabled: false 384 | Style/BisectedAttrAccessor: 385 | Enabled: false 386 | Style/CaseLikeIf: 387 | Enabled: false 388 | Style/ClassEqualityComparison: 389 | Enabled: false 390 | Style/ColonMethodDefinition: 391 | Enabled: false 392 | Style/CombinableLoops: 393 | Enabled: false 394 | Style/CommentedKeyword: 395 | Enabled: false 396 | Style/Dir: 397 | Enabled: false 398 | Style/DoubleCopDisableDirective: 399 | Enabled: false 400 | Style/EmptyBlockParameter: 401 | Enabled: false 402 | Style/EmptyLambdaParameter: 403 | Enabled: false 404 | Style/Encoding: 405 | Enabled: false 406 | Style/EvalWithLocation: 407 | Enabled: false 408 | Style/ExpandPathArguments: 409 | Enabled: false 410 | Style/ExplicitBlockArgument: 411 | Enabled: false 412 | Style/ExponentialNotation: 413 | Enabled: false 414 | Style/FloatDivision: 415 | Enabled: false 416 | Style/FrozenStringLiteralComment: 417 | Enabled: false 418 | Style/GlobalStdStream: 419 | Enabled: false 420 | Style/HashAsLastArrayItem: 421 | Enabled: false 422 | Style/HashLikeCase: 423 | Enabled: false 424 | Style/HashTransformKeys: 425 | Enabled: false 426 | Style/HashTransformValues: 427 | Enabled: false 428 | Style/IfUnlessModifier: 429 | Enabled: false 430 | Style/KeywordParametersOrder: 431 | Enabled: false 432 | Style/MinMax: 433 | Enabled: false 434 | Style/MixinUsage: 435 | Enabled: false 436 | Style/MultilineWhenThen: 437 | Enabled: false 438 | Style/NegatedUnless: 439 | Enabled: false 440 | Style/NumericPredicate: 441 | Enabled: false 442 | Style/OptionalBooleanParameter: 443 | Enabled: false 444 | Style/OrAssignment: 445 | Enabled: false 446 | Style/RandomWithOffset: 447 | Enabled: false 448 | Style/RedundantAssignment: 449 | Enabled: false 450 | Style/RedundantCondition: 451 | Enabled: false 452 | Style/RedundantConditional: 453 | Enabled: false 454 | Style/RedundantFetchBlock: 455 | Enabled: false 456 | Style/RedundantFileExtensionInRequire: 457 | Enabled: false 458 | Style/RedundantRegexpCharacterClass: 459 | Enabled: false 460 | Style/RedundantRegexpEscape: 461 | Enabled: false 462 | Style/RedundantSelfAssignment: 463 | Enabled: false 464 | Style/RedundantSort: 465 | Enabled: false 466 | Style/RescueStandardError: 467 | Enabled: false 468 | Style/SingleArgumentDig: 469 | Enabled: false 470 | Style/SlicingWithRange: 471 | Enabled: false 472 | Style/SoleNestedConditional: 473 | Enabled: false 474 | Style/StderrPuts: 475 | Enabled: false 476 | Style/StringConcatenation: 477 | Enabled: false 478 | Style/Strip: 479 | Enabled: false 480 | Style/SymbolProc: 481 | Enabled: false 482 | Style/TrailingBodyOnClass: 483 | Enabled: false 484 | Style/TrailingBodyOnMethodDefinition: 485 | Enabled: false 486 | Style/TrailingBodyOnModule: 487 | Enabled: false 488 | Style/TrailingCommaInHashLiteral: 489 | Enabled: false 490 | Style/TrailingMethodEndStatement: 491 | Enabled: false 492 | Style/UnpackFirst: 493 | Enabled: false 494 | Capybara/MatchStyle: 495 | Enabled: false 496 | Capybara/NegationMatcher: 497 | Enabled: false 498 | Capybara/SpecificActions: 499 | Enabled: false 500 | Capybara/SpecificFinders: 501 | Enabled: false 502 | Capybara/SpecificMatcher: 503 | Enabled: false 504 | Gemspec/DeprecatedAttributeAssignment: 505 | Enabled: false 506 | Gemspec/DevelopmentDependencies: 507 | Enabled: false 508 | Gemspec/RequireMFA: 509 | Enabled: false 510 | Layout/LineContinuationLeadingSpace: 511 | Enabled: false 512 | Layout/LineContinuationSpacing: 513 | Enabled: false 514 | Layout/LineEndStringConcatenationIndentation: 515 | Enabled: false 516 | Layout/SpaceBeforeBrackets: 517 | Enabled: false 518 | Lint/AmbiguousAssignment: 519 | Enabled: false 520 | Lint/AmbiguousOperatorPrecedence: 521 | Enabled: false 522 | Lint/AmbiguousRange: 523 | Enabled: false 524 | Lint/ConstantOverwrittenInRescue: 525 | Enabled: false 526 | Lint/DeprecatedConstants: 527 | Enabled: false 528 | Lint/DuplicateBranch: 529 | Enabled: false 530 | Lint/DuplicateMagicComment: 531 | Enabled: false 532 | Lint/DuplicateMatchPattern: 533 | Enabled: false 534 | Lint/DuplicateRegexpCharacterClassElement: 535 | Enabled: false 536 | Lint/EmptyBlock: 537 | Enabled: false 538 | Lint/EmptyClass: 539 | Enabled: false 540 | Lint/EmptyInPattern: 541 | Enabled: false 542 | Lint/IncompatibleIoSelectWithFiberScheduler: 543 | Enabled: false 544 | Lint/LambdaWithoutLiteralBlock: 545 | Enabled: false 546 | Lint/NoReturnInBeginEndBlocks: 547 | Enabled: false 548 | Lint/NonAtomicFileOperation: 549 | Enabled: false 550 | Lint/NumberedParameterAssignment: 551 | Enabled: false 552 | Lint/OrAssignmentToConstant: 553 | Enabled: false 554 | Lint/RedundantDirGlobSort: 555 | Enabled: false 556 | Lint/RefinementImportMethods: 557 | Enabled: false 558 | Lint/RequireRangeParentheses: 559 | Enabled: false 560 | Lint/RequireRelativeSelfPath: 561 | Enabled: false 562 | Lint/SymbolConversion: 563 | Enabled: false 564 | Lint/ToEnumArguments: 565 | Enabled: false 566 | Lint/TripleQuotes: 567 | Enabled: false 568 | Lint/UnexpectedBlockArity: 569 | Enabled: false 570 | Lint/UnmodifiedReduceAccumulator: 571 | Enabled: false 572 | Lint/UselessRescue: 573 | Enabled: false 574 | Lint/UselessRuby2Keywords: 575 | Enabled: false 576 | Metrics/CollectionLiteralLength: 577 | Enabled: false 578 | Naming/BlockForwarding: 579 | Enabled: false 580 | Performance/CollectionLiteralInLoop: 581 | Enabled: false 582 | Performance/ConcurrentMonotonicTime: 583 | Enabled: false 584 | Performance/MapCompact: 585 | Enabled: false 586 | Performance/RedundantEqualityComparisonBlock: 587 | Enabled: false 588 | Performance/RedundantSplitRegexpArgument: 589 | Enabled: false 590 | Performance/StringIdentifierArgument: 591 | Enabled: false 592 | RSpec/BeEq: 593 | Enabled: false 594 | RSpec/BeNil: 595 | Enabled: false 596 | RSpec/ChangeByZero: 597 | Enabled: false 598 | RSpec/ClassCheck: 599 | Enabled: false 600 | RSpec/DuplicatedMetadata: 601 | Enabled: false 602 | RSpec/ExcessiveDocstringSpacing: 603 | Enabled: false 604 | RSpec/FactoryBot/ConsistentParenthesesStyle: 605 | Enabled: false 606 | RSpec/FactoryBot/FactoryNameStyle: 607 | Enabled: false 608 | RSpec/FactoryBot/SyntaxMethods: 609 | Enabled: false 610 | RSpec/IdenticalEqualityAssertion: 611 | Enabled: false 612 | RSpec/NoExpectationExample: 613 | Enabled: false 614 | RSpec/PendingWithoutReason: 615 | Enabled: false 616 | RSpec/Rails/AvoidSetupHook: 617 | Enabled: false 618 | RSpec/Rails/HaveHttpStatus: 619 | Enabled: false 620 | RSpec/Rails/InferredSpecType: 621 | Enabled: false 622 | RSpec/Rails/MinitestAssertions: 623 | Enabled: false 624 | RSpec/Rails/TravelAround: 625 | Enabled: false 626 | RSpec/RedundantAround: 627 | Enabled: false 628 | RSpec/SkipBlockInsideExample: 629 | Enabled: false 630 | RSpec/SortMetadata: 631 | Enabled: false 632 | RSpec/SubjectDeclaration: 633 | Enabled: false 634 | RSpec/VerifiedDoubleReference: 635 | Enabled: false 636 | Security/CompoundHash: 637 | Enabled: false 638 | Security/IoMethods: 639 | Enabled: false 640 | Style/ArgumentsForwarding: 641 | Enabled: false 642 | Style/ArrayIntersect: 643 | Enabled: false 644 | Style/CollectionCompact: 645 | Enabled: false 646 | Style/ComparableClamp: 647 | Enabled: false 648 | Style/ConcatArrayLiterals: 649 | Enabled: false 650 | Style/DataInheritance: 651 | Enabled: false 652 | Style/DirEmpty: 653 | Enabled: false 654 | Style/DocumentDynamicEvalDefinition: 655 | Enabled: false 656 | Style/EmptyHeredoc: 657 | Enabled: false 658 | Style/EndlessMethod: 659 | Enabled: false 660 | Style/EnvHome: 661 | Enabled: false 662 | Style/FetchEnvVar: 663 | Enabled: false 664 | Style/FileEmpty: 665 | Enabled: false 666 | Style/FileRead: 667 | Enabled: false 668 | Style/FileWrite: 669 | Enabled: false 670 | Style/HashConversion: 671 | Enabled: false 672 | Style/HashExcept: 673 | Enabled: false 674 | Style/IfWithBooleanLiteralBranches: 675 | Enabled: false 676 | Style/InPatternThen: 677 | Enabled: false 678 | Style/MagicCommentFormat: 679 | Enabled: false 680 | Style/MapCompactWithConditionalBlock: 681 | Enabled: false 682 | Style/MapToHash: 683 | Enabled: false 684 | Style/MapToSet: 685 | Enabled: false 686 | Style/MinMaxComparison: 687 | Enabled: false 688 | Style/MultilineInPatternThen: 689 | Enabled: false 690 | Style/NegatedIfElseCondition: 691 | Enabled: false 692 | Style/NestedFileDirname: 693 | Enabled: false 694 | Style/NilLambda: 695 | Enabled: false 696 | Style/NumberedParameters: 697 | Enabled: false 698 | Style/NumberedParametersLimit: 699 | Enabled: false 700 | Style/ObjectThen: 701 | Enabled: false 702 | Style/OpenStructUse: 703 | Enabled: false 704 | Style/OperatorMethodCall: 705 | Enabled: false 706 | Style/QuotedSymbols: 707 | Enabled: false 708 | Style/RedundantArgument: 709 | Enabled: false 710 | Style/RedundantConstantBase: 711 | Enabled: false 712 | Style/RedundantDoubleSplatHashBraces: 713 | Enabled: false 714 | Style/RedundantEach: 715 | Enabled: false 716 | Style/RedundantHeredocDelimiterQuotes: 717 | Enabled: false 718 | Style/RedundantInitialize: 719 | Enabled: false 720 | Style/RedundantLineContinuation: 721 | Enabled: false 722 | Style/RedundantSelfAssignmentBranch: 723 | Enabled: false 724 | Style/RedundantStringEscape: 725 | Enabled: false 726 | Style/SelectByRegexp: 727 | Enabled: false 728 | Style/StringChars: 729 | Enabled: false 730 | Style/SwapValues: 731 | Enabled: false 732 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config` 3 | # on 2023-12-21 07:47:02 UTC using RuboCop version 1.48.1. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | 9 | # Offense count: 3 10 | # This cop supports safe autocorrection (--autocorrect). 11 | Lint/RedundantCopDisableDirective: 12 | Exclude: 13 | - 'spec/unit/puppet/provider/java_ks/keytool_spec.rb' 14 | 15 | # Offense count: 3 16 | RSpec/MultipleExpectations: 17 | Max: 4 18 | -------------------------------------------------------------------------------- /.sync.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ".gitlab-ci.yml": 3 | delete: true 4 | appveyor.yml: 5 | delete: true 6 | 7 | Gemfile: 8 | optional: 9 | ":development": 10 | - gem: ruby-pwsh 11 | spec/spec_helper.rb: 12 | mock_with: ":rspec" 13 | coverage_report: true 14 | .gitpod.Dockerfile: 15 | unmanaged: false 16 | .gitpod.yml: 17 | unmanaged: false 18 | .github/workflows/auto_release.yml: 19 | unmanaged: false 20 | .github/workflows/ci.yml: 21 | unmanaged: false 22 | .github/workflows/nightly.yml: 23 | unmanaged: false 24 | .github/workflows/release.yml: 25 | unmanaged: false 26 | .travis.yml: 27 | delete: true 28 | .rubocop.yml: 29 | include_todos: true 30 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "puppet.puppet-vscode", 4 | "Shopify.ruby-lsp" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --markup markdown 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # Changelog 3 | 4 | All notable changes to this project will be documented in this file. 5 | 6 | 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). 7 | 8 | ## [v5.1.1](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v5.1.1) - 2025-01-24 9 | 10 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v5.1.0...v5.1.1) 11 | 12 | ### Fixed 13 | 14 | - (CAT-2203) Removing legacy facts [#466](https://github.com/puppetlabs/puppetlabs-java_ks/pull/466) ([amitkarsale](https://github.com/amitkarsale)) 15 | 16 | ## [v5.1.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v5.1.0) - 2024-11-27 17 | 18 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v5.0.0...v5.1.0) 19 | 20 | ## [v5.0.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v5.0.0) - 2023-05-22 21 | 22 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v4.4.2...v5.0.0) 23 | 24 | ### Changed 25 | 26 | - (CONT-785) Add Support for Puppet 8 / Drop Support for Puppet 6 [#430](https://github.com/puppetlabs/puppetlabs-java_ks/pull/430) ([david22swan](https://github.com/david22swan)) 27 | 28 | ### Added 29 | 30 | - (CONT-1008) Add missing Windows 2022 Support [#435](https://github.com/puppetlabs/puppetlabs-java_ks/pull/435) ([david22swan](https://github.com/david22swan)) 31 | 32 | ## [v4.4.2](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v4.4.2) - 2023-04-18 33 | 34 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v4.4.1...v4.4.2) 35 | 36 | ### Fixed 37 | 38 | - (CONT-357) Syntax update [#422](https://github.com/puppetlabs/puppetlabs-java_ks/pull/422) ([LukasAud](https://github.com/LukasAud)) 39 | 40 | ## [v4.4.1](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v4.4.1) - 2022-11-21 41 | 42 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v4.4.0...v4.4.1) 43 | 44 | ### Fixed 45 | 46 | - (CONT-186) Set `-deststoretype` [#418](https://github.com/puppetlabs/puppetlabs-java_ks/pull/418) ([david22swan](https://github.com/david22swan)) 47 | - pdksync - (CONT-189) Remove support for RedHat6 / OracleLinux6 / Scientific6 [#417](https://github.com/puppetlabs/puppetlabs-java_ks/pull/417) ([david22swan](https://github.com/david22swan)) 48 | - pdksync - (CONT-130) - Dropping Support for Debian 9 [#414](https://github.com/puppetlabs/puppetlabs-java_ks/pull/414) ([jordanbreen28](https://github.com/jordanbreen28)) 49 | - reversed insync set comparison [#412](https://github.com/puppetlabs/puppetlabs-java_ks/pull/412) ([rstuart-indue](https://github.com/rstuart-indue)) 50 | 51 | ## [v4.4.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v4.4.0) - 2022-10-03 52 | 53 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v4.3.1...v4.4.0) 54 | 55 | ### Added 56 | 57 | - pdksync - (GH-cat-11) Certify Support for Ubuntu 22.04 [#408](https://github.com/puppetlabs/puppetlabs-java_ks/pull/408) ([david22swan](https://github.com/david22swan)) 58 | - pdksync - (GH-cat-12) Add Support for Redhat 9 [#404](https://github.com/puppetlabs/puppetlabs-java_ks/pull/404) ([david22swan](https://github.com/david22swan)) 59 | 60 | ### Fixed 61 | 62 | - (MAINT) Drop support for Solaris 10, Windows Server 2008 R2 and Windows 7+8.1 [#410](https://github.com/puppetlabs/puppetlabs-java_ks/pull/410) ([jordanbreen28](https://github.com/jordanbreen28)) 63 | 64 | ## [v4.3.1](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v4.3.1) - 2022-05-24 65 | 66 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v4.3.0...v4.3.1) 67 | 68 | ### Fixed 69 | 70 | - Don't require certificate or private key params when ensure: absent [#399](https://github.com/puppetlabs/puppetlabs-java_ks/pull/399) ([tparkercbn](https://github.com/tparkercbn)) 71 | 72 | ## [v4.3.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v4.3.0) - 2022-04-05 73 | 74 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v4.2.0...v4.3.0) 75 | 76 | ### Added 77 | 78 | - Add support for certificate_content and private_key_content parameters [#385](https://github.com/puppetlabs/puppetlabs-java_ks/pull/385) ([hajee](https://github.com/hajee)) 79 | - pdksync - (IAC-1753) - Add Support for AlmaLinux 8 [#381](https://github.com/puppetlabs/puppetlabs-java_ks/pull/381) ([david22swan](https://github.com/david22swan)) 80 | - pdksync - (IAC-1751) - Add Support for Rocky 8 [#380](https://github.com/puppetlabs/puppetlabs-java_ks/pull/380) ([david22swan](https://github.com/david22swan)) 81 | 82 | ### Fixed 83 | 84 | - pdksync - (GH-iac-334) Remove Support for Ubuntu 14.04/16.04 [#390](https://github.com/puppetlabs/puppetlabs-java_ks/pull/390) ([david22swan](https://github.com/david22swan)) 85 | - pdksync - (IAC-1787) Remove Support for CentOS 6 [#384](https://github.com/puppetlabs/puppetlabs-java_ks/pull/384) ([david22swan](https://github.com/david22swan)) 86 | - pdksync - (IAC-1598) - Remove Support for Debian 8 [#379](https://github.com/puppetlabs/puppetlabs-java_ks/pull/379) ([david22swan](https://github.com/david22swan)) 87 | - Fix "password" as Property [#378](https://github.com/puppetlabs/puppetlabs-java_ks/pull/378) ([cocker-cc](https://github.com/cocker-cc)) 88 | 89 | ## [v4.2.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v4.2.0) - 2021-08-25 90 | 91 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v4.1.0...v4.2.0) 92 | 93 | ### Added 94 | 95 | - pdksync - (IAC-1709) - Add Support for Debian 11 [#376](https://github.com/puppetlabs/puppetlabs-java_ks/pull/376) ([david22swan](https://github.com/david22swan)) 96 | 97 | ## [v4.1.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v4.1.0) - 2021-06-28 98 | 99 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v4.0.0...v4.1.0) 100 | 101 | ### Added 102 | 103 | - Accept Datatype Sensitive for Secrets [#373](https://github.com/puppetlabs/puppetlabs-java_ks/pull/373) ([cocker-cc](https://github.com/cocker-cc)) 104 | 105 | ### Fixed 106 | 107 | - Fix fingerprint comparison [#372](https://github.com/puppetlabs/puppetlabs-java_ks/pull/372) ([kdehairy](https://github.com/kdehairy)) 108 | - (MODULES-11067) Fix keytool output parsing [#370](https://github.com/puppetlabs/puppetlabs-java_ks/pull/370) ([durist](https://github.com/durist)) 109 | 110 | ## [v4.0.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v4.0.0) - 2021-03-01 111 | 112 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v3.4.0...v4.0.0) 113 | 114 | ### Changed 115 | 116 | - pdksync - (MAINT) Remove SLES 11 support [#354](https://github.com/puppetlabs/puppetlabs-java_ks/pull/354) ([sanfrancrisko](https://github.com/sanfrancrisko)) 117 | - pdksync - (MAINT) Remove RHEL 5 family support [#353](https://github.com/puppetlabs/puppetlabs-java_ks/pull/353) ([sanfrancrisko](https://github.com/sanfrancrisko)) 118 | - pdksync - Remove Puppet 5 from testing and bump minimal version to 6.0.0 [#351](https://github.com/puppetlabs/puppetlabs-java_ks/pull/351) ([carabasdaniel](https://github.com/carabasdaniel)) 119 | 120 | ### Fixed 121 | 122 | - Fix keytool path handling [#349](https://github.com/puppetlabs/puppetlabs-java_ks/pull/349) ([chillinger](https://github.com/chillinger)) 123 | 124 | ## [v3.4.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v3.4.0) - 2020-12-16 125 | 126 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v3.3.0...v3.4.0) 127 | 128 | ## [v3.3.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v3.3.0) - 2020-12-07 129 | 130 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v3.2.0...v3.3.0) 131 | 132 | ### Added 133 | 134 | - pdksync - (feat) Add support for Puppet 7 [#342](https://github.com/puppetlabs/puppetlabs-java_ks/pull/342) ([daianamezdrea](https://github.com/daianamezdrea)) 135 | - (IAC-994) Removal of inappropriate terminology [#335](https://github.com/puppetlabs/puppetlabs-java_ks/pull/335) ([pmcmaw](https://github.com/pmcmaw)) 136 | - pdksync - (IAC-973) - Update travis/appveyor to run on new default branch `main` [#327](https://github.com/puppetlabs/puppetlabs-java_ks/pull/327) ([david22swan](https://github.com/david22swan)) 137 | 138 | ### Fixed 139 | 140 | - Change latest/current comparison to account for chains [#336](https://github.com/puppetlabs/puppetlabs-java_ks/pull/336) ([mwpower](https://github.com/mwpower)) 141 | - add storetype parameter comparison to 'destroy' method [#333](https://github.com/puppetlabs/puppetlabs-java_ks/pull/333) ([mwpower](https://github.com/mwpower)) 142 | - Correct jceks symbol comparison [#332](https://github.com/puppetlabs/puppetlabs-java_ks/pull/332) ([mwpower](https://github.com/mwpower)) 143 | 144 | ## [v3.2.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v3.2.0) - 2020-07-01 145 | 146 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v3.1.0...v3.2.0) 147 | 148 | ### Added 149 | 150 | - Allow DER formatted certificates with keys. [#319](https://github.com/puppetlabs/puppetlabs-java_ks/pull/319) ([tomkitchen](https://github.com/tomkitchen)) 151 | 152 | ## [v3.1.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v3.1.0) - 2019-12-09 153 | 154 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/v3.0.0...v3.1.0) 155 | 156 | ### Added 157 | 158 | - (FM-8224) - Addition of support for CentOS 8 [#294](https://github.com/puppetlabs/puppetlabs-java_ks/pull/294) ([david22swan](https://github.com/david22swan)) 159 | - (feat) adding litmus support [#292](https://github.com/puppetlabs/puppetlabs-java_ks/pull/292) ([tphoney](https://github.com/tphoney)) 160 | - pdksync - "Add support on Debian10" [#288](https://github.com/puppetlabs/puppetlabs-java_ks/pull/288) ([lionce](https://github.com/lionce)) 161 | 162 | ## [v3.0.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/v3.0.0) - 2019-08-20 163 | 164 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/2.4.0...v3.0.0) 165 | 166 | ### Changed 167 | 168 | - pdksync - (MODULES-8444) - Raise lower Puppet bound [#276](https://github.com/puppetlabs/puppetlabs-java_ks/pull/276) ([david22swan](https://github.com/david22swan)) 169 | 170 | ### Added 171 | 172 | - (FM-8155) Add Window Server 2019 support [#281](https://github.com/puppetlabs/puppetlabs-java_ks/pull/281) ([eimlav](https://github.com/eimlav)) 173 | - (FM-8042) Add RedHat 8 support [#280](https://github.com/puppetlabs/puppetlabs-java_ks/pull/280) ([eimlav](https://github.com/eimlav)) 174 | - Add initial support for DSA private keys. [#273](https://github.com/puppetlabs/puppetlabs-java_ks/pull/273) ([surcouf](https://github.com/surcouf)) 175 | 176 | ### Fixed 177 | 178 | - FM-7945 stringify java_ks [#279](https://github.com/puppetlabs/puppetlabs-java_ks/pull/279) ([lionce](https://github.com/lionce)) 179 | - Modules 8962 - java_ks - Windows 2012 failing smoke [#278](https://github.com/puppetlabs/puppetlabs-java_ks/pull/278) ([lionce](https://github.com/lionce)) 180 | 181 | ## [2.4.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/2.4.0) - 2019-02-19 182 | 183 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/2.3.0...2.4.0) 184 | 185 | ### Added 186 | 187 | - (MODULES-8146) - Add SLES 15 support [#255](https://github.com/puppetlabs/puppetlabs-java_ks/pull/255) ([eimlav](https://github.com/eimlav)) 188 | 189 | ### Fixed 190 | 191 | - (MODULES-8549) - Bump of Java version used for test [#260](https://github.com/puppetlabs/puppetlabs-java_ks/pull/260) ([david22swan](https://github.com/david22swan)) 192 | - pdksync - (FM-7655) Fix rubygems-update for ruby < 2.3 [#257](https://github.com/puppetlabs/puppetlabs-java_ks/pull/257) ([tphoney](https://github.com/tphoney)) 193 | - Fix provider so "latest" gets the MD5 AND SHA1 hashes for comparing [#252](https://github.com/puppetlabs/puppetlabs-java_ks/pull/252) ([absltkaos](https://github.com/absltkaos)) 194 | - (FM-7505) - Bumping Windows jdk version to 8.0.191 [#251](https://github.com/puppetlabs/puppetlabs-java_ks/pull/251) ([pmcmaw](https://github.com/pmcmaw)) 195 | - (MODULES-8125) Fix unnecessary change when using intermediate certificates [#250](https://github.com/puppetlabs/puppetlabs-java_ks/pull/250) ([johngmyers](https://github.com/johngmyers)) 196 | 197 | ## [2.3.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/2.3.0) - 2018-09-28 198 | 199 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/2.2.0...2.3.0) 200 | 201 | ### Changed 202 | 203 | - [FM-6966] Removal of unsupported OS from java_ks [#230](https://github.com/puppetlabs/puppetlabs-java_ks/pull/230) ([david22swan](https://github.com/david22swan)) 204 | 205 | ### Added 206 | 207 | - pdksync - (MODULES-6805) metadata.json shows support for puppet 6 [#246](https://github.com/puppetlabs/puppetlabs-java_ks/pull/246) ([tphoney](https://github.com/tphoney)) 208 | - (FM-7238) - Addition of support for Ubuntu 18.04 [#237](https://github.com/puppetlabs/puppetlabs-java_ks/pull/237) ([david22swan](https://github.com/david22swan)) 209 | 210 | ### Fixed 211 | 212 | - (MODULES-7632) - Update README Limitations section [#239](https://github.com/puppetlabs/puppetlabs-java_ks/pull/239) ([eimlav](https://github.com/eimlav)) 213 | - (MODULES-1997) - Update the target when the cert chain changes [#233](https://github.com/puppetlabs/puppetlabs-java_ks/pull/233) ([johngmyers](https://github.com/johngmyers)) 214 | - (MODULES-6342) Update pathing for new java in #229 [#231](https://github.com/puppetlabs/puppetlabs-java_ks/pull/231) ([hunner](https://github.com/hunner)) 215 | 216 | ## [2.2.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/2.2.0) - 2018-03-02 217 | 218 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/2.1.0...2.2.0) 219 | 220 | ### Other 221 | 222 | - Release Prep 2.2.0 [#224](https://github.com/puppetlabs/puppetlabs-java_ks/pull/224) ([HelenCampbell](https://github.com/HelenCampbell)) 223 | - Add support for 'destkeypass' when importing PKCS12 keystores. [#221](https://github.com/puppetlabs/puppetlabs-java_ks/pull/221) ([fatmcgav](https://github.com/fatmcgav)) 224 | - Release merge back 2.1.0 [#219](https://github.com/puppetlabs/puppetlabs-java_ks/pull/219) ([pmcmaw](https://github.com/pmcmaw)) 225 | 226 | ## [2.1.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/2.1.0) - 2018-02-07 227 | 228 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/2.0.0...2.1.0) 229 | 230 | ### Other 231 | 232 | - 2.1.0PreRelease [#217](https://github.com/puppetlabs/puppetlabs-java_ks/pull/217) ([david22swan](https://github.com/david22swan)) 233 | - Update JDK to 8u161 [#215](https://github.com/puppetlabs/puppetlabs-java_ks/pull/215) ([HelenCampbell](https://github.com/HelenCampbell)) 234 | - 'Latest' method updated to mirror 'Current' method. Code shared by both extracted into it's own method. [#214](https://github.com/puppetlabs/puppetlabs-java_ks/pull/214) ([david22swan](https://github.com/david22swan)) 235 | - Rubocop Implemented [#212](https://github.com/puppetlabs/puppetlabs-java_ks/pull/212) ([david22swan](https://github.com/david22swan)) 236 | - (maint) modulesync 65530a4 Update Travis [#211](https://github.com/puppetlabs/puppetlabs-java_ks/pull/211) ([michaeltlombardi](https://github.com/michaeltlombardi)) 237 | - (maint) modulesync cd884db Remove AppVeyor OpenSSL update on Ruby 2.4 [#210](https://github.com/puppetlabs/puppetlabs-java_ks/pull/210) ([michaeltlombardi](https://github.com/michaeltlombardi)) 238 | - (maint) - modulesync 384f4c1 [#209](https://github.com/puppetlabs/puppetlabs-java_ks/pull/209) ([tphoney](https://github.com/tphoney)) 239 | - Merge back to master [#208](https://github.com/puppetlabs/puppetlabs-java_ks/pull/208) ([tphoney](https://github.com/tphoney)) 240 | - Add support for specifying a source cert alias [#205](https://github.com/puppetlabs/puppetlabs-java_ks/pull/205) ([fatmcgav](https://github.com/fatmcgav)) 241 | 242 | ## [2.0.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/2.0.0) - 2017-12-05 243 | 244 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.6.0...2.0.0) 245 | 246 | ### Changed 247 | 248 | - (MODULES-5814) - Removing Windows 8 [#197](https://github.com/puppetlabs/puppetlabs-java_ks/pull/197) ([pmcmaw](https://github.com/pmcmaw)) 249 | 250 | ### Added 251 | 252 | - Add Java 9 support [#195](https://github.com/puppetlabs/puppetlabs-java_ks/pull/195) ([SndR85](https://github.com/SndR85)) 253 | - support removal of keystore file if password incorrect [#151](https://github.com/puppetlabs/puppetlabs-java_ks/pull/151) ([jessereynolds](https://github.com/jessereynolds)) 254 | 255 | ### Fixed 256 | 257 | - (FM-6457) Fix Windows CI [#200](https://github.com/puppetlabs/puppetlabs-java_ks/pull/200) ([michaeltlombardi](https://github.com/michaeltlombardi)) 258 | 259 | ### Other 260 | 261 | - (FM-6588) - Remove vulnerable puppet3 support dependencies (modulesync e6d4a7d) [#207](https://github.com/puppetlabs/puppetlabs-java_ks/pull/207) ([pmcmaw](https://github.com/pmcmaw)) 262 | - (MODULES-6161) - Release Prep for 2.0.0 [#206](https://github.com/puppetlabs/puppetlabs-java_ks/pull/206) ([pmcmaw](https://github.com/pmcmaw)) 263 | - (maint) - modulesync 1d81b6a [#204](https://github.com/puppetlabs/puppetlabs-java_ks/pull/204) ([pmcmaw](https://github.com/pmcmaw)) 264 | - (maint) - Updating flag to stop appveyor config from being deleted [#203](https://github.com/puppetlabs/puppetlabs-java_ks/pull/203) ([pmcmaw](https://github.com/pmcmaw)) 265 | - Adding appveyor config file [#201](https://github.com/puppetlabs/puppetlabs-java_ks/pull/201) ([pmcmaw](https://github.com/pmcmaw)) 266 | - FM-6517 On SLES we do not have pkcs12 installed [#198](https://github.com/puppetlabs/puppetlabs-java_ks/pull/198) ([tphoney](https://github.com/tphoney)) 267 | - Update metadata [#196](https://github.com/puppetlabs/puppetlabs-java_ks/pull/196) ([pmcmaw](https://github.com/pmcmaw)) 268 | - Rubocop cleanup of java_ks type [#194](https://github.com/puppetlabs/puppetlabs-java_ks/pull/194) ([tphoney](https://github.com/tphoney)) 269 | - (maint) modulesync 892c4cf [#193](https://github.com/puppetlabs/puppetlabs-java_ks/pull/193) ([HAIL9000](https://github.com/HAIL9000)) 270 | - (MODULES-5501) - Remove unsupported Ubuntu [#191](https://github.com/puppetlabs/puppetlabs-java_ks/pull/191) ([pmcmaw](https://github.com/pmcmaw)) 271 | - (MODULES-5357) Pin JDK installation pacakge to 8.0.144 [#189](https://github.com/puppetlabs/puppetlabs-java_ks/pull/189) ([glennsarti](https://github.com/glennsarti)) 272 | - (maint) modulesync 915cde70e20 [#188](https://github.com/puppetlabs/puppetlabs-java_ks/pull/188) ([glennsarti](https://github.com/glennsarti)) 273 | - fix java install on windows in acceptance [#187](https://github.com/puppetlabs/puppetlabs-java_ks/pull/187) ([tphoney](https://github.com/tphoney)) 274 | - (MODULES-5187) mysnc puppet 5 and ruby 2.4 [#186](https://github.com/puppetlabs/puppetlabs-java_ks/pull/186) ([eputnam](https://github.com/eputnam)) 275 | - (MODULES-5144) Prep for puppet 5 [#184](https://github.com/puppetlabs/puppetlabs-java_ks/pull/184) ([hunner](https://github.com/hunner)) 276 | - (MODULES-4833) Update to Puppet version dependancy #puppethack [#183](https://github.com/puppetlabs/puppetlabs-java_ks/pull/183) ([HelenCampbell](https://github.com/HelenCampbell)) 277 | - Add support for importing PKCS12 files. [#182](https://github.com/puppetlabs/puppetlabs-java_ks/pull/182) ([fatmcgav](https://github.com/fatmcgav)) 278 | - Release mergeback [#181](https://github.com/puppetlabs/puppetlabs-java_ks/pull/181) ([hunner](https://github.com/hunner)) 279 | 280 | ## [1.6.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.6.0) - 2017-05-03 281 | 282 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.5.0...1.6.0) 283 | 284 | ### Other 285 | 286 | - Fix timing on older rubies [#180](https://github.com/puppetlabs/puppetlabs-java_ks/pull/180) ([hunner](https://github.com/hunner)) 287 | - (PE-17635) Wrap keytool in timeout [#179](https://github.com/puppetlabs/puppetlabs-java_ks/pull/179) ([hunner](https://github.com/hunner)) 288 | - Release mergeback for 1.5.0 [#178](https://github.com/puppetlabs/puppetlabs-java_ks/pull/178) ([HelenCampbell](https://github.com/HelenCampbell)) 289 | - [msync] 786266 Implement puppet-module-gems, a45803 Remove metadata.json from locales config [#177](https://github.com/puppetlabs/puppetlabs-java_ks/pull/177) ([wilson208](https://github.com/wilson208)) 290 | - Correct markdown formatting [#175](https://github.com/puppetlabs/puppetlabs-java_ks/pull/175) ([ekohl](https://github.com/ekohl)) 291 | - [MODULES-4528] Replace Puppet.version.to_f version comparison from spec_helper.rb [#174](https://github.com/puppetlabs/puppetlabs-java_ks/pull/174) ([wilson208](https://github.com/wilson208)) 292 | - [MODULES-4556] Remove PE requirement from metadata.json [#173](https://github.com/puppetlabs/puppetlabs-java_ks/pull/173) ([wilson208](https://github.com/wilson208)) 293 | 294 | ## [1.5.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.5.0) - 2017-03-14 295 | 296 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.4.1...1.5.0) 297 | 298 | ### Other 299 | 300 | - (docs)[FM-6102] 1.5.0 release docs edit [#171](https://github.com/puppetlabs/puppetlabs-java_ks/pull/171) ([jtappa](https://github.com/jtappa)) 301 | - [FM-6102] Release 1.5.0 Prep [#170](https://github.com/puppetlabs/puppetlabs-java_ks/pull/170) ([wilson208](https://github.com/wilson208)) 302 | - [MODULES-4505] Fix error: title patterns that use procs are not supported [#169](https://github.com/puppetlabs/puppetlabs-java_ks/pull/169) ([wilson208](https://github.com/wilson208)) 303 | - (maint) Change SHA256 fingerprint verification for certificates to SHA1 [#168](https://github.com/puppetlabs/puppetlabs-java_ks/pull/168) ([wilson208](https://github.com/wilson208)) 304 | - (MODULES-2495): use password with encrypted private keys [#167](https://github.com/puppetlabs/puppetlabs-java_ks/pull/167) ([tompsett](https://github.com/tompsett)) 305 | - (MODULES-4098) Sync the rest of the files [#166](https://github.com/puppetlabs/puppetlabs-java_ks/pull/166) ([hunner](https://github.com/hunner)) 306 | - (MODULES-4097) Sync travis.yml [#164](https://github.com/puppetlabs/puppetlabs-java_ks/pull/164) ([hunner](https://github.com/hunner)) 307 | - add xenial to metadata [#163](https://github.com/puppetlabs/puppetlabs-java_ks/pull/163) ([eputnam](https://github.com/eputnam)) 308 | - Support EC keys [#162](https://github.com/puppetlabs/puppetlabs-java_ks/pull/162) ([antaflos](https://github.com/antaflos)) 309 | - (FM-5972) gettext and spec.opts [#161](https://github.com/puppetlabs/puppetlabs-java_ks/pull/161) ([eputnam](https://github.com/eputnam)) 310 | - Support for systems running in FIPS mode [#160](https://github.com/puppetlabs/puppetlabs-java_ks/pull/160) ([jstuart](https://github.com/jstuart)) 311 | - (MODULES-3631) msync Gemfile for 1.9 frozen strings [#159](https://github.com/puppetlabs/puppetlabs-java_ks/pull/159) ([hunner](https://github.com/hunner)) 312 | - (MODULES-3704) Update gemfile template to be identical [#158](https://github.com/puppetlabs/puppetlabs-java_ks/pull/158) ([hunner](https://github.com/hunner)) 313 | - mocha version update [#157](https://github.com/puppetlabs/puppetlabs-java_ks/pull/157) ([eputnam](https://github.com/eputnam)) 314 | - (MODULES-3983) Update parallel_tests for ruby 2.0.0 [#156](https://github.com/puppetlabs/puppetlabs-java_ks/pull/156) ([pmcmaw](https://github.com/pmcmaw)) 315 | - Update modulesync_config [51f469d] [#154](https://github.com/puppetlabs/puppetlabs-java_ks/pull/154) ([DavidS](https://github.com/DavidS)) 316 | - Created simple java_ks::config class with create_resources so we can hiera manage configs [#153](https://github.com/puppetlabs/puppetlabs-java_ks/pull/153) ([arthurbarton](https://github.com/arthurbarton)) 317 | - Update modulesync_config [a3fe424] [#152](https://github.com/puppetlabs/puppetlabs-java_ks/pull/152) ([DavidS](https://github.com/DavidS)) 318 | - (MAINT) Update for modulesync_config 72d19f184 [#150](https://github.com/puppetlabs/puppetlabs-java_ks/pull/150) ([DavidS](https://github.com/DavidS)) 319 | - (MODULES-3581) modulesync [067d08a] [#149](https://github.com/puppetlabs/puppetlabs-java_ks/pull/149) ([DavidS](https://github.com/DavidS)) 320 | - {maint} modulesync 0794b2c [#148](https://github.com/puppetlabs/puppetlabs-java_ks/pull/148) ([tphoney](https://github.com/tphoney)) 321 | - Update to newest modulesync_configs [9ca280f] [#147](https://github.com/puppetlabs/puppetlabs-java_ks/pull/147) ([DavidS](https://github.com/DavidS)) 322 | - Mergeback 1.4.x [#146](https://github.com/puppetlabs/puppetlabs-java_ks/pull/146) ([bmjen](https://github.com/bmjen)) 323 | 324 | ## [1.4.1](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.4.1) - 2016-02-16 325 | 326 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.4.0...1.4.1) 327 | 328 | ### Other 329 | 330 | - (FM-4046) Update to current msync configs [006831f] [#145](https://github.com/puppetlabs/puppetlabs-java_ks/pull/145) ([DavidS](https://github.com/DavidS)) 331 | - 1.4.1 release prep [#144](https://github.com/puppetlabs/puppetlabs-java_ks/pull/144) ([tphoney](https://github.com/tphoney)) 332 | - (MODULES-3023) Support certificate chains in certificate file. [#143](https://github.com/puppetlabs/puppetlabs-java_ks/pull/143) ([johngmyers](https://github.com/johngmyers)) 333 | - (FM-4049) update to modulesync_configs [#142](https://github.com/puppetlabs/puppetlabs-java_ks/pull/142) ([DavidS](https://github.com/DavidS)) 334 | - Support multiple intermediate certs in chain [#141](https://github.com/puppetlabs/puppetlabs-java_ks/pull/141) ([johngmyers](https://github.com/johngmyers)) 335 | - (#2915) Don't expose keystore content when keystore initally empty [#140](https://github.com/puppetlabs/puppetlabs-java_ks/pull/140) ([johngmyers](https://github.com/johngmyers)) 336 | - 1.4.x mergeback [#139](https://github.com/puppetlabs/puppetlabs-java_ks/pull/139) ([bmjen](https://github.com/bmjen)) 337 | 338 | ## [1.4.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.4.0) - 2015-12-07 339 | 340 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.3.1...1.4.0) 341 | 342 | ### Other 343 | 344 | - Rebase from master [#138](https://github.com/puppetlabs/puppetlabs-java_ks/pull/138) ([bmjen](https://github.com/bmjen)) 345 | - 1.3.x mergeback [#137](https://github.com/puppetlabs/puppetlabs-java_ks/pull/137) ([bmjen](https://github.com/bmjen)) 346 | - Fixes metadata.json dependencies. [#136](https://github.com/puppetlabs/puppetlabs-java_ks/pull/136) ([bmjen](https://github.com/bmjen)) 347 | - Release prep for 1.4.0. [#135](https://github.com/puppetlabs/puppetlabs-java_ks/pull/135) ([bmjen](https://github.com/bmjen)) 348 | - Fix acceptance tests [#133](https://github.com/puppetlabs/puppetlabs-java_ks/pull/133) ([DavidS](https://github.com/DavidS)) 349 | - Adding jceks support [#132](https://github.com/puppetlabs/puppetlabs-java_ks/pull/132) ([albac](https://github.com/albac)) 350 | - (MODULES-2561) resolve title properly when on windows [#131](https://github.com/puppetlabs/puppetlabs-java_ks/pull/131) ([cyberious](https://github.com/cyberious)) 351 | - Implement destkeypass option [#130](https://github.com/puppetlabs/puppetlabs-java_ks/pull/130) ([DavidS](https://github.com/DavidS)) 352 | - (maint) Remove ruby requirement for creating certs [#129](https://github.com/puppetlabs/puppetlabs-java_ks/pull/129) ([cyberious](https://github.com/cyberious)) 353 | - (maint) Removed setup parameter [#128](https://github.com/puppetlabs/puppetlabs-java_ks/pull/128) ([cyberious](https://github.com/cyberious)) 354 | 355 | ## [1.3.1](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.3.1) - 2015-07-17 356 | 357 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.3.0...1.3.1) 358 | 359 | ### Other 360 | 361 | - CHANGELOG and docs cleanup [#127](https://github.com/puppetlabs/puppetlabs-java_ks/pull/127) ([bmjen](https://github.com/bmjen)) 362 | - 1.3.1 prep [#126](https://github.com/puppetlabs/puppetlabs-java_ks/pull/126) ([bmjen](https://github.com/bmjen)) 363 | - adds pe path to ruby for acceptance tests [#125](https://github.com/puppetlabs/puppetlabs-java_ks/pull/125) ([bmjen](https://github.com/bmjen)) 364 | - Add helper to install puppet/pe/puppet-agent [#124](https://github.com/puppetlabs/puppetlabs-java_ks/pull/124) ([hunner](https://github.com/hunner)) 365 | - (maint) allow setting PUPPET_VERSION in acceptance [#123](https://github.com/puppetlabs/puppetlabs-java_ks/pull/123) ([justinstoller](https://github.com/justinstoller)) 366 | - Updated travisci file to remove allow_failures on Puppet 4 [#122](https://github.com/puppetlabs/puppetlabs-java_ks/pull/122) ([jonnytdevops](https://github.com/jonnytdevops)) 367 | - Modulesync updates [#121](https://github.com/puppetlabs/puppetlabs-java_ks/pull/121) ([underscorgan](https://github.com/underscorgan)) 368 | - (MODULES-2017) Fix Puppet.newtype deprecation warning [#120](https://github.com/puppetlabs/puppetlabs-java_ks/pull/120) ([roman-mueller](https://github.com/roman-mueller)) 369 | - Merge 1.3.x to master [#119](https://github.com/puppetlabs/puppetlabs-java_ks/pull/119) ([underscorgan](https://github.com/underscorgan)) 370 | 371 | ## [1.3.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.3.0) - 2015-04-15 372 | 373 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.2.6...1.3.0) 374 | 375 | ### Other 376 | 377 | - FM-2347 Release Prep [#118](https://github.com/puppetlabs/puppetlabs-java_ks/pull/118) ([cyberious](https://github.com/cyberious)) 378 | - (BKR-147) add Gemfile setting for BEAKER_VERSION for puppet... [#116](https://github.com/puppetlabs/puppetlabs-java_ks/pull/116) ([anodelman](https://github.com/anodelman)) 379 | - Test and future parser updates [#115](https://github.com/puppetlabs/puppetlabs-java_ks/pull/115) ([cmurphy](https://github.com/cmurphy)) 380 | - final formatting and wording changes [#114](https://github.com/puppetlabs/puppetlabs-java_ks/pull/114) ([jtappa](https://github.com/jtappa)) 381 | - reorganized README, markdown styling, grammar, and descriptions [#113](https://github.com/puppetlabs/puppetlabs-java_ks/pull/113) ([jtappa](https://github.com/jtappa)) 382 | - Adding puppet noop support [#112](https://github.com/puppetlabs/puppetlabs-java_ks/pull/112) ([jitran](https://github.com/jitran)) 383 | - edits to descriptions of params [#111](https://github.com/puppetlabs/puppetlabs-java_ks/pull/111) ([jtappa](https://github.com/jtappa)) 384 | - Pin rspec gems [#110](https://github.com/puppetlabs/puppetlabs-java_ks/pull/110) ([cmurphy](https://github.com/cmurphy)) 385 | - Add IntelliJ files to the ignore list [#109](https://github.com/puppetlabs/puppetlabs-java_ks/pull/109) ([cmurphy](https://github.com/cmurphy)) 386 | - More spec_helper_acceptance fixes [#108](https://github.com/puppetlabs/puppetlabs-java_ks/pull/108) ([underscorgan](https://github.com/underscorgan)) 387 | - Fix spec_helper_acceptance for pe [#107](https://github.com/puppetlabs/puppetlabs-java_ks/pull/107) ([underscorgan](https://github.com/underscorgan)) 388 | - Update .travis.yml, Gemfile, Rakefile, and CONTRIBUTING.md [#106](https://github.com/puppetlabs/puppetlabs-java_ks/pull/106) ([cmurphy](https://github.com/cmurphy)) 389 | - Update .sync.yml for new Gemfile template [#105](https://github.com/puppetlabs/puppetlabs-java_ks/pull/105) ([cmurphy](https://github.com/cmurphy)) 390 | - update README to reflect that java 7 works as of 1.0.0/310b89b [#104](https://github.com/puppetlabs/puppetlabs-java_ks/pull/104) ([rdark](https://github.com/rdark)) 391 | - MODULES-618 - fix java_ks when using password_file [#103](https://github.com/puppetlabs/puppetlabs-java_ks/pull/103) ([underscorgan](https://github.com/underscorgan)) 392 | - Merge 1.2.x [#102](https://github.com/puppetlabs/puppetlabs-java_ks/pull/102) ([underscorgan](https://github.com/underscorgan)) 393 | - Add tests for windows and remove usage of OPENSSL to check MD5 as keytool has that capability [#91](https://github.com/puppetlabs/puppetlabs-java_ks/pull/91) ([cyberious](https://github.com/cyberious)) 394 | 395 | ## [1.2.6](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.2.6) - 2014-11-11 396 | 397 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.2.5...1.2.6) 398 | 399 | ### Other 400 | 401 | - Fix for sles10 [#101](https://github.com/puppetlabs/puppetlabs-java_ks/pull/101) ([underscorgan](https://github.com/underscorgan)) 402 | - Fix path for PE [#100](https://github.com/puppetlabs/puppetlabs-java_ks/pull/100) ([underscorgan](https://github.com/underscorgan)) 403 | - Fix path for solaris [#99](https://github.com/puppetlabs/puppetlabs-java_ks/pull/99) ([underscorgan](https://github.com/underscorgan)) 404 | - Let the java module fail [#98](https://github.com/puppetlabs/puppetlabs-java_ks/pull/98) ([underscorgan](https://github.com/underscorgan)) 405 | - I had some rebase fail [#97](https://github.com/puppetlabs/puppetlabs-java_ks/pull/97) ([underscorgan](https://github.com/underscorgan)) 406 | - 1.2.6 prep [#96](https://github.com/puppetlabs/puppetlabs-java_ks/pull/96) ([underscorgan](https://github.com/underscorgan)) 407 | - 1.2.x rebase master [#95](https://github.com/puppetlabs/puppetlabs-java_ks/pull/95) ([underscorgan](https://github.com/underscorgan)) 408 | - Merge 1.2.x into master [#94](https://github.com/puppetlabs/puppetlabs-java_ks/pull/94) ([underscorgan](https://github.com/underscorgan)) 409 | - Update PE and OS compatibility info in metadata [#92](https://github.com/puppetlabs/puppetlabs-java_ks/pull/92) ([cmurphy](https://github.com/cmurphy)) 410 | - Only install modules on masters during tests [#89](https://github.com/puppetlabs/puppetlabs-java_ks/pull/89) ([cmurphy](https://github.com/cmurphy)) 411 | - Fix solaris 10 tests [#88](https://github.com/puppetlabs/puppetlabs-java_ks/pull/88) ([cmurphy](https://github.com/cmurphy)) 412 | - Stop depending on puppet certs to test java_ks [#87](https://github.com/puppetlabs/puppetlabs-java_ks/pull/87) ([cmurphy](https://github.com/cmurphy)) 413 | - Fix acceptance helper [#86](https://github.com/puppetlabs/puppetlabs-java_ks/pull/86) ([cmurphy](https://github.com/cmurphy)) 414 | - Remove puppet_module_install in favor of copy_module_to [#85](https://github.com/puppetlabs/puppetlabs-java_ks/pull/85) ([cyberious](https://github.com/cyberious)) 415 | - Update spec_helper for more consistency [#84](https://github.com/puppetlabs/puppetlabs-java_ks/pull/84) ([underscorgan](https://github.com/underscorgan)) 416 | - Capture back metadata.json reformating [#81](https://github.com/puppetlabs/puppetlabs-java_ks/pull/81) ([cyberious](https://github.com/cyberious)) 417 | 418 | ## [1.2.5](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.2.5) - 2014-07-14 419 | 420 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.2.4...1.2.5) 421 | 422 | ### Other 423 | 424 | - Remove AIX 5.3 support as we can't test against it. [#80](https://github.com/puppetlabs/puppetlabs-java_ks/pull/80) ([underscorgan](https://github.com/underscorgan)) 425 | - 1.2.5 prep. [#79](https://github.com/puppetlabs/puppetlabs-java_ks/pull/79) ([underscorgan](https://github.com/underscorgan)) 426 | - Add validate and lint tasks to travis script [#77](https://github.com/puppetlabs/puppetlabs-java_ks/pull/77) ([cmurphy](https://github.com/cmurphy)) 427 | - Synchronize .travis.yml [#76](https://github.com/puppetlabs/puppetlabs-java_ks/pull/76) ([cmurphy](https://github.com/cmurphy)) 428 | - Start synchronizing module files [#75](https://github.com/puppetlabs/puppetlabs-java_ks/pull/75) ([cmurphy](https://github.com/cmurphy)) 429 | - openssl on sol 11 is in /usr/bin [#74](https://github.com/puppetlabs/puppetlabs-java_ks/pull/74) ([hunner](https://github.com/hunner)) 430 | - Remove support for puppet:/// files. [#73](https://github.com/puppetlabs/puppetlabs-java_ks/pull/73) ([apenney](https://github.com/apenney)) 431 | - Remove windows support. [#72](https://github.com/puppetlabs/puppetlabs-java_ks/pull/72) ([underscorgan](https://github.com/underscorgan)) 432 | - Pin rspec ~> 2.99 due to bundle issues [#71](https://github.com/puppetlabs/puppetlabs-java_ks/pull/71) ([hunner](https://github.com/hunner)) 433 | - Pin to new beaker-rspec [#70](https://github.com/puppetlabs/puppetlabs-java_ks/pull/70) ([hunner](https://github.com/hunner)) 434 | - Rspec pinning [#69](https://github.com/puppetlabs/puppetlabs-java_ks/pull/69) ([underscorgan](https://github.com/underscorgan)) 435 | - Merge test [#68](https://github.com/puppetlabs/puppetlabs-java_ks/pull/68) ([underscorgan](https://github.com/underscorgan)) 436 | - Rspec3 [#67](https://github.com/puppetlabs/puppetlabs-java_ks/pull/67) ([apenney](https://github.com/apenney)) 437 | 438 | ## [1.2.4](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.2.4) - 2014-06-05 439 | 440 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.2.3...1.2.4) 441 | 442 | ### Other 443 | 444 | - Release 1.2.4 [#64](https://github.com/puppetlabs/puppetlabs-java_ks/pull/64) ([hunner](https://github.com/hunner)) 445 | - Add RHEL7 and Ubuntu 14.04. [#62](https://github.com/puppetlabs/puppetlabs-java_ks/pull/62) ([apenney](https://github.com/apenney)) 446 | - 12xmerge [#61](https://github.com/puppetlabs/puppetlabs-java_ks/pull/61) ([apenney](https://github.com/apenney)) 447 | - Fixing tests. [#60](https://github.com/puppetlabs/puppetlabs-java_ks/pull/60) ([underscorgan](https://github.com/underscorgan)) 448 | 449 | ## [1.2.3](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.2.3) - 2014-03-04 450 | 451 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.2.2...1.2.3) 452 | 453 | ### Other 454 | 455 | - Fix the { location in metadata.json [#57](https://github.com/puppetlabs/puppetlabs-java_ks/pull/57) ([hunner](https://github.com/hunner)) 456 | - Add Scientific linux as a supported platform [#56](https://github.com/puppetlabs/puppetlabs-java_ks/pull/56) ([hunner](https://github.com/hunner)) 457 | - Prepare a 1.2.3 supported release. [#55](https://github.com/puppetlabs/puppetlabs-java_ks/pull/55) ([apenney](https://github.com/apenney)) 458 | - Replace the symlink with the actual file to resolve a PMT issue. [#54](https://github.com/puppetlabs/puppetlabs-java_ks/pull/54) ([apenney](https://github.com/apenney)) 459 | 460 | ## [1.2.2](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.2.2) - 2014-03-03 461 | 462 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.2.1...1.2.2) 463 | 464 | ### Other 465 | 466 | - Add missing fields back to work around Puppet bug. [#53](https://github.com/puppetlabs/puppetlabs-java_ks/pull/53) ([apenney](https://github.com/apenney)) 467 | - Ensure this works in irb. [#52](https://github.com/puppetlabs/puppetlabs-java_ks/pull/52) ([apenney](https://github.com/apenney)) 468 | - Prepare supported 1.2.2 release. [#51](https://github.com/puppetlabs/puppetlabs-java_ks/pull/51) ([apenney](https://github.com/apenney)) 469 | - Adds "Release Notes/Known Bugs" to Changelog, updates file format to markdown, standardizes the format of previous entries [#50](https://github.com/puppetlabs/puppetlabs-java_ks/pull/50) ([lrnrthr](https://github.com/lrnrthr)) 470 | - Prepare metadata for supported modules. [#49](https://github.com/puppetlabs/puppetlabs-java_ks/pull/49) ([apenney](https://github.com/apenney)) 471 | - Adding AIX paths for java6 [#48](https://github.com/puppetlabs/puppetlabs-java_ks/pull/48) ([hunner](https://github.com/hunner)) 472 | - Make it all work on solaris... [#47](https://github.com/puppetlabs/puppetlabs-java_ks/pull/47) ([hunner](https://github.com/hunner)) 473 | - Fix stderr. [#46](https://github.com/puppetlabs/puppetlabs-java_ks/pull/46) ([apenney](https://github.com/apenney)) 474 | - Correct the wording here. [#45](https://github.com/puppetlabs/puppetlabs-java_ks/pull/45) ([apenney](https://github.com/apenney)) 475 | - Checking the stderr wasn't correct [#44](https://github.com/puppetlabs/puppetlabs-java_ks/pull/44) ([hunner](https://github.com/hunner)) 476 | - Switch to operatingsystem instead of osfamily for finer control. [#43](https://github.com/puppetlabs/puppetlabs-java_ks/pull/43) ([apenney](https://github.com/apenney)) 477 | - Fix up the tests for the extended platforms. [#42](https://github.com/puppetlabs/puppetlabs-java_ks/pull/42) ([apenney](https://github.com/apenney)) 478 | - Missing a ' [#41](https://github.com/puppetlabs/puppetlabs-java_ks/pull/41) ([hunner](https://github.com/hunner)) 479 | - Don't assume FOSS paths in java_ks tests [#39](https://github.com/puppetlabs/puppetlabs-java_ks/pull/39) ([justinstoller](https://github.com/justinstoller)) 480 | - Release 1.2.1 [#38](https://github.com/puppetlabs/puppetlabs-java_ks/pull/38) ([hunner](https://github.com/hunner)) 481 | 482 | ## [1.2.1](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.2.1) - 2014-02-12 483 | 484 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.2.0...1.2.1) 485 | 486 | ### Other 487 | 488 | - Allow custom gemsource [#37](https://github.com/puppetlabs/puppetlabs-java_ks/pull/37) ([hunner](https://github.com/hunner)) 489 | - include puppet-lint in the Gemfile [#36](https://github.com/puppetlabs/puppetlabs-java_ks/pull/36) ([justinstoller](https://github.com/justinstoller)) 490 | - Convert rspec-system tests to beaker. [#35](https://github.com/puppetlabs/puppetlabs-java_ks/pull/35) ([apenney](https://github.com/apenney)) 491 | - Release 1.2.0 [#30](https://github.com/puppetlabs/puppetlabs-java_ks/pull/30) ([hunner](https://github.com/hunner)) 492 | 493 | ## [1.2.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.2.0) - 2013-09-18 494 | 495 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.1.0...1.2.0) 496 | 497 | ### Other 498 | 499 | - Validate password length [#29](https://github.com/puppetlabs/puppetlabs-java_ks/pull/29) ([hunner](https://github.com/hunner)) 500 | - Clean up PKCS12 generation and testing [#28](https://github.com/puppetlabs/puppetlabs-java_ks/pull/28) ([hunner](https://github.com/hunner)) 501 | - Add puppet:// type path support for certificate, private_key and chain [#27](https://github.com/puppetlabs/puppetlabs-java_ks/pull/27) ([hunner](https://github.com/hunner)) 502 | - Spec tests [#26](https://github.com/puppetlabs/puppetlabs-java_ks/pull/26) ([hunner](https://github.com/hunner)) 503 | - Use better `raise` syntax to suppress compatibility warnings. [#25](https://github.com/puppetlabs/puppetlabs-java_ks/pull/25) ([ojacobson](https://github.com/ojacobson)) 504 | - Use the openssl pkcs12 '-out' option to write pkcs12 keystore [#10](https://github.com/puppetlabs/puppetlabs-java_ks/pull/10) ([jcraigbrown](https://github.com/jcraigbrown)) 505 | 506 | ## [1.1.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.1.0) - 2013-06-12 507 | 508 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.0.1...1.1.0) 509 | 510 | ## [1.0.1](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.0.1) - 2013-06-12 511 | 512 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.0.0...1.0.1) 513 | 514 | ### Other 515 | 516 | - Release 1.1.0 [#24](https://github.com/puppetlabs/puppetlabs-java_ks/pull/24) ([kbarber](https://github.com/kbarber)) 517 | - Travis ci support [#23](https://github.com/puppetlabs/puppetlabs-java_ks/pull/23) ([adrienthebo](https://github.com/adrienthebo)) 518 | - (maint) refactor keytool provider specs [#22](https://github.com/puppetlabs/puppetlabs-java_ks/pull/22) ([adrienthebo](https://github.com/adrienthebo)) 519 | - Add password_file to type [#20](https://github.com/puppetlabs/puppetlabs-java_ks/pull/20) ([raphink](https://github.com/raphink)) 520 | - Support for executables outside the system default path [#18](https://github.com/puppetlabs/puppetlabs-java_ks/pull/18) ([fhrbek](https://github.com/fhrbek)) 521 | 522 | ## [1.0.0](https://github.com/puppetlabs/puppetlabs-java_ks/tree/1.0.0) - 2013-02-14 523 | 524 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/0.0.6...1.0.0) 525 | 526 | ### Other 527 | 528 | - 1.0.0 [#17](https://github.com/puppetlabs/puppetlabs-java_ks/pull/17) ([reidmv](https://github.com/reidmv)) 529 | - Updated content to conform to README best practices template [#16](https://github.com/puppetlabs/puppetlabs-java_ks/pull/16) ([lrnrthr](https://github.com/lrnrthr)) 530 | 531 | ## [0.0.6](https://github.com/puppetlabs/puppetlabs-java_ks/tree/0.0.6) - 2013-01-22 532 | 533 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/0.0.5...0.0.6) 534 | 535 | ### Other 536 | 537 | - Fix/empty target bug rm [#14](https://github.com/puppetlabs/puppetlabs-java_ks/pull/14) ([reidmv](https://github.com/reidmv)) 538 | 539 | ## [0.0.5](https://github.com/puppetlabs/puppetlabs-java_ks/tree/0.0.5) - 2013-01-17 540 | 541 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/0.0.4...0.0.5) 542 | 543 | ### Other 544 | 545 | - Fix/empty target bug [#13](https://github.com/puppetlabs/puppetlabs-java_ks/pull/13) ([reidmv](https://github.com/reidmv)) 546 | 547 | ## [0.0.4](https://github.com/puppetlabs/puppetlabs-java_ks/tree/0.0.4) - 2013-01-16 548 | 549 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/0.0.3...0.0.4) 550 | 551 | ### Other 552 | 553 | - Add LICENSE file. Update Modulefile to use ASL instead of APL to refer t... [#12](https://github.com/puppetlabs/puppetlabs-java_ks/pull/12) ([haus](https://github.com/haus)) 554 | - Allow non-composite title [#9](https://github.com/puppetlabs/puppetlabs-java_ks/pull/9) ([reidmv](https://github.com/reidmv)) 555 | - Update Modulefile release number [#8](https://github.com/puppetlabs/puppetlabs-java_ks/pull/8) ([reidmv](https://github.com/reidmv)) 556 | 557 | ## [0.0.3](https://github.com/puppetlabs/puppetlabs-java_ks/tree/0.0.3) - 2012-06-12 558 | 559 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/0.0.2...0.0.3) 560 | 561 | ### Other 562 | 563 | - Adds a chain parameter to the type. [#5](https://github.com/puppetlabs/puppetlabs-java_ks/pull/5) ([ody](https://github.com/ody)) 564 | 565 | ## [0.0.2](https://github.com/puppetlabs/puppetlabs-java_ks/tree/0.0.2) - 2012-05-09 566 | 567 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/0.0.1...0.0.2) 568 | 569 | ## [0.0.1](https://github.com/puppetlabs/puppetlabs-java_ks/tree/0.0.1) - 2012-05-09 570 | 571 | [Full Changelog](https://github.com/puppetlabs/puppetlabs-java_ks/compare/f4aa4057597420c5fada555e5e5c8d9545826593...0.0.1) 572 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Setting ownership to the modules team 2 | * @puppetlabs/modules 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Puppet modules 2 | 3 | Check out our [Contributing to Supported Modules Blog Post](https://puppetlabs.github.io/iac/docs/contributing_to_a_module.html) to find all the information that you will need. 4 | -------------------------------------------------------------------------------- /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 | group :development do 17 | 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)) 18 | gem "json", '= 2.3.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 19 | gem "json", '= 2.5.1', require: false if Gem::Requirement.create(['>= 3.0.0', '< 3.0.5']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 20 | gem "json", '= 2.6.1', require: false if Gem::Requirement.create(['>= 3.1.0', '< 3.1.3']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 21 | gem "json", '= 2.6.3', require: false if Gem::Requirement.create(['>= 3.2.0', '< 4.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 22 | gem "racc", '~> 1.4.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 23 | gem "deep_merge", '~> 1.2.2', require: false 24 | gem "voxpupuli-puppet-lint-plugins", '~> 5.0', require: false 25 | gem "facterdb", '~> 2.1', require: false 26 | gem "metadata-json-lint", '~> 4.0', require: false 27 | gem "rspec-puppet-facts", '~> 4.0', require: false 28 | gem "dependency_checker", '~> 1.0.0', require: false 29 | gem "parallel_tests", '= 3.12.1', require: false 30 | gem "pry", '~> 0.10', require: false 31 | gem "simplecov-console", '~> 0.9', require: false 32 | gem "puppet-debugger", '~> 1.0', require: false 33 | gem "rubocop", '~> 1.50.0', require: false 34 | gem "rubocop-performance", '= 1.16.0', require: false 35 | gem "rubocop-rspec", '= 2.19.0', require: false 36 | gem "rb-readline", '= 0.5.5', require: false, platforms: [:mswin, :mingw, :x64_mingw] 37 | gem "rexml", '>= 3.3.9', require: false 38 | gem "ruby-pwsh", require: false 39 | end 40 | group :development, :release_prep do 41 | gem "puppet-strings", '~> 4.0', require: false 42 | gem "puppetlabs_spec_helper", '~> 7.0', require: false 43 | end 44 | group :system_tests do 45 | gem "puppet_litmus", '~> 1.0', require: false, platforms: [:ruby, :x64_mingw] 46 | gem "CFPropertyList", '< 3.0.7', require: false, platforms: [:mswin, :mingw, :x64_mingw] 47 | gem "serverspec", '~> 2.41', require: false 48 | end 49 | 50 | puppet_version = ENV['PUPPET_GEM_VERSION'] 51 | facter_version = ENV['FACTER_GEM_VERSION'] 52 | hiera_version = ENV['HIERA_GEM_VERSION'] 53 | 54 | gems = {} 55 | 56 | gems['puppet'] = location_for(puppet_version) 57 | 58 | # If facter or hiera versions have been specified via the environment 59 | # variables 60 | 61 | gems['facter'] = location_for(facter_version) if facter_version 62 | gems['hiera'] = location_for(hiera_version) if hiera_version 63 | 64 | gems.each do |gem_name, gem_params| 65 | gem gem_name, *gem_params 66 | end 67 | 68 | # Evaluate Gemfile.local and ~/.gemfile if they exist 69 | extra_gemfiles = [ 70 | "#{__FILE__}.local", 71 | File.join(Dir.home, '.gemfile'), 72 | ] 73 | 74 | extra_gemfiles.each do |gemfile| 75 | if File.file?(gemfile) && File.readable?(gemfile) 76 | eval(File.read(gemfile), binding) 77 | end 78 | end 79 | # vim: syntax=ruby 80 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | ## 2.2.0 2 | ### Summary 3 | A release that converts the module to the PDK version 1.3.2, alongside an additional parameter added. 4 | 5 | ### Added 6 | - Add support for `destkeypass` when importing PKCS12 keystores. 7 | 8 | ### Changed 9 | - Module has been converted to the PDK with version 1.3.2. 10 | 11 | ## Supported Release [2.1.0] 12 | ### Summary 13 | The main purpose of this module is to release Rubocop changes, with some other minor updates included. 14 | 15 | ### Added 16 | - Support added for the specifying of source cert alias. 17 | 18 | ### Changed 19 | - The module has been changed to comply with the set rubocop guidelines. 20 | - JDK updated to 8u161. 21 | - Fingerprint extraction in keytool.rb has been improved upon. 22 | - Modulesync changes. 23 | 24 | ## Supported Release [2.0.0] 25 | ### Summary 26 | This is a roll up of maintainence changes, features and compatibility updates from throughout the year. This release is backwards incompatible because the Puppet version requirements have now changed with the lower Puppet version boundary jumping from 3.0.0 to 4.7.0 and we have removed vulnerable puppet3 support dependencies. 27 | 28 | ### Added 29 | - Debian 9 entry in 'metadata.json' 30 | - Support for importing pkcs12 files by introducing a function called `import pkcs12` 31 | - Support for removal of key store file on invalid password by introducing `password_fail_reset` 32 | 33 | ### Changed 34 | - Appveyor testing has been enabled 35 | - General maintainence changes via modulessync 36 | - Java-ks is now being managed in modulesync as a cross-platform module 37 | - [FM-6547](https://tickets.puppetlabs.com/browse/FM-6547) - Pin JDK installation package to 8.0.152 for Windows 38 | - pkcs12 acceptance tests no longer run on SLES 39 | - CONTRIBUTING.md updates 40 | - Travis ruby version to 2.4.0 and 2.1.9 41 | - Upper Puppet boundary to Puppet 6.0.0 42 | - Lower Puppet boundary to Puppet 4.7.0 43 | 44 | ### Fixed 45 | - Unit test failures on Windows 46 | - Java 9 support 47 | 48 | ### Removed 49 | - SLES 10 SP4 entry in 'metadata.json' 50 | - Debian 6 entry in 'metadata.json' 51 | - Windows Server 2003 R2 and Windows 8 entry in 'metadata.json' 52 | - Ubuntu 10.04 and 12.04 entry in 'metadata.json' 53 | - [FM-6588](https://tickets.puppetlabs.com/browse/FM-6588) - Remove vulnerable puppet3 support dependencies 54 | 55 | ## Supported Release 1.6.0 56 | ### Summary 57 | The keytool would hang on occasion for unexplained reasons, so keytool executions are wrapped in a timeout that defaults to 120 seconds and is configurable by the `keytool_timeout` parameter. 58 | 59 | ### Added 60 | - New parameter: `keytool_timeout` 61 | 62 | ## Supported Release 1.5.0 63 | ### Summary 64 | This release contains some small features and one bugfix which makes the module environment safe. 65 | 66 | #### Features 67 | - Added a new parameter, `private_key_type` which defaults to `rsa` but can also be set to `ec` for ECDSA keys. 68 | - Added `java_ks::config` class with `create_resources` so that Hiera can be used to manage the config. 69 | - [MODULES-2495] Allows the provider to work with encrypted private keys. 70 | 71 | #### Bugfixes 72 | - [MODULES-4505] Fixed `self.title_patterns` in java_ks type so it doesn't return a Proc so the module is environment safe. 73 | 74 | ## Supported Release 1.4.1 75 | ### Summary 76 | This release contains bugfixes around certificate chains and other testing improvements. 77 | 78 | #### Bugfixes 79 | - Dont expose keystore content when keystore initally empty. 80 | - Support certificate chains in certificate file. 81 | - Support multiple intermediate certificates in chain. 82 | - Improve cert chain acceptance tests. 83 | - Update to current msync configs. 84 | - Debian 8 support. 85 | 86 | ## Supported Release 1.4.0 87 | ### Summary 88 | This release contains a new option to provide destkeypass. Also contains 89 | bugfixes and a metadata update to support Puppet Enterprise 2015.3.x. 90 | 91 | #### Features 92 | - Adds `destkeypass` option to pass in password when importing into the keystore. 93 | - Adds feature support for JCEKS format and extensions. 94 | 95 | #### Bugfixes 96 | - Fixes composite title patterns in provider to improve support for Windows. 97 | 98 | #### Test Improvements 99 | - Improves Windows testing. 100 | 101 | ## 2015-07-20 - Supported Release 1.3.1 102 | ### Summary 103 | This release updates the metadata for the upcoming release of PE as well as an additional bugfix. 104 | 105 | #### Bugfixes 106 | - Fixes Puppet.newtype deprecation warning 107 | 108 | ## 2015-04-14 - Supported Release 1.3.0 109 | ### Summary 110 | Remove openssl command line tool from requirements 111 | 112 | #### Features 113 | - Add Windows support and tests 114 | 115 | ## 2014-11-11 - Supported Release 1.2.6 116 | ### Summary 117 | 118 | This release has test fixes and files synced from modulesync. 119 | 120 | ## 2014-07-10 - Supported Release 1.2.5 121 | ### Summary 122 | 123 | This release has bugfixes and test improvements. 124 | 125 | #### Features 126 | - Update tests to use RSpec 2.99 syntax 127 | 128 | #### Bugfixes 129 | - Remove broken support for puppet:// files. 130 | - Remove incorrect statment of windows support from metadata.json. 131 | - Fix path issue for openssl on solaris 11. 132 | 133 | #### Known Bugs 134 | * No known bugs 135 | 136 | ## 2014-06-04 - Release 1.2.4 137 | ### Summary 138 | 139 | This is a compatibility release. No functional changes to this module were made 140 | in this release, just testing infrastructure changes to extend tests to RHEL7 141 | and Ubuntu 14.04 142 | 143 | #### Features 144 | 145 | #### Bugfixes 146 | 147 | #### Known Bugs 148 | * No known bugs 149 | 150 | ## 2014-03-04 - Supported Release 1.2.3 151 | ### Summary 152 | 153 | This is a supported release. This release removes a testing symlink that can 154 | cause trouble on systems where /var is on a seperate filesystem from the 155 | modulepath. 156 | 157 | #### Features 158 | 159 | #### Bugfixes 160 | 161 | #### Known Bugs 162 | * No known bugs 163 | 164 | ## 2014-03-04 - Supported Release 1.2.2 165 | ### Summary 166 | 167 | This is a supported release. Only tests and documentation were changed. 168 | 169 | #### Features 170 | - Test changes. 171 | - Documentation changes. 172 | 173 | #### Bugfixes 174 | 175 | #### Known Bugs 176 | * No known bugs 177 | 178 | 179 | ## 2014-02-12 - Release 1.2.1 180 | 181 | #### Bugfixes 182 | - Updating specs 183 | 184 | 185 | ## 2013-09-18 - Release 1.2.0 186 | 187 | ### Summary 188 | This release adds `puppet://` URI support, a few bugfixes, and lots of tests. 189 | 190 | #### Features 191 | - `puppet://` URI support for the `chain`, `certificate`, and `private_key` parameters 192 | 193 | #### Bugfixes 194 | - Validate that keystore passwords are > 6 characters (would silent fail before) 195 | - Fixed corrupted keystore PKCS12 files in some cases. 196 | - More acceptance tests, unit tests, and rspec-puppet tests. 197 | 198 | 199 | ## 1.1.0 200 | 201 | This minor feature provides a number of new features: 202 | 203 | * We have introduced a new property `password_file` to the java_ks type, so 204 | that users can specify a plain text file to be used for unlocking a Java 205 | keystore file. 206 | * A new property `path` has been also added so you can add a custom search 207 | path for the command line tooling (keystore etc.) 208 | 209 | Travis-CI support has also been added to improve testing. 210 | 211 | #### Detailed Changes 212 | 213 | * Support for executables outside the system default path (Filip Hrbek) 214 | * Add password_file to type (Raphaël Pinson) 215 | * Travis ci support (Adrien Thebo) 216 | * refactor keytool provider specs (Adrien Thebo) 217 | 218 | --------------------------------------- 219 | 220 | ## 0.0.6 221 | 222 | 223 | Fixes an issue with ibm java handling input from stdin on SLES 224 | 225 | [2.1.0]:https://github.com/puppetlabs/puppetlabs-java_ks/compare/2.0.0...2.1.0 226 | [2.0.0]:https://github.com/puppetlabs/puppetlabs-java_ks/compare/1.6.0...2.0.0 227 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Puppet Module - puppetlabs-java_ks 2 | 3 | Copyright 2018 Puppet, Inc. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # java_ks 2 | 3 | #### Table of Contents 4 | 5 | 1. [Overview](#overview) 6 | 2. [Module Description](#module-description) 7 | * [Beginning with the module](#beginning-with-the-module) 8 | 3. [Setup](#setup) 9 | 4. [Usage](#usage) 10 | * [Certificates](#certificates) 11 | * [Namevars](#namevars) 12 | * [Windows task](#windows-task) 13 | 5. [Reference](#reference) 14 | 6. [Limitations](#limitations) 15 | 7. [License](#license) 16 | 8. [Development](#development) 17 | 18 | ## Overview 19 | 20 | The java_ks module uses a combination of keytool and openssl to manage entries in a Java keystore. 21 | 22 | ## Module Description 23 | 24 | The java_ks module contains a type called `java_ks` and a single provider named `keytool`. Their purpose is to enable importation of arbitrary, already generated and signed certificates into a Java keystore for use by various applications. 25 | 26 | ## Setup 27 | 28 | ### Beginning with the module 29 | 30 | To get started with java_ks, declare each `java_ks` resource you need. 31 | 32 | ```puppet 33 | java_ks { 'puppetca:truststore': 34 | ensure => latest, 35 | certificate => '/etc/puppet/ssl/certs/ca.pem', 36 | target => '/etc/activemq/broker.ts', 37 | password => 'puppet', 38 | trustcacerts => true, 39 | } 40 | ``` 41 | 42 | 43 | ## Usage 44 | 45 | You must specify a target in some way. You can specify `target` after the colon in the title or by using the target attribute in the resource. If you declare both, it will prefer the attribute. 46 | 47 | ```puppet 48 | java_ks { 'puppetca:keystore': 49 | ensure => latest, 50 | certificate => '/etc/puppet/ssl/certs/ca.pem', 51 | target => '/etc/activemq/broker.ks', 52 | password => 'puppet', 53 | trustcacerts => true, 54 | } 55 | 56 | java_ks { 'broker.example.com:/etc/activemq/broker.ks': 57 | ensure => latest, 58 | certificate => '/etc/puppet/ssl/certs/broker.example.com.pe-internal-broker.pem', 59 | private_key => '/etc/puppet/ssl/private_keys/broker.example.com.pe-internal-broker.pem', 60 | password => 'albatros', 61 | password_fail_reset => true, 62 | } 63 | ``` 64 | 65 | For use cases where you want to fetch the certificate data from a secure store, like vault, you can use the `_content` attributes. Here is an example: 66 | 67 | ```puppet 68 | java_ks { 'broker.example.com:/etc/activemq/broker.ks': 69 | ensure => latest, 70 | certificate_content => $certificate_data_fetched_from_secure_store, 71 | private_key_content => $private_key_data_fetched_from_secure_store, 72 | password => 'albatros', 73 | password_fail_reset => true, 74 | } 75 | ``` 76 | 77 | **NOTE:** Sensitive fields like `password`, `certificate_content` and `private_key_content` can be deferred using the [Deferred](https://www.puppet.com/docs/puppet/7/template_with_deferred_values.html) function. This will ensure sensitive values are not present in the Catalog. 78 | 79 | You can see an example of its use below. 80 | 81 | ~~~ puppet 82 | java_ks { 'broker.example.com:/etc/activemq/broker.ks': 83 | ensure => latest, 84 | certificate_content => Deferred('sprintf', [$certificate_data_fetched_from_secure_store], 85 | private_key_content => Deferred('sprintf', [$private_key_data_fetched_from_secure_store], 86 | password => Deferred('sprint', ['albatros']), 87 | password_fail_reset => true, 88 | } 89 | ~~~ 90 | 91 | We recommend using the data type `Senstive` for the attributes `certificate_content` and `private_key_content`. But These attributes also support a regular `String` data type. The `_content` attributes are mutual exclusive with their file-based variants. 92 | 93 | 94 | You can also use Hiera by passing params to the java_ks::config class: 95 | 96 | ```yaml 97 | java_ks::config::params: 98 | 'broker.example.com:/etc/activemq/broker.ks': 99 | ensure: latest 100 | certificate: '/etc/puppet/ssl/certs/broker.example.com.pe-internal-broker.pem' 101 | private_key: '/etc/puppet/ssl/private_keys/broker.example.com.pe-internal-broker.pem' 102 | password: true 103 | ``` 104 | 105 | ### Certificates 106 | To have a Java application server use a specific certificate for incoming connections, use the certificate parameter. You will need to simultaneously import the private key accompanying the signed certificate you want to use. As long as you provide the path to the key and the certificate, the provider will do the conversion for you. 107 | 108 | 109 | ### Namevars 110 | 111 | The java_ks module supports multiple certificates with different keystores but the same alias by implementing Puppet's composite namevar functionality. Titles map to namevars via `$alias:$target` (alias of certificate, colon, on-disk path to the keystore). If you create dependencies on these resources you need to remember to use the same title syntax outlined for generating the composite namevars. 112 | 113 | *Note about composite namevars:* 114 | The way composite namevars currently work, you must have the colon in the title. This is true *even if you define name and target parameters.* The title can be `foo:bar`, but the name and target parameters must be `broker.example.com` and `/etc/activemq/broker.ks`. If you follow convention, it will do as you expect and correctly create an entry in the 115 | broker.ks keystore with the alias of broker.example.com. 116 | 117 | ## Reference 118 | 119 | For information on the classes and types, see the [REFERENCE.md](https://github.com/puppetlabs/puppetlabs-java_ks/blob/main/REFERENCE.md). 120 | 121 | ## Limitations 122 | 123 | The java_ks module uses the `keytool` and `openssl` commands. It should work on all systems with these commands. 124 | 125 | Java 7 is supported as of 1.0.0. 126 | 127 | Developed against IBM Java 6 on AIX. Other versions may be unsupported. 128 | 129 | For an extensive list of supported operating systems, see [metadata.json](https://github.com/puppetlabs/puppetlabs-java_ks/blob/main/metadata.json) 130 | 131 | ## License 132 | 133 | This codebase is licensed under the Apache2.0 licensing, however due to the nature of the codebase the open source dependencies may also use a combination of [AGPL](https://opensource.org/license/agpl-v3/), [BSD-2](https://opensource.org/license/bsd-2-clause/), [BSD-3](https://opensource.org/license/bsd-3-clause/), [GPL2.0](https://opensource.org/license/gpl-2-0/), [LGPL](https://opensource.org/license/lgpl-3-0/), [MIT](https://opensource.org/license/mit/) and [MPL](https://opensource.org/license/mpl-2-0/) Licensing. 134 | 135 | ## Development 136 | 137 | Puppet modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad hardware, software, and deployment configurations that Puppet is intended to serve. 138 | 139 | We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. For more information, see our [module contribution guide.](https://puppet.com/docs/puppet/latest/contributing.html) 140 | -------------------------------------------------------------------------------- /REFERENCE.md: -------------------------------------------------------------------------------- 1 | # Reference 2 | 3 | 4 | 5 | ## Table of Contents 6 | 7 | ### Classes 8 | 9 | * [`java_ks::config`](#java_ks--config): java_ks configuration 10 | 11 | ### Resource types 12 | 13 | * [`java_ks`](#java_ks): Manages the entries in a java keystore, and uses composite namevars to accomplish the same alias spread across multiple target keystores. 14 | 15 | ## Classes 16 | 17 | ### `java_ks::config` 18 | 19 | java_ks configuration 20 | 21 | #### Parameters 22 | 23 | The following parameters are available in the `java_ks::config` class: 24 | 25 | * [`params`](#-java_ks--config--params) 26 | 27 | ##### `params` 28 | 29 | Data type: `Hash` 30 | 31 | A hash containing the parameters required for the java config. 32 | 33 | Default value: `{}` 34 | 35 | ## Resource types 36 | 37 | ### `java_ks` 38 | 39 | Manages the entries in a java keystore, and uses composite namevars to 40 | accomplish the same alias spread across multiple target keystores. 41 | 42 | #### Properties 43 | 44 | The following properties are available in the `java_ks` type. 45 | 46 | ##### `ensure` 47 | 48 | Valid values: `present`, `absent`, `latest` 49 | 50 | Has three states: present, absent, and latest. Latest 51 | will compare the on disk SHA1 fingerprint of the certificate to that 52 | in keytool to determine if insync? returns true or false. We redefine 53 | insync? for this parameter to accomplish this. 54 | 55 | Default value: `present` 56 | 57 | ##### `password` 58 | 59 | The password used to protect the keystore. If private keys are 60 | subsequently also protected this password will be used to attempt 61 | unlocking. Must be six or more characters in length. Cannot be used 62 | together with :password_file, but you must pass at least one of these parameters. 63 | 64 | #### Parameters 65 | 66 | The following parameters are available in the `java_ks` type. 67 | 68 | * [`certificate`](#-java_ks--certificate) 69 | * [`certificate_content`](#-java_ks--certificate_content) 70 | * [`chain`](#-java_ks--chain) 71 | * [`destkeypass`](#-java_ks--destkeypass) 72 | * [`keytool_timeout`](#-java_ks--keytool_timeout) 73 | * [`name`](#-java_ks--name) 74 | * [`password_fail_reset`](#-java_ks--password_fail_reset) 75 | * [`password_file`](#-java_ks--password_file) 76 | * [`path`](#-java_ks--path) 77 | * [`private_key`](#-java_ks--private_key) 78 | * [`private_key_content`](#-java_ks--private_key_content) 79 | * [`private_key_type`](#-java_ks--private_key_type) 80 | * [`provider`](#-java_ks--provider) 81 | * [`source_alias`](#-java_ks--source_alias) 82 | * [`source_password`](#-java_ks--source_password) 83 | * [`storetype`](#-java_ks--storetype) 84 | * [`target`](#-java_ks--target) 85 | * [`trustcacerts`](#-java_ks--trustcacerts) 86 | 87 | ##### `certificate` 88 | 89 | A file containing a server certificate, followed by zero or more intermediate certificate authorities. 90 | All certificates will be placed in the keystore. This will autorequire the specified file. 91 | 92 | ##### `certificate_content` 93 | 94 | A string containing a server certificate, followed by zero or more intermediate certificate authorities. 95 | All certificates will be placed in the keystore. 96 | 97 | ##### `chain` 98 | 99 | The intermediate certificate authorities, if they are to be taken 100 | from a file separate from the server certificate. This will autorequire the specified file. 101 | 102 | ##### `destkeypass` 103 | 104 | The password used to protect the key in keystore. 105 | 106 | ##### `keytool_timeout` 107 | 108 | Timeout for the keytool command in seconds. 109 | 110 | Default value: `120` 111 | 112 | ##### `name` 113 | 114 | namevar 115 | 116 | The alias that is used to identify the entry in the keystore. This will be 117 | converted to lowercase. 118 | 119 | ##### `password_fail_reset` 120 | 121 | Valid values: `true`, `false` 122 | 123 | If the supplied password does not succeed in unlocking the 124 | keystore file, then delete the keystore file and create a new one. 125 | Default: false. 126 | 127 | Default value: `false` 128 | 129 | ##### `password_file` 130 | 131 | The path to a file containing the password used to protect the 132 | keystore. This cannot be used together with :password, but you must pass at least one of these parameters. 133 | 134 | ##### `path` 135 | 136 | The search path used for command (keytool, openssl) execution. 137 | Paths can be specified as an array or as a ' 138 | 139 | ##### `private_key` 140 | 141 | If you want an application to be a server and encrypt traffic, 142 | you will need a private key. Private key entries in a keystore must be 143 | accompanied by a signed certificate for the keytool provider. This parameter 144 | allows you to specify the file name containing the private key. This will autorequire 145 | the specified file. 146 | 147 | ##### `private_key_content` 148 | 149 | If you want an application to be a server and encrypt traffic, 150 | you will need a private key. Private key entries in a keystore must be 151 | accompanied by a signed certificate for the keytool provider. This parameter allows you to specify the content 152 | of the private key. 153 | 154 | ##### `private_key_type` 155 | 156 | Valid values: `rsa`, `dsa`, `ec` 157 | 158 | The type of the private key. Usually the private key is of type RSA 159 | key but it can also be an Elliptic Curve key (EC) or DSA. 160 | Valid options: , , . Defaults to 161 | 162 | Default value: `rsa` 163 | 164 | ##### `provider` 165 | 166 | The specific backend to use for this `java_ks` resource. You will seldom need to specify this --- Puppet will usually 167 | discover the appropriate provider for your platform. 168 | 169 | ##### `source_alias` 170 | 171 | The source certificate alias 172 | 173 | ##### `source_password` 174 | 175 | The source keystore password 176 | 177 | ##### `storetype` 178 | 179 | Valid values: `jceks`, `pkcs12`, `jks` 180 | 181 | Optional storetype 182 | Valid options: , , 183 | 184 | ##### `target` 185 | 186 | namevar 187 | 188 | Destination file for the keystore. This will autorequire the parent directory of the file. 189 | 190 | ##### `trustcacerts` 191 | 192 | Valid values: `true`, `false` 193 | 194 | Certificate authorities aren't by default trusted so if you are adding a CA you need to set this to true. 195 | Defaults to :false. 196 | 197 | Default value: `false` 198 | 199 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler' 4 | require 'puppet_litmus/rake_tasks' if Gem.loaded_specs.key? 'puppet_litmus' 5 | require 'puppetlabs_spec_helper/rake_tasks' 6 | require 'puppet-syntax/tasks/puppet-syntax' 7 | require 'puppet-strings/tasks' if Gem.loaded_specs.key? 'puppet-strings' 8 | 9 | PuppetLint.configuration.send('disable_relative') 10 | -------------------------------------------------------------------------------- /data/common.yaml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /hiera.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 5 3 | 4 | defaults: # Used for any hierarchy level that omits these keys. 5 | datadir: data # This path is relative to hiera.yaml's directory. 6 | data_hash: yaml_data # Use the built-in YAML backend. 7 | 8 | hierarchy: 9 | - name: "os.family/major release" 10 | paths: 11 | # Used to distinguish between Debian and Ubuntu 12 | - "os/%{facts.os.name}/%{facts.os.release.major}.yaml" 13 | - "os/%{facts.os.family}/%{facts.os.release.major}.yaml" 14 | # Used for Solaris 15 | - "os/%{facts.os.family}/%{facts.kernelrelease}.yaml" 16 | - name: "os.family" 17 | paths: 18 | - "os/%{facts.os.name}.yaml" 19 | - "os/%{facts.os.family}.yaml" 20 | - name: 'common' 21 | path: 'common.yaml' 22 | -------------------------------------------------------------------------------- /lib/puppet/provider/java_ks/keytool.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'openssl' 4 | require 'timeout' 5 | require 'puppet/util/filetype' 6 | 7 | Puppet::Type.type(:java_ks).provide(:keytool) do 8 | desc 'Uses a combination of openssl and keytool to manage Java keystores' 9 | 10 | def command_keytool 11 | 'keytool' 12 | end 13 | 14 | # Keytool can only import a keystore if the format is pkcs12. Generating and 15 | # importing a keystore is used to add private_key and certificate pairs. 16 | def to_pkcs12(path) 17 | case private_key_type 18 | when :rsa 19 | pkey = OpenSSL::PKey::RSA.new File.read(private_key), password 20 | when :dsa 21 | pkey = OpenSSL::PKey::DSA.new File.read(private_key), password 22 | when :ec 23 | pkey = OpenSSL::PKey::EC.new File.read(private_key), password 24 | end 25 | 26 | if chain 27 | x509_cert = OpenSSL::X509::Certificate.new File.read certificate 28 | chain_certs = get_chain(chain) 29 | else 30 | chain_certs = get_chain(certificate) 31 | x509_cert = chain_certs.shift 32 | end 33 | pkcs12 = OpenSSL::PKCS12.create(password, @resource[:name], pkey, x509_cert, chain_certs) 34 | File.open(path, 'wb') { |f| f.print pkcs12.to_der } 35 | end 36 | 37 | # Keytool can only import a jceks keystore if the format is der. Generating and 38 | # importing a keystore is used to add private_key and certificate pairs. 39 | def to_der(path) 40 | x509_cert = OpenSSL::X509::Certificate.new File.read certificate 41 | File.open(path, 'wb') { |f| f.print x509_cert.to_der } 42 | end 43 | 44 | def get_chain(path) 45 | chain_certs = File.read(path, encoding: 'ISO-8859-1').scan(%r{-----BEGIN [^\n]*CERTIFICATE.*?-----END [^\n]*CERTIFICATE-----}m) 46 | if chain_certs.any? 47 | chain_certs.map { |cert| OpenSSL::X509::Certificate.new cert } 48 | else 49 | chain_certs << ((OpenSSL::X509::Certificate.new File.binread path)) 50 | end 51 | end 52 | 53 | def password 54 | if @resource[:password_file].nil? 55 | @resource[:password] 56 | else 57 | file = File.open(@resource[:password_file], 'r') 58 | pword = file.read 59 | file.close 60 | pword.chomp 61 | end 62 | end 63 | 64 | def password_file 65 | pword = password 66 | source_pword = sourcepassword 67 | 68 | tmpfile = Tempfile.new("#{@resource[:name]}.") 69 | contents = if File.exist?(@resource[:target]) && !File.empty?(@resource[:target]) 70 | if source_pword.nil? 71 | "#{pword}\n#{pword}" 72 | else 73 | "#{pword}\n#{source_pword}" 74 | end 75 | elsif !source_pword.nil? 76 | "#{pword}\n#{pword}\n#{source_pword}" 77 | else 78 | "#{pword}\n#{pword}\n#{pword}" 79 | end 80 | tmpfile.write(contents) 81 | tmpfile.flush 82 | tmpfile 83 | end 84 | 85 | # Where we actually to the import of the file created using to_pkcs12. 86 | def import_ks 87 | tmppk12 = Tempfile.new("#{@resource[:name]}.") 88 | to_pkcs12(tmppk12.path) 89 | cmd = [ 90 | command_keytool, 91 | '-importkeystore', '-srcstoretype', 'PKCS12', 92 | '-destkeystore', @resource[:target], 93 | '-srckeystore', tmppk12.path, 94 | '-alias', @resource[:name] 95 | ] 96 | cmd << '-trustcacerts' if @resource[:trustcacerts] 97 | cmd += ['-destkeypass', @resource[:destkeypass]] unless @resource[:destkeypass].nil? 98 | cmd += ['-deststoretype', storetype] unless storetype.nil? 99 | 100 | pwfile = password_file 101 | run_command(cmd, @resource[:target], pwfile) 102 | tmppk12.close! 103 | pwfile.close! if pwfile.is_a? Tempfile 104 | end 105 | 106 | def import_pkcs12 107 | cmd = [ 108 | command_keytool, 109 | '-importkeystore', '-srcstoretype', 'PKCS12', 110 | '-destkeystore', @resource[:target], 111 | '-srckeystore', certificate 112 | ] 113 | 114 | if @resource[:source_alias] 115 | cmd.push( 116 | '-srcalias', @resource[:source_alias], 117 | '-destalias', @resource[:name] 118 | ) 119 | end 120 | 121 | if @resource[:destkeypass] 122 | cmd.push( 123 | '-destkeypass', @resource[:destkeypass] 124 | ) 125 | end 126 | 127 | pwfile = password_file 128 | run_command(cmd, @resource[:target], pwfile) 129 | pwfile.close! if pwfile.is_a? Tempfile 130 | end 131 | 132 | def import_jceks 133 | tmpder = Tempfile.new("#{@resource[:name]}.") 134 | to_der(tmpder.path) 135 | cmd = [ 136 | command_keytool, 137 | '-importcert', '-noprompt', 138 | '-alias', @resource[:name], 139 | '-file', tmpder.path, 140 | '-keystore', @resource[:target], 141 | '-storetype', storetype 142 | ] 143 | cmd << '-trustcacerts' if @resource[:trustcacerts] 144 | cmd += ['-destkeypass', @resource[:destkeypass]] unless @resource[:destkeypass].nil? 145 | 146 | pwfile = password_file 147 | run_command(cmd, @resource[:target], pwfile) 148 | pwfile.close! if pwfile.is_a? Tempfile 149 | end 150 | 151 | def exists? 152 | cmd = [ 153 | command_keytool, 154 | '-list', 155 | '-keystore', @resource[:target], 156 | '-alias', @resource[:name] 157 | ] 158 | cmd += ['-storetype', storetype] if storetype == :jceks 159 | begin 160 | tmpfile = password_file 161 | run_command(cmd, false, tmpfile) 162 | tmpfile.close! 163 | true 164 | rescue StandardError => e 165 | if e.message.match?(%r{password was incorrect}i) && (@resource[:password_fail_reset]) 166 | # we have the wrong password for the keystore. so delete it if :password_fail_reset 167 | File.delete(@resource[:target]) 168 | end 169 | false 170 | end 171 | end 172 | 173 | # Extracts the fingerprints of a given output 174 | def extract_fingerprint(output) 175 | fps = [] 176 | output.scan(%r{^Certificate fingerprints:(.*?)Signature?}m).flatten.each do |certblock| 177 | fps.push(certblock.scan(%r{^\s+\S+:\s+(\S+)}m)) 178 | end 179 | fps.flatten.sort.join('/') 180 | end 181 | 182 | # Reading the fingerprint of the certificate on disk. 183 | def latest 184 | # The certificate file may not exist during a puppet noop run as it's managed by puppet. 185 | # Return value must be different to provider.current to signify a possible trigger event. 186 | if Puppet[:noop] && !File.exist?(certificate) 187 | 'latest' 188 | elsif storetype == :pkcs12 189 | cmd = [ 190 | command_keytool, '-v', 191 | '-list', '-keystore', certificate, 192 | '-storetype', 'PKCS12', '-storepass', sourcepassword 193 | ] 194 | output = run_command(cmd) 195 | extract_fingerprint(output) 196 | 197 | else 198 | cmd = [ 199 | command_keytool, 200 | '-v', '-printcert', '-file', certificate 201 | ] 202 | output = run_command(cmd) 203 | if chain 204 | cmd = [ 205 | command_keytool, 206 | '-v', '-printcert', '-file', chain 207 | ] 208 | output += run_command(cmd) 209 | end 210 | extract_fingerprint(output) 211 | 212 | end 213 | end 214 | 215 | # Reading the fingerprint of the certificate currently in the keystore. 216 | def current 217 | # The keystore file may not exist during a puppet noop run as it's managed by puppet. 218 | if Puppet[:noop] && !File.exist?(@resource[:target]) 219 | 'current' 220 | else 221 | cmd = [ 222 | command_keytool, 223 | '-list', '-v', 224 | '-keystore', @resource[:target], 225 | '-alias', @resource[:name] 226 | ] 227 | cmd += ['-storetype', storetype] if storetype == :jceks 228 | tmpfile = password_file 229 | output = run_command(cmd, false, tmpfile) 230 | tmpfile.close! 231 | extract_fingerprint(output) 232 | 233 | end 234 | end 235 | 236 | # Determine if we need to do an import of a private_key and certificate pair 237 | # or just add a signed certificate, then do it. 238 | def create 239 | if !certificate.nil? && !private_key.nil? 240 | import_ks 241 | elsif certificate.nil? && !private_key.nil? 242 | raise Puppet::Error, 'Keytool is not capable of importing a private key without an accompanying certificate.' 243 | elsif storetype == :jceks 244 | import_jceks 245 | elsif storetype == :pkcs12 246 | import_pkcs12 247 | else 248 | cmd = [ 249 | command_keytool, 250 | '-importcert', '-noprompt', 251 | '-alias', @resource[:name], 252 | '-file', certificate, 253 | '-keystore', @resource[:target] 254 | ] 255 | cmd << '-trustcacerts' if @resource[:trustcacerts] 256 | tmpfile = password_file 257 | run_command(cmd, @resource[:target], tmpfile) 258 | tmpfile.close! 259 | end 260 | end 261 | 262 | def destroy 263 | cmd = [ 264 | command_keytool, 265 | '-delete', 266 | '-alias', @resource[:name], 267 | '-keystore', @resource[:target] 268 | ] 269 | cmd += ['-storetype', storetype] if storetype == :jceks 270 | tmpfile = password_file 271 | run_command(cmd, false, tmpfile) 272 | tmpfile.close! 273 | end 274 | 275 | # Being safe since I have seen some additions overwrite and some just throw errors. 276 | def update 277 | destroy 278 | create 279 | end 280 | 281 | def certificate 282 | return @resource[:certificate] if @resource[:certificate] 283 | 284 | # When no certificate file is specified, we infer the usage of 285 | # certificate content and create a tempfile containing this value. 286 | # we leave it to to the tempfile to clean it up after the pupet run exists. 287 | @temp_certificate_file ||= begin 288 | file = Tempfile.new('certificate') 289 | # Check if the specified value is a Sensitive data type. If so, unwrap it and use 290 | # the value. 291 | content = @resource[:certificate_content].respond_to?(:unwrap) ? @resource[:certificate_content].unwrap : @resource[:certificate_content] 292 | file.write(content) 293 | file.close 294 | file 295 | end 296 | 297 | @temp_certificate_file.path 298 | end 299 | 300 | def private_key 301 | return @resource[:private_key] if @resource[:private_key] 302 | return unless @resource[:private_key_content] 303 | 304 | # When no private key file is specified, we infer the usage of 305 | # private key content and create a tempfile containing this value. 306 | # we leave it to to the tempfile to clean it up after the pupet run exists. 307 | @temp_private_key_file ||= begin 308 | file = Tempfile.new('private_key') 309 | # Check if the specified value is a Sensitive data type. If so, unwrap it and use 310 | # the value. 311 | content = @resource[:private_key_content].respond_to?(:unwrap) ? @resource[:private_key_content].unwrap : @resource[:private_key_content] 312 | file.write(content) 313 | file.close 314 | file 315 | end 316 | @temp_private_key_file.path 317 | end 318 | 319 | def private_key_type 320 | @resource[:private_key_type] 321 | end 322 | 323 | def chain 324 | @resource[:chain] 325 | end 326 | 327 | def sourcepassword 328 | @resource[:source_password] 329 | end 330 | 331 | def storetype 332 | @resource[:storetype] 333 | end 334 | 335 | def run_command(cmd, target = false, stdinfile = false, env = {}) 336 | env[:PATH] = @resource[:path].join(File::PATH_SEPARATOR) if @resource[:path] 337 | 338 | # The Puppet::Util::Execution.execute method is deprecated in Puppet 3.x 339 | # but we need this to work on 2.7.x too. 340 | exec_method = if Puppet::Util::Execution.respond_to?(:execute) 341 | Puppet::Util::Execution.method(:execute) 342 | else 343 | Puppet::Util.method(:execute) 344 | end 345 | 346 | withenv = if Puppet::Util::Execution.respond_to?(:withenv) 347 | Puppet::Util::Execution.method(:withenv) 348 | else 349 | Puppet::Util.method(:withenv) 350 | end 351 | 352 | # the java keytool will not correctly deal with an empty target keystore 353 | # file. If we encounter an empty keystore target file, preserve the mode, 354 | # owner and group, temporarily raise the umask, and delete the empty file. 355 | if target && (File.exist?(target) && File.empty?(target)) 356 | stat = File.stat(target) 357 | umask = File.umask(0o077) 358 | File.delete(target) 359 | end 360 | 361 | # There's a problem in IBM java keytool wherein stdin cannot be used 362 | # (trivially) to pass in the keystore passwords. The below hack makes the 363 | # provider work on SLES with minimal effort at the cost of letting the 364 | # passphrase to the keystore show up in the process list as an argument. 365 | # From a best practice standpoint the keystore should be protected by file 366 | # permissions and not just the passphrase so "making it work on SLES" 367 | # trumps. 368 | if Facter.value('os.family') == 'Suse' && @resource[:password] 369 | cmd_to_run = cmd.is_a?(String) ? cmd.split(%r{\s}).first : cmd.first 370 | if cmd_to_run == command_keytool 371 | cmd << '-srcstorepass' << @resource[:password] 372 | cmd << '-deststorepass' << @resource[:password] 373 | end 374 | end 375 | 376 | # Now run the command 377 | options = { failonfail: true, combine: true } 378 | output = nil 379 | begin 380 | Timeout.timeout(@resource[:keytool_timeout], Timeout::Error) do 381 | output = if stdinfile 382 | withenv.call(env) do 383 | exec_method.call(cmd, options.merge(stdinfile: stdinfile.path)) 384 | end 385 | else 386 | withenv.call(env) do 387 | exec_method.call(cmd, options) 388 | end 389 | end 390 | end 391 | rescue Timeout::Error 392 | raise Puppet::Error, "Timed out waiting for '#{@resource[:name]}' to run keytool" 393 | end 394 | 395 | # for previously empty files, restore the umask, mode, owner and group. 396 | # The funky double-take check is because on Suse defined? doesn't seem 397 | # to behave quite the same as on Debian, RedHat 398 | if target and (defined? stat and stat) # rubocop:disable Style/AndOr : Changing 'and' to '&&' causes test failures. 399 | File.umask(umask) 400 | # Need to change group ownership before mode to prevent making the file 401 | # accessible to the wrong group. 402 | File.chown(stat.uid, stat.gid, target) 403 | File.chmod(stat.mode, target) 404 | end 405 | 406 | output 407 | end 408 | end 409 | -------------------------------------------------------------------------------- /lib/puppet/type/java_ks.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'puppet/parameter/boolean' 4 | 5 | Puppet::Type.newtype(:java_ks) do 6 | @doc = 'Manages the entries in a java keystore, and uses composite namevars to 7 | accomplish the same alias spread across multiple target keystores.' 8 | 9 | ensurable do 10 | desc 'Has three states: present, absent, and latest. Latest 11 | will compare the on disk SHA1 fingerprint of the certificate to that 12 | in keytool to determine if insync? returns true or false. We redefine 13 | insync? for this parameter to accomplish this.' 14 | 15 | newvalue(:present) do 16 | provider.create 17 | end 18 | 19 | newvalue(:absent) do 20 | provider.destroy 21 | end 22 | 23 | newvalue(:latest) do 24 | if provider.exists? 25 | provider.update 26 | else 27 | provider.create 28 | end 29 | end 30 | 31 | def insync?(is) 32 | @should.each do |should| 33 | case should 34 | when :present 35 | return true if is == :present 36 | when :absent 37 | return true if is == :absent 38 | when :latest 39 | unless is == :absent 40 | current = provider.current.split('/') 41 | latest = provider.latest.split('/') 42 | return true if latest.to_set.subset?(current.to_set) 43 | end 44 | end 45 | end 46 | 47 | false 48 | end 49 | 50 | defaultto :present 51 | end 52 | 53 | newparam(:name) do 54 | desc 'The alias that is used to identify the entry in the keystore. This will be 55 | converted to lowercase.' 56 | 57 | isnamevar 58 | 59 | munge(&:downcase) 60 | end 61 | 62 | newparam(:target) do 63 | desc 'Destination file for the keystore. This will autorequire the parent directory of the file.' 64 | 65 | isnamevar 66 | end 67 | 68 | newparam(:certificate) do 69 | desc 'A file containing a server certificate, followed by zero or more intermediate certificate authorities. 70 | All certificates will be placed in the keystore. This will autorequire the specified file.' 71 | end 72 | 73 | newparam(:certificate_content) do 74 | desc 'A string containing a server certificate, followed by zero or more intermediate certificate authorities. 75 | All certificates will be placed in the keystore.' 76 | end 77 | 78 | newparam(:storetype) do 79 | desc 'Optional storetype 80 | Valid options: , , ' 81 | 82 | newvalues(:jceks, :pkcs12, :jks) 83 | end 84 | 85 | newparam(:private_key) do 86 | desc 'If you want an application to be a server and encrypt traffic, 87 | you will need a private key. Private key entries in a keystore must be 88 | accompanied by a signed certificate for the keytool provider. This parameter 89 | allows you to specify the file name containing the private key. This will autorequire 90 | the specified file.' 91 | end 92 | 93 | newparam(:private_key_content) do 94 | desc 'If you want an application to be a server and encrypt traffic, 95 | you will need a private key. Private key entries in a keystore must be 96 | accompanied by a signed certificate for the keytool provider. This parameter allows you to specify the content 97 | of the private key.' 98 | end 99 | 100 | newparam(:private_key_type) do 101 | desc 'The type of the private key. Usually the private key is of type RSA 102 | key but it can also be an Elliptic Curve key (EC) or DSA. 103 | Valid options: , , . Defaults to ' 104 | 105 | newvalues(:rsa, :dsa, :ec) 106 | 107 | defaultto :rsa 108 | end 109 | 110 | newparam(:chain) do 111 | desc 'The intermediate certificate authorities, if they are to be taken 112 | from a file separate from the server certificate. This will autorequire the specified file.' 113 | end 114 | 115 | newproperty(:password) do 116 | desc 'The password used to protect the keystore. If private keys are 117 | subsequently also protected this password will be used to attempt 118 | unlocking. Must be six or more characters in length. Cannot be used 119 | together with :password_file, but you must pass at least one of these parameters.' 120 | 121 | munge do |value| 122 | value = value.unwrap if value.respond_to?(:unwrap) 123 | super(value) 124 | end 125 | 126 | validate do |value| 127 | value = value.unwrap if value.respond_to?(:unwrap) 128 | raise Puppet::Error, "password is #{value.length} characters long; must be 6 characters or greater in length" if value.length < 6 129 | end 130 | end 131 | 132 | newparam(:password_file) do 133 | desc 'The path to a file containing the password used to protect the 134 | keystore. This cannot be used together with :password, but you must pass at least one of these parameters.' 135 | end 136 | 137 | newparam(:password_fail_reset, boolean: true, parent: Puppet::Parameter::Boolean) do 138 | desc "If the supplied password does not succeed in unlocking the 139 | keystore file, then delete the keystore file and create a new one. 140 | Default: false." 141 | 142 | defaultto :false 143 | end 144 | 145 | newparam(:destkeypass) do 146 | desc 'The password used to protect the key in keystore.' 147 | 148 | munge do |value| 149 | value = value.unwrap if value.respond_to?(:unwrap) 150 | super(value) 151 | end 152 | 153 | validate do |value| 154 | value = value.unwrap if value.respond_to?(:unwrap) 155 | raise Puppet::Error, "destkeypass is #{value.length} characters long; must be of length 6 or greater" if value.length < 6 156 | end 157 | end 158 | 159 | newparam(:trustcacerts, boolean: true, parent: Puppet::Parameter::Boolean) do 160 | desc "Certificate authorities aren't by default trusted so if you are adding a CA you need to set this to true. 161 | Defaults to :false." 162 | 163 | defaultto :false 164 | end 165 | 166 | newparam(:path) do 167 | desc "The search path used for command (keytool, openssl) execution. 168 | Paths can be specified as an array or as a '#{File::PATH_SEPARATOR}' separated list." 169 | 170 | # Support both arrays and colon-separated fields. 171 | def value=(*values) 172 | @value = values.flatten.map { |val| 173 | val.split(File::PATH_SEPARATOR) 174 | }.flatten 175 | end 176 | end 177 | 178 | newparam(:keytool_timeout) do 179 | desc 'Timeout for the keytool command in seconds.' 180 | 181 | defaultto 120 182 | end 183 | 184 | newparam(:source_password) do 185 | munge do |value| 186 | value = value.unwrap if value.respond_to?(:unwrap) 187 | super(value) 188 | end 189 | 190 | desc 'The source keystore password' 191 | end 192 | 193 | newparam(:source_alias) do 194 | desc 'The source certificate alias' 195 | end 196 | 197 | # Where we setup autorequires. 198 | autorequire(:file) do 199 | auto_requires = [] 200 | [:private_key, :certificate, :chain].each do |param| 201 | auto_requires << @parameters[param].value if @parameters.include?(param) 202 | end 203 | auto_requires << File.dirname(@parameters[:target].value) if @parameters.include?(:target) 204 | auto_requires 205 | end 206 | 207 | # Our title_patterns method for mapping titles to namevars for supporting 208 | # composite namevars. 209 | def self.title_patterns 210 | [ 211 | [ 212 | %r{^([^:]+)$}, 213 | [ 214 | [:name], 215 | ], 216 | ], 217 | [ 218 | %r{^(.*):([a-z]:(/|\\).*)$}i, 219 | [ 220 | [:name], 221 | [:target], 222 | ], 223 | ], 224 | [ 225 | %r{^(.*):(.*)$}, 226 | [ 227 | [:name], 228 | [:target], 229 | ], 230 | ], 231 | ] 232 | end 233 | 234 | validate do 235 | if self[:ensure] != :absent 236 | raise Puppet::Error, "You must pass one of 'certificate' or 'certificate_content'" unless value(:certificate) || value(:certificate_content) 237 | 238 | raise Puppet::Error, "You must pass either 'certificate' or 'certificate_content', not both." if value(:certificate) && value(:certificate_content) 239 | 240 | raise Puppet::Error, "You must pass either 'private_key' or 'private_key_content', not both." if value(:private_key) && value(:private_key_content) 241 | end 242 | 243 | raise Puppet::Error, "You must pass either 'password' or 'password_file', not both." if value(:password) && value(:password_file) 244 | 245 | raise Puppet::Error, "You must pass one of 'password' or 'password_file'." unless value(:password) || value(:password_file) 246 | 247 | if value(:storetype) == :pkcs12 && value(:source_password).nil? 248 | fail "You must provide 'source_password' when using a 'pkcs12' storetype." # rubocop:disable Style/SignalException : Associated test fails if 'raise' is used 249 | end 250 | end 251 | end 252 | -------------------------------------------------------------------------------- /manifests/config.pp: -------------------------------------------------------------------------------- 1 | # @summary 2 | # java_ks configuration 3 | # 4 | # @param params 5 | # A hash containing the parameters required for the java config. 6 | # 7 | class java_ks::config ( 8 | Hash $params = {}, 9 | ) { 10 | create_resources('java_ks', $params ) 11 | } 12 | -------------------------------------------------------------------------------- /metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-java_ks", 3 | "version": "5.1.1", 4 | "author": "puppetlabs", 5 | "summary": "Manage arbitrary Java keystore files", 6 | "license": "Apache-2.0", 7 | "source": "https://github.com/puppetlabs/puppetlabs-java_ks", 8 | "project_page": "https://github.com/puppetlabs/puppetlabs-java_ks", 9 | "issues_url": "https://github.com/puppetlabs/puppetlabs-java_ks/issues", 10 | "dependencies": [ 11 | 12 | ], 13 | "operatingsystem_support": [ 14 | { 15 | "operatingsystem": "RedHat", 16 | "operatingsystemrelease": [ 17 | "7", 18 | "8", 19 | "9" 20 | ] 21 | }, 22 | { 23 | "operatingsystem": "CentOS", 24 | "operatingsystemrelease": [ 25 | "7", 26 | "8" 27 | ] 28 | }, 29 | { 30 | "operatingsystem": "OracleLinux", 31 | "operatingsystemrelease": [ 32 | "7" 33 | ] 34 | }, 35 | { 36 | "operatingsystem": "Scientific", 37 | "operatingsystemrelease": [ 38 | "7" 39 | ] 40 | }, 41 | { 42 | "operatingsystem": "SLES", 43 | "operatingsystemrelease": [ 44 | "12", 45 | "15" 46 | ] 47 | }, 48 | { 49 | "operatingsystem": "Debian", 50 | "operatingsystemrelease": [ 51 | "10", 52 | "11", 53 | "12" 54 | ] 55 | }, 56 | { 57 | "operatingsystem": "Ubuntu", 58 | "operatingsystemrelease": [ 59 | "18.04", 60 | "20.04", 61 | "22.04" 62 | ] 63 | }, 64 | { 65 | "operatingsystem": "Solaris", 66 | "operatingsystemrelease": [ 67 | "11" 68 | ] 69 | }, 70 | { 71 | "operatingsystem": "AIX", 72 | "operatingsystemrelease": [ 73 | "7.1" 74 | ] 75 | }, 76 | { 77 | "operatingsystem": "Windows", 78 | "operatingsystemrelease": [ 79 | "2012", 80 | "2012 R2", 81 | "2016", 82 | "2019", 83 | "10", 84 | "2022" 85 | ] 86 | }, 87 | { 88 | "operatingsystem": "Rocky", 89 | "operatingsystemrelease": [ 90 | "8" 91 | ] 92 | }, 93 | { 94 | "operatingsystem": "AlmaLinux", 95 | "operatingsystemrelease": [ 96 | "8" 97 | ] 98 | } 99 | ], 100 | "requirements": [ 101 | { 102 | "name": "puppet", 103 | "version_requirement": ">= 7.0.0 < 9.0.0" 104 | } 105 | ], 106 | "description": "Uses a combination of keytool and Ruby openssl library to manage entries in a Java keystore.", 107 | "template-url": "https://github.com/puppetlabs/pdk-templates.git#main", 108 | "template-ref": "tags/3.2.0.4-0-g5d17ec1", 109 | "pdk-version": "3.2.0" 110 | } 111 | -------------------------------------------------------------------------------- /pdk.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ignore: [] 3 | -------------------------------------------------------------------------------- /provision.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | default: 3 | provisioner: docker 4 | images: 5 | - litmusimage/debian:8 6 | vagrant: 7 | provisioner: vagrant 8 | images: 9 | - centos/7 10 | - generic/ubuntu1804 11 | - gusztavvargadr/windows-server 12 | docker_deb: 13 | provisioner: docker 14 | images: 15 | - litmusimage/debian:8 16 | - litmusimage/debian:9 17 | - litmusimage/debian:10 18 | docker_ub_6: 19 | provisioner: docker 20 | images: 21 | - litmusimage/ubuntu:14.04 22 | - litmusimage/ubuntu:16.04 23 | - litmusimage/ubuntu:18.04 24 | - litmusimage/ubuntu:20.04 25 | docker_el7: 26 | provisioner: docker 27 | images: 28 | - litmusimage/centos:7 29 | - litmusimage/oraclelinux:7 30 | - litmusimage/scientificlinux:7 31 | docker_el8: 32 | provisioner: docker 33 | images: 34 | - litmusimage/centos:8 35 | release_checks_6: 36 | provisioner: abs 37 | images: 38 | - redhat-6-x86_64 39 | - redhat-7-x86_64 40 | - redhat-8-x86_64 41 | - centos-6-x86_64 42 | - centos-7-x86_64 43 | - centos-8-x86_64 44 | - oracle-6-x86_64 45 | - oracle-7-x86_64 46 | - scientific-6-x86_64 47 | - scientific-7-x86_64 48 | - debian-8-x86_64 49 | - debian-9-x86_64 50 | - debian-10-x86_64 51 | - ubuntu-1404-x86_64 52 | - ubuntu-1604-x86_64 53 | - ubuntu-1804-x86_64 54 | - ubuntu-2004-x86_64 55 | - sles-12-x86_64 56 | - sles-15-x86_64 57 | - win-2012r2-x86_64 58 | - win-2016-x86_64 59 | - win-10-pro-x86_64 60 | release_checks_7: 61 | provisioner: abs 62 | images: 63 | - redhat-7-x86_64 64 | - redhat-8-x86_64 65 | - centos-7-x86_64 66 | - centos-8-x86_64 67 | - oracle-7-x86_64 68 | - scientific-7-x86_64 69 | - sles-12-x86_64 70 | - sles-15-x86_64 71 | - debian-9-x86_64 72 | - debian-10-x86_64 73 | - ubuntu-1804-x86_64 74 | - ubuntu-2004-x86_64 75 | - win-2012r2-x86_64 76 | - win-2016-x86_64 77 | - win-2019-x86_64 78 | - win-10-pro-x86_64 79 | -------------------------------------------------------------------------------- /spec/acceptance/certs/ca.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppetlabs/puppetlabs-java_ks/173027fd9cb469498aa22f3d077cbc7711ba5f5b/spec/acceptance/certs/ca.der -------------------------------------------------------------------------------- /spec/acceptance/certs/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDNjCCAh4CAQEwDQYJKoZIhvcNAQELBQAwYTEQMA4GA1UEAwwHVGVzdCBDQTEP 3 | MA0GA1UECAwGRGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwD 4 | RGlzMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wHhcNMjMwNTE4MTA0ODA2WhcN 5 | MjMwNTE4MTA1NDA2WjBhMRAwDgYDVQQDDAdUZXN0IENBMQ8wDQYDVQQIDAZEZW5p 6 | YWwxFDASBgNVBAcMC1NwcmluZ2ZpZWxkMQwwCgYDVQQKDANEaXMxGDAWBgNVBAMM 7 | D3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 8 | ALSzsYpk+P7DqRp0jYlEQ1SWWIDZggto3sm2eEGc4EEjTQqTEqkkWORNqZeXRL6+ 9 | KaJwn94R/0M13lCnPa8P2fyN5hCWfYr0VqWfDt0hr7nD3DpqdxbRAcqUcQm0Ac2d 10 | X+wBI//r8GzADoMmHkVj7ch6zlbxUCU/x2dVyZ8jxXfVGunJco7xvY7tBDXyUIXE 11 | MiVV0kPTk3vGZ5RY21d/RTzAYINBA2FbiYVkB+dHKLwWupb3R8NX2pocUQ/eBXuM 12 | ftobHxBGgV+GWng9qailedxIn2aBdFPesWFdqrt06GWzXRhYHLT2CDi+rPAYnhYU 13 | I+ssb6kyKFq8S4VtvW9tMTECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEASL113oRw 14 | RVHBRdjDE9iVyO3QAvT8DsH0v4tRrSDuO2JZKn3R+KwroyHKlMsuU9AQA8cjU839 15 | hYRYc+ipccPglHv/if0y5PfHZWTqafBzxZdipdSM7waAYFnb1rS1DrYQiOb9L+w1 16 | p1oYU5vCKnFqsCrtL/wMXE794cns5UJkM+C3+rxXQv6T87UUyz/ZC+vq3+EymSH3 17 | XIhXgqToVGs5AAznxFSFr/D4GHYewn29REB8ztpJM7ZVmXyGFMuzn6oP/05Yw5nz 18 | 5K5OUIt2P2FKEXQLGZVbk7pHZTyYb5956w2tp8AeaCKRcWONBYnRX49b9PqDm15/ 19 | 6HQNMQdE5JYtLw== 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /spec/acceptance/certs/ca2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDNjCCAh4CAQIwDQYJKoZIhvcNAQELBQAwYTEQMA4GA1UEAwwHVGVzdCBDQTEP 3 | MA0GA1UECAwGRGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwD 4 | RGlzMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wHhcNMjMwNTE4MTA0ODA2WhcN 5 | MjMwNTE4MTA1NDA2WjBhMRAwDgYDVQQDDAdUZXN0IENBMQ8wDQYDVQQIDAZEZW5p 6 | YWwxFDASBgNVBAcMC1NwcmluZ2ZpZWxkMQwwCgYDVQQKDANEaXMxGDAWBgNVBAMM 7 | D3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 8 | AKxdUn7hJd86c7yGOKSKm9UI2jkkr6DWBde6s9u533hneR7mhjeeZ0trp5dCzHeV 9 | LLMxOHvTcM9FSfxyw9RbQJs/1FamieMMoYay6MeW3c/DJ2zqy3GWT0YXmPxvFCyM 10 | pSFkg7Wp1ur1ld5HvETihGrJltaOrnSaKkkWCPWkGM+/ZuyqCERYd1MlTeVUAEQK 11 | 03D0OSC7kDynF01g1IcG8muaYyqABZVgnJnZKUUd7LG1k4+TYNfmiXfx3I+8wWDG 12 | JXFJeSGQ9oCHOZKgG+MWkhQKJ/a42IgUCTRIK5C6XCuNPm1sUaS/oCHeBckG5NkU 13 | utDUBrdSD8Pf1PF9fDn1mz8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAB6VDPChJ 14 | wHH0+3HhqyLCe6UuNJtwa01R3xFpTucgYIcoANq9n3vPSRWh9Ix6R2iXtexDyETo 15 | b6EgbNTUNKJVm8SFnq7no6CWaxORNg/fBSiQ765GmCrCvV0InmLCzBObANJQz0iF 16 | 7PhZOJLbm7KIlEAu114T6uaxmHv+2mpGmg6w9He3y4Vpd58J35Ym2Pgkg5D9XIl4 17 | ApzagLSIm1kf3MA4IeeXpXYLabt9qY8uQIBr8su9LH93CBtOEJp+izSK1voC3cBh 18 | 8XEgWqDYBeoWprlh9rSrN/DHegLjCNGO7MAFRFJJ8zS7S1mbJL0n28EEpcZSc0nU 19 | +NzH2e/+7kxwRg== 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /spec/acceptance/certs/chain.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDOjCCAiICAQQwDQYJKoZIhvcNAQELBQAwYjERMA8GA1UEAwwIQ2hhaW4gQ0Ex 3 | DzANBgNVBAgMBkRlbmlhbDEUMBIGA1UEBwwLU3ByaW5nZmllbGQxDDAKBgNVBAoM 4 | A0RpczEYMBYGA1UEAwwPd3d3LmV4YW1wbGUubmV0MB4XDTIzMDUxODEwNDgwNloX 5 | DTIzMDUxODEwNTQwNlowZDETMBEGA1UEAwwKQ2hhaW4gQ0EgMjEPMA0GA1UECAwG 6 | RGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwDRGlzMRgwFgYD 7 | VQQDDA93d3cuZXhhbXBsZS5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK 8 | AoIBAQD1FET2g0t76XhJqd+EDXFvTgcjSo9OEK8JUnshGBUXZOMzl7FmMSeKjBt3 9 | k01Lf9N9GLtPvPXpMNq2pjv1I1gRLknII6L1QUb1z8s4icaLOgg8tB0gn4L5gLig 10 | W6xq8p4tNJajbNpNDAjLIuyvSfYF0PH8LAfNKQSEhcp0fos98OCrgagS/s69Arhv 11 | E5Q32/5KYUVyYX4bs4dKmslK8A6rGqJwp3uO6WpIV7GrCzqDEpGvHChiWivH9UZN 12 | 42RTVtzGbdbIrbKY1o+TgIgOv3LZfQORhttdZP+KQpiHDBQ+dVOU2N9d8F78s0aQ 13 | E6xIaNaXz9P3VwCSa5+af9TSHOrrAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHqv 14 | z0oCLaF3KVpYcSYNosWQuklRJd7E0Q7SVRGrB7sq5fgtyo7BC4iSrnFmJOU2d0Bq 15 | B5Ymmm9rOTlyzUvX/S1MexKPcbsxQMBk3RGW/X5pHMaNUVlamZw0pUlVOGhN1XD9 16 | isbKPNf9qg+sIcURY7ji/JoycLdIFf2leYZKwur/OBRy4sxnhwL3BgNx9Z0lj0ru 17 | RFMEDkIx/tuKIdW9eQFRlk20xqdhWho8LiHU2SAS9o5wDaWoLgwk0kOzWe03oWay 18 | viE4+mSdHzHjfaye/anRTFrmj1+gN6TMkeSWm0Tf1w2yGADPOXf1TItAsSN7ZWn3 19 | QgKMPHigjYXJeLpgKQ8= 20 | -----END CERTIFICATE----- 21 | -----BEGIN CERTIFICATE----- 22 | MIIDNzCCAh8CAQMwDQYJKoZIhvcNAQELBQAwYTEQMA4GA1UEAwwHVGVzdCBDQTEP 23 | MA0GA1UECAwGRGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwD 24 | RGlzMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wHhcNMjMwNTE4MTA0ODA2WhcN 25 | MjMwNTE4MTA1NDA2WjBiMREwDwYDVQQDDAhDaGFpbiBDQTEPMA0GA1UECAwGRGVu 26 | aWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwDRGlzMRgwFgYDVQQD 27 | DA93d3cuZXhhbXBsZS5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB 28 | AQCu7dDNAKqwwgWaGwfNpds3SVumek/ugm6ofYrN88cz4hIoTYWsujndO+1SHXg4 29 | PM1YeRfT5UbMJ5jWvT0M7XcQmYoimNx7ZqLrqJWQLlQVaffY+pPOSm/p8bDAyPsD 30 | EFLDLbtDQiapkm78gl7VxlyxdD+U6Cb4khGS1EVsRcpWthrIr7Tt5nN28g+4ycWf 31 | Lp2gUg+Yd5kQp7Bs+wwT5pdajYAVeAqaeujivIvsZdMhN+W6V5Jx3JYsEYS1w8Zc 32 | uVLB47qAMTB1M702lPNjR8TYjhM8yPC8EQJGv3r4U8G2bLPdL6HaLqIC2oWrCC2W 33 | 1mqfgdw2OhH0sPL1kai/yBv5AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIOlOmm2 34 | dB9n7I3h/ttAeO9T0XdnXTwbjOu+haxjTV/9vlX904cE4+jWtu09LYiM7bThjkW3 35 | hkruW1c6uiX5PfbIhHWLJJyJ4tMPrpYTJNI0HfTJTdNkZkNntsyJ7Mci8hJpW5Oq 36 | sHO2U1xGIKJ1DPHSWBFjzuUPBgFMAIcg6i72BDoFUVCrxE9Lj27cbI6NjhiTHYMa 37 | 9wGDKSm2tw52KZWC1VYZi3O7gvmduBJLdkrziDTaZxSGd7ElYJmRpEmHD2Weqx7o 38 | HAha+pFbqNe82q+jtgw2Zz9PfNdJIJzG02QTzTDVb3IB/TVV/ja/tDyvFEnUPIL5 39 | pWhWmq41LzBkK2M= 40 | -----END CERTIFICATE----- 41 | -------------------------------------------------------------------------------- /spec/acceptance/certs/chain2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDOTCCAiECAQYwDQYJKoZIhvcNAQELBQAwYTEQMA4GA1UEAwwHVGVzdCBDQTEP 3 | MA0GA1UECAwGRGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwD 4 | RGlzMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wHhcNMjMwNTE4MTA0ODA2WhcN 5 | MjMwNTE4MTA1NDA2WjBkMRMwEQYDVQQDDApDaGFpbiBDQSAyMQ8wDQYDVQQIDAZE 6 | ZW5pYWwxFDASBgNVBAcMC1NwcmluZ2ZpZWxkMQwwCgYDVQQKDANEaXMxGDAWBgNV 7 | BAMMD3d3dy5leGFtcGxlLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC 8 | ggEBAPUURPaDS3vpeEmp34QNcW9OByNKj04QrwlSeyEYFRdk4zOXsWYxJ4qMG3eT 9 | TUt/030Yu0+89ekw2ramO/UjWBEuScgjovVBRvXPyziJxos6CDy0HSCfgvmAuKBb 10 | rGryni00lqNs2k0MCMsi7K9J9gXQ8fwsB80pBISFynR+iz3w4KuBqBL+zr0CuG8T 11 | lDfb/kphRXJhfhuzh0qayUrwDqsaonCne47pakhXsasLOoMSka8cKGJaK8f1Rk3j 12 | ZFNW3MZt1sitspjWj5OAiA6/ctl9A5GG211k/4pCmIcMFD51U5TY313wXvyzRpAT 13 | rEho1pfP0/dXAJJrn5p/1NIc6usCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAgf4k 14 | pn5MxAJ3bPOE2t/OnRI8hRVUXBgpHxPucGgPZrwpeT9xB0ENXfZy/RMihm80Va21 15 | 26JldZULCmidwy03+mBGExhoLgmvHCcW5Ogx9yewxc8H4wFCgUlmcQ9MSI/mCNbr 16 | icVT4EwkPuNBWXBJD6y+SPXVRpzOu6Pz1ieJRijichY8H9ZkKpC+3qu+Z/DddEt7 17 | RO1te2p6S/gHjjOZJNaOKV0r4FqHLXyGRRPnBSlfN0+J8bX/1TYX/zfnC9aKHMR/ 18 | rXItAZxouc1LPwxcW4q5aqenQcLe/zuBzGywM9+ohNc6RPkQgdhbbKCZ5SwCKAYI 19 | Wfyx/vbK1SdOVcbpiQ== 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /spec/acceptance/certs/leaf.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppetlabs/puppetlabs-java_ks/173027fd9cb469498aa22f3d077cbc7711ba5f5b/spec/acceptance/certs/leaf.p12 -------------------------------------------------------------------------------- /spec/acceptance/certs/leaf.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDOzCCAiMCAQUwDQYJKoZIhvcNAQELBQAwZDETMBEGA1UEAwwKQ2hhaW4gQ0Eg 3 | MjEPMA0GA1UECAwGRGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UE 4 | CgwDRGlzMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5uZXQwHhcNMjMwNTE4MTA0ODA2 5 | WhcNMjMwNTE4MTA1NDA2WjBjMRIwEAYDVQQDDAlMZWFmIENlcnQxDzANBgNVBAgM 6 | BkRlbmlhbDEUMBIGA1UEBwwLU3ByaW5nZmllbGQxDDAKBgNVBAoMA0RpczEYMBYG 7 | A1UEAwwPd3d3LmV4YW1wbGUubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 8 | CgKCAQEAwNfyzKuA/uHHDiUMnGjdEgcGIeSG5sSNZNZ2Yo39p2opbu2vs6jerbx8 9 | wPklcEhITfEW2MFRTutIbvPkLtPhG6Jw7Q3sqH0WCqy5elU6o6nr6MohhMmpFa1D 10 | xWD84HogoM82sSBXW+YnemVDUYjoKFrH7TkP6w1cfgoxPFDXeE/jRUIgzIjnpc0I 11 | Oj+nOL/oSrOstlIZFWjvzjB42qCstnbzHbDGqepc7U1PP2AY8SP1eEHSvCCeU7SO 12 | LOMoVJv9f9Fj21kyikuMmxA1iBHaPVzG25NPkE4jNK0fRCRePk4WQ4WJOnLyyt0P 13 | yQshOqE6uyLwrZujsI04PkXZYSdcvQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBq 14 | sOQC2GG0tmwa0D9kDarUCQnG16MLaKCoMtSz0wflG70DT9RYaYIp1/6q8ESWT086 15 | arLd/A04EE/n8nXe1vov5LnSZa4jwlQQ5LA5wjQQOP6KPSpP4HeD5+xjMGfsxSEF 16 | FUIooonZ91+3SbBxX3tsihh88Sdl07LhexUdrQhGk3UGvOJrLUnuDzkz37bacVNw 17 | GAxPclYa41XI/SuutinJFf0EqVI2CMownGTOTk4XqzoLouMo5d1dzoRn9fKmED8b 18 | tQci8JieF7NQohGDB+SFaZSlkte/jgkux6tAIfx4d/L+//5njy2AEvrzDLUtDXit 19 | n+ck7IhoWAFoqRGDqOis 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /spec/acceptance/certs/leaf2.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puppetlabs/puppetlabs-java_ks/173027fd9cb469498aa22f3d077cbc7711ba5f5b/spec/acceptance/certs/leaf2.p12 -------------------------------------------------------------------------------- /spec/acceptance/certs/leafchain.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDOzCCAiMCAQUwDQYJKoZIhvcNAQELBQAwZDETMBEGA1UEAwwKQ2hhaW4gQ0Eg 3 | MjEPMA0GA1UECAwGRGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UE 4 | CgwDRGlzMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5uZXQwHhcNMjMwNTE4MTA0ODA2 5 | WhcNMjMwNTE4MTA1NDA2WjBjMRIwEAYDVQQDDAlMZWFmIENlcnQxDzANBgNVBAgM 6 | BkRlbmlhbDEUMBIGA1UEBwwLU3ByaW5nZmllbGQxDDAKBgNVBAoMA0RpczEYMBYG 7 | A1UEAwwPd3d3LmV4YW1wbGUubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 8 | CgKCAQEAwNfyzKuA/uHHDiUMnGjdEgcGIeSG5sSNZNZ2Yo39p2opbu2vs6jerbx8 9 | wPklcEhITfEW2MFRTutIbvPkLtPhG6Jw7Q3sqH0WCqy5elU6o6nr6MohhMmpFa1D 10 | xWD84HogoM82sSBXW+YnemVDUYjoKFrH7TkP6w1cfgoxPFDXeE/jRUIgzIjnpc0I 11 | Oj+nOL/oSrOstlIZFWjvzjB42qCstnbzHbDGqepc7U1PP2AY8SP1eEHSvCCeU7SO 12 | LOMoVJv9f9Fj21kyikuMmxA1iBHaPVzG25NPkE4jNK0fRCRePk4WQ4WJOnLyyt0P 13 | yQshOqE6uyLwrZujsI04PkXZYSdcvQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBq 14 | sOQC2GG0tmwa0D9kDarUCQnG16MLaKCoMtSz0wflG70DT9RYaYIp1/6q8ESWT086 15 | arLd/A04EE/n8nXe1vov5LnSZa4jwlQQ5LA5wjQQOP6KPSpP4HeD5+xjMGfsxSEF 16 | FUIooonZ91+3SbBxX3tsihh88Sdl07LhexUdrQhGk3UGvOJrLUnuDzkz37bacVNw 17 | GAxPclYa41XI/SuutinJFf0EqVI2CMownGTOTk4XqzoLouMo5d1dzoRn9fKmED8b 18 | tQci8JieF7NQohGDB+SFaZSlkte/jgkux6tAIfx4d/L+//5njy2AEvrzDLUtDXit 19 | n+ck7IhoWAFoqRGDqOis 20 | -----END CERTIFICATE----- 21 | -----BEGIN CERTIFICATE----- 22 | MIIDOjCCAiICAQQwDQYJKoZIhvcNAQELBQAwYjERMA8GA1UEAwwIQ2hhaW4gQ0Ex 23 | DzANBgNVBAgMBkRlbmlhbDEUMBIGA1UEBwwLU3ByaW5nZmllbGQxDDAKBgNVBAoM 24 | A0RpczEYMBYGA1UEAwwPd3d3LmV4YW1wbGUubmV0MB4XDTIzMDUxODEwNDgwNloX 25 | DTIzMDUxODEwNTQwNlowZDETMBEGA1UEAwwKQ2hhaW4gQ0EgMjEPMA0GA1UECAwG 26 | RGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwDRGlzMRgwFgYD 27 | VQQDDA93d3cuZXhhbXBsZS5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK 28 | AoIBAQD1FET2g0t76XhJqd+EDXFvTgcjSo9OEK8JUnshGBUXZOMzl7FmMSeKjBt3 29 | k01Lf9N9GLtPvPXpMNq2pjv1I1gRLknII6L1QUb1z8s4icaLOgg8tB0gn4L5gLig 30 | W6xq8p4tNJajbNpNDAjLIuyvSfYF0PH8LAfNKQSEhcp0fos98OCrgagS/s69Arhv 31 | E5Q32/5KYUVyYX4bs4dKmslK8A6rGqJwp3uO6WpIV7GrCzqDEpGvHChiWivH9UZN 32 | 42RTVtzGbdbIrbKY1o+TgIgOv3LZfQORhttdZP+KQpiHDBQ+dVOU2N9d8F78s0aQ 33 | E6xIaNaXz9P3VwCSa5+af9TSHOrrAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHqv 34 | z0oCLaF3KVpYcSYNosWQuklRJd7E0Q7SVRGrB7sq5fgtyo7BC4iSrnFmJOU2d0Bq 35 | B5Ymmm9rOTlyzUvX/S1MexKPcbsxQMBk3RGW/X5pHMaNUVlamZw0pUlVOGhN1XD9 36 | isbKPNf9qg+sIcURY7ji/JoycLdIFf2leYZKwur/OBRy4sxnhwL3BgNx9Z0lj0ru 37 | RFMEDkIx/tuKIdW9eQFRlk20xqdhWho8LiHU2SAS9o5wDaWoLgwk0kOzWe03oWay 38 | viE4+mSdHzHjfaye/anRTFrmj1+gN6TMkeSWm0Tf1w2yGADPOXf1TItAsSN7ZWn3 39 | QgKMPHigjYXJeLpgKQ8= 40 | -----END CERTIFICATE----- 41 | -----BEGIN CERTIFICATE----- 42 | MIIDNzCCAh8CAQMwDQYJKoZIhvcNAQELBQAwYTEQMA4GA1UEAwwHVGVzdCBDQTEP 43 | MA0GA1UECAwGRGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwD 44 | RGlzMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wHhcNMjMwNTE4MTA0ODA2WhcN 45 | MjMwNTE4MTA1NDA2WjBiMREwDwYDVQQDDAhDaGFpbiBDQTEPMA0GA1UECAwGRGVu 46 | aWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwDRGlzMRgwFgYDVQQD 47 | DA93d3cuZXhhbXBsZS5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB 48 | AQCu7dDNAKqwwgWaGwfNpds3SVumek/ugm6ofYrN88cz4hIoTYWsujndO+1SHXg4 49 | PM1YeRfT5UbMJ5jWvT0M7XcQmYoimNx7ZqLrqJWQLlQVaffY+pPOSm/p8bDAyPsD 50 | EFLDLbtDQiapkm78gl7VxlyxdD+U6Cb4khGS1EVsRcpWthrIr7Tt5nN28g+4ycWf 51 | Lp2gUg+Yd5kQp7Bs+wwT5pdajYAVeAqaeujivIvsZdMhN+W6V5Jx3JYsEYS1w8Zc 52 | uVLB47qAMTB1M702lPNjR8TYjhM8yPC8EQJGv3r4U8G2bLPdL6HaLqIC2oWrCC2W 53 | 1mqfgdw2OhH0sPL1kai/yBv5AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIOlOmm2 54 | dB9n7I3h/ttAeO9T0XdnXTwbjOu+haxjTV/9vlX904cE4+jWtu09LYiM7bThjkW3 55 | hkruW1c6uiX5PfbIhHWLJJyJ4tMPrpYTJNI0HfTJTdNkZkNntsyJ7Mci8hJpW5Oq 56 | sHO2U1xGIKJ1DPHSWBFjzuUPBgFMAIcg6i72BDoFUVCrxE9Lj27cbI6NjhiTHYMa 57 | 9wGDKSm2tw52KZWC1VYZi3O7gvmduBJLdkrziDTaZxSGd7ElYJmRpEmHD2Weqx7o 58 | HAha+pFbqNe82q+jtgw2Zz9PfNdJIJzG02QTzTDVb3IB/TVV/ja/tDyvFEnUPIL5 59 | pWhWmq41LzBkK2M= 60 | -----END CERTIFICATE----- 61 | -------------------------------------------------------------------------------- /spec/acceptance/certs/leafchain2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDOzCCAiMCAQUwDQYJKoZIhvcNAQELBQAwZDETMBEGA1UEAwwKQ2hhaW4gQ0Eg 3 | MjEPMA0GA1UECAwGRGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UE 4 | CgwDRGlzMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5uZXQwHhcNMjMwNTE4MTA0ODA2 5 | WhcNMjMwNTE4MTA1NDA2WjBjMRIwEAYDVQQDDAlMZWFmIENlcnQxDzANBgNVBAgM 6 | BkRlbmlhbDEUMBIGA1UEBwwLU3ByaW5nZmllbGQxDDAKBgNVBAoMA0RpczEYMBYG 7 | A1UEAwwPd3d3LmV4YW1wbGUubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 8 | CgKCAQEAwNfyzKuA/uHHDiUMnGjdEgcGIeSG5sSNZNZ2Yo39p2opbu2vs6jerbx8 9 | wPklcEhITfEW2MFRTutIbvPkLtPhG6Jw7Q3sqH0WCqy5elU6o6nr6MohhMmpFa1D 10 | xWD84HogoM82sSBXW+YnemVDUYjoKFrH7TkP6w1cfgoxPFDXeE/jRUIgzIjnpc0I 11 | Oj+nOL/oSrOstlIZFWjvzjB42qCstnbzHbDGqepc7U1PP2AY8SP1eEHSvCCeU7SO 12 | LOMoVJv9f9Fj21kyikuMmxA1iBHaPVzG25NPkE4jNK0fRCRePk4WQ4WJOnLyyt0P 13 | yQshOqE6uyLwrZujsI04PkXZYSdcvQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBq 14 | sOQC2GG0tmwa0D9kDarUCQnG16MLaKCoMtSz0wflG70DT9RYaYIp1/6q8ESWT086 15 | arLd/A04EE/n8nXe1vov5LnSZa4jwlQQ5LA5wjQQOP6KPSpP4HeD5+xjMGfsxSEF 16 | FUIooonZ91+3SbBxX3tsihh88Sdl07LhexUdrQhGk3UGvOJrLUnuDzkz37bacVNw 17 | GAxPclYa41XI/SuutinJFf0EqVI2CMownGTOTk4XqzoLouMo5d1dzoRn9fKmED8b 18 | tQci8JieF7NQohGDB+SFaZSlkte/jgkux6tAIfx4d/L+//5njy2AEvrzDLUtDXit 19 | n+ck7IhoWAFoqRGDqOis 20 | -----END CERTIFICATE----- 21 | -----BEGIN CERTIFICATE----- 22 | MIIDOTCCAiECAQYwDQYJKoZIhvcNAQELBQAwYTEQMA4GA1UEAwwHVGVzdCBDQTEP 23 | MA0GA1UECAwGRGVuaWFsMRQwEgYDVQQHDAtTcHJpbmdmaWVsZDEMMAoGA1UECgwD 24 | RGlzMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wHhcNMjMwNTE4MTA0ODA2WhcN 25 | MjMwNTE4MTA1NDA2WjBkMRMwEQYDVQQDDApDaGFpbiBDQSAyMQ8wDQYDVQQIDAZE 26 | ZW5pYWwxFDASBgNVBAcMC1NwcmluZ2ZpZWxkMQwwCgYDVQQKDANEaXMxGDAWBgNV 27 | BAMMD3d3dy5leGFtcGxlLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC 28 | ggEBAPUURPaDS3vpeEmp34QNcW9OByNKj04QrwlSeyEYFRdk4zOXsWYxJ4qMG3eT 29 | TUt/030Yu0+89ekw2ramO/UjWBEuScgjovVBRvXPyziJxos6CDy0HSCfgvmAuKBb 30 | rGryni00lqNs2k0MCMsi7K9J9gXQ8fwsB80pBISFynR+iz3w4KuBqBL+zr0CuG8T 31 | lDfb/kphRXJhfhuzh0qayUrwDqsaonCne47pakhXsasLOoMSka8cKGJaK8f1Rk3j 32 | ZFNW3MZt1sitspjWj5OAiA6/ctl9A5GG211k/4pCmIcMFD51U5TY313wXvyzRpAT 33 | rEho1pfP0/dXAJJrn5p/1NIc6usCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAgf4k 34 | pn5MxAJ3bPOE2t/OnRI8hRVUXBgpHxPucGgPZrwpeT9xB0ENXfZy/RMihm80Va21 35 | 26JldZULCmidwy03+mBGExhoLgmvHCcW5Ogx9yewxc8H4wFCgUlmcQ9MSI/mCNbr 36 | icVT4EwkPuNBWXBJD6y+SPXVRpzOu6Pz1ieJRijichY8H9ZkKpC+3qu+Z/DddEt7 37 | RO1te2p6S/gHjjOZJNaOKV0r4FqHLXyGRRPnBSlfN0+J8bX/1TYX/zfnC9aKHMR/ 38 | rXItAZxouc1LPwxcW4q5aqenQcLe/zuBzGywM9+ohNc6RPkQgdhbbKCZ5SwCKAYI 39 | Wfyx/vbK1SdOVcbpiQ== 40 | -----END CERTIFICATE----- 41 | -------------------------------------------------------------------------------- /spec/acceptance/certs/leafkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEAwNfyzKuA/uHHDiUMnGjdEgcGIeSG5sSNZNZ2Yo39p2opbu2v 3 | s6jerbx8wPklcEhITfEW2MFRTutIbvPkLtPhG6Jw7Q3sqH0WCqy5elU6o6nr6Moh 4 | hMmpFa1DxWD84HogoM82sSBXW+YnemVDUYjoKFrH7TkP6w1cfgoxPFDXeE/jRUIg 5 | zIjnpc0IOj+nOL/oSrOstlIZFWjvzjB42qCstnbzHbDGqepc7U1PP2AY8SP1eEHS 6 | vCCeU7SOLOMoVJv9f9Fj21kyikuMmxA1iBHaPVzG25NPkE4jNK0fRCRePk4WQ4WJ 7 | OnLyyt0PyQshOqE6uyLwrZujsI04PkXZYSdcvQIDAQABAoIBAEUS9M6X3dguIgEw 8 | hyBdNVZYOruYIjP1klncscHib0lwrs+jhoxZQA3GFn9+nojl8zQr142jTQ7yGttX 9 | M9QMI7UkzcMzeiHt0B/Zt4QYlCz8V9pl0HTCUPTJP52q/FkhlZ9UKZhvZ6ssuNZQ 10 | ADlryxBtV/BiQI/mlMs2tmUO5ecbQbqTCpUyJsPiRQ28bz2V3BIlMqffQkwmFBJ6 11 | tfN1o+kHRCvklETmULNY9OetNj99MTvSR5pZq4f3SsIhnYU3grBJbufhkINorF/z 12 | LmlnFaICdRe1+yEZ2ypfI9M/8AJmPSt1U+puZCc6Ufg1nZrVuXWnSizLCsrCpt/c 13 | bWiYg/cCgYEAwdz+7CphCj5e2Jf8WkiztEDzsNVK6WO4YtD+gkowE03pzWquJ/X1 14 | nUdVNcBiL9clRBP4zaL11jOkd4IRtgpasFcdU2gOhmL/LFiv3yhPLVjWuVsSK/id 15 | iyFlV54DAREO00h0+CFwFBLQ6rXZPdeRAcQPRkMsL3FDhfcU/sc6KH8CgYEA/qdI 16 | PJuxEnxlUK7IUIfjfG8RzeEKN1b+7ma+9eF6LPfdCHAtzF1DIssfTrD/XJ7sDZd7 17 | ENvBa4aMeqebnZCRUNNP92s+aRMKGFS+9cXNg9aMHXRuaoaxnyfqZloKRjj5JPCD 18 | gvjpwl/WyETvB2iAaLzgjb/4S3Ug8lu+i6VDfMMCgYEAnLBscqGGMWtb6aBeXPKq 19 | HKTq0iBzHdR1sZjOPKyN0uyEbn0tKitIS8jd/EX0lkpEWpPx4vM1092Frvo4KnSP 20 | /DtM/p76LnBRYpyD+dBwvmwxkTskotmdLFjfukOClhgdbXQA5pTQK8lRhoNYhP14 21 | vH6lAdtFGUtokhy0oYCRZy0CgYEA1UB9K9Qtyw9FQPW9ZkMF7BSPUlucVI+T2U1N 22 | qVbzG2lOPlzC3ZtUN3TmeN2cW5Hyl8c9FfcR2NvKFIT7uk1wg8ER/F5g21lIYOvH 23 | JsZIvpkSqS/xr1+wq1mf36qTZA8eBSMs3qdYCqB7myavDQMkVZGmcs5KPdaOiqbt 24 | wL/a7kUCgYBD/wBvYNtMSIXL0Ev8B4dV+4XvpoQjelBEkJ8jN0H75rh+V/WLiBzg 25 | vQjCBMm2CoQgnGdoFXiCntIQ3SbFcP+dYmBIBjJg8s/VAmMQ7+wDGevv4wGt37/d 26 | zWH9x2TnK8/hHeUo5RqmdPw0905WqIqDtxpfuuFhyuZmGYtg9XAkjQ== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /spec/acceptance/certs/privkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAtLOximT4/sOpGnSNiURDVJZYgNmCC2jeybZ4QZzgQSNNCpMS 3 | qSRY5E2pl5dEvr4ponCf3hH/QzXeUKc9rw/Z/I3mEJZ9ivRWpZ8O3SGvucPcOmp3 4 | FtEBypRxCbQBzZ1f7AEj/+vwbMAOgyYeRWPtyHrOVvFQJT/HZ1XJnyPFd9Ua6cly 5 | jvG9ju0ENfJQhcQyJVXSQ9OTe8ZnlFjbV39FPMBgg0EDYVuJhWQH50covBa6lvdH 6 | w1famhxRD94Fe4x+2hsfEEaBX4ZaeD2pqKV53EifZoF0U96xYV2qu3ToZbNdGFgc 7 | tPYIOL6s8BieFhQj6yxvqTIoWrxLhW29b20xMQIDAQABAoIBABAMb4Wvjw+tV+zy 8 | EgnxZptyGN0ktDCIOVUn4AlPwfj3BiYcxsj/4ecw4JGGjUP1hqQXJZOm/Ik/FQYL 9 | vGY6Xa1Y+uhZPUAkkDd4Z20LS1yPwRTtFLORj3uq8FkgxBI7WmQO++AEV9+ItSE/ 10 | tuuJwvoNshq1pt0QC4kpbNU165lHTTglyet/sXWcE/DeCRWz6D+2jflzhTaSyzd4 11 | zKA4mgLcgHipk7LgBfVdMupx4jioULvl7lJe4ltO0818DBXSAZghsVJXR3JlMHYx 12 | YVz0k1Pmp6pujruISjV/yM0uHhoUT+iZvlAey2FtkUFyq08xpuEvfS/+VQd9I6bS 13 | b4R/l/kCgYEAz0htryDxmyhesYesPjxuvB+w1cqlm45GjhircqJ8JForK9CmONEP 14 | 8Hp/8upeT3zJXM0yTw3cwdDziPC+/6NT/IGjTFGM6uv6QeEExENjPyvwWytnEfvh 15 | 3i77uzJ58W9Z9SdECeRaV6z9pnhHtbMEMCS3+QomJoVBtgWfB8w+gtUCgYEA3yv4 16 | B7jJqfaYz4FkAOzF54N3Ccy/GnjKpqZRU9CDZKRH9T7oGLj9xzUE7LGTjy3RS+wA 17 | pWSQ5vH3idnEdbhJEoOaLPOcBNFVeeKX2g4ndBZGYnyrzhMnbvKyPAWsmPaNCr8m 18 | 0FdjQpR2/qNzMRiUZvjz3Tuwi2tA9fRbcEIKyu0CgYEAoSS4iI5+5dWDkFZeNF/8 19 | 4mlsqzgIeR8pgKxzFQJ2qjgjGcPyhXcaAiTptWo4eWkUjf3EH6syNMcBnTMz+T77 20 | OvF5hwpbGALuIisR7pZI4MKC8A2U6mk8FePGtagvHuAnOiwVe+83wLNu2ezmKr6K 21 | Afd5wrT+JbIw/JXwJTrGWiUCgYBQKCe/BkUQkezS4yN7HY/7loGD+JFPPcFz19rw 22 | Ir1+wW7DDGQqtQ8ZpNZu+V0JmShKf6q/vP46pQAG+DuTGKzORIx0xs7sABAWZieq 23 | f1j2XiXLrAG9U63fMLaJznPuwOdpy7xyKmERgee3kBeIs85hqdtVQ+ImQVCkxq6t 24 | BFuCBQKBgFMvbfYKQLsdfa6r+TXeyi5MpN/PFZRvzNAiPhtjplM2ueRLqtg3jBet 25 | 13IIgs5aXli1WbimXpD4XNlxpEBJxkQxydWnesZ6CpND8feXrD49XNd10bpg+VYI 26 | ec6FH3lgMwhluR/d2F79KKPBHPztYdPv2b2SBZNoQN7u/v8qAs6G 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /spec/acceptance/chain_key_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | 5 | describe 'managing intermediate certificates' do 6 | # rubocop:disable RSpec/InstanceVariable : Instance variables are inherited and thus cannot be contained within lets 7 | describe 'managing combined and seperate java chain keys' do 8 | include_context 'with common variables' 9 | 10 | it 'verifies keytool is setup', unless: os[:family] == 'windows' do 11 | i = 0 12 | loop do 13 | keytool_status = run_shell('keytool') 14 | break if keytool_status['exit_code'] == 0 15 | 16 | if i >= 8 17 | puts keytool_status 18 | exit 1 19 | else 20 | i += 1 21 | sleep 30.seconds 22 | end 23 | end 24 | end 25 | 26 | it 'creates two private key with chain certs' do 27 | pp = <<-MANIFEST 28 | java_ks { 'combined.example.com:#{@temp_dir}chain_combined_key.ks': 29 | ensure => latest, 30 | certificate => "#{@temp_dir}leafchain.pem", 31 | private_key => "#{@temp_dir}leafkey.pem", 32 | password => 'puppet', 33 | path => #{@resource_path}, 34 | } 35 | 36 | java_ks { 'seperate.example.com:#{@temp_dir}chain_key.ks': 37 | ensure => latest, 38 | certificate => "#{@temp_dir}leaf.pem", 39 | chain => "#{@temp_dir}chain.pem", 40 | private_key => "#{@temp_dir}leafkey.pem", 41 | password => 'puppet', 42 | path => #{@resource_path}, 43 | } 44 | MANIFEST 45 | 46 | idempotent_apply(pp) 47 | end 48 | 49 | expectations_combined = [ 50 | %r{Alias name: combined\.example\.com}, 51 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 52 | %r{Certificate chain length: 3}, 53 | %r{^Serial number: 5.*^Serial number: 4.*^Serial number: 3}m, 54 | ] 55 | it 'verifies the private key #combined' do 56 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}chain_combined_key.ks -storepass puppet"), expect_failures: true) do |r| 57 | expectations_combined.each do |expect| 58 | expect(r.stdout).to match(expect) 59 | end 60 | end 61 | end 62 | 63 | expectations_seperate = [ 64 | %r{Alias name: seperate\.example\.com}, 65 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 66 | %r{Certificate chain length: 3}, 67 | %r{^Serial number: 5.*^Serial number: 4.*^Serial number: 3}m, 68 | ] 69 | it 'verifies the private key #seperate' do 70 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}chain_key.ks -storepass puppet"), expect_failures: true) do |r| 71 | expectations_seperate.each do |expect| 72 | expect(r.stdout).to match(expect) 73 | end 74 | end 75 | end 76 | 77 | it 'updates the two key chains' do 78 | pp = <<-MANIFEST 79 | java_ks { 'combined.example.com:#{@temp_dir}chain_combined_key.ks': 80 | ensure => latest, 81 | certificate => "#{@temp_dir}leafchain2.pem", 82 | private_key => "#{@temp_dir}leafkey.pem", 83 | password => 'puppet', 84 | path => #{@resource_path}, 85 | } 86 | 87 | java_ks { 'seperate.example.com:#{@temp_dir}chain_key.ks': 88 | ensure => latest, 89 | certificate => "#{@temp_dir}leaf.pem", 90 | chain => "#{@temp_dir}chain2.pem", 91 | private_key => "#{@temp_dir}leafkey.pem", 92 | password => 'puppet', 93 | path => #{@resource_path}, 94 | } 95 | MANIFEST 96 | 97 | idempotent_apply(pp) 98 | 99 | expectations_combined = [ 100 | %r{Alias name: combined\.example\.com}, 101 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 102 | %r{Certificate chain length: 2}, 103 | %r{^Serial number: 5.*^Serial number: 6}m, 104 | ] 105 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}chain_combined_key.ks -storepass puppet"), expect_failures: true) do |r| 106 | expectations_combined.each do |expect| 107 | expect(r.stdout).to match(expect) 108 | end 109 | end 110 | 111 | expectations_seperate = [ 112 | %r{Alias name: seperate\.example\.com}, 113 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 114 | %r{Certificate chain length: 2}, 115 | %r{^Serial number: 5.*Serial number: 6}m, 116 | ] 117 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}chain_key.ks -storepass puppet"), expect_failures: true) do |r| 118 | expectations_seperate.each do |expect| 119 | expect(r.stdout).to match(expect) 120 | end 121 | end 122 | end 123 | end 124 | 125 | describe 'managing non existent java chain keys in noop' do 126 | include_context 'with common variables' 127 | 128 | it 'does not create a new keystore in noop' do 129 | pp = <<-MANIFEST 130 | $filenames = ["#{@temp_dir}noop_ca.pem", 131 | "#{@temp_dir}noop_chain.pem", 132 | "#{@temp_dir}noop_privkey.pem"] 133 | file { $filenames: 134 | ensure => file, 135 | content => 'content', 136 | } -> 137 | java_ks { 'broker.example.com:#{@temp_dir}noop_chain_key.ks': 138 | ensure => latest, 139 | certificate => "#{@temp_dir}noop_ca.pem", 140 | chain => "#{@temp_dir}noop_chain.pem", 141 | private_key => "#{@temp_dir}noop_privkey.pem", 142 | password => 'puppet', 143 | path => #{@resource_path}, 144 | } 145 | MANIFEST 146 | 147 | # in noop mode, when the dependent certificate files are not present in the system, 148 | # java_ks will not invoke openssl to validate their status, thus noop will succeed 149 | apply_manifest(pp, noop: true) 150 | end 151 | 152 | # verifies the dependent files are missing 153 | ['noop_ca.pem', 'noop_chain.pem', 'noop_privkey.pem'].each do |filename| 154 | describe filename do 155 | it "doesn't exist" do 156 | result = remote_file_exists?("#{@temp_dir}#{filename}") 157 | expect(result.exit_code).to be(1) 158 | end 159 | end 160 | end 161 | 162 | # verifies the keystore is not created 163 | describe 'noop_chain_key.ks' do 164 | it "doesn't exist" do 165 | result = remote_file_exists?("#{@temp_dir}noop_chain_key.ks") 166 | expect(result.exit_code).to be(1) 167 | end 168 | end 169 | end 170 | # rubocop:enable RSpec/InstanceVariable 171 | end 172 | -------------------------------------------------------------------------------- /spec/acceptance/content_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | 5 | RSpec.shared_examples 'a private key creator' do |sensitive| 6 | # rubocop:disable RSpec/InstanceVariable : Instance variables are inherited and thus cannot be contained within lets 7 | it 'creates a private key' do 8 | pp = if sensitive 9 | <<-MANIFEST 10 | java_ks { 'broker.example.com:#{temp_dir}private_key.ts': 11 | ensure => #{@ensure_ks}, 12 | certificate_content => "#{ca_content}", 13 | private_key_content => "#{priv_key_content}", 14 | password => 'puppet', 15 | path => #{@resource_path}, 16 | } 17 | MANIFEST 18 | else 19 | <<-MANIFEST 20 | java_ks { 'broker.example.com:#{temp_dir}private_key.ts': 21 | ensure => #{@ensure_ks}, 22 | certificate_content => Sensitive("#{ca_content}"), 23 | private_key_content => Sensitive("#{priv_key_content}"), 24 | password => 'puppet', 25 | path => #{@resource_path}, 26 | } 27 | MANIFEST 28 | end 29 | idempotent_apply(pp) 30 | end 31 | 32 | expectations = [ 33 | %r{Alias name: broker\.example\.com}, 34 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 35 | %r{CN=Test CA}, 36 | ] 37 | it 'verifies the private key' do 38 | run_shell(keytool_command("-list -v -keystore #{temp_dir}private_key.ts -storepass puppet"), expect_failures: true) do |r| 39 | expectations.each do |expect| 40 | expect(r.stdout).to match(expect) 41 | end 42 | end 43 | end 44 | end 45 | 46 | describe 'using certificate_content and private_key_content' do 47 | include_context 'with common variables' 48 | let(:ca_content) { File.read('spec/acceptance/certs/ca.pem') } 49 | let(:priv_key_content) { File.read('spec/acceptance/certs/privkey.pem') } 50 | 51 | context 'when using data type String' do 52 | it_behaves_like 'a private key creator', false 53 | end 54 | 55 | context 'when using data type Sensitive' do 56 | it_behaves_like 'a private key creator', true 57 | end 58 | # rubocop:enable RSpec/InstanceVariable 59 | end 60 | -------------------------------------------------------------------------------- /spec/acceptance/destkeypass_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | 5 | describe 'password protected java private keys', unless: UNSUPPORTED_PLATFORMS.include?(os[:family]) do 6 | # rubocop:disable RSpec/InstanceVariable : Instance variables are inherited and thus cannot be contained within lets 7 | include_context 'with common variables' 8 | target = "#{@target_dir}destkeypass.ks" 9 | 10 | it 'creates a password protected private key' do 11 | pp = <<-MANIFEST 12 | java_ks { 'broker.example.com:#{@temp_dir}#{target}': 13 | ensure => latest, 14 | certificate => "#{@temp_dir}ca.pem", 15 | private_key => "#{@temp_dir}privkey.pem", 16 | password => 'testpass', 17 | destkeypass => 'testkeypass', 18 | path => #{@resource_path}, 19 | } 20 | MANIFEST 21 | 22 | idempotent_apply(pp) 23 | end 24 | 25 | it 'can make a cert req with the right password' do 26 | run_shell(keytool_command('-certreq -alias broker.example.com -v ' \ 27 | "-keystore #{@temp_dir}#{target} -storepass testpass -keypass testkeypass"), expect_failures: true) do |r| 28 | expect(r.stdout).to match(%r{-BEGIN NEW CERTIFICATE REQUEST-}) 29 | end 30 | end 31 | 32 | it 'cannot make a cert req with the wrong password' do 33 | result = run_shell(keytool_command('-certreq -alias broker.example.com -v ' \ 34 | "-keystore #{@temp_dir}#{target} -storepass qwert -keypass qwert"), expect_failures: true) 35 | expect(result.stdout).to match(%r{keytool error}) 36 | end 37 | # rubocop:enable RSpec/InstanceVariable 38 | end 39 | -------------------------------------------------------------------------------- /spec/acceptance/keystore_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | 5 | describe 'managing java keystores' do 6 | # rubocop:disable RSpec/InstanceVariable : Instance variables are inherited and thus cannot be contained within lets 7 | include_context 'with common variables' 8 | 9 | describe 'basic tests' do 10 | it 'creates a keystore' do 11 | command = "rm #{@temp_dir}keystore.ks" 12 | command = interpolate_powershell(command) if os[:family] == 'windows' 13 | run_shell(command, expect_failures: true) 14 | pp_one = <<-MANIFEST 15 | java_ks { 'puppetca:keystore': 16 | ensure => latest, 17 | certificate => "#{@temp_dir}ca.pem", 18 | target => '#{@temp_dir}keystore.ks', 19 | password => 'puppet', 20 | trustcacerts => true, 21 | path => #{@resource_path}, 22 | } 23 | MANIFEST 24 | 25 | idempotent_apply(pp_one) 26 | end 27 | 28 | expectations = [ 29 | %r{Your keystore contains 1 entry}, 30 | %r{Alias name: puppetca}, 31 | %r{CN=Test CA}, 32 | ] 33 | it 'verifies the keytore' do 34 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}keystore.ks -storepass puppet")) do |r| 35 | expect(r.exit_code).to be_zero 36 | expectations.each do |expect| 37 | expect(r.stdout).to match(expect) 38 | end 39 | end 40 | end 41 | 42 | it 'uses password_file' do 43 | pp_two = <<-MANIFEST 44 | file { '#{@temp_dir}password': 45 | ensure => file, 46 | content => 'puppet', 47 | } 48 | java_ks { 'puppetca2:keystore': 49 | ensure => latest, 50 | certificate => "#{@temp_dir}ca2.pem", 51 | target => '#{@temp_dir}keystore.ks', 52 | password_file => '#{@temp_dir}password', 53 | trustcacerts => true, 54 | path => #{@resource_path}, 55 | require => File['#{@temp_dir}password'] 56 | } 57 | MANIFEST 58 | 59 | idempotent_apply(pp_two) 60 | end 61 | 62 | it 'recreates a keystore if password fails' do 63 | pp_three = <<-MANIFEST 64 | 65 | java_ks { 'puppetca:#{@temp_dir}keystore': 66 | ensure => latest, 67 | certificate => "#{@temp_dir}ca.pem", 68 | target => '#{@temp_dir}keystore.ks', 69 | password => 'pepput', 70 | password_fail_reset => true, 71 | trustcacerts => true, 72 | path => #{@resource_path}, 73 | } 74 | MANIFEST 75 | 76 | idempotent_apply(pp_three) 77 | end 78 | 79 | it 'verifies the keystore again' do 80 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}keystore.ks -storepass pepput")) do |r| 81 | expect(r.exit_code).to be_zero 82 | expectations.each do |expect| 83 | expect(r.stdout).to match(expect) 84 | end 85 | end 86 | end 87 | end 88 | 89 | unless os[:family] == 'ubuntu' && os[:release].start_with?('18.04') 90 | describe 'storetype' do 91 | it 'creates a keystore' do 92 | pp = <<-MANIFEST 93 | java_ks { 'puppetca:#{@temp_dir}keystore': 94 | ensure => latest, 95 | certificate => "#{@temp_dir}ca.pem", 96 | target => '#{@temp_dir}keystore.ks', 97 | password => 'pepput', 98 | trustcacerts => true, 99 | path => #{@resource_path}, 100 | storetype => 'jks', 101 | } 102 | MANIFEST 103 | 104 | idempotent_apply(pp) 105 | end 106 | 107 | expectations = [ 108 | %r{Your keystore contains 1 entry}, 109 | %r{Alias name: puppetca}, 110 | %r{CN=Test CA}, 111 | ] 112 | it 'verifies the keytore' do 113 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}keystore.ks -storepass pepput")) do |r| 114 | expect(r.exit_code).to be_zero 115 | expectations.each do |expect| 116 | expect(r.stdout).to match(expect) 117 | end 118 | end 119 | end 120 | end 121 | end 122 | 123 | describe 'with der certificates' do 124 | it 'creates a keystore' do 125 | command = "rm #{@temp_dir}keystore.ks" 126 | command = interpolate_powershell(command) if os[:family] == 'windows' 127 | run_shell(command, expect_failures: true) 128 | pp_one = <<-MANIFEST 129 | java_ks { 'puppetcader:keystore': 130 | ensure => latest, 131 | certificate => "#{@temp_dir}ca.der", 132 | target => '#{@temp_dir}keystore.ks', 133 | password => 'puppet', 134 | trustcacerts => true, 135 | path => #{@resource_path}, 136 | } 137 | MANIFEST 138 | 139 | idempotent_apply(pp_one) 140 | end 141 | 142 | it 'adds a certificate and key' do 143 | pp_two = <<-MANIFEST 144 | java_ks { 'puppetcader_privkey:keystore': 145 | ensure => latest, 146 | certificate => "#{@temp_dir}ca.der", 147 | private_key => "#{@temp_dir}privkey.pem", 148 | target => '#{@temp_dir}keystore.ks', 149 | password => 'puppet', 150 | trustcacerts => true, 151 | path => #{@resource_path}, 152 | } 153 | MANIFEST 154 | 155 | idempotent_apply(pp_two) 156 | end 157 | 158 | expectations = [ 159 | %r{Your keystore contains 2 entries}, 160 | %r{Alias name: puppetcader}, 161 | %r{Alias name: puppetcader_privkey}, 162 | %r{CN=Test CA}, 163 | ] 164 | 165 | context 'when running on Linux', unless: os[:family] == 'windows' do 166 | it 'verifies the keystore' do 167 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}keystore.ks -storepass puppet")) do |r| 168 | expect(r.exit_code).to be_zero 169 | expectations.each do |expect| 170 | expect(r.stdout).to match(expect) 171 | end 172 | end 173 | end 174 | end 175 | 176 | # On Windows, the keystore command warns about using a proprietary format when using DER formatted certs. We should 177 | # not take this as a failure, but also, we should also not blindly ignore all STDERR from the result either. If we 178 | # get an exit code of 1, we'll check to see if the STDERR message was the cert format warning and still pass the 179 | # test. We will still catch any errors that occur and are not related 180 | context 'when running on Windows', if: os[:family] == 'windows' do 181 | it 'verifies the keystore' do 182 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}keystore.ks -storepass puppet"), expect_failures: true) do |r| 183 | expect(r.exit_code).to be_between(0, 1) 184 | expectations.each do |expect| 185 | expect(r.stdout).to match(expect) 186 | end 187 | # Pattern below ensures that it's the only warning printed out by anchoring to the end of line ($). This is to 188 | # handle the case that multiple warnings should ever occur - a looser match could potentially hide additional 189 | # errors 190 | expect(r.stderr.chomp).to match(%r{The JKS keystore.*pkcs12"\.$}) if r.exit_code == 1 191 | end 192 | end 193 | end 194 | end 195 | # rubocop:enable RSpec/InstanceVariable 196 | end 197 | -------------------------------------------------------------------------------- /spec/acceptance/pkcs12_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | 5 | # SLES by default does not support this form of encyrption. 6 | describe 'managing java pkcs12', unless: (os[:family] == 'sles' || (os[:family] == 'debian' && os[:release].start_with?('10')) || (os[:family] == 'ubuntu' && os[:release].start_with?('18'))) do 7 | # rubocop:disable RSpec/InstanceVariable : Instance variables are inherited and thus cannot be contained within lets 8 | include_context 'with common variables' 9 | context 'with defaults' do 10 | it 'creates a private key with chain' do 11 | pp = <<-MANIFEST 12 | java_ks { 'Leaf Cert:#{@temp_dir}pkcs12.ks': 13 | ensure => #{@ensure_ks}, 14 | certificate => "#{@temp_dir}leaf.p12", 15 | storetype => 'pkcs12', 16 | password => 'puppet', 17 | path => #{@resource_path}, 18 | source_password => 'pkcs12pass' 19 | } 20 | MANIFEST 21 | 22 | idempotent_apply(pp) 23 | end 24 | 25 | expectations = [ 26 | %r{Alias name: leaf cert}, 27 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 28 | %r{Certificate chain length: 3}, 29 | %r{^Serial number: 5.*^Serial number: 4.*^Serial number: 3}m, 30 | ] 31 | it 'verifies the private key and chain' do 32 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}pkcs12.ks -storepass puppet"), expect_failures: true) do |r| 33 | expectations.each do |expect| 34 | expect(r.stdout).to match(expect) 35 | end 36 | end 37 | end 38 | 39 | it 'updates the chain' do 40 | pp = <<-MANIFEST 41 | java_ks { 'Leaf Cert:#{@temp_dir}pkcs12.ks': 42 | ensure => #{@ensure_ks}, 43 | certificate => "#{@temp_dir}leaf2.p12", 44 | storetype => 'pkcs12', 45 | password => 'puppet', 46 | path => #{@resource_path}, 47 | source_password => 'pkcs12pass' 48 | } 49 | MANIFEST 50 | 51 | idempotent_apply(pp) 52 | 53 | expectations = if os[:family] == 'windows' || (os[:family] == 'ubuntu' && ['20.04', '22.04'].include?(os[:release])) || 54 | (os[:family] == 'debian' && os[:release] =~ %r{^11|12}) 55 | [ 56 | %r{Alias name: leaf cert}, 57 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 58 | %r{Certificate chain length: 3}, 59 | %r{^Serial number: 3}m, 60 | %r{^Serial number: 4}m, 61 | %r{^Serial number: 5}m, 62 | ] 63 | else 64 | [ 65 | %r{Alias name: leaf cert}, 66 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 67 | %r{Certificate chain length: 2}, 68 | %r{^Serial number: 5$.*^Serial number: 6$}m, 69 | ] 70 | end 71 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}pkcs12.ks -storepass puppet"), expect_failures: true) do |r| 72 | expectations.each do |expect| 73 | expect(r.stdout).to match(expect) 74 | end 75 | end 76 | end 77 | end 78 | 79 | context 'with a different alias' do 80 | it 'creates a private key with chain' do 81 | pp = <<-MANIFEST 82 | java_ks { 'Leaf_Cert:#{@temp_dir}pkcs12.ks': 83 | ensure => #{@ensure_ks}, 84 | certificate => "#{@temp_dir}leaf.p12", 85 | storetype => 'pkcs12', 86 | password => 'puppet', 87 | path => #{@resource_path}, 88 | source_password => 'pkcs12pass', 89 | source_alias => 'Leaf Cert' 90 | } 91 | MANIFEST 92 | 93 | idempotent_apply(pp) 94 | end 95 | 96 | expectations = [ 97 | %r{Alias name: leaf_cert}, 98 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 99 | %r{Certificate chain length: 3}, 100 | %r{^Serial number: 5.*^Serial number: 4.*^Serial number: 3}m, 101 | ] 102 | it 'verifies the private key and chain' do 103 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}pkcs12.ks -storepass puppet"), expect_failures: true) do |r| 104 | expectations.each do |expect| 105 | expect(r.stdout).to match(expect) 106 | end 107 | end 108 | end 109 | end 110 | 111 | context 'with a destkeypass' do 112 | command = if os[:family] == 'windows' 113 | interpolate_powershell("rm -force #{@temp_dir}pkcs12.ks") 114 | else 115 | "rm -f #{@temp_dir}pkcs12.ks" 116 | end 117 | before(:all) { run_shell(command, expect_failures: true) } 118 | 119 | it 'creates a private key with chain' do 120 | pp = <<-MANIFEST 121 | java_ks { 'Leaf_Cert:#{@temp_dir}/pkcs12.ks': 122 | ensure => #{@ensure_ks}, 123 | certificate => "#{@temp_dir}leaf.p12", 124 | destkeypass => "abcdef123456", 125 | storetype => 'pkcs12', 126 | password => 'puppet', 127 | path => #{@resource_path}, 128 | source_password => 'pkcs12pass', 129 | source_alias => 'Leaf Cert' 130 | } 131 | MANIFEST 132 | 133 | idempotent_apply(pp) 134 | end 135 | 136 | expectations = [ 137 | %r{Alias name: leaf_cert}, 138 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 139 | %r{Certificate chain length: 3}, 140 | %r{^Serial number: 5.*^Serial number: 4.*^Serial number: 3}m, 141 | ] 142 | it 'verifies the private key and chain' do 143 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}pkcs12.ks -storepass puppet"), expect_failures: true) do |r| 144 | expectations.each do |expect| 145 | expect(r.stdout).to match(expect) 146 | end 147 | end 148 | end 149 | end 150 | # rubocop:enable RSpec/InstanceVariable 151 | end 152 | -------------------------------------------------------------------------------- /spec/acceptance/private_key_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | 5 | describe 'managing java private keys' do 6 | # rubocop:disable RSpec/InstanceVariable : Instance variables are inherited and thus cannot be contained within lets 7 | include_context 'with common variables' 8 | 9 | it 'creates a private key' do 10 | pp = <<-MANIFEST 11 | java_ks { 'broker.example.com:#{@temp_dir}private_key.ts': 12 | ensure => #{@ensure_ks}, 13 | certificate => "#{@temp_dir}ca.pem", 14 | private_key => "#{@temp_dir}privkey.pem", 15 | password => 'puppet', 16 | path => #{@resource_path}, 17 | } 18 | MANIFEST 19 | 20 | idempotent_apply(pp) 21 | end 22 | 23 | expectations = [ 24 | %r{Alias name: broker\.example\.com}, 25 | %r{Entry type: (keyEntry|PrivateKeyEntry)}, 26 | %r{CN=Test CA}, 27 | ] 28 | it 'verifies the private key' do 29 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}private_key.ts -storepass puppet"), expect_failures: true) do |r| 30 | expectations.each do |expect| 31 | expect(r.stdout).to match(expect) 32 | end 33 | end 34 | end 35 | # rubocop:enable RSpec/InstanceVariable 36 | end 37 | -------------------------------------------------------------------------------- /spec/acceptance/truststore_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | 5 | describe 'managing java truststores' do 6 | # rubocop:disable RSpec/InstanceVariable : Instance variables are inherited and thus cannot be contained within lets 7 | include_context 'with common variables' 8 | 9 | it 'creates a truststore' do 10 | command = "rm #{@temp_dir}truststore.ts" 11 | command = interpolate_powershell(command) if os[:family] == 'windows' 12 | run_shell(command, expect_failures: true) 13 | pp = <<-MANIFEST 14 | java_ks { 'puppetca:#{@temp_dir}truststore': 15 | ensure => #{@ensure_ks}, 16 | certificate => "#{@temp_dir}ca.pem", 17 | target => "#{@temp_dir}truststore.ts", 18 | password => 'puppet', 19 | trustcacerts => true, 20 | path => #{@resource_path}, 21 | } 22 | MANIFEST 23 | idempotent_apply(pp) 24 | end 25 | 26 | expectations = [ 27 | %r{Your keystore contains 1 entry}, 28 | %r{Alias name: puppetca}, 29 | %r{CN=Test CA}, 30 | ] 31 | it 'verifies the truststore' do 32 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}truststore.ts -storepass puppet")) do |r| 33 | expect(r.exit_code).to be_zero 34 | expectations.each do |expect| 35 | expect(r.stdout).to match(expect) 36 | end 37 | end 38 | end 39 | 40 | it 'recreates a truststore if password fails' do 41 | pp = <<-MANIFEST 42 | java_ks { 'puppetca:#{@temp_dir}truststore': 43 | ensure => latest, 44 | certificate => "#{@temp_dir}ca.pem", 45 | target => "#{@temp_dir}truststore.ts", 46 | password => 'bobinsky', 47 | password_fail_reset => true, 48 | trustcacerts => true, 49 | path => #{@resource_path}, 50 | } 51 | MANIFEST 52 | idempotent_apply(pp) 53 | end 54 | 55 | it 'verifies the truststore again' do 56 | run_shell(keytool_command("-list -v -keystore #{@temp_dir}truststore.ts -storepass bobinsky")) do |r| 57 | expect(r.exit_code).to be_zero 58 | expectations.each do |expect| 59 | expect(r.stdout).to match(expect) 60 | end 61 | end 62 | end 63 | # rubocop:enable RSpec/InstanceVariable 64 | end 65 | -------------------------------------------------------------------------------- /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 | networking: 6 | ip: "172.16.254.254" 7 | ip6: "FE80:0000:0000:0000:AAAA:AAAA:AAAA" 8 | mac: "AA:AA:AA:AA:AA:AA" 9 | is_pe: false 10 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |c| 4 | c.mock_with :rspec 5 | end 6 | 7 | require 'puppetlabs_spec_helper/module_spec_helper' 8 | require 'rspec-puppet-facts' 9 | 10 | require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) 11 | 12 | include RspecPuppetFacts 13 | 14 | default_facts = { 15 | puppetversion: Puppet.version, 16 | facterversion: Facter.version, 17 | } 18 | 19 | default_fact_files = [ 20 | File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')), 21 | File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')), 22 | ] 23 | 24 | default_fact_files.each do |f| 25 | next unless File.exist?(f) && File.readable?(f) && File.size?(f) 26 | 27 | begin 28 | require 'deep_merge' 29 | default_facts.deep_merge!(YAML.safe_load(File.read(f), permitted_classes: [], permitted_symbols: [], aliases: true)) 30 | rescue StandardError => e 31 | RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" 32 | end 33 | end 34 | 35 | # read default_facts and merge them over what is provided by facterdb 36 | default_facts.each do |fact, value| 37 | add_custom_fact fact, value, merge_facts: true 38 | end 39 | 40 | RSpec.configure do |c| 41 | c.default_facts = default_facts 42 | c.before :each do 43 | # set to strictest setting for testing 44 | # by default Puppet runs at warning level 45 | Puppet.settings[:strict] = :warning 46 | Puppet.settings[:strict_variables] = true 47 | end 48 | c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] 49 | c.after(:suite) do 50 | RSpec::Puppet::Coverage.report!(0) 51 | end 52 | 53 | # Filter backtrace noise 54 | backtrace_exclusion_patterns = [ 55 | %r{spec_helper}, 56 | %r{gems}, 57 | ] 58 | 59 | if c.respond_to?(:backtrace_exclusion_patterns) 60 | c.backtrace_exclusion_patterns = backtrace_exclusion_patterns 61 | elsif c.respond_to?(:backtrace_clean_patterns) 62 | c.backtrace_clean_patterns = backtrace_exclusion_patterns 63 | end 64 | end 65 | 66 | # Ensures that a module is defined 67 | # @param module_name Name of the module 68 | def ensure_module_defined(module_name) 69 | module_name.split('::').reduce(Object) do |last_module, next_module| 70 | last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false) 71 | last_module.const_get(next_module, false) 72 | end 73 | end 74 | 75 | # 'spec_overrides' from sync.yml will appear below this line 76 | -------------------------------------------------------------------------------- /spec/spec_helper_acceptance.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'puppet_litmus' 4 | require 'spec_helper_acceptance_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_acceptance_local.rb')) 5 | 6 | PuppetLitmus.configure! 7 | -------------------------------------------------------------------------------- /spec/spec_helper_acceptance_local.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | UNSUPPORTED_PLATFORMS = [].freeze 4 | require 'singleton' 5 | 6 | class LitmusHelper 7 | include Singleton 8 | include PuppetLitmus 9 | end 10 | 11 | def keytool_command(arguments) 12 | # The @keytool global does not exist right now as the function is defined. 13 | # When the tests call the function, RSpec.shared_context below will have run 14 | # by then and the variable will exist. 15 | # os[:family] == 'windows' ? interpolate_powershell("& '#{@keytool_path}keytool'") : "'#{@keytool_path}keytool'" 16 | if os[:family] == 'windows' 17 | interpolate_powershell("& '#{@keytool_path}keytool' #{arguments}") 18 | else 19 | "'#{@keytool_path}keytool' #{arguments}" 20 | end 21 | end 22 | 23 | def interpolate_powershell(command) 24 | "powershell.exe -NoProfile -Nologo -Command \"#{command}\"" 25 | end 26 | 27 | def remote_windows_temp_dir 28 | @remote_windows_temp_dir ||= "#{LitmusHelper.instance.run_shell(interpolate_powershell('echo "$ENV:TEMP"')).stdout.strip.tr('\\', '/')}/" 29 | @remote_windows_temp_dir 30 | end 31 | 32 | def remote_file_exists?(filename) 33 | if os[:family] == 'windows' 34 | LitmusHelper.instance.run_shell(interpolate_powershell("Get-Item -Path '#{filename}' -ErrorAction SilentlyContinue"), expect_failures: true) 35 | else 36 | LitmusHelper.instance.run_shell("test -f '#{filename}'", expect_failures: true) 37 | end 38 | end 39 | 40 | def temp_dir 41 | @temp_dir ||= (os[:family] == 'windows') ? remote_windows_temp_dir : '/tmp/' 42 | @temp_dir 43 | end 44 | 45 | def create_and_upload_certs 46 | cert_files = ['privkey.pem', 'ca.pem', 'ca.der', 'ca2.pem', 'chain.pem', 'chain2.pem', 'leafkey.pem', 'leaf.pem', 'leafchain.pem', 'leafchain2.pem', 'leaf.p12', 'leaf2.p12'] 47 | recreate_certs = false 48 | cert_files.each do |cert_file| 49 | recreate_certs = true unless File.file?("spec/acceptance/certs/#{cert_file}") 50 | end 51 | create_certs if recreate_certs 52 | cert_files.each do |cert_file| 53 | if ENV['TARGET_HOST'].nil? || ENV['TARGET_HOST'] == 'localhost' 54 | command = "cp spec\\acceptance\\certs\\#{cert_file} #{ENV.fetch('TEMP', nil)}\\#{cert_file}" 55 | command = interpolate_powershell(command) if os[:family] == 'windows' 56 | Open3.capture3(command) 57 | else 58 | LitmusHelper.instance.bolt_upload_file("spec/acceptance/certs/#{cert_file}", "#{temp_dir}#{cert_file}") 59 | end 60 | end 61 | end 62 | 63 | def create_certs 64 | require 'openssl' 65 | key = OpenSSL::PKey::RSA.new 2048 66 | ca = OpenSSL::X509::Certificate.new 67 | ca.serial = 1 68 | ca.public_key = key.public_key 69 | subj = '/CN=Test CA/ST=Denial/L=Springfield/O=Dis/CN=www.example.com' 70 | ca.subject = OpenSSL::X509::Name.parse subj 71 | ca.issuer = ca.subject 72 | ca.not_before = Time.now 73 | ca.not_after = ca.not_before + 360 74 | ca.sign(key, OpenSSL::Digest.new('SHA256')) 75 | 76 | key2 = OpenSSL::PKey::RSA.new 2048 77 | ca2 = OpenSSL::X509::Certificate.new 78 | ca2.serial = 2 79 | ca2.public_key = key2.public_key 80 | subj2 = '/CN=Test CA/ST=Denial/L=Springfield/O=Dis/CN=www.example.com' 81 | ca2.subject = OpenSSL::X509::Name.parse subj2 82 | ca2.issuer = ca2.subject 83 | ca2.not_before = Time.now 84 | ca2.not_after = ca2.not_before + 360 85 | ca2.sign(key2, OpenSSL::Digest.new('SHA256')) 86 | 87 | key_chain = OpenSSL::PKey::RSA.new 2048 88 | chain = OpenSSL::X509::Certificate.new 89 | chain.serial = 3 90 | chain.public_key = key_chain.public_key 91 | chain_subj = '/CN=Chain CA/ST=Denial/L=Springfield/O=Dis/CN=www.example.net' 92 | chain.subject = OpenSSL::X509::Name.parse chain_subj 93 | chain.issuer = ca.subject 94 | chain.not_before = Time.now 95 | chain.not_after = chain.not_before + 360 96 | chain.sign(key, OpenSSL::Digest.new('SHA256')) 97 | 98 | key_chain2 = OpenSSL::PKey::RSA.new 2048 99 | chain2 = OpenSSL::X509::Certificate.new 100 | chain2.serial = 4 101 | chain2.public_key = key_chain2.public_key 102 | chain2_subj = '/CN=Chain CA 2/ST=Denial/L=Springfield/O=Dis/CN=www.example.net' 103 | chain2.subject = OpenSSL::X509::Name.parse chain2_subj 104 | chain2.issuer = chain.subject 105 | chain2.not_before = Time.now 106 | chain2.not_after = chain2.not_before + 360 107 | chain2.sign(key_chain, OpenSSL::Digest.new('SHA256')) 108 | 109 | key_leaf = OpenSSL::PKey::RSA.new 2048 110 | leaf = OpenSSL::X509::Certificate.new 111 | leaf.serial = 5 112 | leaf.public_key = key_leaf.public_key 113 | leaf_subj = '/CN=Leaf Cert/ST=Denial/L=Springfield/O=Dis/CN=www.example.net' 114 | leaf.subject = OpenSSL::X509::Name.parse leaf_subj 115 | leaf.issuer = chain2.subject 116 | leaf.not_before = Time.now 117 | leaf.not_after = leaf.not_before + 360 118 | leaf.sign(key_chain2, OpenSSL::Digest.new('SHA256')) 119 | 120 | chain3 = OpenSSL::X509::Certificate.new 121 | chain3.serial = 6 122 | chain3.public_key = key_chain2.public_key 123 | chain3.subject = OpenSSL::X509::Name.parse chain2_subj 124 | chain3.issuer = ca.subject 125 | chain3.not_before = Time.now 126 | chain3.not_after = chain3.not_before + 360 127 | chain3.sign(key, OpenSSL::Digest.new('SHA256')) 128 | 129 | pkcs12 = OpenSSL::PKCS12.create('pkcs12pass', 'Leaf Cert', key_leaf, leaf, [chain2, chain]) 130 | pkcs12_chain3 = OpenSSL::PKCS12.create('pkcs12pass', 'Leaf Cert', key_leaf, leaf, [chain3]) 131 | 132 | create_cert_file('privkey.pem', key.to_pem) 133 | create_cert_file('ca.pem', ca.to_pem) 134 | create_cert_file('ca.der', ca.to_der) 135 | create_cert_file('ca2.pem', ca2.to_pem) 136 | create_cert_file('chain.pem', chain2.to_pem + chain.to_pem) 137 | create_cert_file('chain2.pem', chain3.to_pem) 138 | create_cert_file('leafkey.pem', key_leaf.to_pem) 139 | create_cert_file('leaf.pem', leaf.to_pem) 140 | create_cert_file('leafchain.pem', leaf.to_pem + chain2.to_pem + chain.to_pem) 141 | create_cert_file('leafchain2.pem', leaf.to_pem + chain3.to_pem) 142 | create_cert_file('leaf.p12', pkcs12.to_der) 143 | create_cert_file('leaf2.p12', pkcs12_chain3.to_der) 144 | end 145 | 146 | def create_cert_file(cert_name, contents) 147 | return if File.file?("spec/acceptance/certs/#{cert_name}") 148 | 149 | out_file = File.new("spec/acceptance/certs/#{cert_name}", 'w+') 150 | out_file.puts(contents) 151 | out_file.close 152 | end 153 | 154 | RSpec.configure do |c| 155 | c.before :suite do 156 | create_and_upload_certs 157 | # install java if windows 158 | if os[:family] == 'windows' 159 | LitmusHelper.instance.run_shell('puppet module install puppetlabs-chocolatey') 160 | pp_windows = <<~MANIFEST 161 | include chocolatey 162 | package { 'jre8': 163 | ensure => '8.0.371', 164 | provider => 'chocolatey', 165 | install_options => ['-y'] 166 | } 167 | MANIFEST 168 | LitmusHelper.instance.apply_manifest(pp_windows, catch_failures: true) 169 | else 170 | LitmusHelper.instance.run_shell('puppet module install puppetlabs-java') 171 | pp_linux = <<~MANIFEST 172 | class { 'java': } 173 | MANIFEST 174 | LitmusHelper.instance.apply_manifest(pp_linux) 175 | end 176 | end 177 | end 178 | 179 | RSpec.shared_context 'with common variables' do 180 | before(:each) do 181 | java_major, _java_minor = (ENV['JAVA_VERSION'] || '8u371').split('u') 182 | @ensure_ks = 'latest' 183 | @resource_path = 'undef' 184 | @target_dir = '/etc/' 185 | @temp_dir = temp_dir 186 | case os[:family] 187 | when 'solaris' 188 | @keytool_path = '/usr/java/bin/' 189 | @resource_path = "['/usr/java/bin/','/opt/puppet/bin/']" 190 | when 'aix' 191 | @keytool_path = '/usr/java6/bin/' 192 | @resource_path = "['/usr/java6/bin/','/usr/bin/']" 193 | when 'windows' 194 | @ensure_ks = 'present' 195 | @keytool_path = "C:/Program Files/Java/jre-1.#{java_major}/bin/" 196 | @resource_path = "['C:/Program Files/Java/jre-1.#{java_major}/bin/']" 197 | when 'ubuntu' 198 | @ensure_ks = 'present' if ['20.04', '22.04'].include?(os[:release]) 199 | when 'debian' 200 | @ensure_ks = 'present' if os[:release].match?(%r{^11|12}) 201 | end 202 | end 203 | end 204 | -------------------------------------------------------------------------------- /spec/spec_helper_local.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | if ENV['COVERAGE'] == 'yes' 4 | require 'simplecov' 5 | require 'simplecov-console' 6 | require 'codecov' 7 | 8 | SimpleCov.formatters = [ 9 | SimpleCov::Formatter::HTMLFormatter, 10 | SimpleCov::Formatter::Console, 11 | SimpleCov::Formatter::Codecov, 12 | ] 13 | SimpleCov.start do 14 | track_files 'lib/**/*.rb' 15 | 16 | add_filter '/spec' 17 | 18 | # do not track vendored files 19 | add_filter '/vendor' 20 | add_filter '/.vendor' 21 | 22 | # do not track gitignored files 23 | # this adds about 4 seconds to the coverage check 24 | # this could definitely be optimized 25 | add_filter do |f| 26 | # system returns true if exit status is 0, which with git-check-ignore means file is ignored 27 | system("git check-ignore --quiet #{f.filename}") 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/unit/puppet/provider/java_ks/keytool_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Puppet::Type.type(:java_ks).provider(:keytool) do 6 | let(:temp_dir) do 7 | if Puppet.features.microsoft_windows? 8 | ENV.fetch('TEMP', nil) 9 | else 10 | '/tmp/' 11 | end 12 | end 13 | 14 | let(:global_params) do 15 | { 16 | title: "app.example.com:#{temp_dir}application.jks", 17 | name: 'app.example.com', 18 | target: "#{temp_dir}application.jks", 19 | password: 'puppet', 20 | certificate: "#{temp_dir}app.example.com.pem", 21 | private_key: "#{temp_dir}private/app.example.com.pem", 22 | storetype: 'jceks', 23 | provider: described_class.name 24 | } 25 | end 26 | let(:params) do 27 | global_params 28 | end 29 | 30 | let(:resource) do 31 | Puppet::Type.type(:java_ks).new(params) 32 | end 33 | 34 | let(:provider) do 35 | resource.provider 36 | end 37 | 38 | before(:each) do 39 | allow(provider).to receive(:command).with(:keytool).and_return('mykeytool') 40 | allow(provider).to receive(:command).with(:openssl).and_return('myopenssl') 41 | 42 | allow(provider).to receive(:command_keytool).and_return('mykeytool') 43 | allow(provider).to receive(:command_openssl).and_return('myopenssl') 44 | 45 | tempfile = class_double('tempfile', class: Tempfile, 46 | write: true, 47 | flush: true, 48 | close!: true, 49 | close: true, 50 | path: "#{temp_dir}testing.stuff") 51 | allow(Tempfile).to receive(:new).and_return(tempfile) 52 | end 53 | 54 | describe 'when updating a certificate' do 55 | it 'calls destroy and create' do 56 | expect(provider).to receive(:destroy) 57 | expect(provider).to receive(:create) 58 | provider.update 59 | end 60 | end 61 | 62 | describe 'when running keystore commands', if: !Puppet.features.microsoft_windows? do 63 | it 'calls the passed command' do 64 | cmd = '/bin/echo testing 1 2 3' 65 | 66 | exec_class = if Puppet::Util::Execution.respond_to?(:execute) 67 | Puppet::Util::Execution 68 | else 69 | Puppet::Util 70 | end 71 | expect(exec_class).to receive(:execute).with(cmd, { failonfail: true, combine: true }) 72 | provider.run_command(cmd) 73 | end 74 | 75 | context 'with short timeout' do 76 | let(:params) do 77 | global_params.merge(keytool_timeout: 0.1) 78 | end 79 | 80 | it 'errors if timeout occurs' do 81 | cmd = 'sleep 1' 82 | 83 | expect { provider.run_command(cmd) }.to raise_error Puppet::Error, "Timed out waiting for 'app.example.com' to run keytool" 84 | end 85 | end 86 | 87 | it 'normally times out after 120 seconds' do 88 | cmd = '/bin/echo testing 1 2 3' 89 | allow(Timeout).to receive(:timeout).with(120, Timeout::Error).and_raise(Timeout::Error) 90 | 91 | expect { provider.run_command(cmd) }.to raise_error Puppet::Error, "Timed out waiting for 'app.example.com' to run keytool" 92 | end 93 | end 94 | 95 | describe 'when importing a private key and certifcate' do 96 | describe '#to_pkcs12' do 97 | sleep 0.1 # due to https://github.com/mitchellh/vagrant/issues/5056 98 | testing_key = OpenSSL::PKey::RSA.new 1024 99 | testing_ca = OpenSSL::X509::Certificate.new 100 | testing_ca.serial = 1 101 | testing_ca.public_key = testing_key.public_key 102 | testing_subj = '/CN=Test CA/ST=Denial/L=Springfield/O=Dis/CN=www.example.com' 103 | testing_ca.subject = OpenSSL::X509::Name.parse testing_subj 104 | testing_ca.issuer = testing_ca.subject 105 | testing_ca.not_before = Time.now 106 | testing_ca.not_after = testing_ca.not_before + 360 107 | testing_ca.sign(testing_key, OpenSSL::Digest.new('SHA256')) 108 | 109 | context 'when using the file based parameters for certificate and private_key' do 110 | # rubocop:disable RSpec/MultipleExpectations 111 | # rubocop:disable RSpec/StubbedMock 112 | it 'converts a certificate to a pkcs12 file' do 113 | allow(provider).to receive(:password).and_return(resource[:password]) 114 | allow(File).to receive(:read).with(resource[:private_key]).and_return('private key') 115 | allow(File).to receive(:read).with(resource[:certificate], hash_including(encoding: 'ISO-8859-1')).and_return(testing_ca.to_pem) 116 | expect(OpenSSL::PKey::RSA).to receive(:new).with('private key', 'puppet').and_return('priv_obj') 117 | expect(OpenSSL::X509::Certificate).to receive(:new).with(testing_ca.to_pem.chomp).and_return('cert_obj') 118 | 119 | pkcs_double = BogusPkcs.new 120 | expect(pkcs_double).to receive(:to_der) 121 | expect(OpenSSL::PKCS12).to receive(:create).with(resource[:password], resource[:name], 'priv_obj', 'cert_obj', []).and_return(pkcs_double) 122 | provider.to_pkcs12("#{temp_dir}testing.stuff") 123 | end 124 | # rubocop:enable RSpec/MultipleExpectations 125 | # rubocop:enable RSpec/StubbedMock 126 | end 127 | 128 | context 'when using content based parameters for certificate and private_key' do 129 | let(:params) do 130 | global_params.tap { |h| [:certificate, :private_key].each { |k| h.delete(k) } }.merge( 131 | private_key_content: 'private_key', 132 | certificate_content: testing_ca.to_pem, 133 | ) 134 | end 135 | 136 | # rubocop:disable RSpec/MultipleExpectations 137 | # rubocop:disable RSpec/StubbedMock 138 | it 'converts a certificate to a pkcs12 file' do 139 | allow(provider).to receive(:password).and_return(resource[:password]) 140 | allow(File).to receive(:read).with('/tmp/testing.stuff').ordered.and_return('private key') 141 | allow(File).to receive(:read).with('/tmp/testing.stuff', hash_including(encoding: 'ISO-8859-1')).ordered.and_return(testing_ca.to_pem) 142 | expect(OpenSSL::PKey::RSA).to receive(:new).with('private key', 'puppet').and_return('priv_obj') 143 | expect(OpenSSL::X509::Certificate).to receive(:new).with(testing_ca.to_pem.chomp).and_return('cert_obj') 144 | 145 | pkcs_double = BogusPkcs.new 146 | expect(pkcs_double).to receive(:to_der) 147 | expect(OpenSSL::PKCS12).to receive(:create).with(resource[:password], resource[:name], 'priv_obj', 'cert_obj', []).and_return(pkcs_double) 148 | provider.to_pkcs12("#{temp_dir}testing.stuff") 149 | end 150 | # rubocop:enable RSpec/MultipleExpectations 151 | # rubocop:enable RSpec/StubbedMock 152 | end 153 | end 154 | 155 | describe '#import_ks' do 156 | it 'executes openssl and keytool with specific options' do 157 | expect(provider).to receive(:to_pkcs12).with("#{temp_dir}testing.stuff") 158 | expect(provider).to receive(:run_command).with(['mykeytool', '-importkeystore', '-srcstoretype', 'PKCS12', '-destkeystore', 159 | resource[:target], '-srckeystore', "#{temp_dir}testing.stuff", '-alias', 160 | resource[:name], '-deststoretype', :jceks], any_args) 161 | provider.import_ks 162 | end 163 | 164 | it 'uses destkeypass when provided' do 165 | dkp = resource.dup 166 | dkp[:destkeypass] = 'keypass' 167 | expect(provider).to receive(:to_pkcs12).with("#{temp_dir}testing.stuff") 168 | expect(provider).to receive(:run_command).with(['mykeytool', '-importkeystore', '-srcstoretype', 'PKCS12', '-destkeystore', 169 | dkp[:target], '-srckeystore', "#{temp_dir}testing.stuff", '-alias', dkp[:name], 170 | '-destkeypass', dkp[:destkeypass], '-deststoretype', dkp[:storetype]], any_args) 171 | provider.import_ks 172 | end 173 | end 174 | end 175 | 176 | describe 'when importing a pkcs12 file' do 177 | let(:params) do 178 | { 179 | title: "app.example.com:#{temp_dir}testing.jks", 180 | name: 'app.example.com', 181 | target: "#{temp_dir}application.jks", 182 | password: 'puppet', 183 | certificate: "#{temp_dir}testing.p12", 184 | storetype: 'pkcs12', 185 | source_password: 'password', 186 | provider: described_class.name 187 | } 188 | end 189 | 190 | let(:resource) do 191 | Puppet::Type.type(:java_ks).new(params) 192 | end 193 | 194 | let(:provider) do 195 | resource.provider 196 | end 197 | 198 | describe '#import_pkcs12' do 199 | it 'supports pkcs12 source' do 200 | pkcs12 = resource.dup 201 | pkcs12[:storetype] = 'pkcs12' 202 | expect(provider).to receive(:run_command).with(['mykeytool', '-importkeystore', '-srcstoretype', 203 | 'PKCS12', '-destkeystore', pkcs12[:target], '-srckeystore', "#{temp_dir}testing.p12"], any_args) 204 | provider.import_pkcs12 205 | end 206 | end 207 | end 208 | 209 | describe 'when creating entries in a keystore' do 210 | let(:params) do 211 | { 212 | title: "app.example.com:#{temp_dir}application.jks", 213 | name: 'app.example.com', 214 | target: "#{temp_dir}application.jks", 215 | password: 'puppet', 216 | certificate: "#{temp_dir}app.example.com.pem", 217 | private_key: "#{temp_dir}private/app.example.com.pem", 218 | provider: described_class.name 219 | } 220 | end 221 | 222 | let(:resource) do 223 | Puppet::Type.type(:java_ks).new(params) 224 | end 225 | 226 | let(:provider) do 227 | resource.provider 228 | end 229 | 230 | it 'calls import_ks if private_key and certificate are provided' do 231 | expect(provider).to receive(:import_ks) 232 | provider.create 233 | end 234 | 235 | it 'calls keytool with specific options if only certificate is provided' do 236 | no_pk = resource.dup 237 | no_pk.delete(:private_key) 238 | expect(provider).to receive(:run_command).with(['mykeytool', '-importcert', '-noprompt', '-alias', no_pk[:name], '-file', no_pk[:certificate], '-keystore', no_pk[:target]], any_args) 239 | expect(no_pk.provider).not_to receive(:import_ks) 240 | no_pk.provider.create 241 | end 242 | end 243 | 244 | describe 'when removing entries from keytool' do 245 | it 'executes keytool with a specific set of options' do 246 | expect(provider).to receive(:run_command).with(['mykeytool', '-delete', '-alias', resource[:name], '-keystore', resource[:target], '-storetype', resource[:storetype]], any_args) 247 | provider.destroy 248 | end 249 | end 250 | end 251 | 252 | # rubocop:disable Lint/EmptyClass 253 | class BogusPkcs 254 | end 255 | # rubocop:enable Lint/EmptyClass 256 | -------------------------------------------------------------------------------- /spec/unit/puppet/type/java_ks_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe Puppet::Type.type(:java_ks) do 6 | let(:temp_dir) do 7 | if Puppet.features.microsoft_windows? 8 | ENV.fetch('TEMP', nil) 9 | else 10 | '/tmp/' 11 | end 12 | end 13 | let(:provider_var) { class_double('provider', class: described_class.defaultprovider, clear: nil) } 14 | let(:app_example_com) do 15 | { 16 | title: "app.example.com:#{temp_dir}application.jks", 17 | name: 'app.example.com', 18 | target: "#{temp_dir}application.jks", 19 | password: 'puppet', 20 | destkeypass: 'keypass', 21 | certificate: "#{temp_dir}app.example.com.pem", 22 | private_key: "#{temp_dir}private/app.example.com.pem", 23 | private_key_type: 'rsa', 24 | storetype: 'jceks', 25 | provider: :keytool 26 | } 27 | end 28 | let(:jks_resource) do 29 | app_example_com 30 | end 31 | 32 | before(:each) do 33 | allow(described_class.defaultprovider).to receive(:new).and_return(provider_var) 34 | end 35 | 36 | it 'defaults to being present' do 37 | expect(described_class.new(app_example_com)[:ensure]).to eq(:present) 38 | end 39 | 40 | describe 'when validating attributes' do 41 | [:name, :target, :private_key, :private_key_type, :certificate, :password_file, :trustcacerts, :destkeypass, :password_fail_reset, :source_password].each do |param| 42 | it "has a #{param} parameter" do 43 | expect(described_class.attrtype(param)).to eq(:param) 44 | end 45 | end 46 | 47 | [:ensure, :password].each do |prop| 48 | it "has a #{prop} property" do 49 | expect(described_class.attrtype(prop)).to eq(:property) 50 | end 51 | end 52 | end 53 | 54 | describe 'when validating attribute values' do 55 | [:present, :absent, :latest].each do |value| 56 | it "supports #{value} as a value to ensure" do 57 | described_class.new(jks_resource.merge(ensure: value)) 58 | end 59 | end 60 | 61 | it 'first half of title should map to name parameter' do 62 | jks = jks_resource.dup 63 | jks.delete(:name) 64 | expect(described_class.new(jks)[:name]).to eq(jks_resource[:name]) 65 | end 66 | 67 | it 'second half of title should map to target parameter when no target is supplied' do 68 | jks = jks_resource.dup 69 | jks.delete(:target) 70 | expect(described_class.new(jks)[:target]).to eq(jks_resource[:target]) 71 | end 72 | 73 | it 'second half of title should not map to target parameter when target is supplied #not to equal' do 74 | jks = jks_resource.dup 75 | jks[:target] = "#{temp_dir}some_other_app.jks" 76 | expect(described_class.new(jks)[:target]).not_to eq(jks_resource[:target]) 77 | end 78 | 79 | it 'second half of title should not map to target parameter when target is supplied #to equal' do 80 | jks = jks_resource.dup 81 | jks[:target] = "#{temp_dir}some_other_app.jks" 82 | expect(described_class.new(jks)[:target]).to eq("#{temp_dir}some_other_app.jks") 83 | end 84 | 85 | it 'title components should map to namevar parameters #name' do 86 | jks = jks_resource.dup 87 | jks.delete(:name) 88 | jks.delete(:target) 89 | expect(described_class.new(jks)[:name]).to eq(jks_resource[:name]) 90 | end 91 | 92 | it 'title components should map to namevar parameters #target' do 93 | jks = jks_resource.dup 94 | jks.delete(:name) 95 | jks.delete(:target) 96 | expect(described_class.new(jks)[:target]).to eq(jks_resource[:target]) 97 | end 98 | 99 | it 'downcases :name values' do 100 | jks = jks_resource.dup 101 | jks[:name] = 'APP.EXAMPLE.COM' 102 | expect(described_class.new(jks)[:name]).to eq(jks_resource[:name]) 103 | end 104 | 105 | it 'resource[:trustcacerts] is falsey when parameter not provided' do 106 | expect(described_class.new(jks_resource)[:trustcacerts]).to be_falsey 107 | end 108 | 109 | it 'resource[:trustcacerts] is the boolean `false` when set to `false`' do 110 | jks = jks_resource.dup 111 | jks[:trustcacerts] = false 112 | 113 | expect(described_class.new(jks)[:trustcacerts]).to be false 114 | end 115 | 116 | it 'resource[:trustcacerts] is the boolean `true` when set to `true`' do 117 | jks = jks_resource.dup 118 | jks[:trustcacerts] = true 119 | 120 | expect(described_class.new(jks)[:trustcacerts]).to be true 121 | end 122 | 123 | it 'has :rsa as the default value for :private_key_type' do 124 | expect(described_class.new(jks_resource)[:private_key_type]).to eq(:rsa) 125 | end 126 | 127 | it 'fails if :private_key_type is neither :rsa nor :ec nor :dsa' do 128 | jks = jks_resource.dup 129 | jks[:private_key_type] = 'nosuchkeytype' 130 | 131 | expect { 132 | described_class.new(jks) 133 | }.to raise_error(Puppet::Error) 134 | end 135 | 136 | it 'fails if both :certificate and :certificate_content are provided' do 137 | jks = jks_resource.dup 138 | jks[:certificate_content] = 'certificate_content' 139 | expect { 140 | described_class.new(jks) 141 | }.to raise_error(Puppet::Error, %r{You must pass either}) 142 | end 143 | 144 | it 'fails if neither :certificate or :certificate_content is provided' do 145 | jks = jks_resource.dup 146 | jks.delete(:certificate) 147 | expect { 148 | described_class.new(jks) 149 | }.to raise_error(Puppet::Error, %r{You must pass one of}) 150 | end 151 | 152 | it 'fails if both :private_key and :private_key_content are provided' do 153 | jks = jks_resource.dup 154 | jks[:private_key_content] = 'private_content' 155 | expect { 156 | described_class.new(jks) 157 | }.to raise_error(Puppet::Error, %r{You must pass either}) 158 | end 159 | 160 | it 'fails if both :password and :password_file are provided' do 161 | jks = jks_resource.dup 162 | jks[:password_file] = '/path/to/password_file' 163 | expect { 164 | described_class.new(jks) 165 | }.to raise_error(Puppet::Error, %r{You must pass either}) 166 | end 167 | 168 | it 'fails if neither :password or :password_file is provided' do 169 | jks = jks_resource.dup 170 | jks.delete(:password) 171 | expect { 172 | described_class.new(jks) 173 | }.to raise_error(Puppet::Error, %r{You must pass one of}) 174 | end 175 | 176 | it 'fails if :password is fewer than 6 characters' do 177 | jks = jks_resource.dup 178 | jks[:password] = 'aoeui' 179 | expect { 180 | described_class.new(jks) 181 | }.to raise_error(Puppet::Error, %r{6 characters}) 182 | end 183 | 184 | it 'fails if :destkeypass is fewer than 6 characters' do 185 | jks = jks_resource.dup 186 | jks[:destkeypass] = 'aoeui' 187 | expect { 188 | described_class.new(jks) 189 | }.to raise_error(Puppet::Error, %r{length 6}) 190 | end 191 | 192 | it 'resource[:password_fail_reset] is falsey when parameter not provided' do 193 | expect(described_class.new(jks_resource)[:password_fail_reset]).to be_falsey 194 | end 195 | 196 | it 'resource[:password_fail_reset] is the boolean `false` when parameter set to `false`' do 197 | jks = jks_resource.dup 198 | jks[:password_fail_reset] = false 199 | 200 | expect(described_class.new(jks)[:password_fail_reset]).to be false 201 | end 202 | 203 | it 'resource[:password_fail_reset] is the boolean `true` when parameter set to `true`' do 204 | jks = jks_resource.dup 205 | jks[:password_fail_reset] = true 206 | 207 | expect(described_class.new(jks)[:password_fail_reset]).to be true 208 | end 209 | 210 | it 'fails if :source_password is not provided for pkcs12 :storetype' do 211 | jks = jks_resource.dup 212 | jks[:storetype] = 'pkcs12' 213 | expect { 214 | described_class.new(jks) 215 | }.to raise_error(Puppet::Error, %r{You must provide 'source_password' when using a 'pkcs12' storetype}) 216 | end 217 | end 218 | 219 | describe 'when ensure is set to latest' do 220 | it 'insync? should return false if sha1 fingerprints do not match and state is :present' do 221 | jks = jks_resource.dup 222 | jks[:ensure] = :latest 223 | allow(provider_var).to receive(:latest).and_return('9B:8B:23:4C:6A:9A:08:F6:4E:B6:01:23:EA:5A:E7:8F:6A') 224 | allow(provider_var).to receive(:current).and_return('21:46:45:65:57:50:FE:2D:DA:7C:C8:57:D2:33:3A:B0:A6') 225 | expect(described_class.new(jks).property(:ensure)).not_to be_insync(:present) 226 | end 227 | 228 | it 'insync? should return false if state is :absent' do 229 | jks = jks_resource.dup 230 | jks[:ensure] = :latest 231 | expect(described_class.new(jks).property(:ensure)).not_to be_insync(:absent) 232 | end 233 | 234 | it 'insync? should return true if sha1 fingerprints match and state is :present' do 235 | jks = jks_resource.dup 236 | jks[:ensure] = :latest 237 | allow(provider_var).to receive(:latest).and_return('66:9B:8B:23:4C:6A:9A:08:F6:4E:B6:01:23:EA:5A') 238 | allow(provider_var).to receive(:current).and_return('66:9B:8B:23:4C:6A:9A:08:F6:4E:B6:01:23:EA:5A') 239 | expect(described_class.new(jks).property(:ensure)).to be_insync(:present) 240 | end 241 | 242 | it 'insync? should return true if subset of sha1 fingerprints match and state is :present' do 243 | jks = jks_resource.dup 244 | jks[:ensure] = :latest 245 | allow(provider_var).to receive(:current).and_return('9B:8B:23:4C:6A:9A:08:F6:4E:B6:01:23:EA:5A:E7:8F:6A/66:9B:8B:23:4C:6A:9A:08:F6:4E:B6:01:23:EA:5A') 246 | allow(provider_var).to receive(:latest).and_return('66:9B:8B:23:4C:6A:9A:08:F6:4E:B6:01:23:EA:5A') 247 | expect(described_class.new(jks).property(:ensure)).to be_insync(:present) 248 | end 249 | end 250 | 251 | describe 'when file resources are in the catalog' do 252 | let(:file_provider) { class_double('provider', class: Puppet::Type.type(:file).defaultprovider, clear: nil) } 253 | 254 | before(:each) do 255 | allow(Puppet::Type.type(:file).defaultprovider).to receive(:new).and_return(file_provider) 256 | end 257 | 258 | [:private_key, :certificate].each do |file| 259 | it "autorequires for #{file} #file" do 260 | test_jks = described_class.new(jks_resource) 261 | test_file = Puppet::Type.type(:file).new(title: jks_resource[file]) 262 | 263 | Puppet::Resource::Catalog.new :testing do |conf| 264 | [test_jks, test_file].each { |resource| conf.add_resource resource } 265 | end 266 | 267 | rel = test_jks.autorequire[0] 268 | expect(rel.source.ref).to eq(test_file.ref) 269 | end 270 | 271 | it "autorequires for #{file} #jks" do 272 | test_jks = described_class.new(jks_resource) 273 | test_file = Puppet::Type.type(:file).new(title: jks_resource[file]) 274 | 275 | Puppet::Resource::Catalog.new :testing do |conf| 276 | [test_jks, test_file].each { |resource| conf.add_resource resource } 277 | end 278 | 279 | rel = test_jks.autorequire[0] 280 | expect(rel.target.ref).to eq(test_jks.ref) 281 | end 282 | end 283 | 284 | it 'autorequires for the :target directory #file' do 285 | test_jks = described_class.new(jks_resource) 286 | test_file = Puppet::Type.type(:file).new(title: File.dirname(jks_resource[:target])) 287 | 288 | Puppet::Resource::Catalog.new :testing do |conf| 289 | [test_jks, test_file].each { |resource| conf.add_resource resource } 290 | end 291 | 292 | rel = test_jks.autorequire[0] 293 | expect(rel.source.ref).to eq(test_file.ref) 294 | end 295 | 296 | it 'autorequires for the :target directory #jks' do 297 | test_jks = described_class.new(jks_resource) 298 | test_file = Puppet::Type.type(:file).new(title: File.dirname(jks_resource[:target])) 299 | 300 | Puppet::Resource::Catalog.new :testing do |conf| 301 | [test_jks, test_file].each { |resource| conf.add_resource resource } 302 | end 303 | 304 | rel = test_jks.autorequire[0] 305 | expect(rel.target.ref).to eq(test_jks.ref) 306 | end 307 | end 308 | end 309 | --------------------------------------------------------------------------------