diff --git a/lib/puppet/provider/sqlserver_features/mssql.rb b/lib/puppet/provider/sqlserver_features/mssql.rb index 3002b94c..844d0bc8 100644 --- a/lib/puppet/provider/sqlserver_features/mssql.rb +++ b/lib/puppet/provider/sqlserver_features/mssql.rb @@ -11,8 +11,8 @@ def self.instances existing_instance = {:name => "Generic Features", :ensure => :present, :features => - PuppetX::Sqlserver::ServerHelper.translate_features( - jsonResult['Generic Features']).sort! + PuppetX::Sqlserver::ServerHelper.translate_features( + jsonResult['Generic Features']).sort! } debug "Parsed features = #{existing_instance[:features]}" @@ -58,6 +58,15 @@ def modify_features(action, features) if not_nil_and_not_empty?(@resource[:pid]) cmd_args << "/PID=#{@resource[:pid]}" end + if not_nil_and_not_empty?(@resource[:install_switches]) + @resource[:install_switches].each_pair do |k, v| + if v.is_a?(Numeric) || (v.is_a?(String) && v =~ /\d/) + cmd_args << "/#{k}=#{v}" + else + cmd_args << "/#{k}='#{v}'" + end + end + end end try_execute(cmd_args, "Unable to #{action} features (#{features.join(', ')})") end diff --git a/lib/puppet/provider/sqlserver_instance/mssql.rb b/lib/puppet/provider/sqlserver_instance/mssql.rb index 906f9ea8..93acd57f 100644 --- a/lib/puppet/provider/sqlserver_instance/mssql.rb +++ b/lib/puppet/provider/sqlserver_instance/mssql.rb @@ -12,8 +12,8 @@ def self.instances existing_instance = {:name => instance_name, :ensure => :present, :features => - PuppetX::Sqlserver::ServerHelper.translate_features( - jsonResult[instance_name]['features']).sort! + PuppetX::Sqlserver::ServerHelper.translate_features( + jsonResult[instance_name]['features']).sort! } instance = new(existing_instance) instances << instance @@ -73,7 +73,7 @@ def basic_cmd_args(features, action) def build_cmd_args(features, action="install") cmd_args = basic_cmd_args(features, action) if action == 'install' - (@resource.parameters.keys - %w(ensure loglevel features name provider source sql_sysadmin_accounts sql_security_mode).map(&:to_sym)).sort.collect do |key| + (@resource.parameters.keys - %w(ensure loglevel features name provider source sql_sysadmin_accounts sql_security_mode install_switches).map(&:to_sym)).sort.collect do |key| cmd_args << "/#{key.to_s.gsub(/_/, '').upcase}=\"#{@resource[key]}\"" end if not_nil_and_not_empty? @resource[:sql_sysadmin_accounts] @@ -83,6 +83,15 @@ def build_cmd_args(features, action="install") cmd_args << "/SQLSYSADMINACCOUNTS=\"#{@resource[:sql_sysadmin_accounts]}\"" end end + if not_nil_and_not_empty? @resource[:install_switches] + @resource[:install_switches].each_pair do |k, v| + if v.is_a?(Numeric) || (v.is_a?(String) && v =~ /\d/) + cmd_args << "/#{k}=#{v}" + else + cmd_args << "/#{k}='#{v}'" + end + end + end end cmd_args end diff --git a/lib/puppet/type/sqlserver_features.rb b/lib/puppet/type/sqlserver_features.rb index c7b33653..55a8edfb 100644 --- a/lib/puppet/type/sqlserver_features.rb +++ b/lib/puppet/type/sqlserver_features.rb @@ -43,6 +43,13 @@ end end + newparam(:install_switches) do + desc 'A hash of switches you want to pass to the installer' + validate do |value| + fail ArguemntError, 'install_switch must be in the form of a Hash' unless value.is_a?(Hash) + end + end + def validate if set?(:features) self[:features] = self[:features].flatten.sort.uniq diff --git a/lib/puppet/type/sqlserver_instance.rb b/lib/puppet/type/sqlserver_instance.rb index a776b825..7ca7bfbb 100644 --- a/lib/puppet/type/sqlserver_instance.rb +++ b/lib/puppet/type/sqlserver_instance.rb @@ -2,7 +2,9 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'puppet_x/sqlserver/server_helper')) Puppet::Type::newtype(:sqlserver_instance) do + ensurable + newparam(:name, :namevar => true) do munge do |value| value.upcase @@ -114,6 +116,13 @@ newvalues('SQL') end + newparam(:install_switches) do + desc 'A hash of switches you want to pass to the installer' + validate do |value| + fail ArguemntError, 'install_switch must be in the form of a Hash' unless value.is_a?(Hash) + end + end + def validate if set?(:agt_svc_account) diff --git a/spec/unit/puppet/provider/sqlserver__instance_spec.rb b/spec/unit/puppet/provider/sqlserver__instance_spec.rb index a9a6488e..d73dc6c1 100644 --- a/spec/unit/puppet/provider/sqlserver__instance_spec.rb +++ b/spec/unit/puppet/provider/sqlserver__instance_spec.rb @@ -6,6 +6,7 @@ RSpec.describe provider_class do subject { provider_class } + let(:additional_install_switches) { [] } def stub_uninstall(args, installed_features) cmd_args = ["#{args[:source]}/setup.exe", @@ -32,7 +33,7 @@ def stub_uninstall(args, installed_features) '/IACCEPTSQLSERVERLICENSETERMS', "/INSTANCENAME=#{execute_args[:name]}", "/FEATURES=#{execute_args[:features].join(',')}",] - (execute_args.keys - %w(ensure loglevel features name source sql_sysadmin_accounts sql_security_mode).map(&:to_sym)).sort.collect do |key| + (execute_args.keys - %w(ensure loglevel features name source sql_sysadmin_accounts sql_security_mode install_switches).map(&:to_sym)).sort.collect do |key| cmd_args << "/#{key.to_s.gsub(/_/, '').upcase}=\"#{@resource[key]}\"" end if execute_args[:sql_security_mode] @@ -58,13 +59,16 @@ def stub_uninstall(args, installed_features) '/IACCEPTSQLSERVERLICENSETERMS', "/INSTANCENAME=#{execute_args[:name]}", "/FEATURES=#{execute_args[:features].join(',')}",] - (execute_args.keys - %w( ensure loglevel features name source sql_sysadmin_accounts sql_security_mode).map(&:to_sym)).sort.collect do |key| + (execute_args.keys - %w( ensure loglevel features name source sql_sysadmin_accounts sql_security_mode install_switches).map(&:to_sym)).sort.collect do |key| cmd_args << "/#{key.to_s.gsub(/_/, '').upcase}=\"#{@resource[key]}\"" end if execute_args[:sql_security_mode] cmd_args << "/SECURITYMODE=SQL" end cmd_args << "/SQLSYSADMINACCOUNTS=#{ Array.new(@resource[:sql_sysadmin_accounts]).collect { |account| "\"#{account}\"" }.join(' ')}" + additional_install_switches.each do |switch| + cmd_args << switch + end Puppet::Util::Execution.stubs(:execute).with(cmd_args.compact).returns(0) @provider.create } @@ -110,9 +114,9 @@ def stub_uninstall(args, installed_features) it_behaves_like 'destroy on create' do let(:installed_features) { %w(SQLEngine Replication) } let(:args) { { - :name => 'MYSQLSERVER', - :source => 'C:\myinstallexecs', - :features => [] + :name => 'MYSQLSERVER', + :source => 'C:\myinstallexecs', + :features => [] } } end end @@ -120,9 +124,9 @@ def stub_uninstall(args, installed_features) describe 'it should uninstall' do it_behaves_like 'destroy' do let(:args) { { - :name => 'MYSQLSERVER', - :source => 'C:\myinstallexecs', - :features => [] + :name => 'MYSQLSERVER', + :source => 'C:\myinstallexecs', + :features => [] } } let(:installed_features) { %w(SQLEngine Replication) } end @@ -131,11 +135,36 @@ def stub_uninstall(args, installed_features) describe 'installed features even if provided features' do it_behaves_like 'destroy' do let(:args) { { - :name => 'MYSQLSERVER', - :source => 'C:\myinstallexecs', - :features => ['SQL'] + :name => 'MYSQLSERVER', + :source => 'C:\myinstallexecs', + :features => ['SQL'] } } let(:installed_features) { %w(SQLEngine Replication) } end end + + describe 'install_switches' do + it_behaves_like 'create' do + args = get_basic_args + args[:install_switches] = {'ERRORREPORTING' => 1} + let(:additional_install_switches) { ['/ERRORREPORTING=1'] } + let(:args) { args } + munged = {:features => Array.new(args[:features])} + munged[:features].delete('SQL') + munged[:features] += %w(DQ FullText Replication SQLEngine) + munged[:features].sort! + let(:munged_values) { munged } + end + it_behaves_like 'create' do + args = get_basic_args + args[:install_switches] = {'ERRORREPORTING' => 1, 'SQLBACKUPDIR' => 'I:\DBbackup'} + let(:additional_install_switches) { ['/ERRORREPORTING=1', '/SQLBACKUPDIR=\'I:\DBbackup\''] } + let(:args) { args } + munged = {:features => Array.new(args[:features])} + munged[:features].delete('SQL') + munged[:features] += %w(DQ FullText Replication SQLEngine) + munged[:features].sort! + let(:munged_values) { munged } + end + end end diff --git a/spec/unit/puppet/provider/sqlserver_features_spec.rb b/spec/unit/puppet/provider/sqlserver_features_spec.rb index e43e27a8..0140f0df 100644 --- a/spec/unit/puppet/provider/sqlserver_features_spec.rb +++ b/spec/unit/puppet/provider/sqlserver_features_spec.rb @@ -7,7 +7,7 @@ RSpec.describe provider_class do subject { provider_class } - shared_examples 'create' do |args, munged_args = {}| + shared_examples 'create' do |args, munged_args = {}, additional_switches = []| it { @resource = Puppet::Type::Sqlserver_features.new(args) @provider = provider_class.new(@resource) @@ -15,16 +15,16 @@ stub_powershell_call(subject) executed_args = args.merge(munged_args) - stub_add_features(executed_args, executed_args[:features]) + stub_add_features(executed_args, executed_args[:features], additional_switches) @provider.create } end shared_context 'features' do @feature_params = { - :name => 'Base features', - :source => 'C:\myinstallexecs', - :features => %w(BC SSMS) + :name => 'Base features', + :source => 'C:\myinstallexecs', + :features => %w(BC SSMS) } let(:feature_remove) { [] } let(:feature_add) { [] } @@ -35,6 +35,13 @@ it_should_behave_like 'create', @feature_params end + context 'it should provide the correct command default command' do + include_context 'features' + @feature_params[:install_switches] ={'ERRORREPORTING' => 1, 'SQLBACKUPDIR' => 'I:\DBbackup'} + additional_switches = ['/ERRORREPORTING=1', '/SQLBACKUPDIR=\'I:\DBbackup\''] + it_should_behave_like 'create', @feature_params, {}, additional_switches + end + context 'it should expand the superset for features' do include_context 'features' @feature_params[:features] = %w(Tools) @@ -100,21 +107,21 @@ describe 'it should call destroy on empty array' do it { feature_params = { - :name => 'Base features', - :source => 'C:\myinstallexecs', - :features => [] + :name => 'Base features', + :source => 'C:\myinstallexecs', + :features => [] } @resource = Puppet::Type::Sqlserver_features.new(feature_params) @provider = provider_class.new(@resource) @provider.stubs(:current_installed_features).returns(%w(SSMS ADV_SSMS Conn)) Puppet::Util.stubs(:which).with("#{feature_params[:source]}/setup.exe").returns("#{feature_params[:source]}/setup.exe") Puppet::Util::Execution.expects(:execute).with( - ["#{feature_params[:source]}/setup.exe", - "/ACTION=uninstall", - '/Q', - '/IACCEPTSQLSERVERLICENSETERMS', - "/FEATURES=#{%w(SSMS ADV_SSMS Conn).join(',')}", - ]).returns(0) + ["#{feature_params[:source]}/setup.exe", + "/ACTION=uninstall", + '/Q', + '/IACCEPTSQLSERVERLICENSETERMS', + "/FEATURES=#{%w(SSMS ADV_SSMS Conn).join(',')}", + ]).returns(0) @provider.create } end diff --git a/spec/unit/puppet/sqlserver_spec_helper.rb b/spec/unit/puppet/sqlserver_spec_helper.rb index 8cce4d0a..141a4259 100644 --- a/spec/unit/puppet/sqlserver_spec_helper.rb +++ b/spec/unit/puppet/sqlserver_spec_helper.rb @@ -7,15 +7,15 @@ def stub_powershell_call(subject) Puppet::Provider::Sqlserver.stubs(:run_install_dot_net).returns() end -def stub_add_features(args, features) - stub_modify_features('install', args, features) +def stub_add_features(args, features, additional_switches = []) + stub_modify_features('install', args, features, additional_switches) end def stub_remove_features(args, features) stub_modify_features('uninstall', args, features) end -def stub_modify_features(action, args, features) +def stub_modify_features(action, args, features, additional_switches = []) cmds = ["#{args[:source]}/setup.exe", "/ACTION=#{action}", '/Q', @@ -28,5 +28,8 @@ def stub_modify_features(action, args, features) if args.has_key?(:is_svc_password) cmds << "/ISSVCPASSWORD=#{args[:is_svc_password]}" end + additional_switches.each do |switch| + cmds << switch + end Puppet::Util::Execution.stubs(:execute).with(cmds).returns(0) end