choria-mcorpc-support 2.23.0.pre → 2.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/lib/mcollective.rb +3 -3
  3. data/lib/mcollective/agent/bolt_tasks.ddl +18 -0
  4. data/lib/mcollective/agent/bolt_tasks.json +18 -0
  5. data/lib/mcollective/agent/bolt_tasks.rb +4 -2
  6. data/lib/mcollective/agent/rpcutil.ddl +2 -2
  7. data/lib/mcollective/agent/rpcutil.json +2 -2
  8. data/lib/mcollective/application/choria.rb +3 -63
  9. data/lib/mcollective/application/facts.rb +2 -67
  10. data/lib/mcollective/application/federation.rb +1 -3
  11. data/lib/mcollective/application/find.rb +1 -1
  12. data/lib/mcollective/application/ping.rb +31 -3
  13. data/lib/mcollective/application/plugin.rb +2 -15
  14. data/lib/mcollective/application/tasks.rb +9 -0
  15. data/lib/mcollective/client.rb +1 -1
  16. data/lib/mcollective/config.rb +135 -103
  17. data/lib/mcollective/discovery.rb +12 -65
  18. data/lib/mcollective/discovery/broadcast.ddl +11 -0
  19. data/lib/mcollective/discovery/choria.ddl +6 -4
  20. data/lib/mcollective/discovery/delegate.ddl +13 -0
  21. data/lib/mcollective/discovery/delegate.rb +73 -0
  22. data/lib/mcollective/discovery/external.ddl +13 -0
  23. data/lib/mcollective/discovery/file.ddl +13 -0
  24. data/lib/mcollective/discovery/flatfile.ddl +7 -5
  25. data/lib/mcollective/discovery/inventory.ddl +13 -0
  26. data/lib/mcollective/discovery/mc.ddl +3 -3
  27. data/lib/mcollective/message.rb +0 -24
  28. data/lib/mcollective/optionparser.rb +2 -2
  29. data/lib/mcollective/pluginpackager/forge_packager.rb +1 -1
  30. data/lib/mcollective/rpc/client.rb +6 -4
  31. data/lib/mcollective/security/base.rb +1 -37
  32. data/lib/mcollective/util.rb +23 -31
  33. data/lib/mcollective/util/choria.rb +0 -157
  34. data/lib/mcollective/util/tasks_support.rb +22 -3
  35. metadata +11 -29
  36. data/lib/mcollective/application/describe_filter.rb +0 -87
  37. data/lib/mcollective/data.rb +0 -96
  38. data/lib/mcollective/data/agent_data.ddl +0 -22
  39. data/lib/mcollective/data/agent_data.rb +0 -17
  40. data/lib/mcollective/data/base.rb +0 -68
  41. data/lib/mcollective/data/bolt_task_data.ddl +0 -90
  42. data/lib/mcollective/data/bolt_task_data.rb +0 -32
  43. data/lib/mcollective/data/collective_data.ddl +0 -20
  44. data/lib/mcollective/data/collective_data.rb +0 -9
  45. data/lib/mcollective/data/fact_data.ddl +0 -28
  46. data/lib/mcollective/data/fact_data.rb +0 -55
  47. data/lib/mcollective/data/fstat_data.ddl +0 -89
  48. data/lib/mcollective/data/fstat_data.rb +0 -54
  49. data/lib/mcollective/data/result.rb +0 -50
  50. data/lib/mcollective/ddl/dataddl.rb +0 -56
  51. data/lib/mcollective/discovery/choria.rb +0 -223
  52. data/lib/mcollective/discovery/flatfile.rb +0 -47
  53. data/lib/mcollective/discovery/stdin.ddl +0 -11
  54. data/lib/mcollective/discovery/stdin.rb +0 -67
  55. data/lib/mcollective/generators/data_generator.rb +0 -50
  56. data/lib/mcollective/generators/templates/data_input_snippet.erb +0 -7
  57. data/lib/mcollective/matcher.rb +0 -220
  58. data/lib/mcollective/matcher/parser.rb +0 -118
  59. data/lib/mcollective/matcher/scanner.rb +0 -236
