Class: RightScale::DynamicPowershellProvider

Inherits:
Object
  • Object
show all
Includes:
Chef::Mixin::ConvertToClassName
Defined in:
lib/chef/windows/dynamic_powershell_provider.rb

Overview

Dynamically create Chef providers from Powershell scripts. All the Powershell scripts defining a Chef provider should be contained in a folder under the cookbook ‘powershell_providers’ directory. For example creating an IIS Chef provider exposing a start web site and a stop web site action in Powershell would involve creating the following file hierarchy:

‘–iis_cookbook

|-- .json
|-- .rb
|-- powershell_providers
|   `-- iis
|       |-- _init.ps1
|       |-- _load_current_resource.ps1
|       |-- start.ps1
|       |-- stop.ps1
|       `-- _term.ps1
|-- recipes
|   |-- default.rb
|   |-- install.rb
|   |-- restart.rb
|   |-- start.rb
|   `-- stop.rb
`-- resources
    `-- powershell_iis.rb

In this example, the ‘start.rb’, ‘stop.rb’ and ‘restart.rb’ recipes would use the ‘start’ and/or ‘stop’ actions implemented by the corresponding Powershell scripts.

The ‘_init.ps1’ and ‘_term.ps1’ are optional scripts that can contain initialization and cleanup code respectively. These two scripts are called once during a single Chef converge and can be used e.g. to load required .NET assemblies in the Powershell environment used to run the action scripts. The ‘_load_current_resource.ps1’ script is also optional. Chef calls this script right before executing an action if it exists. The script should load any state from the system that the provider needs in order to run its actions (in this example this script could check whether the website is currently running so that the start and stop scripts would know whether any action is required on their part).

Note that there should be a light weight resource defined for each Powershell provider. By default the resource name should match the name of the provider (that is the name of the folder containing the Powershell scripts). A lightweight resource can specify a different name for its corresponding provider though.

Typical usage for this class involved calling ‘generate_providers’ multiple times then inspecting ‘validation_errors’

Constant Summary collapse

POWERSHELL_PROVIDERS_DIR_NAME =

Name of directory under cookbook that contains Powershell providers

'powershell_providers'
INIT_SCRIPT =

List of files with built-in behavior

'_init'
TERM_SCRIPT =
'_term'
LOAD_SCRIPT =
'_load_current_resource'
BUILT_IN_SCRIPTS =
[INIT_SCRIPT, TERM_SCRIPT, LOAD_SCRIPT]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDynamicPowershellProvider

Initialize instance



98
99
100
101
102
# File 'lib/chef/windows/dynamic_powershell_provider.rb', line 98

def initialize
  @validation_errors = {}
  @providers = []
  @providers_names = []
end

Instance Attribute Details

#providersObject (readonly)

Generated providers classes initialized by ‘generate_providers’



92
93
94
# File 'lib/chef/windows/dynamic_powershell_provider.rb', line 92

def providers
  @providers
end

#validation_errorsObject (readonly)

Hash of Powershell Chef providers validation errors keyed by provider path and initialized by ‘generate_providers’



88
89
90
# File 'lib/chef/windows/dynamic_powershell_provider.rb', line 88

def validation_errors
  @validation_errors
end

Instance Method Details

#generate_providers(cookbooks_paths) ⇒ Object

Generate Chef providers from cookbooks in given path Initializes ‘validation_errors’ accordingly Skip providers that have already been created by this instance

Parameters

cookbooks_path(String|Array)

Path(s) to cookbooks directories

Return

providers(Array)

List of generated providers names



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/chef/windows/dynamic_powershell_provider.rb', line 113

def generate_providers(cookbooks_paths)
  providers = []
  cookbooks_paths = [cookbooks_paths] unless cookbooks_paths.is_a?(Array)
  cookbooks_paths.each do |cookbooks_path|
    return [] unless File.directory?(cookbooks_path)
    Dir[File.normalize_path(File.join(cookbooks_path, '*/'))].each do |cookbook_path|
      cookbook_name = File.basename(cookbook_path)
      Dir[File.normalize_path(File.join(cookbook_path, POWERSHELL_PROVIDERS_DIR_NAME, '*/'))].each do |provider_file_path|
        provider_name = filename_to_qualified_string(cookbook_name, provider_file_path)
        provider_class_name = convert_to_class_name(provider_name)
        next if @providers_names.include?(provider_class_name)
        generate_single_provider(provider_class_name, provider_file_path)
        providers << provider_name
      end
    end
  end
  @providers_names += providers
  true
end