From 64ab3ee55d5f6a8af854d371301dac823800151f Mon Sep 17 00:00:00 2001
From: Fabien COMBERNOUS <fabien.combernous@adullact.org>
Date: Thu, 3 Nov 2022 09:54:54 +0100
Subject: [PATCH] initial commit

---
 .devcontainer/Dockerfile        |   6 +
 .devcontainer/README.md         |  38 +++
 .devcontainer/devcontainer.json |  17 ++
 .fixtures.yml                   |  10 +
 .gitattributes                  |   5 +
 .gitignore                      |  28 ++
 .gitlab-ci.yml                  |  53 ++++
 .pdkignore                      |  47 +++
 .puppet-lint.rc                 |   1 +
 .rspec                          |   2 +
 .rubocop.yml                    | 519 ++++++++++++++++++++++++++++++++
 .sync.yml                       |   1 +
 .travis.yml                     |  45 +++
 .vscode/extensions.json         |   6 +
 .yardopts                       |   1 +
 CHANGELOG.md                    |  11 +
 Gemfile                         |  63 ++++
 README.md                       | 143 +++++----
 Rakefile                        |  89 ++++++
 appveyor.yml                    |  49 +++
 data/common.yaml                |   1 +
 hiera.yaml                      |  21 ++
 manifests/ca/root.pp            |  28 ++
 manifests/goose.pp              |  23 ++
 manifests/init.pp               | 168 +++++++++++
 metadata.json                   |  34 +++
 spec/classes/ca/root_spec.rb    |  17 ++
 spec/classes/cfssl_spec.rb      |  17 ++
 spec/classes/goose_spec.rb      |  17 ++
 spec/default_facts.yml          |   8 +
 spec/spec_helper.rb             |  73 +++++
 templates/cfssl.service.epp     |  16 +
 templates/db-config.json.epp    |   4 +
 templates/goose-dbconf.yml.epp  |   3 +
 types/authkey.pp                |   4 +
 types/ca/key.pp                 |   4 +
 types/serveconfig.pp            |   7 +
 types/serveconfig.pp.save       |   7 +
 types/serveconfig.pp.works      |   5 +
 types/signing/profile.pp        |  10 +
 types/usage.pp                  |  25 ++
 41 files changed, 1567 insertions(+), 59 deletions(-)
 create mode 100644 .devcontainer/Dockerfile
 create mode 100644 .devcontainer/README.md
 create mode 100644 .devcontainer/devcontainer.json
 create mode 100644 .fixtures.yml
 create mode 100644 .gitattributes
 create mode 100644 .gitignore
 create mode 100644 .gitlab-ci.yml
 create mode 100644 .pdkignore
 create mode 100644 .puppet-lint.rc
 create mode 100644 .rspec
 create mode 100644 .rubocop.yml
 create mode 100644 .sync.yml
 create mode 100644 .travis.yml
 create mode 100644 .vscode/extensions.json
 create mode 100644 .yardopts
 create mode 100644 CHANGELOG.md
 create mode 100644 Gemfile
 create mode 100644 Rakefile
 create mode 100644 appveyor.yml
 create mode 100644 data/common.yaml
 create mode 100644 hiera.yaml
 create mode 100644 manifests/ca/root.pp
 create mode 100644 manifests/goose.pp
 create mode 100644 manifests/init.pp
 create mode 100644 metadata.json
 create mode 100644 spec/classes/ca/root_spec.rb
 create mode 100644 spec/classes/cfssl_spec.rb
 create mode 100644 spec/classes/goose_spec.rb
 create mode 100644 spec/default_facts.yml
 create mode 100644 spec/spec_helper.rb
 create mode 100644 templates/cfssl.service.epp
 create mode 100644 templates/db-config.json.epp
 create mode 100644 templates/goose-dbconf.yml.epp
 create mode 100644 types/authkey.pp
 create mode 100644 types/ca/key.pp
 create mode 100644 types/serveconfig.pp
 create mode 100644 types/serveconfig.pp.save
 create mode 100644 types/serveconfig.pp.works
 create mode 100644 types/signing/profile.pp
 create mode 100644 types/usage.pp

diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 0000000..12ed4ff
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,6 @@
+FROM puppet/pdk:latest
+
+# [Optional] Uncomment this section to install additional packages.
+# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
+#     && apt-get -y install --no-install-recommends <your-package-list-here>
+
diff --git a/.devcontainer/README.md b/.devcontainer/README.md
new file mode 100644
index 0000000..a719361
--- /dev/null
+++ b/.devcontainer/README.md
@@ -0,0 +1,38 @@
+# devcontainer
+
+
+For format details, see https://aka.ms/devcontainer.json. 
+
+For config options, see the README at:
+https://github.com/microsoft/vscode-dev-containers/tree/v0.140.1/containers/puppet
+ 
+``` json
+{
+	"name": "Puppet Development Kit (Community)",
+	"dockerFile": "Dockerfile",
+
+	// Set *default* container specific settings.json values on container create.
+	"settings": {
+		"terminal.integrated.profiles.linux": {
+			"bash": {
+				"path": "bash",
+			}
+		}
+	},
+
+	// Add the IDs of extensions you want installed when the container is created.
+	"extensions": [
+		"puppet.puppet-vscode",
+		"rebornix.Ruby"
+	],
+
+	// Use 'forwardPorts' to make a list of ports inside the container available locally.
+	"forwardPorts": [],
+
+	// Use 'postCreateCommand' to run commands after the container is created.
+	"postCreateCommand": "pdk --version",
+}
+```
+
+
+
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..fe7a8b1
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,17 @@
+{
+	"name": "Puppet Development Kit (Community)",
+	"dockerFile": "Dockerfile",
+
+	"settings": {
+		"terminal.integrated.profiles.linux": {
+			"bash": {
+				"path": "bash",
+			}
+		}
+	},
+
+	"extensions": [
+		"puppet.puppet-vscode",
+		"rebornix.Ruby"
+	]
+}
diff --git a/.fixtures.yml b/.fixtures.yml
new file mode 100644
index 0000000..264a154
--- /dev/null
+++ b/.fixtures.yml
@@ -0,0 +1,10 @@
+# This file can be used to install module dependencies for unit testing
+# See https://github.com/puppetlabs/puppetlabs_spec_helper#using-fixtures for details
+---
+fixtures:
+  repositories:
+    stdlib: https://github.com/puppetlabs/puppetlabs-stdlib.git
+    vcsrepo: https://github.com/puppetlabs/puppetlabs-vcsrepo.git
+    concat: https://github.com/puppetlabs/puppetlabs-concat.git
+    postgresql: https://github.com/puppetlabs/puppetlabs-postgresql.git
+    archive: https://github.com/voxpupuli/puppet-archive.git
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..9032a01
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,5 @@
+*.rb eol=lf
+*.erb eol=lf
+*.pp eol=lf
+*.sh eol=lf
+*.epp eol=lf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..988dcbb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,28 @@
+.git/
+.*.sw[op]
+.metadata
+.yardoc
+.yardwarns
+*.iml
+/.bundle/
+/.idea/
+/.vagrant/
+/coverage/
+/bin/
+/doc/
+/Gemfile.local
+/Gemfile.lock
+/junit/
+/log/
+/pkg/
+/spec/fixtures/manifests/
+/spec/fixtures/modules/
+/tmp/
+/vendor/
+/convert_report.txt
+/update_report.txt
+.DS_Store
+.project
+.envrc
+/inventory.yaml
+/spec/fixtures/litmus_inventory.yaml
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..6d5e786
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,53 @@
+---
+stages:
+  - syntax
+  - unit
+
+default:
+  cache:
+    paths:
+      - vendor/bundle
+
+  before_script: &before_script
+    - bundle -v
+    - rm Gemfile.lock || true
+    - "# Update system gems if requested. This is useful to temporarily workaround troubles in the test runner"
+    - "# Set `rubygems_version` in the .sync.yml to set a value"
+    - "# Ignore exit code of SIGPIPE'd yes to not fail with shell's pipefail set"
+    - '[ -z "$RUBYGEMS_VERSION" ] || (yes || true) | gem update --system $RUBYGEMS_VERSION'
+    - gem --version
+    - bundle -v
+    - bundle install --without system_tests --path vendor/bundle --jobs $(nproc)
+
+validate lint check rubocop-Ruby 2.5.7-Puppet ~> 6:
+  stage: syntax
+  image: ruby:2.5.7
+  script:
+    - bundle exec rake validate lint check rubocop
+  variables:
+    PUPPET_GEM_VERSION: '~> 6'
+
+parallel_spec-Ruby 2.5.7-Puppet ~> 6:
+  stage: unit
+  image: ruby:2.5.7
+  script:
+    - bundle exec rake parallel_spec
+  variables:
+    PUPPET_GEM_VERSION: '~> 6'
+
+validate lint check rubocop-Ruby 2.7.2-Puppet ~> 7:
+  stage: syntax
+  image: ruby:2.7.2
+  script:
+    - bundle exec rake validate lint check rubocop
+  variables:
+    PUPPET_GEM_VERSION: '~> 7'
+
+parallel_spec-Ruby 2.7.2-Puppet ~> 7:
+  stage: unit
+  image: ruby:2.7.2
+  script:
+    - bundle exec rake parallel_spec
+  variables:
+    PUPPET_GEM_VERSION: '~> 7'
+
diff --git a/.pdkignore b/.pdkignore
new file mode 100644
index 0000000..c538bea
--- /dev/null
+++ b/.pdkignore
@@ -0,0 +1,47 @@
+.git/
+.*.sw[op]
+.metadata
+.yardoc
+.yardwarns
+*.iml
+/.bundle/
+/.idea/
+/.vagrant/
+/coverage/
+/bin/
+/doc/
+/Gemfile.local
+/Gemfile.lock
+/junit/
+/log/
+/pkg/
+/spec/fixtures/manifests/
+/spec/fixtures/modules/
+/tmp/
+/vendor/
+/convert_report.txt
+/update_report.txt
+.DS_Store
+.project
+.envrc
+/inventory.yaml
+/spec/fixtures/litmus_inventory.yaml
+/appveyor.yml
+/.editorconfig
+/.fixtures.yml
+/Gemfile
+/.gitattributes
+/.gitignore
+/.gitlab-ci.yml
+/.pdkignore
+/.puppet-lint.rc
+/Rakefile
+/rakelib/
+/.rspec
+/.rubocop.yml
+/.travis.yml
+/.yardopts
+/spec/
+/.vscode/
+/.sync.yml
+/.devcontainer/
diff --git a/.puppet-lint.rc b/.puppet-lint.rc
new file mode 100644
index 0000000..cc96ece
--- /dev/null
+++ b/.puppet-lint.rc
@@ -0,0 +1 @@
+--relative
diff --git a/.rspec b/.rspec
new file mode 100644
index 0000000..16f9cdb
--- /dev/null
+++ b/.rspec
@@ -0,0 +1,2 @@
+--color
+--format documentation
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 0000000..31e8248
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,519 @@
+---
+require:
+- rubocop-performance
+- rubocop-rspec
+AllCops:
+  DisplayCopNames: true
+  TargetRubyVersion: '2.5'
+  Include:
+  - "**/*.rb"
+  Exclude:
+  - bin/*
+  - ".vendor/**/*"
+  - "**/Gemfile"
+  - "**/Rakefile"
+  - pkg/**/*
+  - spec/fixtures/**/*
+  - vendor/**/*
+  - "**/Puppetfile"
+  - "**/Vagrantfile"
+  - "**/Guardfile"
+Layout/LineLength:
+  Description: People have wide screens, use them.
+  Max: 200
+RSpec/BeforeAfterAll:
+  Description: Beware of using after(:all) as it may cause state to leak between tests.
+    A necessary evil in acceptance testing.
+  Exclude:
+  - spec/acceptance/**/*.rb
+RSpec/HookArgument:
+  Description: Prefer explicit :each argument, matching existing module's style
+  EnforcedStyle: each
+RSpec/DescribeSymbol:
+  Exclude:
+  - spec/unit/facter/**/*.rb
+Style/BlockDelimiters:
+  Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to
+    be consistent then.
+  EnforcedStyle: braces_for_chaining
+Style/ClassAndModuleChildren:
+  Description: Compact style reduces the required amount of indentation.
+  EnforcedStyle: compact
+Style/EmptyElse:
+  Description: Enforce against empty else clauses, but allow `nil` for clarity.
+  EnforcedStyle: empty
+Style/FormatString:
+  Description: Following the main puppet project's style, prefer the % format format.
+  EnforcedStyle: percent
+Style/FormatStringToken:
+  Description: Following the main puppet project's style, prefer the simpler template
+    tokens over annotated ones.
+  EnforcedStyle: template
+Style/Lambda:
+  Description: Prefer the keyword for easier discoverability.
+  EnforcedStyle: literal
+Style/RegexpLiteral:
+  Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168
+  EnforcedStyle: percent_r
+Style/TernaryParentheses:
+  Description: Checks for use of parentheses around ternary conditions. Enforce parentheses
+    on complex expressions for better readability, but seriously consider breaking
+    it up.
+  EnforcedStyle: require_parentheses_when_complex
+Style/TrailingCommaInArguments:
+  Description: Prefer always trailing comma on multiline argument lists. This makes
+    diffs, and re-ordering nicer.
+  EnforcedStyleForMultiline: comma
+Style/TrailingCommaInArrayLiteral:
+  Description: Prefer always trailing comma on multiline literals. This makes diffs,
+    and re-ordering nicer.
+  EnforcedStyleForMultiline: comma
+Style/SymbolArray:
+  Description: Using percent style obscures symbolic intent of array's contents.
+  EnforcedStyle: brackets
+RSpec/MessageSpies:
+  EnforcedStyle: receive
+Style/Documentation:
+  Exclude:
+  - lib/puppet/parser/functions/**/*
+  - spec/**/*
+Style/WordArray:
+  EnforcedStyle: brackets
+Performance/AncestorsInclude:
+  Enabled: true
+Performance/BigDecimalWithNumericArgument:
+  Enabled: true
+Performance/BlockGivenWithExplicitBlock:
+  Enabled: true
+Performance/CaseWhenSplat:
+  Enabled: true
+Performance/ConstantRegexp:
+  Enabled: true
+Performance/MethodObjectAsBlock:
+  Enabled: true
+Performance/RedundantSortBlock:
+  Enabled: true
+Performance/RedundantStringChars:
+  Enabled: true
+Performance/ReverseFirst:
+  Enabled: true
+Performance/SortReverse:
+  Enabled: true
+Performance/Squeeze:
+  Enabled: true
+Performance/StringInclude:
+  Enabled: true
+Performance/Sum:
+  Enabled: true
+Style/CollectionMethods:
+  Enabled: true
+Style/MethodCalledOnDoEndBlock:
+  Enabled: true
+Style/StringMethods:
+  Enabled: true
+Bundler/InsecureProtocolSource:
+  Enabled: false
+Gemspec/DuplicatedAssignment:
+  Enabled: false
+Gemspec/OrderedDependencies:
+  Enabled: false
+Gemspec/RequiredRubyVersion:
+  Enabled: false
+Gemspec/RubyVersionGlobalsUsage:
+  Enabled: false
+Layout/ArgumentAlignment:
+  Enabled: false
+Layout/BeginEndAlignment:
+  Enabled: false
+Layout/ClosingHeredocIndentation:
+  Enabled: false
+Layout/EmptyComment:
+  Enabled: false
+Layout/EmptyLineAfterGuardClause:
+  Enabled: false
+Layout/EmptyLinesAroundArguments:
+  Enabled: false
+Layout/EmptyLinesAroundAttributeAccessor:
+  Enabled: false
+Layout/EndOfLine:
+  Enabled: false
+Layout/FirstArgumentIndentation:
+  Enabled: false
+Layout/HashAlignment:
+  Enabled: false
+Layout/HeredocIndentation:
+  Enabled: false
+Layout/LeadingEmptyLines:
+  Enabled: false
+Layout/SpaceAroundMethodCallOperator:
+  Enabled: false
+Layout/SpaceInsideArrayLiteralBrackets:
+  Enabled: false
+Layout/SpaceInsideReferenceBrackets:
+  Enabled: false
+Lint/BigDecimalNew:
+  Enabled: false
+Lint/BooleanSymbol:
+  Enabled: false
+Lint/ConstantDefinitionInBlock:
+  Enabled: false
+Lint/DeprecatedOpenSSLConstant:
+  Enabled: false
+Lint/DisjunctiveAssignmentInConstructor:
+  Enabled: false
+Lint/DuplicateElsifCondition:
+  Enabled: false
+Lint/DuplicateRequire:
+  Enabled: false
+Lint/DuplicateRescueException:
+  Enabled: false
+Lint/EmptyConditionalBody:
+  Enabled: false
+Lint/EmptyFile:
+  Enabled: false
+Lint/ErbNewArguments:
+  Enabled: false
+Lint/FloatComparison:
+  Enabled: false
+Lint/HashCompareByIdentity:
+  Enabled: false
+Lint/IdentityComparison:
+  Enabled: false
+Lint/InterpolationCheck:
+  Enabled: false
+Lint/MissingCopEnableDirective:
+  Enabled: false
+Lint/MixedRegexpCaptureTypes:
+  Enabled: false
+Lint/NestedPercentLiteral:
+  Enabled: false
+Lint/NonDeterministicRequireOrder:
+  Enabled: false
+Lint/OrderedMagicComments:
+  Enabled: false
+Lint/OutOfRangeRegexpRef:
+  Enabled: false
+Lint/RaiseException:
+  Enabled: false
+Lint/RedundantCopEnableDirective:
+  Enabled: false
+Lint/RedundantRequireStatement:
+  Enabled: false
+Lint/RedundantSafeNavigation:
+  Enabled: false
+Lint/RedundantWithIndex:
+  Enabled: false
+Lint/RedundantWithObject:
+  Enabled: false
+Lint/RegexpAsCondition:
+  Enabled: false
+Lint/ReturnInVoidContext:
+  Enabled: false
+Lint/SafeNavigationConsistency:
+  Enabled: false
+Lint/SafeNavigationWithEmpty:
+  Enabled: false
+Lint/SelfAssignment:
+  Enabled: false
+Lint/SendWithMixinArgument:
+  Enabled: false
+Lint/ShadowedArgument:
+  Enabled: false
+Lint/StructNewOverride:
+  Enabled: false
+Lint/ToJSON:
+  Enabled: false
+Lint/TopLevelReturnWithArgument:
+  Enabled: false
+Lint/TrailingCommaInAttributeDeclaration:
+  Enabled: false
+Lint/UnreachableLoop:
+  Enabled: false
+Lint/UriEscapeUnescape:
+  Enabled: false
+Lint/UriRegexp:
+  Enabled: false
+Lint/UselessMethodDefinition:
+  Enabled: false
+Lint/UselessTimes:
+  Enabled: false
+Metrics/AbcSize:
+  Enabled: false
+Metrics/BlockLength:
+  Enabled: false
+Metrics/BlockNesting:
+  Enabled: false
+Metrics/ClassLength:
+  Enabled: false
+Metrics/CyclomaticComplexity:
+  Enabled: false
+Metrics/MethodLength:
+  Enabled: false
+Metrics/ModuleLength:
+  Enabled: false
+Metrics/ParameterLists:
+  Enabled: false
+Metrics/PerceivedComplexity:
+  Enabled: false
+Migration/DepartmentName:
+  Enabled: false
+Naming/AccessorMethodName:
+  Enabled: false
+Naming/BlockParameterName:
+  Enabled: false
+Naming/HeredocDelimiterCase:
+  Enabled: false
+Naming/HeredocDelimiterNaming:
+  Enabled: false
+Naming/MemoizedInstanceVariableName:
+  Enabled: false
+Naming/MethodParameterName:
+  Enabled: false
+Naming/RescuedExceptionsVariableName:
+  Enabled: false
+Naming/VariableNumber:
+  Enabled: false
+Performance/BindCall:
+  Enabled: false
+Performance/DeletePrefix:
+  Enabled: false
+Performance/DeleteSuffix:
+  Enabled: false
+Performance/InefficientHashSearch:
+  Enabled: false
+Performance/UnfreezeString:
+  Enabled: false
+Performance/UriDefaultParser:
+  Enabled: false
+RSpec/Be:
+  Enabled: false
+RSpec/Capybara/CurrentPathExpectation:
+  Enabled: false
+RSpec/Capybara/FeatureMethods:
+  Enabled: false
+RSpec/Capybara/VisibilityMatcher:
+  Enabled: false
+RSpec/ContextMethod:
+  Enabled: false
+RSpec/ContextWording:
+  Enabled: false
+RSpec/DescribeClass:
+  Enabled: false
+RSpec/EmptyHook:
+  Enabled: false
+RSpec/EmptyLineAfterExample:
+  Enabled: false
+RSpec/EmptyLineAfterExampleGroup:
+  Enabled: false
+RSpec/EmptyLineAfterHook:
+  Enabled: false
+RSpec/ExampleLength:
+  Enabled: false
+RSpec/ExampleWithoutDescription:
+  Enabled: false
+RSpec/ExpectChange:
+  Enabled: false
+RSpec/ExpectInHook:
+  Enabled: false
+RSpec/FactoryBot/AttributeDefinedStatically:
+  Enabled: false
+RSpec/FactoryBot/CreateList:
+  Enabled: false
+RSpec/FactoryBot/FactoryClassName:
+  Enabled: false
+RSpec/HooksBeforeExamples:
+  Enabled: false
+RSpec/ImplicitBlockExpectation:
+  Enabled: false
+RSpec/ImplicitSubject:
+  Enabled: false
+RSpec/LeakyConstantDeclaration:
+  Enabled: false
+RSpec/LetBeforeExamples:
+  Enabled: false
+RSpec/MissingExampleGroupArgument:
+  Enabled: false
+RSpec/MultipleExpectations:
+  Enabled: false
+RSpec/MultipleMemoizedHelpers:
+  Enabled: false
+RSpec/MultipleSubjects:
+  Enabled: false
+RSpec/NestedGroups:
+  Enabled: false
+RSpec/PredicateMatcher:
+  Enabled: false
+RSpec/ReceiveCounts:
+  Enabled: false
+RSpec/ReceiveNever:
+  Enabled: false
+RSpec/RepeatedExampleGroupBody:
+  Enabled: false
+RSpec/RepeatedExampleGroupDescription:
+  Enabled: false
+RSpec/RepeatedIncludeExample:
+  Enabled: false
+RSpec/ReturnFromStub:
+  Enabled: false
+RSpec/SharedExamples:
+  Enabled: false
+RSpec/StubbedMock:
+  Enabled: false
+RSpec/UnspecifiedException:
+  Enabled: false
+RSpec/VariableDefinition:
+  Enabled: false
+RSpec/VoidExpect:
+  Enabled: false
+RSpec/Yield:
+  Enabled: false
+Security/Open:
+  Enabled: false
+Style/AccessModifierDeclarations:
+  Enabled: false
+Style/AccessorGrouping:
+  Enabled: false
+Style/AsciiComments:
+  Enabled: false
+Style/BisectedAttrAccessor:
+  Enabled: false
+Style/CaseLikeIf:
+  Enabled: false
+Style/ClassEqualityComparison:
+  Enabled: false
+Style/ColonMethodDefinition:
+  Enabled: false
+Style/CombinableLoops:
+  Enabled: false
+Style/CommentedKeyword:
+  Enabled: false
+Style/Dir:
+  Enabled: false
+Style/DoubleCopDisableDirective:
+  Enabled: false
+Style/EmptyBlockParameter:
+  Enabled: false
+Style/EmptyLambdaParameter:
+  Enabled: false
+Style/Encoding:
+  Enabled: false
+Style/EvalWithLocation:
+  Enabled: false
+Style/ExpandPathArguments:
+  Enabled: false
+Style/ExplicitBlockArgument:
+  Enabled: false
+Style/ExponentialNotation:
+  Enabled: false
+Style/FloatDivision:
+  Enabled: false
+Style/FrozenStringLiteralComment:
+  Enabled: false
+Style/GlobalStdStream:
+  Enabled: false
+Style/HashAsLastArrayItem:
+  Enabled: false
+Style/HashLikeCase:
+  Enabled: false
+Style/HashTransformKeys:
+  Enabled: false
+Style/HashTransformValues:
+  Enabled: false
+Style/IfUnlessModifier:
+  Enabled: false
+Style/KeywordParametersOrder:
+  Enabled: false
+Style/MinMax:
+  Enabled: false
+Style/MixinUsage:
+  Enabled: false
+Style/MultilineWhenThen:
+  Enabled: false
+Style/NegatedUnless:
+  Enabled: false
+Style/NumericPredicate:
+  Enabled: false
+Style/OptionalBooleanParameter:
+  Enabled: false
+Style/OrAssignment:
+  Enabled: false
+Style/RandomWithOffset:
+  Enabled: false
+Style/RedundantAssignment:
+  Enabled: false
+Style/RedundantCondition:
+  Enabled: false
+Style/RedundantConditional:
+  Enabled: false
+Style/RedundantFetchBlock:
+  Enabled: false
+Style/RedundantFileExtensionInRequire:
+  Enabled: false
+Style/RedundantRegexpCharacterClass:
+  Enabled: false
+Style/RedundantRegexpEscape:
+  Enabled: false
+Style/RedundantSelfAssignment:
+  Enabled: false
+Style/RedundantSort:
+  Enabled: false
+Style/RescueStandardError:
+  Enabled: false
+Style/SingleArgumentDig:
+  Enabled: false
+Style/SlicingWithRange:
+  Enabled: false
+Style/SoleNestedConditional:
+  Enabled: false
+Style/StderrPuts:
+  Enabled: false
+Style/StringConcatenation:
+  Enabled: false
+Style/Strip:
+  Enabled: false
+Style/SymbolProc:
+  Enabled: false
+Style/TrailingBodyOnClass:
+  Enabled: false
+Style/TrailingBodyOnMethodDefinition:
+  Enabled: false
+Style/TrailingBodyOnModule:
+  Enabled: false
+Style/TrailingCommaInHashLiteral:
+  Enabled: false
+Style/TrailingMethodEndStatement:
+  Enabled: false
+Style/UnpackFirst:
+  Enabled: false
+Lint/DuplicateBranch:
+  Enabled: false
+Lint/DuplicateRegexpCharacterClassElement:
+  Enabled: false
+Lint/EmptyBlock:
+  Enabled: false
+Lint/EmptyClass:
+  Enabled: false
+Lint/NoReturnInBeginEndBlocks:
+  Enabled: false
+Lint/ToEnumArguments:
+  Enabled: false
+Lint/UnexpectedBlockArity:
+  Enabled: false
+Lint/UnmodifiedReduceAccumulator:
+  Enabled: false
+Performance/CollectionLiteralInLoop:
+  Enabled: false
+Style/ArgumentsForwarding:
+  Enabled: false
+Style/CollectionCompact:
+  Enabled: false
+Style/DocumentDynamicEvalDefinition:
+  Enabled: false
+Style/NegatedIfElseCondition:
+  Enabled: false
+Style/NilLambda:
+  Enabled: false
+Style/RedundantArgument:
+  Enabled: false
+Style/SwapValues:
+  Enabled: false
diff --git a/.sync.yml b/.sync.yml
new file mode 100644
index 0000000..2fbf0ff
--- /dev/null
+++ b/.sync.yml
@@ -0,0 +1 @@
+--- {}
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..444e17a
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,45 @@
+---
+os: linux
+dist: xenial
+language: ruby
+cache: bundler
+before_install:
+  - bundle -v
+  - rm -f Gemfile.lock
+  - "# Update system gems if requested. This is useful to temporarily workaround troubles in the test runner"
+  - "# See https://github.com/puppetlabs/pdk-templates/commit/705154d5c437796b821691b707156e1b056d244f for an example of how this was used"
+  - "# Ignore exit code of SIGPIPE'd yes to not fail with shell's pipefail set"
+  - '[ -z "$RUBYGEMS_VERSION" ] || (yes || true) | gem update --system $RUBYGEMS_VERSION'
+  - gem --version
+  - bundle -v
+script:
+  - 'bundle exec rake $CHECK'
+bundler_args: --without system_tests
+rvm:
+  - 2.5.7
+stages:
+  - static
+  - spec
+  - acceptance
+  -
+    if: tag =~ ^v\d
+    name: deploy
+jobs:
+  fast_finish: true
+  include:
+    -
+      env: CHECK="validate lint check rubocop"
+      stage: static
+    -
+      env: PUPPET_GEM_VERSION="~> 6.0" CHECK=parallel_spec
+      rvm: 2.5.7
+      stage: spec
+    -
+      env: DEPLOY_TO_FORGE=yes
+      stage: deploy
+branches:
+  only:
+    - main
+    - /^v\d/
+notifications:
+  email: false
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..2f1e4f7
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,6 @@
+{
+  "recommendations": [
+    "puppet.puppet-vscode",
+    "rebornix.Ruby"
+  ]
+}
diff --git a/.yardopts b/.yardopts
new file mode 100644
index 0000000..29c933b
--- /dev/null
+++ b/.yardopts
@@ -0,0 +1 @@
+--markup markdown
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..4c954cd
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,11 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+## Release 0.1.0
+
+**Features**
+
+**Bugfixes**
+
+**Known Issues**
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..fc28658
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,63 @@
+source ENV['GEM_SOURCE'] || 'https://rubygems.org'
+
+def location_for(place_or_version, fake_version = nil)
+  git_url_regex = %r{\A(?<url>(https?|git)[:@][^#]*)(#(?<branch>.*))?}
+  file_url_regex = %r{\Afile:\/\/(?<path>.*)}
+
+  if place_or_version && (git_url = place_or_version.match(git_url_regex))
+    [fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact
+  elsif place_or_version && (file_url = place_or_version.match(file_url_regex))
+    ['>= 0', { path: File.expand_path(file_url[:path]), require: false }]
+  else
+    [place_or_version, { require: false }]
+  end
+end
+
+ruby_version_segments = Gem::Version.new(RUBY_VERSION.dup).segments
+minor_version = ruby_version_segments[0..1].join('.')
+
+group :development do
+  gem "json", '= 2.0.4',                                         require: false if Gem::Requirement.create('~> 2.4.2').satisfied_by?(Gem::Version.new(RUBY_VERSION.dup))
+  gem "json", '= 2.1.0',                                         require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup))
+  gem "json", '= 2.3.0',                                         require: false if Gem::Requirement.create(['>= 2.7.0', '< 2.8.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup))
+  gem "puppet-module-posix-default-r#{minor_version}", '~> 1.0', require: false, platforms: [:ruby]
+  gem "puppet-module-posix-dev-r#{minor_version}", '~> 1.0',     require: false, platforms: [:ruby]
+  gem "puppet-module-win-default-r#{minor_version}", '~> 1.0',   require: false, platforms: [:mswin, :mingw, :x64_mingw]
+  gem "puppet-module-win-dev-r#{minor_version}", '~> 1.0',       require: false, platforms: [:mswin, :mingw, :x64_mingw]
+  gem "voxpupuli-puppet-lint-plugins", '>= 3.0',                 require: false
+end
+group :system_tests do
+  gem "puppet-module-posix-system-r#{minor_version}", '~> 1.0', require: false, platforms: [:ruby]
+  gem "puppet-module-win-system-r#{minor_version}", '~> 1.0',   require: false, platforms: [:mswin, :mingw, :x64_mingw]
+end
+
+puppet_version = ENV['PUPPET_GEM_VERSION']
+facter_version = ENV['FACTER_GEM_VERSION']
+hiera_version = ENV['HIERA_GEM_VERSION']
+
+gems = {}
+
+gems['puppet'] = location_for(puppet_version)
+
+# If facter or hiera versions have been specified via the environment
+# variables
+
+gems['facter'] = location_for(facter_version) if facter_version
+gems['hiera'] = location_for(hiera_version) if hiera_version
+
+gems.each do |gem_name, gem_params|
+  gem gem_name, *gem_params
+end
+
+# Evaluate Gemfile.local and ~/.gemfile if they exist
+extra_gemfiles = [
+  "#{__FILE__}.local",
+  File.join(Dir.home, '.gemfile'),
+]
+
+extra_gemfiles.each do |gemfile|
+  if File.file?(gemfile) && File.readable?(gemfile)
+    eval(File.read(gemfile), binding)
+  end
+end
+# vim: syntax=ruby
diff --git a/README.md b/README.md
index 6d887de..cbfd7d5 100644
--- a/README.md
+++ b/README.md
@@ -1,92 +1,117 @@
-# puppet-cfssl
+# cfssl
 
+Welcome to your new module. A short overview of the generated parts can be found
+in the [PDK documentation][1].
 
+The README template below provides a starting point with details about what
+information to include in your README.
 
-## Getting started
+## Table of Contents
 
-To make it easy for you to get started with GitLab, here's a list of recommended next steps.
+1. [Description](#description)
+1. [Setup - The basics of getting started with cfssl](#setup)
+    * [What cfssl affects](#what-cfssl-affects)
+    * [Setup requirements](#setup-requirements)
+    * [Beginning with cfssl](#beginning-with-cfssl)
+1. [Usage - Configuration options and additional functionality](#usage)
+1. [Limitations - OS compatibility, etc.](#limitations)
+1. [Development - Guide for contributing to the module](#development)
 
-Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
+## Description
 
-## Add your files
+Briefly tell users why they might want to use your module. Explain what your
+module does and what kind of problems users can solve with it.
 
-- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
-- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
+This should be a fairly short description helps the user decide if your module
+is what they want.
 
-```
-cd existing_repo
-git remote add origin https://gitlab.adullact.net/adullact/puppet-cfssl.git
-git branch -M main
-git push -uf origin main
-```
+## Setup
 
-## Integrate with your tools
+### What cfssl affects **OPTIONAL**
 
-- [ ] [Set up project integrations](https://gitlab.adullact.net/adullact/puppet-cfssl/-/settings/integrations)
+If it's obvious what your module touches, you can skip this section. For
+example, folks can probably figure out that your mysql_instance module affects
+their MySQL instances.
 
-## Collaborate with your team
+If there's more that they should know about, though, this is the place to
+mention:
 
-- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
-- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
-- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
-- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
-- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
+* Files, packages, services, or operations that the module will alter, impact,
+  or execute.
+* Dependencies that your module automatically installs.
+* Warnings or other important notices.
 
-## Test and Deploy
+### Setup Requirements **OPTIONAL**
 
-Use the built-in continuous integration in GitLab.
+If your module requires anything extra before setting up (pluginsync enabled,
+another module, etc.), mention it here.
 
-- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
-- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
-- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
-- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
-- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
+If your most recent release breaks compatibility or requires particular steps
+for upgrading, you might want to include an additional "Upgrading" section here.
 
-***
+### Beginning with cfssl
 
-# Editing this README
+The very basic steps needed for a user to get the module up and running. This
+can include setup steps, if necessary, or it can be an example of the most basic
+use of the module.
 
-When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
+## Usage
 
-## Suggestions for a good README
-Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
+Include usage examples for common use cases in the **Usage** section. Show your
+users how to use your module to solve problems, and be sure to include code
+examples. Include three to five examples of the most important or common tasks a
+user can accomplish with your module. Show users how to accomplish more complex
+tasks that involve different types, classes, and functions working in tandem.
 
-## Name
-Choose a self-explaining name for your project.
+## Reference
 
-## Description
-Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
+This section is deprecated. Instead, add reference information to your code as
+Puppet Strings comments, and then use Strings to generate a REFERENCE.md in your
+module. For details on how to add code comments and generate documentation with
+Strings, see the [Puppet Strings documentation][2] and [style guide][3].
 
-## Badges
-On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
+If you aren't ready to use Strings yet, manually create a REFERENCE.md in the
+root of your module directory and list out each of your module's classes,
+defined types, facts, functions, Puppet tasks, task plans, and resource types
+and providers, along with the parameters for each.
 
-## Visuals
-Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
+For each element (class, defined type, function, and so on), list:
 
-## Installation
-Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
+* The data type, if applicable.
+* A description of what the element does.
+* Valid values, if the data type doesn't make it obvious.
+* Default value, if any.
 
-## Usage
-Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
+For example:
 
-## Support
-Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
+```
+### `pet::cat`
+
+#### Parameters
+
+##### `meow`
+
+Enables vocalization in your cat. Valid options: 'string'.
+
+Default: 'medium-loud'.
+```
 
-## Roadmap
-If you have ideas for releases in the future, it is a good idea to list them in the README.
+## Limitations
 
-## Contributing
-State if you are open to contributions and what your requirements are for accepting them.
+In the Limitations section, list any incompatibilities, known issues, or other
+warnings.
 
-For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
+## Development
 
-You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
+In the Development section, tell other users the ground rules for contributing
+to your project and how they should submit their work.
 
-## Authors and acknowledgment
-Show your appreciation to those who have contributed to the project.
+## Release Notes/Contributors/Etc. **Optional**
 
-## License
-For open source projects, say how it is licensed.
+If you aren't using changelog, put your release notes here (though you should
+consider using changelog). You can also add any additional sections you feel are
+necessary or important to include here. Please use the `##` header.
 
-## Project status
-If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
+[1]: https://puppet.com/docs/pdk/latest/pdk_generating_modules.html
+[2]: https://puppet.com/docs/puppet/latest/puppet_strings.html
+[3]: https://puppet.com/docs/puppet/latest/puppet_strings_style.html
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..0f8754e
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,89 @@
+# frozen_string_literal: true
+
+require 'bundler'
+require 'puppet_litmus/rake_tasks' if Bundler.rubygems.find_name('puppet_litmus').any?
+require 'puppetlabs_spec_helper/rake_tasks'
+require 'puppet-syntax/tasks/puppet-syntax'
+require 'puppet_blacksmith/rake_tasks' if Bundler.rubygems.find_name('puppet-blacksmith').any?
+require 'github_changelog_generator/task' if Bundler.rubygems.find_name('github_changelog_generator').any?
+require 'puppet-strings/tasks' if Bundler.rubygems.find_name('puppet-strings').any?
+
+def changelog_user
+  return unless Rake.application.top_level_tasks.include? "changelog"
+  returnVal = nil || JSON.load(File.read('metadata.json'))['author']
+  raise "unable to find the changelog_user in .sync.yml, or the author in metadata.json" if returnVal.nil?
+  puts "GitHubChangelogGenerator user:#{returnVal}"
+  returnVal
+end
+
+def changelog_project
+  return unless Rake.application.top_level_tasks.include? "changelog"
+
+  returnVal = nil
+  returnVal ||= begin
+    metadata_source = JSON.load(File.read('metadata.json'))['source']
+    metadata_source_match = metadata_source && metadata_source.match(%r{.*\/([^\/]*?)(?:\.git)?\Z})
+
+    metadata_source_match && metadata_source_match[1]
+  end
+
+  raise "unable to find the changelog_project in .sync.yml or calculate it from the source in metadata.json" if returnVal.nil?
+
+  puts "GitHubChangelogGenerator project:#{returnVal}"
+  returnVal
+end
+
+def changelog_future_release
+  return unless Rake.application.top_level_tasks.include? "changelog"
+  returnVal = "v%s" % JSON.load(File.read('metadata.json'))['version']
+  raise "unable to find the future_release (version) in metadata.json" if returnVal.nil?
+  puts "GitHubChangelogGenerator future_release:#{returnVal}"
+  returnVal
+end
+
+PuppetLint.configuration.send('disable_relative')
+
+
+if Bundler.rubygems.find_name('github_changelog_generator').any?
+  GitHubChangelogGenerator::RakeTask.new :changelog do |config|
+    raise "Set CHANGELOG_GITHUB_TOKEN environment variable eg 'export CHANGELOG_GITHUB_TOKEN=valid_token_here'" if Rake.application.top_level_tasks.include? "changelog" and ENV['CHANGELOG_GITHUB_TOKEN'].nil?
+    config.user = "#{changelog_user}"
+    config.project = "#{changelog_project}"
+    config.future_release = "#{changelog_future_release}"
+    config.exclude_labels = ['maintenance']
+    config.header = "# Change log\n\nAll notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org)."
+    config.add_pr_wo_labels = true
+    config.issues = false
+    config.merge_prefix = "### UNCATEGORIZED PRS; LABEL THEM ON GITHUB"
+    config.configure_sections = {
+      "Changed" => {
+        "prefix" => "### Changed",
+        "labels" => ["backwards-incompatible"],
+      },
+      "Added" => {
+        "prefix" => "### Added",
+        "labels" => ["enhancement", "feature"],
+      },
+      "Fixed" => {
+        "prefix" => "### Fixed",
+        "labels" => ["bug", "documentation", "bugfix"],
+      },
+    }
+  end
+else
+  desc 'Generate a Changelog from GitHub'
+  task :changelog do
+    raise <<EOM
+The changelog tasks depends on recent features of the github_changelog_generator gem.
+Please manually add it to your .sync.yml for now, and run `pdk update`:
+---
+Gemfile:
+  optional:
+    ':development':
+      - gem: 'github_changelog_generator'
+        version: '~> 1.15'
+        condition: "Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0')"
+EOM
+  end
+end
+
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..a70c01e
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,49 @@
+---
+version: 1.1.x.{build}
+skip_branch_with_pr: true
+branches:
+  only:
+    - main
+    - release
+skip_commits:
+  message: /^\(?doc\)?.*/
+clone_depth: 10
+init:
+  - SET
+  - 'mkdir C:\ProgramData\PuppetLabs\code && exit 0'
+  - 'mkdir C:\ProgramData\PuppetLabs\facter && exit 0'
+  - 'mkdir C:\ProgramData\PuppetLabs\hiera && exit 0'
+  - 'mkdir C:\ProgramData\PuppetLabs\puppet\var && exit 0'
+environment:
+  matrix:
+    -
+      RUBY_VERSION: 25-x64
+      CHECK: validate lint check rubocop
+    -
+      PUPPET_GEM_VERSION: ~> 6.0
+      RUBY_VERSION: 25
+      CHECK: parallel_spec
+    -
+      PUPPET_GEM_VERSION: ~> 6.0
+      RUBY_VERSION: 25-x64
+      CHECK: parallel_spec
+matrix:
+  fast_finish: true
+install:
+  - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
+  - bundle install --jobs 4 --retry 2 --without system_tests
+  - type Gemfile.lock
+build: off
+test_script:
+  - bundle exec puppet -V
+  - ruby -v
+  - gem -v
+  - bundle -v
+  - bundle exec rake %CHECK%
+notifications:
+  - provider: Email
+    to:
+      - nobody@nowhere.com
+    on_build_success: false
+    on_build_failure: false
+    on_build_status_changed: false
diff --git a/data/common.yaml b/data/common.yaml
new file mode 100644
index 0000000..2fbf0ff
--- /dev/null
+++ b/data/common.yaml
@@ -0,0 +1 @@
+--- {}
diff --git a/hiera.yaml b/hiera.yaml
new file mode 100644
index 0000000..545fff3
--- /dev/null
+++ b/hiera.yaml
@@ -0,0 +1,21 @@
+---
+version: 5
+
+defaults:  # Used for any hierarchy level that omits these keys.
+  datadir: data         # This path is relative to hiera.yaml's directory.
+  data_hash: yaml_data  # Use the built-in YAML backend.
+
+hierarchy:
+  - name: "osfamily/major release"
+    paths:
+        # Used to distinguish between Debian and Ubuntu
+      - "os/%{facts.os.name}/%{facts.os.release.major}.yaml"
+      - "os/%{facts.os.family}/%{facts.os.release.major}.yaml"
+        # Used for Solaris
+      - "os/%{facts.os.family}/%{facts.kernelrelease}.yaml"
+  - name: "osfamily"
+    paths:
+      - "os/%{facts.os.name}.yaml"
+      - "os/%{facts.os.family}.yaml"
+  - name: 'common'
+    path: 'common.yaml'
diff --git a/manifests/ca/root.pp b/manifests/ca/root.pp
new file mode 100644
index 0000000..e235d46
--- /dev/null
+++ b/manifests/ca/root.pp
@@ -0,0 +1,28 @@
+# @summary A short summary of the purpose of this class
+#
+# A description of what this class does
+#
+# @example
+#   include cfssl::ca::root
+class cfssl::ca::root (
+  Hash $subject = { 'C' => 'FR', 'L' => 'MONTPELLIER', 'O' => 'EXEMPLE ORG', 'OU' => 'IT Dept'},
+  String[1] $cn = 'EXEMPLE ROOT CA GEN1',
+  String[1] $expiry = '43800h',
+  Cfssl::Ca::Key $key = { algo => 'rsa', size => 2048 },
+){
+  $_rootca_filename = 'ROOT_ca'
+  $_rootca_csr = {
+    cn    => $cn,
+    names => [$subject],
+    ca    => {expiry => $expiry},
+    key   => $key,
+  }
+  $_rootca_csr_json = to_json($_rootca_csr)
+
+  exec {"initca ${cn}":
+    path    => "/usr/bin:${cfssl::binpath}",
+    command => "echo '${_rootca_csr_json}' | cfssl gencert -initca - | cfssljson -bare ${cfssl::confdir}/ca/${_rootca_filename}",
+    creates => "${cfssl::confdir}/ca/${_rootca_filename}-key.pem",
+    user    => $cfssl::sysuser,
+  }
+}
diff --git a/manifests/goose.pp b/manifests/goose.pp
new file mode 100644
index 0000000..d521937
--- /dev/null
+++ b/manifests/goose.pp
@@ -0,0 +1,23 @@
+# @summary A short summary of the purpose of this class
+#
+# A description of what this class does
+#
+# @example
+#   include cfssl::goose
+class cfssl::goose {
+  # stuffs for goose : a database migration tool used by CFSSL
+  package { 'golang-1.16':
+    ensure => present,
+  }
+  -> file { '/usr/local/bin/go':
+    ensure => link,
+    target => '/usr/lib/go-1.16/bin/go',
+  }
+  -> exec { 'install goose':
+      command     => '/usr/local/bin/go get bitbucket.org/liamstask/goose/cmd/goose',
+      creates     => "/home/${cfssl::sysuser}/go/bin/goose",
+      user        => $cfssl::sysuser,
+      environment => ["HOME=/home/${cfssl::sysuser}/"],
+      require     => User[$cfssl::sysuser],
+  }
+}
diff --git a/manifests/init.pp b/manifests/init.pp
new file mode 100644
index 0000000..003c27b
--- /dev/null
+++ b/manifests/init.pp
@@ -0,0 +1,168 @@
+# @summary A short summary of the purpose of this class
+#
+# A description of what this class does
+#
+# @example
+#   include cfssl
+class cfssl (
+  Hash $rootca_manifest = {},
+  Stdlib::HTTPSUrl $downloadurl = 'https://github.com/cloudflare/cfssl/releases/download',
+  String[1] $version = '1.6.3',
+  String[1] $downloadchecksum = '824ff707e54611e8911210a5e8e1afbf745bba1dab55babdeb1a39d85b2f8c10',
+  Enum['md5', 'sha1', 'sha2','sha256', 'sha384', 'sha512'] $checksum_type = 'sha256',
+  String[1] $sysuser = 'cfssl',
+  String[1] $sysgroup = 'cfssl',
+  Stdlib::IP::Address $binding_ip = '127.0.0.1',
+  Stdlib::Port $port = 8080,
+  Enum['0','1','2','3','4'] $log_level = '1',
+  Stdlib::Absolutepath $logdir = '/var/log/cfssl',
+  String[1] $dbname = 'db_cfssl',
+  String[1] $dbuser = 'u_cfssl',
+  String[1] $dbpassword = 'changeme',
+  Stdlib::Absolutepath $confdir = '/etc/cfssl',
+  Stdlib::Absolutepath $binpath = '/usr/local/bin',
+  Cfssl::Serveconfig $serve_config = { signing => { 'default' => { expiry => '1h', usages => ['client auth'] }}},
+  String[1] $serve_ca = 'ROOT_ca',
+){
+
+  # modify serve_config needs restart cfssl serve
+  include cfssl::goose
+  include postgresql::server
+
+  $_binaries = ['cfssljson','cfssl-certinfo']
+  $_systemd_unit_file = '/etc/systemd/system/cfssl.service'
+  $_goose_cfssldbmigrate_path = "/home/${sysuser}/goose-cfssldbmigrate"
+  $_serve_config_json = 'serve-config.json'
+  $_db_config_json = 'db-config.json'
+
+  group { $sysgroup :
+    ensure => present,
+  }
+  -> user { $sysuser :
+    ensure     => present,
+    managehome => true,
+    shell      => '/bin/bash',
+    gid        => $sysgroup,
+  }
+
+  archive::download { "${binpath}/cfssl" :
+    ensure        => present,
+    url           => "${downloadurl}/v${version}/cfssl_${version}_linux_amd64",
+    checksum      => true,
+    digest_type   => $checksum_type,
+    digest_string => $downloadchecksum,
+  }
+  -> file { "${binpath}/cfssl" :
+    ensure  => file,
+    mode    => '0700',
+    owner   => $sysuser,
+    group   => $sysgroup,
+    require => User[$sysuser],
+  }
+
+  $_binaries.each | String $_bin | {
+    $_archiveurn = "v${version}/${_bin}_${version}_linux_amd64"
+
+    archive::download { "${binpath}/${_bin}" :
+      ensure     => present,
+      url        => "${downloadurl}/${_archiveurn}",
+      subscribe  => Archive::Download["${binpath}/cfssl"],
+    }
+    ~> file { "${binpath}/${_bin}" :
+      ensure  => file,
+      mode    => '0700',
+      owner   => $sysuser,
+      group   => $sysgroup,
+      require => User[$sysuser],
+    }
+  }
+
+  file { [$confdir, "${confdir}/ca", $logdir] :
+    ensure  => directory,
+    mode    => '0700',
+    owner   => $sysuser,
+    group   => $sysgroup,
+    require => User[$sysuser],
+  }
+
+  postgresql::server::db { $dbname:
+    user     => $dbuser,
+    password => postgresql::postgresql_password($dbuser, $dbpassword),
+  }
+
+  file { "${confdir}/${_db_config_json}":
+    ensure  => file,
+    mode    => '0600',
+    owner   => $sysuser,
+    group   => $sysgroup,
+    content => epp('cfssl/db-config.json.epp'),
+  }
+  file { "${confdir}/${_serve_config_json}":
+    ensure  => file,
+    mode    => '0600',
+    owner   => $sysuser,
+    group   => $sysgroup,
+    content => to_json_pretty($serve_config),
+  }
+
+
+  vcsrepo { $_goose_cfssldbmigrate_path:
+    ensure   => present,
+    provider => git,
+    source   => 'https://github.com/cloudflare/cfssl.git',
+    revision => "v${version}",
+    user     => $sysuser,
+  }
+  -> file { "${_goose_cfssldbmigrate_path}/certdb/pg/dbconf.yml":
+    ensure  => file,
+    mode    => '0600',
+    owner   => $sysuser,
+    group   => $sysgroup,
+    content => epp('cfssl/goose-dbconf.yml.epp'),
+  }
+
+  exec { 'goose pg up':
+    command     => "/home/${sysuser}/go/bin/goose --env puppetmigrate -path ${_goose_cfssldbmigrate_path}/certdb/pg up",
+    user        => $sysuser,
+    environment => ["HOME=/home/${sysuser}/"],
+    require     => [
+      User[$sysuser],
+      Vcsrepo[$_goose_cfssldbmigrate_path],
+      Postgresql::Server::Db[$dbname],
+    ],
+    subscribe   => Vcsrepo[$_goose_cfssldbmigrate_path],
+    refreshonly => true,
+  }
+
+  class { 'cfssl::ca::root':
+    *       => $rootca_manifest,
+    require => [
+      File[$cfssl::confdir],
+      File["${cfssl::confdir}/ca"],
+      Archive::Download["${binpath}/cfssl"],
+      Archive::Download["${binpath}/cfssljson"],
+    ],
+  }
+
+  file { $_systemd_unit_file:
+    ensure  => file,
+    mode    => '0644',
+    owner   => 0,
+    group   => 0,
+    content => epp('cfssl/cfssl.service.epp'),
+  }
+  ~> service { 'cfssl':
+    ensure    => 'running',
+    enable    => true,
+    require   => [
+      Archive::Download["${binpath}/cfssl"],
+      Postgresql::Server::Db[$dbname],
+      Exec['goose pg up'],
+      File["${confdir}/${_serve_config_json}"],
+      File["${confdir}/${_db_config_json}"],
+      Class['cfssl::ca::root'],
+    ],
+    subscribe => Archive::Download["${binpath}/cfssl"],
+    provider  => 'systemd',
+  }
+}
diff --git a/metadata.json b/metadata.json
new file mode 100644
index 0000000..00fd7dc
--- /dev/null
+++ b/metadata.json
@@ -0,0 +1,34 @@
+{
+  "name": "adullact-cfssl",
+  "version": "0.1.0",
+  "author": "adullact",
+  "summary": "",
+  "license": "AGPL-3.0",
+  "source": "",
+  "dependencies": [
+
+  ],
+  "operatingsystem_support": [
+    {
+      "operatingsystem": "Debian",
+      "operatingsystemrelease": [
+        "10"
+      ]
+    },
+    {
+      "operatingsystem": "Ubuntu",
+      "operatingsystemrelease": [
+        "18.04"
+      ]
+    }
+  ],
+  "requirements": [
+    {
+      "name": "puppet",
+      "version_requirement": ">= 6.21.0 < 8.0.0"
+    }
+  ],
+  "pdk-version": "2.5.0",
+  "template-url": "https://github.com/puppetlabs/pdk-templates#2.5.0",
+  "template-ref": "tags/2.5.0-0-g369d483"
+}
diff --git a/spec/classes/ca/root_spec.rb b/spec/classes/ca/root_spec.rb
new file mode 100644
index 0000000..0b6a7e0
--- /dev/null
+++ b/spec/classes/ca/root_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'cfssl::ca::root' do
+  let(:pre_condition) do
+    'include cfssl'
+  end
+
+  on_supported_os.each do |os, os_facts|
+    context "on #{os}" do
+      let(:facts) { os_facts.merge(service_provider: 'systemd') }
+
+      it { is_expected.to compile }
+    end
+  end
+end
diff --git a/spec/classes/cfssl_spec.rb b/spec/classes/cfssl_spec.rb
new file mode 100644
index 0000000..ad53d0c
--- /dev/null
+++ b/spec/classes/cfssl_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'cfssl' do
+  let(:pre_condition) do
+    'require postgresql::server'
+  end
+
+  on_supported_os.each do |os, os_facts|
+    context "on #{os}" do
+      let(:facts) { os_facts.merge(service_provider: 'systemd') }
+
+      it { is_expected.to compile }
+    end
+  end
+end
diff --git a/spec/classes/goose_spec.rb b/spec/classes/goose_spec.rb
new file mode 100644
index 0000000..cc69dca
--- /dev/null
+++ b/spec/classes/goose_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'cfssl::goose' do
+  let(:pre_condition) do
+    'include cfssl'
+  end
+
+  on_supported_os.each do |os, os_facts|
+    context "on #{os}" do
+      let(:facts) { os_facts.merge(service_provider: 'systemd') }
+
+      it { is_expected.to compile }
+    end
+  end
+end
diff --git a/spec/default_facts.yml b/spec/default_facts.yml
new file mode 100644
index 0000000..f777abf
--- /dev/null
+++ b/spec/default_facts.yml
@@ -0,0 +1,8 @@
+# Use default_module_facts.yml for module specific facts.
+#
+# Facts specified here will override the values provided by rspec-puppet-facts.
+---
+ipaddress: "172.16.254.254"
+ipaddress6: "FE80:0000:0000:0000:AAAA:AAAA:AAAA"
+is_pe: false
+macaddress: "AA:AA:AA:AA:AA:AA"
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..9b1fa6f
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+RSpec.configure do |c|
+  c.mock_with :rspec
+end
+
+require 'puppetlabs_spec_helper/module_spec_helper'
+require 'rspec-puppet-facts'
+
+require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb'))
+
+include RspecPuppetFacts
+
+default_facts = {
+  puppetversion: Puppet.version,
+  facterversion: Facter.version,
+}
+
+default_fact_files = [
+  File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')),
+  File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')),
+]
+
+default_fact_files.each do |f|
+  next unless File.exist?(f) && File.readable?(f) && File.size?(f)
+
+  begin
+    default_facts.merge!(YAML.safe_load(File.read(f), [], [], true))
+  rescue => e
+    RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}"
+  end
+end
+
+# read default_facts and merge them over what is provided by facterdb
+default_facts.each do |fact, value|
+  add_custom_fact fact, value
+end
+
+RSpec.configure do |c|
+  c.default_facts = default_facts
+  c.before :each do
+    # set to strictest setting for testing
+    # by default Puppet runs at warning level
+    Puppet.settings[:strict] = :warning
+    Puppet.settings[:strict_variables] = true
+  end
+  c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT']
+  c.after(:suite) do
+  end
+
+  # Filter backtrace noise
+  backtrace_exclusion_patterns = [
+    %r{spec_helper},
+    %r{gems},
+  ]
+
+  if c.respond_to?(:backtrace_exclusion_patterns)
+    c.backtrace_exclusion_patterns = backtrace_exclusion_patterns
+  elsif c.respond_to?(:backtrace_clean_patterns)
+    c.backtrace_clean_patterns = backtrace_exclusion_patterns
+  end
+end
+
+# Ensures that a module is defined
+# @param module_name Name of the module
+def ensure_module_defined(module_name)
+  module_name.split('::').reduce(Object) do |last_module, next_module|
+    last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false)
+    last_module.const_get(next_module, false)
+  end
+end
+
+# 'spec_overrides' from sync.yml will appear below this line
diff --git a/templates/cfssl.service.epp b/templates/cfssl.service.epp
new file mode 100644
index 0000000..f568d8b
--- /dev/null
+++ b/templates/cfssl.service.epp
@@ -0,0 +1,16 @@
+[Unit]
+Description=CloudFlare's PKI/TLS toolkit
+Requires=network-online.target
+After=network-online.target
+
+[Service]
+User=<%= $cfssl::sysuser %>
+Group=<%= $cfssl::sysgroup %>
+ExecStart=<%= $cfssl::binpath %>/cfssl -log_dir <%= $cfssl::logdir %> serve -address <%= $cfssl::binding_ip %> -ca <%= $cfssl::confdir %>/ca/<%= $cfssl::serve_ca %>.pem -ca-key <%= $cfssl::confdir %>/ca/<%= $cfssl::serve_ca %>-key.pem -port <%= $cfssl::port %> -db-config <%= $cfssl::confdir %>/db-config.json -config <%= $cfssl::confdir %>/serve-config.json -loglevel <%= $cfssl::log_level %>
+Restart=always
+PrivateTmp=yes
+ProtectSystem=full
+NoNewPrivileges=yes
+
+[Install]
+WantedBy=multi-user.target
diff --git a/templates/db-config.json.epp b/templates/db-config.json.epp
new file mode 100644
index 0000000..a33aed0
--- /dev/null
+++ b/templates/db-config.json.epp
@@ -0,0 +1,4 @@
+{
+    "driver": "postgres",
+    "data_source": "postgres://<%= $cfssl::dbuser %>:<%= $cfssl::dbpassword %>@localhost/<%= $cfssl::dbname %>"
+}
diff --git a/templates/goose-dbconf.yml.epp b/templates/goose-dbconf.yml.epp
new file mode 100644
index 0000000..694a921
--- /dev/null
+++ b/templates/goose-dbconf.yml.epp
@@ -0,0 +1,3 @@
+puppetmigrate:
+  driver: postgres
+  open: user=<%= $cfssl::dbuser %> password=<%= $cfssl::dbpassword %> dbname=<%= $cfssl::dbname %> sslmode=disable
diff --git a/types/authkey.pp b/types/authkey.pp
new file mode 100644
index 0000000..bf0bfa1
--- /dev/null
+++ b/types/authkey.pp
@@ -0,0 +1,4 @@
+type Cfssl::Authkey = Struct[{
+  type => Enum['standard'],
+  key  => String[1],
+}]
diff --git a/types/ca/key.pp b/types/ca/key.pp
new file mode 100644
index 0000000..18f5ca8
--- /dev/null
+++ b/types/ca/key.pp
@@ -0,0 +1,4 @@
+type Cfssl::Ca::Key = Struct[{
+  algo => Enum['rsa','ecdsa'],
+  size => Integer,
+}]
diff --git a/types/serveconfig.pp b/types/serveconfig.pp
new file mode 100644
index 0000000..e71133d
--- /dev/null
+++ b/types/serveconfig.pp
@@ -0,0 +1,7 @@
+type Cfssl::Serveconfig = Struct[{
+  auth_keys => Optional[Hash[String,Cfssl::Authkey]],
+  signing   => Struct[{
+    'default' => Cfssl::Signing::Profile,
+    profiles  => Optional[Hash[String,Cfssl::Signing::Profile]],
+  }],
+}]
diff --git a/types/serveconfig.pp.save b/types/serveconfig.pp.save
new file mode 100644
index 0000000..1e4d42f
--- /dev/null
+++ b/types/serveconfig.pp.save
@@ -0,0 +1,7 @@
+type Cfssl::Serveconfig = Struct[{
+  auth_keys => Optional[Hash[String,Cfssl::Authkey]],
+  signing   => Struct[{
+    default  => Hash,
+    profiles => Optional[Hash[String,Cfssl::Signing::Profile]],
+  }],
+}]
diff --git a/types/serveconfig.pp.works b/types/serveconfig.pp.works
new file mode 100644
index 0000000..d74e907
--- /dev/null
+++ b/types/serveconfig.pp.works
@@ -0,0 +1,5 @@
+type Cfssl::Serveconfig = Struct[{
+  signing   => Struct[{
+    defkiki => Cfssl::Signing::Profile,
+  }],
+}]
diff --git a/types/signing/profile.pp b/types/signing/profile.pp
new file mode 100644
index 0000000..3f40697
--- /dev/null
+++ b/types/signing/profile.pp
@@ -0,0 +1,10 @@
+type Cfssl::Signing::Profile = Struct[{
+  expiry         => String[1],
+  usages         => Array[Cfssl::Usage],
+  crl_url        => Optional[Stdlib::HTTPUrl],
+  ocsp_url       => Optional[Stdlib::HTTPUrl],
+  not_before     => Optional[String[1]],
+  not_after      => Optional[String[1]],
+  name_whitelist => Optional[String[1]],
+  auth_key       => Optional[String[1]],
+}]
diff --git a/types/usage.pp b/types/usage.pp
new file mode 100644
index 0000000..e628b13
--- /dev/null
+++ b/types/usage.pp
@@ -0,0 +1,25 @@
+type Cfssl::Usage = Enum[
+  'signing',
+  'digital signature',
+  'content commitment',
+  'key encipherment',
+  'key agreement',
+  'data encipherment',
+  'cert sign',
+  'crl sign',
+  'encipher only',
+  'decipher only',
+  'any',
+  'server auth',
+  'client auth',
+  'code signing',
+  'email protection',
+  's/mime',
+  'ipsec end system',
+  'ipsec tunnel',
+  'ipsec user',
+  'timestamping',
+  'ocsp signing',
+  'microsoft sgc',
+  'netscape sgc',
+]
-- 
GitLab