@@ -0,0 +1,13 @@
1
+ metadata :name => "delegate",
2
+ :description => "Choria CLI based delegated discovery",
3
+ :author => "R.I.Pienaar <rip@devco.net>",
4
+ :license => "Apache-2.0",
5
+ :version => "0.1",
6
+ :url => "https://choria.io/",
7
+ :timeout => 2
8
+
9
+ discovery do
10
+ capabilities [:classes, :facts, :identity, :agents, :compound]
11
+ end
12
+
13
+
@@ -0,0 +1,73 @@
1
+ module MCollective
2
+ class Discovery
3
+ class Delegate
4
+ def self.binary_name
5
+ "choria"
6
+ end
7
+
8
+ def self.discover(filter, timeout, limit, client)
9
+ raise("Cannot find the choria binary in your path") unless Util.command_in_path?("choria")
10
+
11
+ cmd = [binary_name, "discover", "-j", "--silent"]
12
+
13
+ cmd << "-T" << filter["collective"] if filter["collective"]
14
+
15
+ filter.fetch("identity", []).each do |i|
16
+ cmd << "-I" << i
17
+ end
18
+
19
+ filter.fetch("cf_class", []).each do |c|
20
+ cmd << "-C" << c
21
+ end
22
+
23
+ filter.fetch("fact", []).each do |f|
24
+ cmd << "-F" << "%s%s%s" % [f[:fact], f[:operator], f[:value]]
25
+ end
26
+
27
+ filter.fetch("agent", []).each do |a|
28
+ cmd << "-A" << a
29
+ end
30
+
31
+ filter.fetch("compound", []).each do |c|
32
+ next unless c.is_a?(Array)
33
+
34
+ cmd << "-S" << c.first["expr"]
35
+ end
36
+
37
+ client.options.fetch(:discovery_options, []).each do |opt|
38
+ cmd << "--do" << opt
39
+ end
40
+
41
+ cmd << "--dm" << (client.options.fetch(:discovery_method, "broadcast") rescue "broadcast")
42
+
43
+ run_discover(cmd, timeout)
44
+ end
45
+
46
+ def self.run_discover(cmd, timeout)
47
+ nodes = []
48
+
49
+ Log.debug("Executing choria for discovery using: %s" % cmd.join(" "))
50
+
51
+ Open3.popen3(ENV, *cmd) do |stdin, stdout, stderr, wait_thr|
52
+ stdin.close
53
+
54
+ begin
55
+ Timeout.timeout(timeout + 0.5) do
56
+ status = wait_thr.value
57
+
58
+ raise("Choria discovery failed: %s" % stderr.read) unless status.exitstatus == 0
59
+ end
60
+ rescue Timeout::Error
61
+ Log.warn("Timeout waiting for Choria to perform discovery")
62
+ Process.kill("KILL", wait_thr[:pid])
63
+ raise("Choria failed to complete discovery within %d timeout" % timeout)
64
+ end
65
+
66
+ nodes.concat(JSON.parse(stdout.read))
67
+ end
68
+
69
+ nodes
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,13 @@
1
+ metadata :name => "external",
2
+ :description => "External executable based discovery",
3
+ :author => "R.I.Pienaar <rip@devco.net>",
4
+ :license => "Apache-2.0",
5
+ :version => "0.1",
6
+ :url => "https://choria.io/",
7
+ :timeout => 2
8
+
9
+ discovery do
10
+ capabilities [:classes, :facts, :identity, :agents, :compound]
11
+ end
12
+
13
+
@@ -0,0 +1,13 @@
1
+ metadata :name => "file",
2
+ :description => "Discovers from JSON, YAML and Text files",
3
+ :author => "R.I.Pienaar <rip@devco.net>",
4
+ :license => "Apache-2.0",
5
+ :version => "0.1",
6
+ :url => "https://choria.io/",
7
+ :timeout => 2
8
+
9
+ discovery do
10
+ capabilities [:identity]
11
+ end
12
+
13
+
@@ -1,11 +1,13 @@
1
1
  metadata :name => "flatfile",
2
- :description => "Flatfile based discovery for node identities",
2
+ :description => "Discovers from JSON, YAML and Text files",
3
3
  :author => "R.I.Pienaar <rip@devco.net>",
4
- :license => "ASL 2.0",
4
+ :license => "Apache-2.0",
5
5
  :version => "0.1",
6
- :url => "https://docs.puppetlabs.com/mcollective/",
7
- :timeout => 0
6
+ :url => "https://choria.io/",
7
+ :timeout => 2
8
8
 
9
9
  discovery do
10
- capabilities :identity
10
+ capabilities [:identity]
11
11
  end
