Class: Retrospec::Plugins::V1::Puppet

Inherits:
Plugin
  • Object
show all
Includes:
Retrospec::Puppet::TemplateHelpers
Defined in:
lib/retrospec/plugins/v1/plugin/puppet.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Retrospec::Puppet::TemplateHelpers

#clone_hook_file, #create_user_template_dir, #default_user_template_dir, #gem_template_dir, #run_clone_hook, #setup_user_template_dir, #sync_user_template_dir

Constructor Details

#initialize(module_path = nil, config = {}) ⇒ Puppet

Returns a new instance of Puppet.

Parameters:

  • module_path (String) (defaults to: nil)
    • the path to the module

  • config (Hash) (defaults to: {})
    • the configuration, which is passed to the parent



27
28
29
30
31
32
33
34
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 27

def initialize(module_path = nil, config = {})
  super
  ::Puppet[:environment] = 'retrospec'
  ::Puppet[:environmentpath] = Utilities::PuppetModule.base_environment_path
  @manifest_dir = File.join(module_path, 'manifests')
  # user supplied a template path or user wants to use local templates
  @template_dir = setup_user_template_dir(config_data[:template_dir], config_data[:scm_url], config_data[:ref])
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



22
23
24
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 22

def context
  @context
end

#manifest_dirObject

Returns the value of attribute manifest_dir.



23
24
25
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 23

def manifest_dir
  @manifest_dir
end

#manifest_filesString (readonly) Also known as: files

Note:

menomizes the files

Returns - a list of puppet manifest files.

Returns:

  • (String)
    • a list of puppet manifest files



375
376
377
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 375

def manifest_files
  @manifest_files
end

#template_dirString (readonly)

the template directory located inside the retrospec gem

Returns:

  • (String)
    • the path to the template directory



314
315
316
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 314

def template_dir
  @template_dir
end

Class Method Details

.file_typeString

the main file type that is used to help discover what the module is

Returns:

  • (String)
    • the puppet file extension



382
383
384
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 382

def self.file_type
  '.pp'
end

.loggerLogger

Returns - instance of a logger.

Returns:

  • (Logger)
    • instance of a logger



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 37

def self.logger
  @logger ||= begin
    require 'logger'
    log = Logger.new(STDOUT)
    if ENV['RETROSPEC_LOGGER_LEVEL'] == 'debug'
      log.level = Logger::DEBUG
    else
      log.level = Logger::INFO
    end
    log
  end
end

.run_cli(global_opts, global_config, plugin_config, args = ARGV) ⇒ Object

used to display subcommand options to the global_config cli the global options are passed in for your usage trollop.rubyforge.org all options here are available in the config passed into the initialize code this is the only entry point into the plugin

Parameters:

  • global_opts (Hash)
    • the global options for retrospec supplied on the cli

  • global_config (Hash)
    • the global config file options

  • plugin_config (Hash)
    • the global config for the puppet plugin

  • args (Array) (defaults to: ARGV)
    • the args passed in on the cli through ARGV, useful for testing



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 100

def self.run_cli(global_opts, global_config, plugin_config, args=ARGV)
  template_dir = ENV['RETROSPEC_TEMPLATES_DIR'] || plugin_config['plugins::puppet::template_dir'] || File.expand_path('~/.retrospec/repos/retrospec-puppet-templates')
  scm_url = ENV['RETROSPEC_PUPPET_SCM_URL'] || plugin_config['plugins::puppet::templates::url']
  #scm_branch = ENV['RETROSPEC_PUPPET_SCM_BRANCH'] || plugin_config['plugins::puppet::templates::ref'] || 'master'
  # TODO next major release - remove the RETROSPEC_PUPPET_SCM_BRANCH as env setting
  scm_ref = ENV['RETROSPEC_PUPPET_SCM_REF'] || ENV['RETROSPEC_PUPPET_SCM_BRANCH'] || plugin_config['plugins::puppet::templates::ref'] || 'master'
  beaker_tests  = plugin_config['plugins::puppet::enable_beaker_tests'] || false
  # a list of subcommands for this plugin
  sub_commands  = %w(new_module new_task new_fact new_type new_provider new_function new_report module_data)
  if sub_commands.count > 0
    sub_command_help = "Subcommands:\n  #{sub_commands.join("\n  ")}\n"
  else
    sub_command_help = ''
  end
  plugin_opts = Trollop.options(args) do
    version "Retrospec puppet plugin: #{Retrospec::Puppet::VERSION} (c) Corey Osman at NWOPS, LLC"
    banner <<-EOS
