summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Mundrawala <jdmundrawala@gmail.com>2015-02-12 16:02:57 -0600
committerJay Mundrawala <jdmundrawala@gmail.com>2015-02-12 16:02:57 -0600
commit0df0e36f82e24cfb7cb22eaef0c8d99002a177b8 (patch)
tree2e629b5a0b4a1a315e3c08aeda33bf7201684f1a
parentab6aeedae48d37bca177a983232f35b518557d2f (diff)
parent0f794c42243138b1b0cdcfa572ed805274562c68 (diff)
downloadchef-0df0e36f82e24cfb7cb22eaef0c8d99002a177b8.tar.gz
Merge pull request #2779 from chef/jdm/dsc_script_imports
Allow dsc_script to import dsc resources
-rw-r--r--lib/chef/provider/dsc_script.rb2
-rw-r--r--lib/chef/resource/dsc_script.rb14
-rw-r--r--lib/chef/util/dsc/configuration_generator.rb36
-rw-r--r--spec/unit/provider/dsc_script_spec.rb2
-rw-r--r--spec/unit/resource/dsc_script_spec.rb32
-rw-r--r--spec/unit/util/dsc/configuration_generator_spec.rb26
6 files changed, 102 insertions, 10 deletions
diff --git a/lib/chef/provider/dsc_script.rb b/lib/chef/provider/dsc_script.rb
index c183f871e9..a75e68a475 100644
--- a/lib/chef/provider/dsc_script.rb
+++ b/lib/chef/provider/dsc_script.rb
@@ -129,7 +129,7 @@ class Chef
else
# If code is also not provided, we mimic what the other script resources do (execute nothing)
Chef::Log.warn("Neither code or command were provided for dsc_resource[#{@dsc_resource.name}].") unless @dsc_resource.code
- generator.configuration_document_from_script_code(@dsc_resource.code || '', configuration_flags, shellout_flags)
+ generator.configuration_document_from_script_code(@dsc_resource.code || '', configuration_flags, @dsc_resource.imports, shellout_flags)
end
end
diff --git a/lib/chef/resource/dsc_script.rb b/lib/chef/resource/dsc_script.rb
index 82907c25db..cf96ef6b7f 100644
--- a/lib/chef/resource/dsc_script.rb
+++ b/lib/chef/resource/dsc_script.rb
@@ -29,6 +29,7 @@ class Chef
@allowed_actions.push(:run)
@action = :run
@resource_name = :dsc_script
+ @imports = {}
end
def code(arg=nil)
@@ -89,6 +90,19 @@ class Chef
)
end
+ def imports(module_name=nil, *args)
+ if module_name
+ @imports[module_name] ||= []
+ if args.length == 0
+ @imports[module_name] << '*'
+ else
+ @imports[module_name].push(*args)
+ end
+ else
+ @imports
+ end
+ end
+
def flags(arg=nil)
set_or_return(
:flags,
diff --git a/lib/chef/util/dsc/configuration_generator.rb b/lib/chef/util/dsc/configuration_generator.rb
index 12cd5dc3a2..0d7296eae9 100644
--- a/lib/chef/util/dsc/configuration_generator.rb
+++ b/lib/chef/util/dsc/configuration_generator.rb
@@ -25,9 +25,9 @@ class Chef::Util::DSC
@config_directory = config_directory
end
- def configuration_document_from_script_code(code, configuration_flags, shellout_flags)
+ def configuration_document_from_script_code(code, configuration_flags, imports, shellout_flags)
Chef::Log.debug("DSC: DSC code:\n '#{code}'")
- generated_script_path = write_document_generation_script(code, 'chef_dsc')
+ generated_script_path = write_document_generation_script(code, 'chef_dsc', imports)
begin
configuration_document_from_script_path(generated_script_path, 'chef_dsc', configuration_flags, shellout_flags)
ensure
@@ -80,18 +80,42 @@ class Chef::Util::DSC
merged_configuration_flags
end
- def configuration_code(code, configuration_name)
- "$ProgressPreference = 'SilentlyContinue';Configuration '#{configuration_name}'\n{\n\tnode 'localhost'\n{\n\t#{code}\n}}\n"
+ def configuration_code(code, configuration_name, imports)
+ <<-EOF
+$ProgressPreference = 'SilentlyContinue';
+Configuration '#{configuration_name}'
+{
+ #{generate_import_resource_statements(imports).join(" \n")}
+ node 'localhost'
+ {
+ #{code}
+ }
+}
+ EOF
+ end
+
+ def generate_import_resource_statements(imports)
+ if imports
+ imports.map do |resource_module, resources|
+ if resources.length == 0 || resources.include?('*')
+ "Import-DscResource -ModuleName #{resource_module}"
+ else
+ "Import-DscResource -ModuleName #{resource_module} -Name #{resources.join(',')}"
+ end
+ end
+ else
+ []
+ end
end
def configuration_document_generation_code(configuration_script, configuration_name)
". '#{configuration_script}';#{configuration_name}"
end
- def write_document_generation_script(code, configuration_name)
+ def write_document_generation_script(code, configuration_name, imports)
script_path = "#{@config_directory}/chef_dsc_config.ps1"
::File.open(script_path, 'wt') do | script |
- script.write(configuration_code(code, configuration_name))
+ script.write(configuration_code(code, configuration_name, imports))
end
script_path
end
diff --git a/spec/unit/provider/dsc_script_spec.rb b/spec/unit/provider/dsc_script_spec.rb
index d018c8ad54..d4b2eb3b22 100644
--- a/spec/unit/provider/dsc_script_spec.rb
+++ b/spec/unit/provider/dsc_script_spec.rb
@@ -99,7 +99,7 @@ describe Chef::Provider::DscScript do
it 'should noop if neither code or command are provided' do
allow(provider).to receive(:load_current_resource)
generator = double('Chef::Util::DSC::ConfigurationGenerator')
- expect(generator).to receive(:configuration_document_from_script_code).with('', anything(), anything())
+ expect(generator).to receive(:configuration_document_from_script_code).with('', anything(), anything(), anything())
allow(Chef::Util::DSC::ConfigurationGenerator).to receive(:new).and_return(generator)
provider.send(:generate_configuration_document, 'tmp', nil)
end
diff --git a/spec/unit/resource/dsc_script_spec.rb b/spec/unit/resource/dsc_script_spec.rb
index eb9d19e553..71103ea590 100644
--- a/spec/unit/resource/dsc_script_spec.rb
+++ b/spec/unit/resource/dsc_script_spec.rb
@@ -70,6 +70,38 @@ describe Chef::Resource::DscScript do
expect(dsc_test_resource.configuration_data_script).to eq(configuration_data_script)
end
+ context "when calling imports" do
+ let(:module_name) { 'FooModule' }
+ let(:module_name_b) { 'BarModule' }
+ let(:dsc_resources) { ['ResourceA', 'ResourceB'] }
+
+ it "allows an arbitrary number of resources to be set for a module to be set" do
+ dsc_test_resource.imports module_name, *dsc_resources
+ module_imports = dsc_test_resource.imports[module_name]
+ expect(module_imports).to eq(dsc_resources)
+ end
+
+ it "adds * to the imports when no resources are set for a moudle" do
+ dsc_test_resource.imports module_name
+ module_imports = dsc_test_resource.imports[module_name]
+ expect(module_imports).to eq(['*'])
+ end
+
+ it "allows an arbitrary number of modules" do
+ dsc_test_resource.imports module_name
+ dsc_test_resource.imports module_name_b
+ expect(dsc_test_resource.imports).to have_key(module_name)
+ expect(dsc_test_resource.imports).to have_key(module_name_b)
+ end
+
+ it "allows resources to be added for a module" do
+ dsc_test_resource.imports module_name, dsc_resources[0]
+ dsc_test_resource.imports module_name, dsc_resources[1]
+ module_imports = dsc_test_resource.imports[module_name]
+ expect(module_imports).to eq(dsc_resources)
+ end
+ end
+
it "raises an ArgumentError exception if an attempt is made to set the code attribute when the command attribute is already set" do
dsc_test_resource.command(configuration_path)
expect { dsc_test_resource.code(configuration_code) }.to raise_error(ArgumentError)
diff --git a/spec/unit/util/dsc/configuration_generator_spec.rb b/spec/unit/util/dsc/configuration_generator_spec.rb
index e75e285d43..9fbd3aaa51 100644
--- a/spec/unit/util/dsc/configuration_generator_spec.rb
+++ b/spec/unit/util/dsc/configuration_generator_spec.rb
@@ -130,7 +130,7 @@ describe Chef::Util::DSC::ConfigurationGenerator do
[a,b].join("++")
end
allow(file_like_object).to receive(:write)
- conf_man.send(:write_document_generation_script, 'file', 'hello')
+ conf_man.send(:write_document_generation_script, 'file', 'hello', {})
expect(file_like_object).to have_received(:write)
end
end
@@ -158,7 +158,7 @@ describe Chef::Util::DSC::ConfigurationGenerator do
describe "#configuration_code" do
it "should build dsc" do
- dsc = conf_man.send(:configuration_code, 'archive{}', 'hello')
+ dsc = conf_man.send(:configuration_code, 'archive{}', 'hello', {})
found_configuration = false
dsc.split(';').each do |command|
if command.downcase =~ /\s*configuration\s+'hello'\s*\{\s*node\s+'localhost'\s*\{\s*archive\s*\{\s*\}\s*\}\s*\}\s*/
@@ -167,5 +167,27 @@ describe Chef::Util::DSC::ConfigurationGenerator do
end
expect(found_configuration).to be_truthy
end
+ context "with imports" do
+ it "should import all resources when a module has an empty list" do
+ dsc = conf_man.send(:configuration_code, 'archive{}', 'hello', {'FooModule' => []})
+ expect(dsc).to match(/Import-DscResource -ModuleName FooModule\s*\n/)
+ end
+
+ it "should import all resources when a module has a list with *" do
+ dsc = conf_man.send(:configuration_code, 'archive{}', 'hello', {'FooModule' => ['FooResource', '*', 'BarResource']})
+ expect(dsc).to match(/Import-DscResource -ModuleName FooModule\s*\n/)
+ end
+
+ it "should import specific resources when a module has list without * that is not empty" do
+ dsc = conf_man.send(:configuration_code, 'archive{}', 'hello', {'FooModule' => ['FooResource', 'BarResource']})
+ expect(dsc).to match(/Import-DscResource -ModuleName FooModule -Name FooResource,BarResource/)
+ end
+
+ it "should import multiple modules with multiple import statements" do
+ dsc = conf_man.send(:configuration_code, 'archive{}', 'hello', {'FooModule' => ['FooResource', 'BarResource'], 'BazModule' => []})
+ expect(dsc).to match(/Import-DscResource -ModuleName FooModule -Name FooResource,BarResource/)
+ expect(dsc).to match(/Import-DscResource -ModuleName BazModule\s*\n/)
+ end
+ end
end
end