12
+
13
+
@@ -0,0 +1,13 @@
1
+ metadata :name => "delegate",
2
+ :description => "Choria CLI based delegated discovery",
3
+ :author => "R.I.Pienaar <rip@devco.net>",
4
+ :license => "Apache 2.0",
5
+ :version => "0.1",
6
+ :url => "https://choria.io/",
7
+ :timeout => 2
8
+
9
+ discovery do
10
+ capabilities [:classes, :facts, :identity, :agents, :compound]
11
+ end
12
+
13
+
@@ -1,9 +1,9 @@
1
1
  metadata :name => "mc",
2
- :description => "MCollective Broadcast based discovery",
2
+ :description => "Choria Broadcast based discovery",
3
3
  :author => "R.I.Pienaar <rip@devco.net>",
4
- :license => "ASL 2.0",
4
+ :license => "Apache-2.0",
5
5
  :version => "0.1",
6
- :url => "https://docs.puppetlabs.com/mcollective/",
6
+ :url => "https://choria.io",
7
7
  :timeout => 2
8
8
 
9
9
  discovery do
@@ -148,8 +148,6 @@ module MCollective
148
148
  @requestid = request.payload[:requestid]
149
149
  @payload = PluginManager["security_plugin"].encodereply(agent, payload, requestid, request.payload[:callerid])
150
150
  when :request, :direct_request
151
- validate_compound_filter(@filter["compound"]) unless @filter["compound"].empty?
152
-
153
151
  @requestid ||= create_reqid
154
152
  @payload = PluginManager["security_plugin"].encoderequest(Config.instance.identity, payload, requestid, filter, agent, collective, ttl)
155
153
  else
@@ -157,28 +155,6 @@ module MCollective
157
155
  end
158
156
  end
159
157
 
160
- def validate_compound_filter(compound_filter)
161
- compound_filter.each do |filter|
162
- filter.each do |statement|
163
- next unless statement["fstatement"]
164
-
165
- functionname = statement["fstatement"]["name"]
166
- pluginname = Data.pluginname(functionname)
167
- value = statement["fstatement"]["value"]
168
-
169
- ddl = DDL.new(pluginname, :data)
170
-
171
- # parses numbers and booleans entered as strings into proper
172
- # types of data so that DDL validation will pass
173
- statement["fstatement"]["params"] = Data.ddl_transform_input(ddl, statement["fstatement"]["params"])
174
-
175
- Data.ddl_validate(ddl, statement["fstatement"]["params"])
176
-
177
- raise(DDLValidationError, "Data plugin '%s()' does not return a '%s' value" % [functionname, value]) unless value && Data.ddl_has_output?(ddl, value)
178
- end
179
- end
180
- end
181
-
182
158
  def decode!
183
159
  raise "Cannot decode message type #{type}" unless [:request, :reply].include?(type)
184
160
 
@@ -86,7 +86,7 @@ module MCollective
86
86
  end
87
87
 
88
88
  @parser.on("-S", "--select FILTER", "Compound filter combining facts and classes") do |f|
89
- @options[:filter]["compound"] << Matcher.create_compound_callstack(f)
89
+ @options[:filter]["compound"] << [{"expr" => f}]
90
90
  end
91
91
 
92
92
  @parser.on("-F", "--wf", "--with-fact fact=val", "Match hosts with a certain fact") do |f|
@@ -168,7 +168,7 @@ module MCollective
168
168
  raise "Cannot read the discovery file #{v}" unless File.readable?(v)
169
169
 
170
170
  @options[:discovery_method] = "flatfile"
171
- @options[:discovery_options] << v
171
+ @options[:discovery_options] << "file=%s" % v
172
172
  end
173
173
 
174
174
  @parser.on("--publish_timeout TIMEOUT", Integer, "Timeout for publishing requests to remote agents.") do |pt|
@@ -191,7 +191,7 @@ module MCollective
191
191
  end
192
192
 
193
193
  def render_template(infile, outfile)
194
- erb = ERB.new(File.read(infile), 0, "%")
194
+ erb = ERB.new(File.read(infile), 0, "-")
195
195
  File.open(outfile, "w") do |f|
196
196
  f.puts erb.result(binding)
197
197
  end
@@ -442,7 +442,7 @@ module MCollective
442
442
 
443
443
  # Set a compound filter
444
444
  def compound_filter(filter)
445
- @filter["compound"] = @filter["compound"] | [Matcher.create_compound_callstack(filter)]
445
+ @filter["compound"] = @filter["compound"] | [[{"expr" => filter}]]
446
446
  reset
