puppetserver-ca 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/puppetserver/ca/action/clean.rb +102 -0
  3. data/lib/puppetserver/ca/action/create.rb +161 -0
  4. data/lib/puppetserver/ca/action/generate.rb +313 -0
  5. data/lib/puppetserver/ca/action/import.rb +132 -0
  6. data/lib/puppetserver/ca/action/list.rb +132 -0
  7. data/lib/puppetserver/ca/action/revoke.rb +101 -0
  8. data/lib/puppetserver/ca/action/sign.rb +126 -0
  9. data/lib/puppetserver/ca/certificate_authority.rb +224 -0
  10. data/lib/puppetserver/ca/cli.rb +17 -16
  11. data/lib/puppetserver/ca/config/puppet.rb +242 -0
  12. data/lib/puppetserver/ca/config/puppetserver.rb +85 -0
  13. data/lib/puppetserver/ca/utils/cli_parsing.rb +82 -0
  14. data/lib/puppetserver/ca/utils/config.rb +13 -0
  15. data/lib/puppetserver/ca/utils/file_system.rb +90 -0
  16. data/lib/puppetserver/ca/utils/http_client.rb +129 -0
  17. data/lib/puppetserver/ca/utils/signing_digest.rb +27 -0
  18. data/lib/puppetserver/ca/version.rb +1 -1
  19. metadata +17 -17
  20. data/lib/puppetserver/ca/clean_action.rb +0 -157
  21. data/lib/puppetserver/ca/config_utils.rb +0 -11
  22. data/lib/puppetserver/ca/create_action.rb +0 -265
  23. data/lib/puppetserver/ca/generate_action.rb +0 -227
  24. data/lib/puppetserver/ca/import_action.rb +0 -153
  25. data/lib/puppetserver/ca/list_action.rb +0 -153
  26. data/lib/puppetserver/ca/puppet_config.rb +0 -197
  27. data/lib/puppetserver/ca/puppetserver_config.rb +0 -83
  28. data/lib/puppetserver/ca/revoke_action.rb +0 -136
  29. data/lib/puppetserver/ca/sign_action.rb +0 -190
  30. data/lib/puppetserver/ca/utils.rb +0 -80
  31. data/lib/puppetserver/settings/ttl_setting.rb +0 -48
  32. data/lib/puppetserver/utils/file_utilities.rb +0 -78
  33. data/lib/puppetserver/utils/http_client.rb +0 -129
  34. data/lib/puppetserver/utils/signing_digest.rb +0 -25
