From 1c7696fb302d0152a14ada0fdbcf5c524a8f6006 Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Tue, 30 Jan 2024 11:28:09 +0100 Subject: [PATCH] Refs #37121 - Add dns::dnssec_keygen function This wraps dnssec-keygen and returns the data in a structured format. The result can be used to secure communications. It always generates a random key and the resulting data should be cached or otherwise made idempotent. --- lib/puppet/functions/dns/dnssec_keygen.rb | 28 +++++++++++++++++++++++ spec/functions/dnssec_keygen_spec.rb | 28 +++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 lib/puppet/functions/dns/dnssec_keygen.rb create mode 100644 spec/functions/dnssec_keygen_spec.rb diff --git a/lib/puppet/functions/dns/dnssec_keygen.rb b/lib/puppet/functions/dns/dnssec_keygen.rb new file mode 100644 index 00000000..f0b475b6 --- /dev/null +++ b/lib/puppet/functions/dns/dnssec_keygen.rb @@ -0,0 +1,28 @@ +require 'tmpdir' + +# @summary Generate a DNSSEC key +Puppet::Functions.create_function(:'dns::dnssec_keygen') do + dispatch :keygen do + param 'String[1]', :name + param "String[1]", :algorithm + optional_param 'Integer[1, 4096]', :keysize + optional_param 'String[1]', :nametype + return_type 'Hash[String, String]' + end + + def keygen(name, algorithm, keysize: nil, nametype: nil) + Dir.mktmpdir do |dir| + command = ['dnssec-keygen', '-K', dir] + command << '-a' << algorithm if algorithm + command << '-k' << keysize if keysize + command << '-n' << nametype if nametype + command << name + Puppet::Util::Execution.execute(command, failonfail: true) + + path = Dir.glob(File.join(dir, "K#{name}.+*.private")).first + raise Exception, 'No file private key generated' unless path + + File.readlines(path, chomp: true).to_h { |line| line.split(': ', 2) } + end + end +end diff --git a/spec/functions/dnssec_keygen_spec.rb b/spec/functions/dnssec_keygen_spec.rb new file mode 100644 index 00000000..d3a75a2d --- /dev/null +++ b/spec/functions/dnssec_keygen_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +describe 'dns::dnssec_keygen' do + it do + expect(Puppet::Util::Execution).to receive(:execute).with(['dnssec-keygen', '-K', kind_of(String), '-a', 'ED25519', 'myname'], failonfail: true) do |command, **kwargs| + dir = command[2] + content = <<~PRIVATE + Private-key-format: v1.3 + Algorithm: 15 (ED25519) + PrivateKey: 7F1qiEoDLvTLlOv+xY46MyI3vtcncqme+DExkz5YiRg= + Created: 20240130104725 + Publish: 20240130104725 + Activate: 20240130104725 + PRIVATE + File.write(File.join(dir, 'Kmyname.+015+04808.private'), content) + end + expected = { + 'Private-key-format' => 'v1.3', + 'Algorithm' => '15 (ED25519)', + 'PrivateKey' => '7F1qiEoDLvTLlOv+xY46MyI3vtcncqme+DExkz5YiRg=', + 'Created' => '20240130104725', + 'Publish' => '20240130104725', + 'Activate' => '20240130104725', + } + + is_expected.to run.with_params('myname', 'ED25519').and_return(expected) + end +end