447
447
  end
448
448
 
@@ -533,6 +533,8 @@ module MCollective
533
533
 
534
534
  # All else fails we do it the hard way using a traditional broadcast
535
535
  unless @discovered_agents
536
+ raise("Invalid discovery method %s" % discovery_method) unless @client.discoverer.find_known_methods.include?(discovery_method)
537
+
536
538
  @stats.time_discovery :start
537
539
 
538
540
  @client.options = options
@@ -548,9 +550,9 @@ module MCollective
548
550
  actual_timeout = @client.discoverer.discovery_timeout(discovery_timeout, options[:filter])
549
551
 
550
552
  if actual_timeout > 0
551
- @stderr.print("Discovering hosts using the %s method for %d second(s) .... " % [@client.discoverer.discovery_method, actual_timeout])
553
+ @stderr.print("Discovering hosts using the %s method for %d second(s) .... " % [discovery_method, actual_timeout])
552
554
  else
553
- @stderr.print("Discovering hosts using the %s method .... " % [@client.discoverer.discovery_method])
555
+ @stderr.print("Discovering hosts using the %s method .... " % discovery_method)
554
556
  end
555
557
  end
556
558
 
@@ -822,7 +824,7 @@ module MCollective
822
824
  @stdout.print twirl.twirl(respcount, discovered.size)
823
825
  end
824
826
 
825
- if batch_size =~ /^(\d+)%$/
827
+ if batch_size.is_a?(String) && batch_size =~ /^(\d+)%$/
826
828
  # determine batch_size as a percentage of the discovered array's size
827
829
  batch_size = (discovered.size / 100.0 * Integer($1)).ceil
828
830
  else
@@ -72,43 +72,7 @@ module MCollective
72
72
  end
73
73
 
74
74
  when "compound"
75
- filter[key].each do |compound|
76
- result = false
77
- truth_values = []
78
-
79
- begin
80
- compound.each do |expression|
81
- case expression.keys.first
82
- when "statement"
83
- truth_values << Matcher.eval_compound_statement(expression).to_s
84
- when "fstatement"
85
- truth_values << Matcher.eval_compound_fstatement(expression.values.first)
86
- when "and"
87
- truth_values << "&&"
88
- when "or"
89
- truth_values << "||"
90
- when "("
91
- truth_values << "("
92
- when ")"
93
- truth_values << ")"
94
- when "not"
95
- truth_values << "!"
96
- end
97
- end
98
-
99
- result = eval(truth_values.join(" ")) # rubocop:disable Security/Eval
100
- rescue DDLValidationError
101
- result = false
102
- end
103
-
104
- if result
105
- Log.debug("Passing based on class and fact composition")
106
- passed += 1
107
- else
108
- Log.debug("Failing based on class and fact composition")
109
- failed += 1
110
- end
111
- end
75
+ # removed while rebuilding compound filters, this whole method is probably unused now
112
76
 
113
77
  when "agent"
114
78
  filter[key].each do |f|
@@ -156,19 +156,23 @@ module MCollective
156
156
  File.join(Dir::COMMON_APPDATA, "ChoriaIO", "choria")
157
157
  end
158
158
 
159
- def self.mcollective_config_paths_for_user
159
+ def self.config_paths_for_user
160
160
  config_paths = []
161
161
 
162
- begin
163
- # File.expand_path will raise if HOME isn't set, catch it
164
- user_path = File.expand_path("~/.mcollective")
165
- config_paths << user_path
166
- rescue Exception # rubocop:disable Lint/RescueException, Lint/SuppressedException
162
+ ["~/.choriarc", "~/.mcollective"].each do |f|
163
+ begin
164
+ # File.expand_path will raise if HOME isn't set, catch it
165
+ config_paths << File.expand_path(f)
166
+ rescue ArgumentError # rubocop:disable Lint/SuppressedException
167
+ end
167
168
  end
168
169
 
169
170
  if windows?
171
+ config_paths << File.join(choria_windows_prefix, "etc", "client.conf")
170
172
  config_paths << File.join(windows_prefix, "etc", "client.cfg")
171
173
  else
174
+ config_paths << "/etc/choria/client.conf"
175
+ config_paths << "/usr/local/etc/choria/client.conf"
172
176
  config_paths << "/etc/puppetlabs/mcollective/client.cfg"
173
177
  config_paths << "/etc/mcollective/client.cfg"