@@ -1,48 +0,0 @@
1
- # A setting that represents a span of time to live, and evaluates to Numeric
2
- # seconds to live where 0 means shortest possible time to live, a positive numeric value means time
3
- # to live in seconds, and the symbolic entry 'unlimited' is an infinite amount of time.
4
- #
5
- module Puppetserver
6
- module Settings
7
- class TTLSetting
8
- # How we convert from various units to seconds.
9
- UNITMAP = {
10
- # 365 days isn't technically a year, but is sufficient for most purposes
11
- "y" => 365 * 24 * 60 * 60,
12
- "d" => 24 * 60 * 60,
13
- "h" => 60 * 60,
14
- "m" => 60,
15
- "s" => 1
16
- }
17
-
18
- # A regex describing valid formats with groups for capturing the value and units
19
- FORMAT = /^(\d+)(y|d|h|m|s)?$/
20
-
21
- attr_reader :errors, :munged_value
22
-
23
- def initialize(name, setting_value)
24
- @errors = []
25
- @munged_value = munge(setting_value, name)
26
- end
27
-
28
- # Convert the value to Numeric, parsing numeric string with units if necessary.
29
- def munge(value, name)
30
- case
31
- when value.is_a?(Numeric)
32
- if value < 0
33
- @errors << "Invalid negative 'time to live' #{value.inspect} - did you mean 'unlimited'?"
34
- end
35
- value
36
-
37
- when value == 'unlimited'
38
- Float::INFINITY
39
-
40
- when (value.is_a?(String) and value =~ FORMAT)
41
- $1.to_i * UNITMAP[$2 || 's']
42
- else
43
- @errors << "Invalid 'time to live' format '#{value.inspect}' for parameter: #{name}"
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,78 +0,0 @@
1
- require 'fileutils'
2
- require 'etc'
3
-
4
- module Puppetserver
5
- module Utils
6
- class FileUtilities
7
-
8
- def self.instance
9
- @instance ||= new
10
- end
11
-
12
- def self.write_file(*args)
13
- instance.write_file(*args)
14
- end
15
-
16
- def self.ensure_dir(setting)
17
- instance.ensure_dir(setting)
18
- end
19
-
20
- def self.ensure_file(location, content, mode)
21
- if !File.exist?(location)
22
- instance.write_file(location, content, mode)
23
- end
24
- end
25
-
26
- def self.validate_file_paths(one_or_more_paths)
27
- errors = []
28
- Array(one_or_more_paths).each do |path|
29
- if !File.exist?(path) || !File.readable?(path)
30
- errors << "Could not read file '#{path}'"
31
- end
32
- end
33
-
34
- errors
35
- end
36
-
37
- def initialize
38
- @user, @group = find_user_and_group
39
- end
40
-
41
- def find_user_and_group
42
- if !running_as_root?
43
- return Process.euid, Process.egid
44
- else
45
- if pe_puppet_exists?
46
- return 'pe-puppet', 'pe-puppet'
47
- else
48
- return 'puppet', 'puppet'
49
- end
50
- end
51
- end
52
-
53
- def running_as_root?
54
- !Gem.win_platform? && Process.euid == 0
55
- end
56
-
57
- def pe_puppet_exists?
58
- !!(Etc.getpwnam('pe-puppet') rescue nil)
59
- end
60
-
61
- def write_file(path, one_or_more_objects, mode)
62
- File.open(path, 'w', mode) do |f|
63
- Array(one_or_more_objects).each do |object|
64
- f.puts object.to_s
65
- end
66
- end
67
- FileUtils.chown(@user, @group, path)
68
- end
69
-
70
- def ensure_dir(setting)
71
- if !File.exist?(setting)
72
- FileUtils.mkdir_p(setting, mode: 0750)
73
- FileUtils.chown(@user, @group, setting)
74
- end
75
- end
76
- end
77
- end
78
- end
@@ -1,129 +0,0 @@
1
- require 'openssl'
2
- require 'net/https'
3
-
4
- module Puppetserver
5
- module Utils
6
- # Utilities for doing HTTPS against the CA that wraps Net::HTTP constructs
7
- class HttpClient
8
-
9
- HEADERS = {
10
- 'User-Agent' => 'PuppetserverCaCli',
11
- 'Content-Type' => 'application/json',
12
- 'Accept' => 'application/json'
13
- }
14
-
15
- attr_reader :store
16
-
17
- def initialize(settings)
18
- @store = make_store(settings[:localcacert],
19
- settings[:certificate_revocation],
20
- settings[:hostcrl])
21
- @cert = load_cert(settings[:hostcert])
22
- @key = load_key(settings[:hostprivkey])
23
- end
24
-
25
- def load_cert(cert_path)
26
- OpenSSL::X509::Certificate.new(File.read(cert_path))
27
- end
28
-
29
- def load_key(key_path)
30
- OpenSSL::PKey.read(File.read(key_path))
31
- end
32
-
33
- # Returns a URI-like wrapper around CA specific urls
34
- def make_ca_url(host, port, resource_type = nil, certname = nil)
35
- URL.new('https', host, port, 'puppet-ca', 'v1', resource_type, certname)
36
- end
37
-
38
- # Takes an instance URL (defined lower in the file), and creates a
39
- # connection. The given block is passed our own Connection object.
40
- # The Connection object should have HTTP verbs defined on it that take
41
- # a body (and optional overrides). Returns whatever the block given returned.
42
- def with_connection(url, &block)
43
- request = ->(conn) { block.call(Connection.new(conn, url)) }
44
-
45
- Net::HTTP.start(url.host, url.port,
46
- use_ssl: true, cert_store: @store,
47
- cert: @cert, key: @key,
48
- &request)
49
- end
50
-
51
- private
52
- # Helper class that wraps a Net::HTTP connection, a HttpClient::URL
53
- # and defines methods named after HTTP verbs that are called on the
54
- # saved connection, returning a Result.
55
- class Connection
56
- def initialize(net_http_connection, url_struct)
57
- @conn = net_http_connection
58
- @url = url_struct
59
- end
60
-
61
- def get(url_overide = nil)
62
- url = url_overide || @url
63
-
64
- request = Net::HTTP::Get.new(url.to_uri, HEADERS)
65
- result = @conn.request(request)
66
-
67
- Result.new(result.code, result.body)
68
- end
69
-
70
- def put(body, url_override = nil)
71
- url = url_override || @url
72
-
73
- request = Net::HTTP::Put.new(url.to_uri, HEADERS)
74
- request.body = body
75
- result = @conn.request(request)
76
-
77
- Result.new(result.code, result.body)
78
- end
79
-
80
- def delete(url_override = nil)
81
- url = url_override || @url
82
-
83
- result = @conn.request(Net::HTTP::Delete.new(url.to_uri, HEADERS))
84
-
85
- Result.new(result.code, result.body)
86
- end
87
- end
88
-
89
- # Just provide the bits of Net::HTTPResponse we care about
90
- Result = Struct.new(:code, :body)
91
-
92
- # Like URI, but not... maybe of suspicious value
93
- URL = Struct.new(:protocol, :host, :port,
94
- :endpoint, :version,
95
- :resource_type, :resource_name) do
96
- def full_url
97
- protocol + '://' + host + ':' + port + '/' +
98
- [endpoint, version, resource_type, resource_name].join('/')
99
- end
100
-
101
- def to_uri
102
- URI(full_url)
103
- end
104
- end
105
-
106
- def make_store(bundle, crl_usage, crls = nil)
107
- store = OpenSSL::X509::Store.new
108
- store.purpose = OpenSSL::X509::PURPOSE_ANY
109
- store.add_file(bundle)
110
-
111
- if crl_usage != :ignore
112
-
113
- flags = OpenSSL::X509::V_FLAG_CRL_CHECK
114
- if crl_usage == :chain
115
- flags |= OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
116
- end
117
-
118
- store.flags = flags
119
- delimiter = /-----BEGIN X509 CRL-----.*?-----END X509 CRL-----/m
120
- File.read(crls).scan(delimiter).each do |crl|
121
- store.add_crl(OpenSSL::X509::CRL.new(crl))
122
- end
123
- end
124
-
125
- store
126
- end
127
- end
128
- end
129
- end
@@ -1,25 +0,0 @@
1
- module Puppetserver
2
- module Utils
3
- class SigningDigest
4
-
5
- attr_reader :errors, :digest
6
-
7
- def initialize
8
- @errors = []
9
- if OpenSSL::Digest.const_defined?('SHA256')
10
- @digest = OpenSSL::Digest::SHA256.new
11
- elsif OpenSSL::Digest.const_defined?('SHA1')
12
- @digest = OpenSSL::Digest::SHA1.new
13
- elsif OpenSSL::Digest.const_defined?('SHA512')
14
- @digest = OpenSSL::Digest::SHA512.new
15
- elsif OpenSSL::Digest.const_defined?('SHA384')
16
- @digest = OpenSSL::Digest::SHA384.new
17
- elsif OpenSSL::Digest.const_defined?('SHA224')
18
- @digest = OpenSSL::Digest::SHA224.new
19
- else
20
- @errors << "Error: No FIPS 140-2 compliant digest algorithm in OpenSSL::Digest"
21
- end
22
- end
23
- end
24
- end
25
- end