Class: Puppet::Util::Puppetdb::Command

Inherits:
Object
  • Object
show all
Includes:
Puppet::Util::Puppetdb, CommandNames
Defined in:
lib/puppet/util/puppetdb/command.rb

Constant Summary collapse

CommandsUrl =
"/v3/commands"

Constants included from CommandNames

Puppet::Util::Puppetdb::CommandNames::CommandDeactivateNode, Puppet::Util::Puppetdb::CommandNames::CommandReplaceCatalog, Puppet::Util::Puppetdb::CommandNames::CommandReplaceFacts, Puppet::Util::Puppetdb::CommandNames::CommandStoreReport

Instance Attribute Summary collapse

Private class methods collapse

Private instance methods collapse

Instance Method Summary collapse

Methods included from Puppet::Util::Puppetdb

config, included, log_x_deprecation_header, port, #profile, puppet3compat?, server, #submit_command, to_bool, to_wire_time, url_path

Constructor Details

#initialize(command, version, certname, payload) ⇒ Command

Initialize a Command object, for later submission.

Parameters:

  • command

    String the name of the command; should be one of the constants defined in ‘Puppet::Util::Puppetdb::CommandNames`

  • version

    Integer the command version number

  • certname

    The certname that this command operates on (is not included in the actual submission)

  • payload

    Object the payload of the command. This object should be a primitive (numeric type, string, array, or hash) that is natively supported by JSON serialization / deserialization libraries.



26
27
28
29
30
31
32
33
# File 'lib/puppet/util/puppetdb/command.rb', line 26

def initialize(command, version, certname, payload)
  @command = command
  @version = version
  @certname = certname
  profile("Format payload", [:puppetdb, :payload, :format]) do
    @payload = self.class.format_payload(command, version, payload)
  end
end

Instance Attribute Details

#certnameObject (readonly)

Returns the value of attribute certname.



35
36
37
# File 'lib/puppet/util/puppetdb/command.rb', line 35

def certname
  @certname
end

#commandObject (readonly)

Returns the value of attribute command.



35
36
37
# File 'lib/puppet/util/puppetdb/command.rb', line 35

def command
  @command
end

#payloadObject (readonly)

Returns the value of attribute payload.



35
36
37
# File 'lib/puppet/util/puppetdb/command.rb', line 35

def payload
  @payload
end

#versionObject (readonly)

Returns the value of attribute version.



35
36
37
# File 'lib/puppet/util/puppetdb/command.rb', line 35

def version
  @version
end

Class Method Details

.format_payload(command, version, payload) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



87
88
89
90
91
92
93
94
95
# File 'lib/puppet/util/puppetdb/command.rb', line 87

def self.format_payload(command, version, payload)
  message = {
    :command => command,
    :version => version,
    :payload => payload,
  }.to_pson

  Puppet::Util::Puppetdb::CharEncoding.utf8_string(message)
end

Instance Method Details

#configObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



108
109
110
111
112
# File 'lib/puppet/util/puppetdb/command.rb', line 108

def config
  # Would prefer to pass this to the constructor or acquire it some other
  # way besides this pseudo-global reference.
  Puppet::Util::Puppetdb.config
end

#headersObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



100
101
102
103
104
105
# File 'lib/puppet/util/puppetdb/command.rb', line 100

def headers
  {
    "Accept" => "application/json",
    "Content-Type" => "application/json",
  }
end

#submitHash <String, String>

Submit the command, returning the result hash.

Returns:

  • (Hash <String, String>)


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
# File 'lib/puppet/util/puppetdb/command.rb', line 40

def submit
  checksum = Digest::SHA1.hexdigest(payload)

  for_whom = " for #{certname}" if certname

  begin
    response = profile("Submit command HTTP post", [:puppetdb, :command, :submit]) do
      http = Puppet::Network::HttpPool.http_instance(config.server, config.port)
      http.post(Puppet::Util::Puppetdb.url_path(CommandsUrl + "?checksum=#{checksum}"),
                payload, headers)
    end

    Puppet::Util::Puppetdb.log_x_deprecation_header(response)

    if response.is_a? Net::HTTPSuccess
      result = JSON.parse(response.body)
      Puppet.info "'#{command}' command#{for_whom} submitted to PuppetDB with UUID #{result['uuid']}"
      result
    else
      # Newline characters cause an HTTP error, so strip them
      error = "[#{response.code} #{response.message}] #{response.body.gsub(/[\r\n]/, '')}"
      if config.soft_write_failure
        Puppet.err "'#{command}'command#{for_whom} failed during submission to PuppetDB: #{error}"
      else
        raise Puppet::Error, error
      end
    end
  rescue => e
    error = "Failed to submit '#{command}' command#{for_whom} to PuppetDB at #{config.server}:#{config.port}: #{e}"
    if config.soft_write_failure
      Puppet.err error
    else
      # TODO: Use new exception handling methods from Puppet 3.0 here as soon as
      #  we are able to do so (can't call them yet w/o breaking backwards
      #  compatibility.)  We should either be using a nested exception or calling
      #  Puppet::Util::Logging#log_exception or #log_and_raise here; w/o them
      #  we lose context as to where the original exception occurred.
      puts e, e.backtrace if Puppet[:trace]
      raise Puppet::Error, error
    end
  end
end