174
178
  config_paths << "/usr/local/etc/mcollective/client.cfg"
@@ -177,42 +181,30 @@ module MCollective
177
181
  config_paths
178
182
  end
179
183
 
180
- def self.choria_config_paths_for_user
181
- config_paths = []
182
-
183
- begin
184
- # File.expand_path will raise if HOME isn't set, catch it
185
- user_path = File.expand_path("~/.choriarc")
186
- config_paths << user_path
187
- rescue Exception # rubocop:disable Lint/RescueException, Lint/SuppressedException
188
- end
189
-
190
- if windows?
191
- config_paths << File.join(choria_windows_prefix, "etc", "client.conf")
192
- else
193
- config_paths << "/etc/choria/client.conf"
194
- config_paths << "/usr/local/etc/choria/client.conf"
195
- end
196
-
197
- config_paths
198
- end
199
-
200
184
  # Picks the default user config file, priorities are first Choria ones then old MCollective ones
201
185
  #
202
186
  # In roughly this order, first to exist is used:
203
187
  #
204
188
  # - ~/.choriarc
205
- # - APPData/ChoriaIO/choria/etc/client.conf on windows
206
- # - /etc/choria/client.conf then
207
- # - /usr/local/etc/choria/client.conf on unix
208
189
  # - ~/.mcollective
209
- # - APPData/PuppetLabs/mcollective/etc/client.cfg on windows
190
+ #
191
+ # On Unix:
192
+ #
193
+ # - /etc/choria/client.conf
194
+ # - /usr/local/etc/choria/client.conf
210
195
  # - /etc/puppetlabs/mcollective/client.cfg
211
196
  # - /etc/mcollective/client.cfg
212
197
  # - /usr/local/etc/mcollective/client.cfg
198
+ #
199
+ # On Windows:
200
+ #
201
+ # - APPData/ChoriaIO/choria/etc/client.conf on windows
202
+ # - APPData/PuppetLabs/mcollective/etc/client.cfg on windows
213
203
  def self.config_file_for_user
214
- config_paths = choria_config_paths_for_user + mcollective_config_paths_for_user
204
+ config_paths = config_paths_for_user
205
+
215
206
  found = config_paths.find_index { |file| File.readable?(file) } || 0
207
+
216
208
  config_paths[found]
217
209
  end
218
210
 
@@ -86,14 +86,6 @@ module MCollective
86
86
  end
87
87
  end
88
88
 
89
- # Which port to provide stats over HTTP on
90
- #
91
- # @return [Integer,nil]
92
- # @raise [StandardError] when not numeric
93
- def stats_port
94
- Integer(get_option("choria.stats_port", "")) if has_option?("choria.stats_port")
95
- end
96
-
97
89
  # Determines if there are any federations configured
98
90
  #
99
91
  # @return [Boolean]
@@ -888,15 +880,6 @@ module MCollective
888
880
  File.exist?(csr_path)
889
881
  end
890
882
 
891
- # The formatted string representation of the CSR fingerprint
892
- #
893
- # @return [String]
894
- def csr_fingerprint
895
- require "puppet"
896
- csr = OpenSSL::X509::Request.new(File.read(csr_path))
897
- Puppet::SSL::Digest.new(nil, csr.to_der)
898
- end
899
-
900
883
  # Searches the PATH for an executable command
901
884
  #
902
885
  # @param command [String] a command to search for
@@ -927,146 +910,6 @@ module MCollective
927
910
  which("facter")
928
911
  end
929
912
 
