Class: Puppet::Indirector::Indirection
- Includes:
- Util::Docs
- Defined in:
- lib/puppet/indirector/indirection.rb
Overview
The class that connects functional classes with their different collection back-ends. Each indirection has a set of associated terminus classes, each of which is a subclass of Puppet::Indirector::Terminus.
Constant Summary collapse
- @@indirections =
[]
Constants included from Util::Docs
Instance Attribute Summary collapse
-
#model ⇒ Object
Returns the value of attribute model.
-
#name ⇒ Object
Returns the value of attribute name.
-
#termini ⇒ Object
readonly
Returns the value of attribute termini.
Attributes included from Util::Docs
Class Method Summary collapse
-
.instance(name) ⇒ Object
Find an indirection by name.
-
.instances ⇒ Object
Return a list of all known indirections.
-
.model(name) ⇒ Object
Find an indirected model by name.
Instance Method Summary collapse
- #allow_remote_requests? ⇒ Boolean
-
#cache ⇒ Object
Create and return our cache terminus.
-
#cache? ⇒ Boolean
Should we use a cache?.
- #cache_class ⇒ Object
-
#cache_class=(class_name) ⇒ Object
Define a terminus class to be used for caching.
-
#delete ⇒ Object
This is only used for testing.
-
#destroy(key, options = {}) ⇒ Object
Remove something via the terminus.
-
#doc ⇒ Object
Generate the full doc string.
-
#expiration ⇒ Object
Calculate the expiration date for a returned instance.
-
#expire(key, options = {}) ⇒ Object
Expire a cached object, if one is cached.
-
#find(key, options = {}) ⇒ Object
Search for an instance in the appropriate terminus, caching the results if caching is configured..
- #find_in_cache(request) ⇒ Object
-
#head(key, options = {}) ⇒ Object
Search for an instance in the appropriate terminus, and return a boolean indicating whether the instance was found.
-
#initialize(model, name, doc: nil, indirected_class: nil, cache_class: nil, terminus_class: nil, terminus_setting: nil, extend: nil) ⇒ Indirection
constructor
A new instance of Indirection.
-
#request(*args) ⇒ Object
Set up our request object.
- #reset_terminus_class ⇒ Object
-
#save(instance, key = nil, options = {}) ⇒ Object
Save the instance in the appropriate terminus.
-
#search(key, options = {}) ⇒ Object
Search for more than one instance.
-
#set_global_setting(setting, value) ⇒ Object
Use this to set indirector settings globally across threads.
-
#terminus(terminus_name = nil) ⇒ Object
Return the singleton terminus for this indirection.
-
#terminus_class ⇒ Object
Determine the terminus class.
-
#terminus_class=(klass) ⇒ Object
Specify the terminus class to use.
-
#terminus_setting ⇒ Object
These can be used to select the terminus class.
- #terminus_setting=(setting) ⇒ Object
-
#ttl ⇒ Object
Default to the runinterval for the ttl.
-
#ttl=(value) ⇒ Object
Set the time-to-live for instances created through this indirection.
-
#validate_terminus_class(terminus_class) ⇒ Object
This is used by terminus_class= and cache=.
Methods included from Util::Docs
#desc, #dochook, #doctable, #markdown_definitionlist, #markdown_header, #nodoc?, #pad, scrub
Constructor Details
#initialize(model, name, doc: nil, indirected_class: nil, cache_class: nil, terminus_class: nil, terminus_setting: nil, extend: nil) ⇒ Indirection
Returns a new instance of Indirection.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/puppet/indirector/indirection.rb', line 96 def initialize(model, name, doc: nil, indirected_class: nil, cache_class: nil, terminus_class: nil, terminus_setting: nil, extend: nil) @model = model @name = name @termini = {} @doc = doc raise(ArgumentError, _("Indirection %{name} is already defined") % { name: @name }) if @@indirections.find { |i| i.name == @name } @@indirections << self @indirected_class = indirected_class self.extend(extend) if extend # Setting these depend on the indirection already being installed so they have to be at the end set_global_setting(:cache_class, cache_class) set_global_setting(:terminus_class, terminus_class) set_global_setting(:terminus_setting, terminus_setting) end |
Instance Attribute Details
#model ⇒ Object
Returns the value of attribute model.
14 15 16 |
# File 'lib/puppet/indirector/indirection.rb', line 14 def model @model end |
#name ⇒ Object
Returns the value of attribute name.
14 15 16 |
# File 'lib/puppet/indirector/indirection.rb', line 14 def name @name end |
#termini ⇒ Object (readonly)
Returns the value of attribute termini.
15 16 17 |
# File 'lib/puppet/indirector/indirection.rb', line 15 def termini @termini end |
Class Method Details
.instance(name) ⇒ Object
Find an indirection by name. This is provided so that Terminus classes can specifically hook up with the indirections they are associated with.
21 22 23 |
# File 'lib/puppet/indirector/indirection.rb', line 21 def self.instance(name) @@indirections.find { |i| i.name == name } end |
.instances ⇒ Object
Return a list of all known indirections. Used to generate the reference.
27 28 29 |
# File 'lib/puppet/indirector/indirection.rb', line 27 def self.instances @@indirections.collect { |i| i.name } end |
.model(name) ⇒ Object
Find an indirected model by name. This is provided so that Terminus classes can specifically hook up with the indirections they are associated with.
33 34 35 36 37 |
# File 'lib/puppet/indirector/indirection.rb', line 33 def self.model(name) match = @@indirections.find { |i| i.name == name } return nil unless match match.model end |
Instance Method Details
#allow_remote_requests? ⇒ Boolean
206 207 208 |
# File 'lib/puppet/indirector/indirection.rb', line 206 def allow_remote_requests? terminus.allow_remote_requests? end |
#cache ⇒ Object
Create and return our cache terminus.
40 41 42 43 |
# File 'lib/puppet/indirector/indirection.rb', line 40 def cache raise Puppet::DevError, _("Tried to cache when no cache class was set") unless cache_class terminus(cache_class) end |
#cache? ⇒ Boolean
Should we use a cache?
46 47 48 |
# File 'lib/puppet/indirector/indirection.rb', line 46 def cache? cache_class ? true : false end |
#cache_class ⇒ Object
50 51 52 |
# File 'lib/puppet/indirector/indirection.rb', line 50 def cache_class @cache_class.value end |
#cache_class=(class_name) ⇒ Object
Define a terminus class to be used for caching.
55 56 57 58 |
# File 'lib/puppet/indirector/indirection.rb', line 55 def cache_class=(class_name) validate_terminus_class(class_name) if class_name @cache_class.value = class_name end |
#delete ⇒ Object
This is only used for testing.
61 62 63 |
# File 'lib/puppet/indirector/indirection.rb', line 61 def delete @@indirections.delete(self) if @@indirections.include?(self) end |
#destroy(key, options = {}) ⇒ Object
Remove something via the terminus.
281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/puppet/indirector/indirection.rb', line 281 def destroy(key, ={}) request = request(:destroy, key, nil, ) terminus = prepare(request) result = terminus.destroy(request) if cache? and cache.find(request(:find, key, nil, )) # Reuse the existing request, since it's equivalent. cache.destroy(request) end result end |
#doc ⇒ Object
Generate the full doc string.
83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/puppet/indirector/indirection.rb', line 83 def doc text = ''.dup text << scrub(@doc) << "\n\n" if @doc text << "* **Indirected Class**: `#{@indirected_class}`\n"; if terminus_setting text << "* **Terminus Setting**: #{terminus_setting}\n" end text end |
#expiration ⇒ Object
Calculate the expiration date for a returned instance.
78 79 80 |
# File 'lib/puppet/indirector/indirection.rb', line 78 def expiration Time.now + ttl end |
#expire(key, options = {}) ⇒ Object
Expire a cached object, if one is cached. Note that we don’t actually remove it, we expire it and write it back out to disk. This way people can still use the expired object if they want.
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/puppet/indirector/indirection.rb', line 190 def expire(key, ={}) request = request(:expire, key, nil, ) return nil unless cache? && !request.ignore_cache_save? instance = cache.find(request(:find, key, nil, )) return nil unless instance Puppet.info _("Expiring the %{cache} cache of %{instance}") % { cache: self.name, instance: instance.name } # Set an expiration date in the past instance.expiration = Time.now - 60 cache.save(request(:save, nil, instance, )) end |
#find(key, options = {}) ⇒ Object
Search for an instance in the appropriate terminus, caching the results if caching is configured..
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/puppet/indirector/indirection.rb', line 212 def find(key, ={}) request = request(:find, key, nil, ) terminus = prepare(request) result = find_in_cache(request) if not result.nil? result elsif request.ignore_terminus? nil else # Otherwise, return the result from the terminus, caching if # appropriate. result = terminus.find(request) if not result.nil? result.expiration ||= self.expiration if result.respond_to?(:expiration) if cache? && !request.ignore_cache_save? Puppet.info _("Caching %{indirection} for %{request}") % { indirection: self.name, request: request.key } begin cache.save request(:save, key, result, ) rescue => detail Puppet.log_exception(detail) raise detail end end filtered = result if terminus.respond_to?(:filter) Puppet::Util::Profiler.profile(_("Filtered result for %{indirection} %{request}") % { indirection: self.name, request: request.key }, [:indirector, :filter, self.name, request.key]) do begin filtered = terminus.filter(result) rescue Puppet::Error => detail Puppet.log_exception(detail) raise detail end end end filtered end end end |
#find_in_cache(request) ⇒ Object
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/puppet/indirector/indirection.rb', line 264 def find_in_cache(request) # See if our instance is in the cache and up to date. cached = cache.find(request) if cache? && ! request.ignore_cache? return nil unless cached if cached.expired? Puppet.info _("Not using expired %{indirection} for %{request} from cache; expired at %{expiration}") % { indirection: self.name, request: request.key, expiration: cached.expiration } return nil end Puppet.debug { "Using cached #{self.name} for #{request.key}" } cached rescue => detail Puppet.log_exception(detail, _("Cached %{indirection} for %{request} failed: %{detail}") % { indirection: self.name, request: request.key, detail: detail }) nil end |
#head(key, options = {}) ⇒ Object
Search for an instance in the appropriate terminus, and return a boolean indicating whether the instance was found.
255 256 257 258 259 260 261 262 |
# File 'lib/puppet/indirector/indirection.rb', line 255 def head(key, ={}) request = request(:head, key, nil, ) terminus = prepare(request) # Look in the cache first, then in the terminus. Force the result # to be a boolean. !!(find_in_cache(request) || terminus.head(request)) end |
#request(*args) ⇒ Object
Set up our request object.
132 133 134 |
# File 'lib/puppet/indirector/indirection.rb', line 132 def request(*args) Puppet::Indirector::Request.new(self.name, *args) end |
#reset_terminus_class ⇒ Object
166 167 168 |
# File 'lib/puppet/indirector/indirection.rb', line 166 def reset_terminus_class @terminus_class.value = nil end |
#save(instance, key = nil, options = {}) ⇒ Object
Save the instance in the appropriate terminus. This method is normally an instance method on the indirected class.
313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/puppet/indirector/indirection.rb', line 313 def save(instance, key = nil, ={}) request = request(:save, key, instance, ) terminus = prepare(request) result = terminus.save(request) if !request.ignore_terminus? # If caching is enabled, save our document there cache.save(request) if cache? && !request.ignore_cache_save? result end |
#search(key, options = {}) ⇒ Object
Search for more than one instance. Should always return an array.
296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/puppet/indirector/indirection.rb', line 296 def search(key, ={}) request = request(:search, key, nil, ) terminus = prepare(request) result = terminus.search(request) if result raise Puppet::DevError, _("Search results from terminus %{terminus_name} are not an array") % { terminus_name: terminus.name } unless result.is_a?(Array) result.each do |instance| next unless instance.respond_to? :expiration instance.expiration ||= self.expiration end return result end end |
#set_global_setting(setting, value) ⇒ Object
Use this to set indirector settings globally across threads.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/puppet/indirector/indirection.rb', line 116 def set_global_setting(setting, value) case setting when :cache_class validate_terminus_class(value) if !value.nil? @cache_class = Puppet::ThreadLocal.new(value) when :terminus_class validate_terminus_class(value) if !value.nil? @terminus_class = Puppet::ThreadLocal.new(value) when :terminus_setting @terminus_setting = Puppet::ThreadLocal.new(value) else raise(ArgumentError, _("The setting %{setting} is not a valid indirection setting.") % {setting: setting}) end end |
#terminus(terminus_name = nil) ⇒ Object
Return the singleton terminus for this indirection.
137 138 139 140 141 142 |
# File 'lib/puppet/indirector/indirection.rb', line 137 def terminus(terminus_name = nil) # Get the name of the terminus. raise Puppet::DevError, _("No terminus specified for %{name}; cannot redirect") % { name: self.name } unless terminus_name ||= terminus_class termini[terminus_name] ||= make_terminus(terminus_name) end |
#terminus_class ⇒ Object
Determine the terminus class.
154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/puppet/indirector/indirection.rb', line 154 def terminus_class unless @terminus_class.value setting = self.terminus_setting if setting self.terminus_class = Puppet.settings[setting] else raise Puppet::DevError, _("No terminus class nor terminus setting was provided for indirection %{name}") % { name: self.name} end end @terminus_class.value end |
#terminus_class=(klass) ⇒ Object
Specify the terminus class to use.
171 172 173 174 |
# File 'lib/puppet/indirector/indirection.rb', line 171 def terminus_class=(klass) validate_terminus_class(klass) @terminus_class.value = klass end |
#terminus_setting ⇒ Object
These can be used to select the terminus class.
145 146 147 |
# File 'lib/puppet/indirector/indirection.rb', line 145 def terminus_setting @terminus_setting.value end |
#terminus_setting=(setting) ⇒ Object
149 150 151 |
# File 'lib/puppet/indirector/indirection.rb', line 149 def terminus_setting=(setting) @terminus_setting.value = setting end |
#ttl ⇒ Object
Default to the runinterval for the ttl.
73 74 75 |
# File 'lib/puppet/indirector/indirection.rb', line 73 def ttl @ttl ||= Puppet[:runinterval] end |
#ttl=(value) ⇒ Object
Set the time-to-live for instances created through this indirection.
66 67 68 69 70 |
# File 'lib/puppet/indirector/indirection.rb', line 66 def ttl=(value) #TRANSLATORS "TTL" stands for "time to live" and refers to a duration of time raise ArgumentError, _("Indirection TTL must be an integer") unless value.is_a?(Integer) @ttl = value end |
#validate_terminus_class(terminus_class) ⇒ Object
This is used by terminus_class= and cache=.
177 178 179 180 181 182 183 184 185 |
# File 'lib/puppet/indirector/indirection.rb', line 177 def validate_terminus_class(terminus_class) unless terminus_class and terminus_class.to_s != "" raise ArgumentError, _("Invalid terminus name %{terminus_class}") % { terminus_class: terminus_class.inspect } end unless Puppet::Indirector::Terminus.terminus_class(self.name, terminus_class) raise ArgumentError, _("Could not find terminus %{terminus_class} for indirection %{name}") % { terminus_class: terminus_class, name: self.name } end end |