Class: Chef::Resource::Template

Inherits:
File show all
Includes:
Mixin::Securable
Defined in:
lib/chef/resource/template.rb

Constant Summary

Constants inherited from Chef::Resource

FORBIDDEN_IVARS, HIDDEN_IVARS

Constants included from Mixin::ShellOut

Mixin::ShellOut::DEPRECATED_OPTIONS

Instance Attribute Summary collapse

Attributes inherited from File

#checksum, #final_checksum

Attributes inherited from Chef::Resource

#allowed_actions, #cookbook_name, #declared_type, #default_guard_interpreter, #elapsed_time, #enclosing_provider, #ignore_failure, #not_if_args, #only_if_args, #params, #recipe_name, #resource_initializing, #retries, #retry_delay, #run_context, #sensitive, #source_line, #updated

Instance Method Summary collapse

Methods included from Mixin::Securable

#group, included, #mode, #owner

Methods included from Mixin::Securable::WindowsSecurableAttributes

#inherits

Methods inherited from File

#special_docker_files?, #state_for_resource_reporter, #verify

Methods inherited from Chef::Resource

#action, action, #action=, action_class, #after_created, allowed_actions, allowed_actions=, #as_json, #before_notifications, #cookbook_version, #current_value, #current_value_does_not_exist!, #custom_exception_message, #customize_exception, declare_action_class, #declared_key, default_action, default_action=, #defined_at, #delayed_action, #delayed_notifications, dsl_name, #events, #guard_interpreter, #identity, identity_attr, identity_property, #immediate_notifications, inherited, #inspect, #is, json_create, load_current_value, #load_from, #lookup_provider_constant, #method_missing, #name, #node, #noop, #not_if, #notifies, #notifies_before, #notifies_delayed, #notifies_immediately, #only_if, #provider, #provider=, provider_base, #provider_for_action, provides, provides?, remove_canonical_dsl, #resolve_notification_references, resource_for_node, resource_matching_short_name, #resource_name, resource_name, resource_name=, #resources, #run_action, #should_skip?, sorted_descendants, #source_line_file, #source_line_number, state_attrs, #state_for_resource_reporter, #subscribes, #supports, #supports=, #to_hash, #to_json, #to_s, #to_text, #updated?, #updated_by_last_action, #updated_by_last_action?, use_automatic_resource_name, #validate_action, #validate_resource_spec!, #value_to_text

Methods included from DeprecatedLWRPClass

#deprecated_constants, #register_deprecated_lwrp_class

Methods included from Mixin::ConvertToClassName

#constantize, #convert_to_class_name, #convert_to_snake_case, #filename_to_qualified_string, #normalize_snake_case_name, #snake_case_basename

Methods included from Mixin::Provides

#provided_as, #provides, #provides?

Methods included from Mixin::DescendantsTracker

descendants, #descendants, direct_descendants, #direct_descendants, find_descendants_by_name, #find_descendants_by_name, #inherited, store_inherited

Methods included from Mixin::Deprecation

#deprecated_attr, #deprecated_attr_reader, #deprecated_attr_writer, #deprecated_ivar

Methods included from Mixin::Properties

included, #property_is_set?, #reset_property

Methods included from Mixin::ParamsValidate

#lazy, #set_or_return, #validate

Methods included from Mixin::ShellOut

#a_to_s, #clean_array, #run_command_compatible_options, #shell_out, #shell_out!, #shell_out_compact, #shell_out_compact!, #shell_out_compact_timeout, #shell_out_compact_timeout!, #shell_out_with_systems_locale, #shell_out_with_systems_locale!

Methods included from Mixin::PowershellOut

#powershell_out, #powershell_out!

Methods included from Mixin::WindowsArchitectureHelper

#assert_valid_windows_architecture!, #disable_wow64_file_redirection, #forced_32bit_override_required?, #is_i386_process_on_x86_64_windows?, #node_supports_windows_architecture?, #node_windows_architecture, #restore_wow64_file_redirection, #valid_windows_architecture?, #with_os_architecture, #wow64_architecture_override_required?, #wow64_directory

Methods included from DSL::PlatformIntrospection

#docker?, #platform?, #platform_family?, #value_for_platform, #value_for_platform_family

Methods included from DSL::RebootPending

#reboot_pending?

Methods included from DSL::RegistryHelper

#registry_data_exists?, #registry_get_subkeys, #registry_get_values, #registry_has_subkeys?, #registry_key_exists?, #registry_value_exists?

Methods included from DSL::DataQuery

#data_bag, #data_bag_item, #search

Methods included from EncryptedDataBagItem::CheckEncrypted

#encrypted?

Constructor Details

#initialize(name, run_context = nil) ⇒ Template



33
34
35
36
37
38
39
40
41
42
# File 'lib/chef/resource/template.rb', line 33

def initialize(name, run_context = nil)
  super
  @source = "#{::File.basename(name)}.erb"
  @cookbook = nil
  @local = false
  @variables = Hash.new
  @inline_helper_blocks = {}
  @inline_helper_modules = []
  @helper_modules = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Chef::Resource

Instance Attribute Details

#inline_helper_blocksObject (readonly)

