File: clean.rb

package info (click to toggle)
puppet-agent 8.10.0-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,404 kB
  • sloc: ruby: 286,820; sh: 492; xml: 116; makefile: 88; cs: 68
file content (109 lines) | stat: -rw-r--r-- 3,391 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# frozen_string_literal: true

Puppet::Face.define(:node, '0.0.1') do
  action(:clean) do
    summary _("Clean up signed certs, cached facts, node objects, and reports for a node stored by the puppetmaster")
    arguments _("<host1> [<host2> ...]")
    description <<-'EOT'
      Cleans up the following information a puppet master knows about a node:

      <Signed certificates> - ($vardir/ssl/ca/signed/node.domain.pem)

      <Cached facts> - ($vardir/yaml/facts/node.domain.yaml)

      <Cached node objects> - ($vardir/yaml/node/node.domain.yaml)

      <Reports> - ($vardir/reports/node.domain)

      NOTE: this action now cleans up certs via Puppet Server's CA API. A running server is required for certs to be cleaned.
    EOT

    when_invoked do |*args|
      nodes = args[0..-2]
      options = args.last
      raise _("At least one node should be passed") if nodes.empty? || nodes == options

      # This seems really bad; run_mode should be set as part of a class
      # definition, and should not be modifiable beyond that.  This is one of
      # the only places left in the code that tries to manipulate it. Other
      # parts of code that handle certificates behave differently if the
      # run_mode is server. Those other behaviors are needed for cleaning the
      # certificates correctly.
      Puppet.settings.preferred_run_mode = "server"

      Puppet::Node::Facts.indirection.terminus_class = :yaml
      Puppet::Node::Facts.indirection.cache_class = :yaml
      Puppet::Node.indirection.terminus_class = :yaml
      Puppet::Node.indirection.cache_class = :yaml

      nodes.each { |node| cleanup(node.downcase) }
    end
  end

  def cleanup(node)
    clean_cert(node)
    clean_cached_facts(node)
    clean_cached_node(node)
    clean_reports(node)
  end

  class LoggerIO
    def debug(message)
      Puppet.debug(message)
    end

    def warn(message)
      Puppet.warning(message) unless message =~ /cadir is currently configured to be inside/
    end

    def err(message)
      Puppet.err(message) unless message =~ /^\s*Error:\s*/
    end

    def inform(message)
      Puppet.notice(message)
    end
  end

  # clean signed cert for +host+
  def clean_cert(node)
    if Puppet.features.puppetserver_ca?
      Puppetserver::Ca::Action::Clean.new(LoggerIO.new).run({ 'certnames' => [node] })
    else
      Puppet.info _("Not managing %{node} certs as this host is not a CA") % { node: node }
    end
  end

  # clean facts for +host+
  def clean_cached_facts(node)
    Puppet::Node::Facts.indirection.destroy(node)
    Puppet.info _("%{node}'s facts removed") % { node: node }
  end

  # clean cached node +host+
  def clean_cached_node(node)
    Puppet::Node.indirection.destroy(node)
    Puppet.info _("%{node}'s cached node removed") % { node: node }
  end

  # clean node reports for +host+
  def clean_reports(node)
    Puppet::Transaction::Report.indirection.destroy(node)
    Puppet.info _("%{node}'s reports removed") % { node: node }
  end

  def environment
    @environment ||= Puppet.lookup(:current_environment)
  end

  def type_is_ensurable(resource)
    if (type = Puppet::Type.type(resource.restype)) && type.validattr?(:ensure)
      return true
    else
      type = environment.known_resource_types.find_definition(resource.restype)
      return true if type && type.arguments.keys.include?('ensure')
    end

    false
  end
end