Generates puppet rspec test code and puppet module components.

#{sub_command_help}

    EOS
    opt :template_dir, 'Path to templates directory (only for overriding Retrospec templates)', :type => :string,
    :required => false, :default => template_dir
    opt :scm_url, 'SCM url for retrospec templates', :type => :string, :required => false,
    :default => scm_url
    opt :ref, 'Branch you want to use for the retrospec template repo', :type => :string, :required => false,
    :default => scm_ref
    opt :enable_beaker_tests, 'Enable the creation of beaker tests', :require => false, :type => :boolean, :default => beaker_tests
    stop_on sub_commands
  end
  # the passed in options will always override the config file
  plugin_data = plugin_opts.merge(global_config).merge(global_opts).merge(plugin_opts).merge(plugin_config)
  # define the default action to use the plugin here, the default is run
  sub_command = (args.shift || :run).to_sym
  # create an instance of this plugin
  plugin = new(plugin_data[:module_path], plugin_data)
  # check if the plugin supports the sub command
  begin
    if plugin.respond_to?(sub_command)
      case sub_command
      when :new_module
        plugin.send(sub_command, plugin_data, args)
        plugin.post_init # finish initialization
      when :run
        plugin.post_init   # finish initialization
      when :new_type
        plugin.new_type(plugin_data, args)
      when :new_function
        plugin.new_function(plugin_data, args)
      when :new_task
        plugin.new_task(plugin_data, args)
      when :new_fact
        plugin.new_fact(plugin_data, args)
      when :new_provider
        plugin.new_provider(plugin_data, args)
      else
        plugin.post_init   # finish initialization
        plugin.send(sub_command, plugin_data[:module_path], plugin_data, args)
      end
      plugin.send(:run)
    else
      puts "The subcommand #{sub_command} is not supported or valid".fatal
      exit 1
    end
  rescue Retrospec::Puppet::InvalidModulePathError => e
    exit 1
  rescue Retrospec::Puppet::NoManifestDirError => e
    exit 1
  rescue Retrospec::Puppet::ParserError => e
    exit 1
  rescue Retrospec::Puppet::Generators::CoreTypeException => e
    puts e.message.fatal
  rescue Errno::ENOENT => e
    puts e.message
  rescue Exception => e
    puts e.message
    exit 1
  end
  plugin_data
end

Instance Method Details

#create_filesBoolean

this is the method that performs all the magic and creates all the files

Returns:

  • (Boolean)
    • returns true if the method completed



352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 352

def create_files
  filter = /nodesets|acceptance|spec_helper_acceptance/ unless context.enable_beaker_tests?
  safe_create_module_files(template_dir, module_path, context, filter)
  fact(module_path, config_data)
  type_spec_files(module_path, config_data)
  provider_spec_files(module_path, config_data)
  function_spec_files(module_path, config_data)
  # FIXME temporary disabling to re-release in future update
  #new_schema(module_path, config_data)
  Retrospec::Puppet::Generators::ModuleGenerator.(context.module_name, config_data)
  Retrospec::Puppet::Generators::ResourceBaseGenerator.generate_spec_files(module_path, config_data)
  Retrospec::Puppet::Generators::AcceptanceGenerator.generate_spec_files(module_path, config_data) if context.enable_beaker_tests?
  Utilities::PuppetModule.clean_tmp_modules_dir
  true
end

#descriptionString

Returns - the description of this project.

Returns:

  • (String)
    • the description of this project



369
370
371
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 369

def description
  'Generates puppet rspec test code based on the classes and defines inside the manifests directory'
end

#fact(module_path, config) ⇒ Array

generates the fact spec files

Parameters:

  • module_path (String)
    • the path to the module

  • config (Hash)
    • the configuration from the cli and retrospec

Returns:

  • (Array)
    • returns the files paths that were generated



299
300
301
302
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 299

def fact(module_path, config)
  f = Retrospec::Puppet::Generators::FactGenerator.new(module_path, config)
  f.generate_fact_spec_files
end

#function_spec_files(module_path, config) ⇒ Array

generates function spec files

Parameters:

  • module_path (String)
    • the path to the module

  • config (Hash)
    • the configuration from the cli and retrospec

Returns:

  • (Array)
    • returns the files paths that were generated



240
241
242
243
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 240

def function_spec_files(module_path, config)
  f = Retrospec::Puppet::Generators::FunctionGenerator.new(module_path, config)
  f.generate_spec_files
end

