puppet-rest 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +7 -0
- data/.pryrc +58 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +73 -0
- data/LICENSE.txt +20 -0
- data/README.md +81 -0
- data/Rakefile +3 -0
- data/lib/puppet-rest.rb +43 -0
- data/lib/puppet-rest/db/client.rb +42 -0
- data/lib/puppet-rest/db/config.rb +83 -0
- data/lib/puppet-rest/db/connection.rb +26 -0
- data/lib/puppet-rest/db/connection/fact-names.rb +9 -0
- data/lib/puppet-rest/db/connection/facts.rb +11 -0
- data/lib/puppet-rest/db/connection/nodes.rb +32 -0
- data/lib/puppet-rest/db/connection/resources.rb +11 -0
- data/lib/puppet-rest/db/entities/base.rb +100 -0
- data/lib/puppet-rest/db/entities/fact.rb +9 -0
- data/lib/puppet-rest/db/entities/node.rb +22 -0
- data/lib/puppet-rest/db/entities/resource.rb +12 -0
- data/lib/puppet-rest/db/request.rb +74 -0
- data/lib/puppet-rest/error.rb +42 -0
- data/lib/puppet-rest/identity_map.rb +4 -0
- data/lib/puppet-rest/monkey_patches/array.rb +7 -0
- data/lib/puppet-rest/monkey_patches/enumerable.rb +11 -0
- data/lib/puppet-rest/monkey_patches/hash.rb +49 -0
- data/lib/puppet-rest/monkey_patches/mash.rb +219 -0
- data/lib/puppet-rest/pe/client.rb +42 -0
- data/lib/puppet-rest/pe/config.rb +93 -0
- data/lib/puppet-rest/pe/connection.rb +25 -0
- data/lib/puppet-rest/pe/connection/ca_cert.rb +10 -0
- data/lib/puppet-rest/pe/connection/catalog.rb +10 -0
- data/lib/puppet-rest/pe/connection/node.rb +10 -0
- data/lib/puppet-rest/pe/entities/base.rb +100 -0
- data/lib/puppet-rest/pe/entities/catalog.rb +16 -0
- data/lib/puppet-rest/pe/entities/node.rb +9 -0
- data/lib/puppet-rest/pe/request.rb +77 -0
- data/lib/puppet-rest/response/client_error.rb +33 -0
- data/lib/puppet-rest/response/parse_json.rb +26 -0
- data/lib/puppet-rest/version.rb +3 -0
- data/puppet-rest.gemspec +28 -0
- data/spec/certificates/ca.pem +35 -0
- data/spec/certificates/cert.pem +35 -0
- data/spec/certificates/pk.pem +51 -0
- data/spec/spec_helper.rb +9 -0
- metadata +143 -0
@@ -0,0 +1,219 @@
|
|
1
|
+
# Copyright (c) 2009 Dan Kubb
|
2
|
+
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
# ---
|
23
|
+
# ---
|
24
|
+
|
25
|
+
# Some portions of blank.rb and mash.rb are verbatim copies of software
|
26
|
+
# licensed under the MIT license. That license is included below:
|
27
|
+
|
28
|
+
# Copyright (c) 2005-2008 David Heinemeier Hansson
|
29
|
+
|
30
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
31
|
+
# a copy of this software and associated documentation files (the
|
32
|
+
# "Software"), to deal in the Software without restriction, including
|
33
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
34
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
35
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
36
|
+
# the following conditions:
|
37
|
+
|
38
|
+
# The above copyright notice and this permission notice shall be
|
39
|
+
# included in all copies or substantial portions of the Software.
|
40
|
+
|
41
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
42
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
43
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
44
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
45
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
46
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
47
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
48
|
+
|
49
|
+
# This class has dubious semantics and we only have it so that people can write
|
50
|
+
# params[:key] instead of params['key'].
|
51
|
+
class Mash < Hash
|
52
|
+
|
53
|
+
# @param constructor<Object>
|
54
|
+
# The default value for the mash. Defaults to an empty hash.
|
55
|
+
#
|
56
|
+
# [Alternatives]
|
57
|
+
# If constructor is a Hash, a new mash will be created based on the keys of
|
58
|
+
# the hash and no default value will be set.
|
59
|
+
def initialize(constructor = {})
|
60
|
+
if constructor.is_a?(Hash)
|
61
|
+
super()
|
62
|
+
update(constructor)
|
63
|
+
else
|
64
|
+
super(constructor)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param orig<Object> Mash being copied
|
69
|
+
#
|
70
|
+
# @return [Object] A new copied Mash
|
71
|
+
def initialize_copy(orig)
|
72
|
+
super
|
73
|
+
# Handle nested values
|
74
|
+
each do |k,v|
|
75
|
+
if v.kind_of?(Mash) || v.is_a?(Array)
|
76
|
+
self[k] = v.dup
|
77
|
+
end
|
78
|
+
end
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
# @param key<Object> The default value for the mash. Defaults to nil.
|
83
|
+
#
|
84
|
+
# [Alternatives]
|
85
|
+
# If key is a Symbol and it is a key in the mash, then the default value will
|
86
|
+
# be set to the value matching the key.
|
87
|
+
def default(key = nil)
|
88
|
+
if key.is_a?(Symbol) && include?(key = key.to_s)
|
89
|
+
self[key]
|
90
|
+
else
|
91
|
+
super
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
96
|
+
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
97
|
+
|
98
|
+
# @param key<Object> The key to set.
|
99
|
+
# @param value<Object>
|
100
|
+
# The value to set the key to.
|
101
|
+
#
|
102
|
+
# @see Mash#convert_key
|
103
|
+
# @see Mash#convert_value
|
104
|
+
def []=(key, value)
|
105
|
+
regular_writer(convert_key(key), convert_value(value))
|
106
|
+
end
|
107
|
+
|
108
|
+
# @param other_hash<Hash>
|
109
|
+
# A hash to update values in the mash with. The keys and the values will be
|
110
|
+
# converted to Mash format.
|
111
|
+
#
|
112
|
+
# @return [Mash] The updated mash.
|
113
|
+
def update(other_hash)
|
114
|
+
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
alias_method :merge!, :update
|
119
|
+
|
120
|
+
# @param key<Object> The key to check for. This will be run through convert_key.
|
121
|
+
#
|
122
|
+
# @return [Boolean] True if the key exists in the mash.
|
123
|
+
def key?(key)
|
124
|
+
super(convert_key(key))
|
125
|
+
end
|
126
|
+
|
127
|
+
# def include? def has_key? def member?
|
128
|
+
alias_method :include?, :key?
|
129
|
+
alias_method :has_key?, :key?
|
130
|
+
alias_method :member?, :key?
|
131
|
+
|
132
|
+
# @param key<Object> The key to fetch. This will be run through convert_key.
|
133
|
+
# @param extras<Array> Default value.
|
134
|
+
#
|
135
|
+
# @return [Object] The value at key or the default value.
|
136
|
+
def fetch(key, *extras)
|
137
|
+
super(convert_key(key), *extras)
|
138
|
+
end
|
139
|
+
|
140
|
+
# @param indices<Array>
|
141
|
+
# The keys to retrieve values for. These will be run through +convert_key+.
|
142
|
+
#
|
143
|
+
# @return [Array] The values at each of the provided keys
|
144
|
+
def values_at(*indices)
|
145
|
+
indices.collect {|key| self[convert_key(key)]}
|
146
|
+
end
|
147
|
+
|
148
|
+
# @param hash<Hash> The hash to merge with the mash.
|
149
|
+
#
|
150
|
+
# @return [Mash] A new mash with the hash values merged in.
|
151
|
+
def merge(hash)
|
152
|
+
self.dup.update(hash)
|
153
|
+
end
|
154
|
+
|
155
|
+
# @param key<Object>
|
156
|
+
# The key to delete from the mash.\
|
157
|
+
def delete(key)
|
158
|
+
super(convert_key(key))
|
159
|
+
end
|
160
|
+
|
161
|
+
# @return [Mash] A new mash without the selected keys.
|
162
|
+
#
|
163
|
+
# @example
|
164
|
+
# { :one => 1, :two => 2, :three => 3 }.except(:one)
|
165
|
+
# #=> { "two" => 2, "three" => 3 }
|
166
|
+
def except(*keys)
|
167
|
+
super(*keys.map {|k| convert_key(k)})
|
168
|
+
end
|
169
|
+
|
170
|
+
# Used to provide the same interface as Hash.
|
171
|
+
#
|
172
|
+
# @return [Mash] This mash unchanged.
|
173
|
+
def stringify_keys!; self end
|
174
|
+
|
175
|
+
# @return [Hash] The mash as a Hash with symbolized keys.
|
176
|
+
def symbolize_keys
|
177
|
+
h = Hash.new(default)
|
178
|
+
each { |key, val| h[key.to_sym] = val }
|
179
|
+
h
|
180
|
+
end
|
181
|
+
|
182
|
+
# @return [Hash] The mash as a Hash with string keys.
|
183
|
+
def to_hash
|
184
|
+
Hash.new(default).merge(self)
|
185
|
+
end
|
186
|
+
|
187
|
+
# @return [Mash] Convert a Hash into a Mash
|
188
|
+
# The input Hash's default value is maintained
|
189
|
+
def self.from_hash(hash)
|
190
|
+
mash = Mash.new(hash)
|
191
|
+
mash.default = hash.default
|
192
|
+
mash
|
193
|
+
end
|
194
|
+
|
195
|
+
protected
|
196
|
+
# @param key<Object> The key to convert.
|
197
|
+
#
|
198
|
+
# @api private
|
199
|
+
def convert_key(key)
|
200
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
201
|
+
end
|
202
|
+
|
203
|
+
# @param value<Object> The value to convert.
|
204
|
+
#
|
205
|
+
# @return [Object]
|
206
|
+
# The converted value. A Hash or an Array of hashes, will be converted to
|
207
|
+
# their Mash equivalents.
|
208
|
+
#
|
209
|
+
# @api private
|
210
|
+
def convert_value(value)
|
211
|
+
if value.class == Hash
|
212
|
+
Mash.from_hash(value)
|
213
|
+
elsif value.is_a?(Array)
|
214
|
+
value.collect { |e| convert_value(e) }
|
215
|
+
else
|
216
|
+
value
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module PuppetRestClient::PE
|
2
|
+
extend PuppetRestClient::PE::Config
|
3
|
+
|
4
|
+
class << self
|
5
|
+
# Convenience alias for PuppetRestClient::DbConnection.new
|
6
|
+
#
|
7
|
+
# return [PuppetRestClient::DbConnection]
|
8
|
+
def new(options=Mash.new)
|
9
|
+
PuppetRestClient::PE::Connection.new(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Delegate methods to PuppetRestClient::Connection
|
13
|
+
def method_missing(method, *args, &block)
|
14
|
+
return super unless new.respond_to?(method)
|
15
|
+
new.send(method, *args, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def respond_to?(method, include_private=false)
|
19
|
+
new.respond_to?(method, include_private) || super(method, include_private)
|
20
|
+
end
|
21
|
+
|
22
|
+
def read_key_file(path)
|
23
|
+
key_file_path = File.expand_path(path)
|
24
|
+
|
25
|
+
begin
|
26
|
+
raw_key = File.read(key_file_path).strip
|
27
|
+
rescue SystemCallError, IOError => e
|
28
|
+
raise IOError, "Unable to read #{key_file_path}"
|
29
|
+
end
|
30
|
+
|
31
|
+
begin_rsa = '-----BEGIN RSA PRIVATE KEY-----'
|
32
|
+
end_rsa = '-----END RSA PRIVATE KEY-----'
|
33
|
+
|
34
|
+
unless (raw_key =~ /\A#{begin_rsa}$/) && (raw_key =~ /^#{end_rsa}\Z/)
|
35
|
+
msg = "The file #{key_file_path} is not a properly formatted private key.\n"
|
36
|
+
msg << "It must contain '#{begin_rsa}' and '#{end_rsa}'"
|
37
|
+
raise ArgumentError, msg
|
38
|
+
end
|
39
|
+
return OpenSSL::PKey::RSA.new(raw_key)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module PuppetRestClient::PE
|
2
|
+
module Config
|
3
|
+
|
4
|
+
# The default Chef server URL
|
5
|
+
DEFAULT_SERVER_URL = 'http://localhost:8140'
|
6
|
+
|
7
|
+
# The default Spice User-Agent header
|
8
|
+
DEFAULT_USER_AGENT = "PuppetRestClient #{PuppetRestClient::VERSION}"
|
9
|
+
|
10
|
+
# Default connection options
|
11
|
+
DEFAULT_CONNECTION_OPTIONS = {}
|
12
|
+
|
13
|
+
# Default client name
|
14
|
+
DEFAULT_CLIENT_NAME = ''
|
15
|
+
|
16
|
+
# Default key file
|
17
|
+
DEFAULT_CLIENT_KEY = ''
|
18
|
+
|
19
|
+
DEFAULT_ENVIRONMENT = 'production'
|
20
|
+
|
21
|
+
DEFAULT_ACCEPT = 'pson'
|
22
|
+
|
23
|
+
# Default puppetpe rest api version
|
24
|
+
# v1, v2 leave blank
|
25
|
+
# 2015.2 or greater pass in 'puppet/v3'
|
26
|
+
DEFAULT_API_VERSION = nil
|
27
|
+
|
28
|
+
# An array of valid config options
|
29
|
+
VALID_OPTIONS_KEYS = [
|
30
|
+
:server_url,
|
31
|
+
:environment,
|
32
|
+
:api_version,
|
33
|
+
:client_name,
|
34
|
+
:client_key,
|
35
|
+
:user_agent,
|
36
|
+
:connection_options,
|
37
|
+
:middleware,
|
38
|
+
:accept
|
39
|
+
]
|
40
|
+
|
41
|
+
# Default middleware stack
|
42
|
+
DEFAULT_MIDDLEWARE = Proc.new do |builder|
|
43
|
+
builder.use PuppetRestClient::Response::ParseJSON
|
44
|
+
builder.use PuppetRestClient::Response::ClientError
|
45
|
+
builder.adapter Faraday.default_adapter
|
46
|
+
end
|
47
|
+
|
48
|
+
VALID_OPTIONS_KEYS.each do |key|
|
49
|
+
attr_accessor key
|
50
|
+
end
|
51
|
+
|
52
|
+
# Reset all config options to default when the module is extended
|
53
|
+
def self.extended(base)
|
54
|
+
base.reset
|
55
|
+
end # def self.extended
|
56
|
+
|
57
|
+
# Convenience method to configure PuppetRestClient in a block
|
58
|
+
# @example Configuring PuppetRestClient
|
59
|
+
# PuppetRestClient.setup do |s|
|
60
|
+
# s.server_url = "http://puppetdb.example.com:8081"
|
61
|
+
# s.client_name = "admin"
|
62
|
+
# s.client_key = PuppetRestClient.read_key_file("/path/to/key_file.pem")
|
63
|
+
# end
|
64
|
+
# @yieldparam PuppetRestClient
|
65
|
+
# @yieldreturn PuppetRestClient
|
66
|
+
def setup
|
67
|
+
yield self
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
# Create an options hash from valid options keys
|
72
|
+
def options
|
73
|
+
options = {}
|
74
|
+
VALID_OPTIONS_KEYS.each{|k| options[k] = send(k)}
|
75
|
+
options
|
76
|
+
end
|
77
|
+
|
78
|
+
# Reset all config options to their defaults
|
79
|
+
def reset
|
80
|
+
self.user_agent = DEFAULT_USER_AGENT
|
81
|
+
self.environment = DEFAULT_ENVIRONMENT
|
82
|
+
self.api_version = DEFAULT_API_VERSION
|
83
|
+
self.server_url = DEFAULT_SERVER_URL
|
84
|
+
self.client_name = DEFAULT_CLIENT_NAME
|
85
|
+
self.client_key = DEFAULT_CLIENT_KEY
|
86
|
+
self.connection_options = DEFAULT_CONNECTION_OPTIONS
|
87
|
+
self.middleware = DEFAULT_MIDDLEWARE
|
88
|
+
self.accept = DEFAULT_ACCEPT
|
89
|
+
self
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module PuppetRestClient::PE
|
2
|
+
class Connection
|
3
|
+
include PuppetRestClient::PE::Connection::Node
|
4
|
+
include PuppetRestClient::PE::Connection::Catalog
|
5
|
+
include PuppetRestClient::PE::Connection::CaCert
|
6
|
+
include PuppetRestClient::PE::Request
|
7
|
+
|
8
|
+
Config::VALID_OPTIONS_KEYS.each do |key|
|
9
|
+
attr_accessor key
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(attrs=Mash.new)
|
13
|
+
attrs = PuppetRestClient::PE.options.merge(attrs)
|
14
|
+
|
15
|
+
#unless attrs[:client_key].is_a?(OpenSSL::PKey::RSA)
|
16
|
+
# attrs[:client_key] = OpenSSL::PKey::RSA.new(attrs[:client_key])
|
17
|
+
#end
|
18
|
+
|
19
|
+
PuppetRestClient::PE::Config::VALID_OPTIONS_KEYS.each do |key|
|
20
|
+
instance_variable_set("@#{key}".to_sym, attrs[key])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module PuppetRestClient::PE
|
2
|
+
class Base
|
3
|
+
attr_accessor :attrs
|
4
|
+
alias :to_hash :attrs
|
5
|
+
|
6
|
+
@@identity_map = PuppetRestClient::IdentityMap.new
|
7
|
+
|
8
|
+
def self.identity_map
|
9
|
+
@@identity_map
|
10
|
+
end # def self.identity_map
|
11
|
+
|
12
|
+
# Define methods that retrieve the value from an initialized instance variable Hash, using the attribute as a key
|
13
|
+
#
|
14
|
+
# @overload self.attr_reader(attr)
|
15
|
+
# @param attr [Symbol]
|
16
|
+
# @overload self.attr_reader(attrs)
|
17
|
+
# @param attrs [Array<Symbol>]
|
18
|
+
def self.attr_reader(*attrs)
|
19
|
+
attrs.each do |attribute|
|
20
|
+
class_eval do
|
21
|
+
define_method attribute do
|
22
|
+
@attrs[attribute.to_s]
|
23
|
+
end
|
24
|
+
define_method "#{attribute}=" do |value|
|
25
|
+
@attrs[attribute.to_s] = value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end # def self.attr_reader
|
30
|
+
|
31
|
+
def self.get(attrs=Mash.new)
|
32
|
+
@@identity_map[self] ||= {}
|
33
|
+
if attrs['title']
|
34
|
+
@@identity_map[self][attrs['title']] && @@identity_map[self][attrs['title']].update(attrs)
|
35
|
+
elsif attrs['resource']
|
36
|
+
@@identity_map[self][attrs['resource']] && @@identity_map[self][attrs['resource']].update(attrs)
|
37
|
+
else
|
38
|
+
@@identity_map[self][Marshal.dump(attrs)]
|
39
|
+
end
|
40
|
+
end # def self.get
|
41
|
+
|
42
|
+
# Retrieve an object from the identity map or initialize a new object
|
43
|
+
def self.get_or_new(attrs=Mash.new)
|
44
|
+
self.get(attrs) || self.new(attrs)
|
45
|
+
end # def self.get_or_new
|
46
|
+
|
47
|
+
# Initializes a new object
|
48
|
+
#
|
49
|
+
# @param attrs [Hash]
|
50
|
+
# @return [PuppetRestClient::Base]
|
51
|
+
def initialize(attrs=Mash.new)
|
52
|
+
self.class.attr_reader *attrs.keys
|
53
|
+
attrs.stringify_keys!
|
54
|
+
self.update attrs
|
55
|
+
if attrs['title']
|
56
|
+
@@identity_map[self.class] ||= {}
|
57
|
+
@@identity_map[self.class][attrs['title']] = self
|
58
|
+
elsif attrs['resource']
|
59
|
+
@@identity_map[self.class] ||= {}
|
60
|
+
@@identity_map[self.class][attrs['resource']] = self
|
61
|
+
else
|
62
|
+
@@identity_map[self.class] ||= {}
|
63
|
+
@@identity_map[self.class][Marshal.dump(attrs)] = self
|
64
|
+
end
|
65
|
+
end # def initialize
|
66
|
+
|
67
|
+
# Fetches an attribute of an object using hash notation
|
68
|
+
#
|
69
|
+
# @param method [String, Symbol] Message to send to the object
|
70
|
+
def [](method)
|
71
|
+
self.__send__(method.to_sym)
|
72
|
+
rescue NoMethodError
|
73
|
+
nil
|
74
|
+
end # def []
|
75
|
+
|
76
|
+
# Update the attributes of an object
|
77
|
+
#
|
78
|
+
# @param attrs [Hash]
|
79
|
+
# @return [PuppetRestClient::Base]
|
80
|
+
def update(attrs)
|
81
|
+
@attrs = attrs
|
82
|
+
self
|
83
|
+
end # def update
|
84
|
+
|
85
|
+
# @return [String]
|
86
|
+
def resource
|
87
|
+
@attrs['resource']
|
88
|
+
end # def id
|
89
|
+
|
90
|
+
# @return [String]
|
91
|
+
def title
|
92
|
+
@attrs['title']
|
93
|
+
end # def name
|
94
|
+
|
95
|
+
def keys
|
96
|
+
@attrs.keys
|
97
|
+
end # def keys
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|