Returns the value of attribute inline_helper_blocks



30
31
32
# File 'lib/chef/resource/template.rb', line 30

def inline_helper_blocks
  @inline_helper_blocks
end

#inline_helper_modulesObject (readonly)

Returns the value of attribute inline_helper_modules



31
32
33
# File 'lib/chef/resource/template.rb', line 31

def inline_helper_modules
  @inline_helper_modules
end

Instance Method Details

#cookbook(args = nil) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/chef/resource/template.rb', line 60

def cookbook(args = nil)
  set_or_return(
    :cookbook,
    args,
    :kind_of => [ String ]
  )
end

#helper(method_name, &block) ⇒ Object

Declares a helper method to be defined in the template context when rendering.

Example:

Basic usage:

Given the following helper:

helper(:static_value) { "hello from helper" }

A template with the following code:

<%= static_value %>

Will render as;

hello from helper

Referencing Instance Variables:

Any instance variables available to the template can be referenced in the method body. For example, you can simplify accessing app-specific node attributes like this:

helper(:app) { @node[:my_app_attributes] }

And use it in a template like this:

<%= app[:listen_ports] %>

This is equivalent to the non-helper template code:

<%= @node[:my_app_attributes][:listen_ports] %>

Method Arguments:

Helper methods can also take arguments. The syntax available for argument specification supports full syntax available for method definition.

Continuing the above example of simplifying attribute access, we can define a helper to look up app-specific attributes like this:

helper(:app) { |setting| @node[:my_app_attributes][setting] }

The template can then look up attributes like this:

<%= app(:listen_ports) %>


109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/chef/resource/template.rb', line 109

def helper(method_name, &block)
  unless block_given?
    raise Exceptions::ValidationFailed,
      "`helper(:method)` requires a block argument (e.g., `helper(:method) { code }`)"
  end

  unless method_name.kind_of?(Symbol)
    raise Exceptions::ValidationFailed,
      "method_name argument to `helper(method_name)` must be a symbol (e.g., `helper(:method) { code }`)"
  end

  @inline_helper_blocks[method_name] = block
end

#helper_modulesObject

Compiles all helpers from inline method definitions, inline module definitions, and external modules into an Array of Modules. The context object for the template is extended with these modules to provide per-resource template logic.



186
187
188
# File 'lib/chef/resource/template.rb', line 186

def helper_modules
  compiled_helper_methods + compiled_helper_modules + @helper_modules
end

#helpers(module_name = nil, &block) ⇒ Object

Declares a module to define helper methods in the template's context when rendering. There are two primary forms.

Inline Module Definition

When a block is given, the block is used to define a module which is then mixed in to the template context w/ `extend`.

Inline Module Example

Given the following code in the template resource:

helpers do
  # Add "syntax sugar" for referencing app-specific attributes
  def app(attribute)
    @node[:my_app_attributes][attribute]
  end
end

You can use it in the template like so:

<%= app(:listen_ports) %>

Which is equivalent to:

<%= @node[:my_app_attributes][:listen_ports] %>

External Module Form

When a module name is given, the template context will be extended with that module. This is the recommended way to customize template contexts when you need to define more than an handful of helper functions (but also try to keep your template helpers from getting out of hand–if you have very complex logic in your template helpers, you should further extract your code into separate libraries).

External Module Example

To extract the above inline module code to a library, you'd create a library file like this:

module MyTemplateHelper
  # Add "syntax sugar" for referencing app-specific attributes
  def app(attribute)
    @node[:my_app_attributes][attribute]
  end
end

And in the template resource:

helpers(MyTemplateHelper)

The template code in the above example will work unmodified.



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/chef/resource/template.rb', line 163

def helpers(module_name = nil, &block)
  if block_given? && !module_name.nil?
    raise Exceptions::ValidationFailed,
      "Passing both a module and block to #helpers is not supported. Call #helpers multiple times instead"
  elsif block_given?
    @inline_helper_modules << block
  elsif module_name.kind_of?(::Module)
    @helper_modules << module_name
  elsif module_name.nil?
    raise Exceptions::ValidationFailed,
      "#helpers requires either a module name or inline module code as a block.\n" +
      "e.g.: helpers do; helper_code; end;\n" +
      "OR: helpers(MyHelpersModule)"
  else
    raise Exceptions::ValidationFailed,
      "Argument to #helpers must be a module. You gave #{module_name.inspect} (#{module_name.class})"
  end
end

#local(args = nil) ⇒ Object



68
69
70
71
72
73
74
# File 'lib/chef/resource/template.rb', line 68

def local(args = nil)
  set_or_return(
    :local,
    args,
    :kind_of => [ TrueClass, FalseClass ]
  )
end

#source(file = nil) ⇒ Object



44
45
46
47
48
49
50
# File 'lib/chef/resource/template.rb', line 44

def source(file = nil)
  set_or_return(
    :source,
    file,
    :kind_of => [ String, Array ]
  )
end

#variables(args = nil) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/chef/resource/template.rb', line 52

def variables(args = nil)
  set_or_return(
    :variables,
    args,
    :kind_of => [ Hash ]
  )
end