#module_data(module_path, config, args = []) ⇒ Array

generates module data files

Parameters:

  • args (Hash) (defaults to: [])
    • the main retrospec args from the config file or cli

  • config (Hash)
    • the cli args passed in for the generator

  • module_path (String)
    • the path to the module

Returns:

  • (Array)
    • returns the files paths that were generated



199
200
201
202
203
204
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 199

def module_data(module_path, config, args=[])
  plugin_data = Retrospec::Puppet::Generators::ModuleDataGenerator.run_cli(config, args)
  plugin_data[:puppet_context] = context
  p = Retrospec::Puppet::Generators::ModuleDataGenerator.new(module_path, plugin_data)
  p.run
end

#new_fact(plugin_data, args) ⇒ Array

generates a new fact file

Parameters:

  • args (Hash)
    • the main retrospec args from the config file or cli

  • plugin_data (Hash)
    • the cli args passed in for the generator

Returns:

  • (Array)
    • returns the files paths that were generated



289
290
291
292
293
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 289

def new_fact(plugin_data, args)
  f = Retrospec::Puppet::Generators::FactGenerator.run_cli(plugin_data, args)
  post_init # finish initialization
  f.generate_fact_file
end

#new_function(config, args) ⇒ Array

generates a new puppet function file

Parameters:

  • args (Hash)
    • the main retrospec args from the config file or cli

  • config (Hash)
    • the cli args passed in for the generator

Returns:

  • (Array)
    • returns the files paths that were generated



229
230
231
232
233
234
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 229

def new_function(config, args)
  plugin_data = Retrospec::Puppet::Generators::FunctionGenerator.run_cli(config, args)
  f = Retrospec::Puppet::Generators::FunctionGenerator.new(plugin_data[:module_path], plugin_data)
  post_init
  f.generate_function_file
end

#new_module(plugin_data, args) ⇒ Object

if the module does not exist lets create it this will create the module directory, manifests directory and basic init.pp file if the manifest directory already exist but an init.pp file does not we do not creating anything since it is not mandatory I thought about using the the module face to perform this generation but it seems like its not supported at this time, and you can’t specify the path to generate the module in generates a new puppet function file

Parameters:

  • args (Hash)
    • the main retrospec args from the config file or cli

  • plugin_data (Hash)
    • the cli args passed in for the generator



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 72

def new_module(plugin_data, args)
  plugin_data = Retrospec::Puppet::Generators::ModuleGenerator.run_cli(plugin_data, args)
  # the user passed in /tmp/test1 and the name is irrelevent
  if ! File.exists?(plugin_data[:module_path])
    plugin_data[:module_path] = File.join(plugin_data[:module_path])
    # if the module path basename is the same as the module name
    # this is a parent directory or the module already exists
  elsif File.basename(plugin_data[:module_path]) != plugin_data[:name]
    plugin_data[:module_path] = File.join(plugin_data[:module_path], plugin_data[:name])
  end
  # we need to set this because the this class is created before we created the new module directory
  # so we now have to set the manifests and module directory
  self.module_path = plugin_data[:module_path]
  config_data[:module_path] = plugin_data[:module_path]
  self.manifest_dir = File.join(plugin_data[:module_path], 'manifests')
  f = Retrospec::Puppet::Generators::ModuleGenerator.new(plugin_data[:module_path], plugin_data)
  f.run(manifest_dir)
end

#new_provider(config, args) ⇒ Array

generates a new provider

Parameters:

  • args (Hash)
    • the main retrospec args from the config file or cli

  • config (Hash)
    • the cli args passed in for the generator

Returns:

  • (Array)
    • returns the files paths that were generated



249
250
251
252
253
254
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 249

def new_provider(config, args)
  plugin_data = Retrospec::Puppet::Generators::ProviderGenerator.run_cli(config, args)
  p = Retrospec::Puppet::Generators::ProviderGenerator.new(plugin_data[:module_path], plugin_data)
  post_init
  p.generate_provider_files
end

#new_report(module_path, config, args = []) ⇒ Array

generates a new puppet report file

Parameters:

  • args (Hash) (defaults to: [])
    • the main retrospec args from the config file or cli

  • config (Hash)
    • the cli args passed in for the generator

  • module_path (String)
    • the path to the module

Returns:

  • (Array)
    • returns the files paths that were generated



211
212
213
214
215
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 211

def new_report(module_path, config, args=[])
  plugin_data = Retrospec::Puppet::Generators::ReportGenerator.run_cli(config, args)
  p = Retrospec::Puppet::Generators::ReportGenerator.new(module_path, plugin_data)
  p.run