930
- # Creates any missing SSL directories
931
- #
932
- # This prepares a Puppet like SSL tree in case Puppet
933
- # has not been initialized yet
934
- #
935
- # @return [void]
936
- def make_ssl_dirs
937
- return if file_security?
938
-
939
- FileUtils.mkdir_p(ssl_dir, :mode => 0o0771)
940
-
941
- ["certificate_requests", "certs", "public_keys"].each do |dir|
942
- FileUtils.mkdir_p(File.join(ssl_dir, dir), :mode => 0o0755)
943
- end
944
-
945
- ["private_keys", "private"].each do |dir|
946
- FileUtils.mkdir_p(File.join(ssl_dir, dir), :mode => 0o0750)
947
- end
948
- end
949
-
950
- # Creates a RSA key of a certain strenth
951
- #
952
- # @return [OpenSSL::PKey::RSA]
953
- def create_rsa_key(bits)
954
- OpenSSL::PKey::RSA.new(bits)
955
- end
956
-
957
- # Writes a new 4096 bit key in the puppet default locatioj
958
- #
959
- # @return [OpenSSL::PKey::RSA]
960
- # @raise [StandardError] when the key already exist
961
- def write_key
962
- raise("Refusing to overwrite existing key in %s" % client_private_key) if has_client_private_key?
963
-
964
- key = create_rsa_key(4096)
965
- File.open(client_private_key, "w", 0o0640) {|f| f.write(key.to_pem)}
966
-
967
- key
968
- end
969
-
970
- # Creates a basic CSR
971
- #
972
- # @return [OpenSSL::X509::Request] signed CSR
973
- def create_csr(comonname, orgunit, key)
974
- csr = OpenSSL::X509::Request.new
975
- csr.version = 0
976
- csr.public_key = key.public_key
977
- csr.subject = OpenSSL::X509::Name.new(
978
- [
979
- ["CN", comonname, OpenSSL::ASN1::UTF8STRING],
980
- ["OU", orgunit, OpenSSL::ASN1::UTF8STRING]
981
- ]
982
- )
983
- csr.sign(key, OpenSSL::Digest.new("SHA1"))
984
-
985
- csr
986
- end
987
-
988
- # Creates a new CSR signed by the given key
989
- #
990
- # @param key [OpenSSL::PKey::RSA]
991
- # @return [String] PEM encoded CSR
992
- def write_csr(key)
993
- raise("Refusing to overwrite existing CSR in %s" % csr_path) if has_csr?
994
-
995
- csr = create_csr(certname, "mcollective", key)
996
-
997
- File.open(csr_path, "w", 0o0644) {|f| f.write(csr.to_pem)}
998
-
999
- csr.to_pem
1000
- end
1001
-
1002
- # Fetch and save the CA from Puppet
1003
- #
1004
- # @return [Boolean]
1005
- def fetch_ca
1006
- return true if has_ca?
1007
-
1008
- server = puppetca_server
1009
-
1010
- req = http_get("/puppet-ca/v1/certificate/ca?environment=production", "Accept" => "text/plain")
1011
- resp, _ = https(server).request(req)
1012
-
1013
- if resp.code == "200"
1014
- File.open(ca_path, "w", 0o0644) {|f| f.write(resp.body)}
1015
- else
1016
- raise(UserError, "Failed to fetch CA from %s:%s: %s: %s" % [server[:target], server[:port], resp.code, resp.message])
1017
- end
1018
-
1019
- has_ca?
1020
- end
1021
-
1022
- # Requests a certificate from the Puppet CA
1023
- #
1024
- # This will attempt to create a new key, write a CSR and
1025
- # then sends it to the CA for signing
1026
- #
1027
- # @return [Boolean]
1028
- # @raise [UserError] when requesting the cert fails
1029
- def request_cert
1030
- key = write_key
1031
- csr = write_csr(key)
1032
-
1033
- server = puppetca_server
1034
-
1035
- req = Net::HTTP::Put.new("/puppet-ca/v1/certificate_request/%s?environment=production" % certname, "Content-Type" => "text/plain")
1036
- req.body = csr
1037
- resp, _ = https(server).request(req)
1038
-
1039
- if resp.code == "200"
1040
- true
1041
- else
1042
- raise(UserError, "Failed to request certificate from %s:%s: %s: %s: %s" % [server[:target], server[:port], resp.code, resp.message, resp.body])
1043
- end
1044
- end
1045
-
1046
- # Attempts to fetch a cert from the CA
1047
- #
1048
- # @return [Boolean]
1049
- def attempt_fetch_cert
1050
- return true if has_client_public_cert?
1051
-
1052
- req = http_get("/puppet-ca/v1/certificate/%s?environment=production" % certname, "Accept" => "text/plain")
1053
- resp, _ = https(puppetca_server).request(req)
1054
-
1055
- if resp.code == "200"
1056
- File.open(client_public_cert, "w", 0o0644) {|f| f.write(resp.body)}
1057
- true
1058
- else
1059
- false
1060
- end
1061
- end
1062
-
1063
- # Determines if a CSR has been sent but not yet retrieved
1064
- #
1065
- # @return [Boolean]
1066
- def waiting_for_cert?
1067
- !has_client_public_cert? && has_client_private_key?
1068
- end
1069
-
1070
913
  # Gets a config option
1071
914
  #
1072
915
  # @param opt [String] config option to look up