end

#new_task(config, args) ⇒ Array

generates a new puppet task

Parameters:

  • args (Hash)
    • the main retrospec args from the config file or cli

  • config (Hash)
    • the cli args passed in for the generator

Returns:

  • (Array)
    • returns the files paths that were generated



186
187
188
189
190
191
192
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 186

def new_task(config, args)
  plugin_data = Retrospec::Puppet::Generators::TaskGenerator.run_cli(config, args)
  plugin_data[:puppet_context] = context
  t = Retrospec::Puppet::Generators::TaskGenerator.new(plugin_data[:module_path], plugin_data)
  t.run
  post_init
end

#new_type(config, args) ⇒ Array

generates a new type

Parameters:

  • args (Hash)
    • the main retrospec args from the config file or cli

  • config (Hash)
    • the cli args passed in for the generator

Returns:

  • (Array)
    • returns the files paths that were generated



269
270
271
272
273
274
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 269

def new_type(config, args)
  plugin_data = Retrospec::Puppet::Generators::TypeGenerator.run_cli(config, args)
  t = Retrospec::Puppet::Generators::TypeGenerator.new(plugin_data[:module_path], plugin_data)
  post_init
  t.generate_type_files
end

#post_initHash

Returns - the context generated after the module has been setup.

Returns:

  • (Hash)
    • the context generated after the module has been setup



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 51

def post_init
  # before we validate the module directory we should ensure the module exists by creating it
  # validation also occurs when setting the module path
  # these are required because the puppet module creates a singleton with some cached values
  Utilities::PuppetModule.instance.module_dir_name = File.basename(module_path)
  Utilities::PuppetModule.instance.module_name = File.basename(module_path)
  Utilities::PuppetModule.instance.module_path = module_path
  Utilities::PuppetModule.create_tmp_module_path # this is required to finish initialization
  # setting the context is required to make other methods below work.  #TODO lazy create the context
  @context = ::Retrospec::Puppet::SpecObject.new(module_path, Utilities::PuppetModule.instance, config_data)
end

#provider_spec_files(module_path, config) ⇒ Array

generates provider spec files

Parameters:

  • module_path (String)
    • the path to the module

  • config (Hash)
    • the configuration from the cli and retrospec

Returns:

  • (Array)
    • returns the files paths that were generated



260
261
262
263
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 260

def provider_spec_files(module_path, config)
  t = Retrospec::Puppet::Generators::ProviderGenerator.new(module_path, config)
  t.generate_provider_spec_files
end

#runObject

this is the main method the starts all the magic This also represents the order in which tasks are run



306
307
308
309
310
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 306

def run
  run_pre_hook
  create_files
  run_post_hook
end

#run_hook(hook_file) ⇒ Object

Note:

the hook file can only be a ruby script

runs the hook file, on windows this is a bit tricky because ruby may not be in the path this is because windows cannot execute just any script and must be directed by prepending with the program name unlike unix shebang magic

Parameters:

  • hook_file (String)
    • the path to the hook file



331
332
333
334
335
336
337
338
339
340
341
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 331

def run_hook(hook_file)
  return unless File.exist?(hook_file)
  output = `ruby #{hook_file} #{module_path}`
  if $CHILD_STATUS.success?
    puts "Successfully ran hook: #{hook_file}".info
    puts output.info
  else
    puts "Error running hook: #{hook_file}".fatal
    puts output.fatal
  end
end

#run_post_hookObject

runs a user defined hook called post-hook if the template directory contains a post-hook file we run that



345
346
347
348
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 345

def run_post_hook
  hook_file = File.join(template_dir, 'post-hook')
  run_hook(hook_file)
end

#run_pre_hookObject

runs a user defined hook called pre-hook



319
320
321
322
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 319

def run_pre_hook
  hook_file = File.join(template_dir, 'pre-hook')
  run_hook(hook_file)
end

#type_spec_files(module_path, config) ⇒ Array

generates spec files for a puppet type

Parameters:

  • module_path (String)
    • the path to the module

  • config (Hash)
    • the configuration from the cli and retrospec

Returns:

  • (Array)
    • returns the files paths that were generated



280
281
282
283
# File 'lib/retrospec/plugins/v1/plugin/puppet.rb', line 280

def type_spec_files(module_path, config)
  t = Retrospec::Puppet::Generators::TypeGenerator.new(module_path, config)
  t.generate_type_spec_files
end