Skip to content

(MODULES-5070) Add polybase parameters to sql_instance #231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,22 @@ Specifies a product key for SQL Server. Valid options: a string containing a val

Default: `undef`.

##### `polybase_svc_account`

*Only applicable if the POLYBASE feature for SQL Server 2016 is being installed*

Specifies a domain or system account for the Polybase Engine service.

Valid options: a string specifying an existing username.

##### `polybase_svc_password`

*Only applicable if the POLYBASE feature for SQL Server 2016 is being installed*

Specifies the password for the Polybase Engine service

Valid options: a string specifying a valid password.

##### `rs_svc_account`

Specifies a domain or system account to be used by the report service. Valid options: a string; cannot include any of the following characters: `'"/ \ [ ] : ; | = , + * ? < >'`. If you specify a domain user account, the domain must be less than 254 characters and the username must be less than 20 characters.
Expand Down
37 changes: 30 additions & 7 deletions lib/puppet/provider/sqlserver_instance/mssql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,28 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'puppet_x/sqlserver/server_helper'))
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'puppet_x/sqlserver/features'))

INSTANCE_RESERVED_SWITCHES =
%w(AGTSVCACCOUNT AGTSVCPASSWORD ASSVCACCOUNT AGTSVCPASSWORD PID
RSSVCACCOUNT RSSVCPASSWORD SAPWD SECURITYMODE SQLSYSADMINACCOUNTS FEATURES)

Puppet::Type::type(:sqlserver_instance).provide(:mssql, :parent => Puppet::Provider::Sqlserver) do
RESOURCEKEY_TO_CMDARG = {
'agt_svc_account' => 'AGTSVCACCOUNT',
'agt_svc_password' => 'AGTSVCPASSWORD',
'as_svc_account' => 'ASSVCACCOUNT',
'as_svc_password' => 'ASSVCPASSWORD',
'pid' => 'PID',
'rs_svc_account' => 'RSSVCACCOUNT',
'rs_svc_password' => 'RSSVCPASSWORD',
'polybase_svc_account' => 'PBENGSVCACCOUNT',
'polybase_svc_password' => 'PBDMSSVCPASSWORD',
'sa_pwd' => 'SAPWD',
'security_mode' => 'SECURITYMODE',
'sql_svc_account' => 'SQLSVCACCOUNT',
'sql_svc_password' => 'SQLSVCPASSWORD',
}

def instance_reserved_switches
# List of all puppet managed install switches
RESOURCEKEY_TO_CMDARG.values + ['FEATURES','SQLSYSADMINACCOUNTS']
end

def self.instances
instances = []
result = Facter.value(:sqlserver_instances)
Expand Down Expand Up @@ -74,6 +91,12 @@ def create
unless @resource[:as_sysadmin_accounts].nil? || @resource[:features].include?('AS')
fail('The parameter as_sysadmin_accounts was specified however the AS feature was not included in the installed features. Either remove the as_sysadmin_accounts parameter or add AS as a feature to the instance.')
end
unless @resource[:polybase_svc_account].nil? || @resource[:features].include?('POLYBASE')
fail('The parameter polybase_svc_account was specified however the POLYBASE feature was not included in the installed features. Either remove the polybase_svc_account parameter or add POLYBASE as a feature to the instance.')
end
unless @resource[:polybase_svc_password].nil? || @resource[:features].include?('POLYBASE')
fail('The parameter polybase_svc_password was specified however the POLYBASE feature was not included in the installed features. Either remove the polybase_svc_password parameter or add POLYBASE as a feature to the instance.')
end

instance_version = PuppetX::Sqlserver::ServerHelper.sql_version_from_install_source(@resource[:source])
Puppet.debug("Installation source detected as version #{instance_version}") unless instance_version.nil?
Expand All @@ -88,7 +111,7 @@ def create_temp_for_install_switch
if not_nil_and_not_empty? @resource[:install_switches]
config_file = ["[OPTIONS]"]
@resource[:install_switches].each_pair do |k, v|
if INSTANCE_RESERVED_SWITCHES.include? k
if instance_reserved_switches.include? k
warn("Reserved switch [#{k}] found for `install_switches`, please know the provided value may be overridden by some command line arguments")
end
if v.is_a?(Numeric) || (v.is_a?(String) && v =~ /^(true|false|1|0)$/i)
Expand Down Expand Up @@ -121,9 +144,9 @@ def build_cmd_args(features, action="install")
cmd_args = basic_cmd_args(features, action)
obfuscated_strings = []
if action == 'install'
%w(pid sa_pwd sql_svc_account sql_svc_password agt_svc_account agt_svc_password as_svc_account as_svc_password rs_svc_account rs_svc_password security_mode).map(&:to_sym).sort.collect do |key|
RESOURCEKEY_TO_CMDARG.keys.sort.collect do |key|
if not_nil_and_not_empty? @resource[key]
cmd_args << "/#{key.to_s.gsub(/_/, '').upcase}=\"#{@resource[key]}\""
cmd_args << "/#{RESOURCEKEY_TO_CMDARG[key]}=\"#{@resource[key.to_sym]}\""
if key.to_s =~ /(_pwd|_password)$/i
obfuscated_strings.push(@resource[key])
end
Expand Down
10 changes: 10 additions & 0 deletions lib/puppet/type/sqlserver_instance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@
end
end

newparam(:polybase_svc_account, :parent => Puppet::Property::SqlserverLogin) do
desc 'The account used by the Polybase Engine service. Only applicable for SQL Server 2016.'

end

newparam(:polybase_svc_password) do
desc 'The password for the Polybase Engine service account. Only applicable for SQL Server 2016.'

end

newparam(:security_mode) do
desc 'Specifies the security mode for SQL Server.
If this parameter is not supplied, then Windows-only authentication mode is supported.
Expand Down
74 changes: 46 additions & 28 deletions spec/unit/puppet/provider/sqlserver_instance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@
subject { provider_class }
let(:additional_install_switches) { [] }

let(:resourcekey_to_cmdarg) {{
'agt_svc_account' => 'AGTSVCACCOUNT',
'agt_svc_password' => 'AGTSVCPASSWORD',
'as_svc_account' => 'ASSVCACCOUNT',
'as_svc_password' => 'ASSVCPASSWORD',
'pid' => 'PID',
'rs_svc_account' => 'RSSVCACCOUNT',
'rs_svc_password' => 'RSSVCPASSWORD',
'polybase_svc_account' => 'PBENGSVCACCOUNT',
'polybase_svc_password' => 'PBDMSSVCPASSWORD',
'sa_pwd' => 'SAPWD',
'security_mode' => 'SECURITYMODE',
'sql_svc_account' => 'SQLSVCACCOUNT',
'sql_svc_password' => 'SQLSVCPASSWORD',
}}

def stub_uninstall(args, installed_features, exit_code = 0)
cmd_args = ["#{args[:source]}/setup.exe",
"/ACTION=uninstall",
Expand All @@ -22,32 +38,6 @@ def stub_uninstall(args, installed_features, exit_code = 0)
Puppet::Util::Execution.stubs(:execute).with(cmd_args.compact, failonfail: false).returns(result)
end

shared_examples 'run' do |args, munged_values = {}|
it {
execute_args = args.merge(munged_values)
@resource = Puppet::Type::Sqlserver_instance.new(args)
@provider = provider_class.new(@resource)

stub_powershell_call(subject)
stub_source_which_call args[:source]

cmd_args = ["#{execute_args[:source]}/setup.exe",
"/ACTION=install",
'/Q',
'/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 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(' ')}"
Puppet::Util::Execution.stubs(:execute).with(cmd_args.compact).returns(0)
@provider.create
}
end
shared_examples 'create' do |exit_code, warning_matcher|
it {
execute_args = args.merge(munged_values)
Expand All @@ -64,7 +54,7 @@ def stub_uninstall(args, installed_features, exit_code = 0)
"/INSTANCENAME=#{execute_args[:name]}",
"/FEATURES=#{execute_args[:features].join(',')}",]
(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]}\""
cmd_args << "/#{resourcekey_to_cmdarg[key.to_s]}=\"#{@resource[key]}\""
end
if execute_args[:sql_security_mode]
cmd_args << "/SECURITYMODE=SQL"
Expand Down Expand Up @@ -106,7 +96,7 @@ def stub_uninstall(args, installed_features, exit_code = 0)
"/INSTANCENAME=#{execute_args[:name]}",
"/FEATURES=#{execute_args[:features].join(',')}",]
(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]}\""
cmd_args << "/#{resourcekey_to_cmdarg[key.to_s]}=\"#{@resource[key]}\""
end
if execute_args[:sql_security_mode]
cmd_args << "/SECURITYMODE=SQL"
Expand Down Expand Up @@ -154,6 +144,7 @@ def stub_uninstall(args, installed_features, exit_code = 0)
provider.create
}
end

describe 'it should provide the correct command default command' do
it_behaves_like 'create' do
args = get_basic_args
Expand All @@ -178,6 +169,33 @@ def stub_uninstall(args, installed_features, exit_code = 0)
end
end

describe 'it should raise error if polybase_svc_account is specified without POLYBASE feature' do
it_behaves_like 'create_failure', 1, /polybase_svc_account was specified however the POLYBASE feature was not included/i do
args = get_basic_args
args[:features] = ['SQLEngine']
args[:polybase_svc_account] = 'username'
args.delete(:polybase_svc_password)

let(:args) { args }
munged = {:features => Array.new(args[:features])}
let(:munged_values) { munged }
end
end

describe 'it should raise error if polybase_svc_password is specified without POLYBASE feature' do
it_behaves_like 'create_failure', 1, /polybase_svc_password was specified however the POLYBASE feature was not included/i do
args = get_basic_args
args[:features] = ['SQLEngine']
args.delete(:polybase_svc_account)
args[:polybase_svc_password] = 'password'

let(:args) { args }
munged = {:features => Array.new(args[:features])}
let(:munged_values) { munged }
end
end


describe 'it should raise warning on install when 1641 exit code returned' do
it_behaves_like 'create', 1641, /reboot initiated/i do
args = get_basic_args
Expand Down
22 changes: 3 additions & 19 deletions spec/unit/puppet/sqlserver_install_context.rb
Original file line number Diff line number Diff line change
@@ -1,33 +1,17 @@
RSpec.shared_context 'install_arguments' do
@install_args = {
:source => 'C:\myinstallexecs',
:pid => 'areallyCrazyLongPid',
:features => %w(SQL AS RS),
:name => 'MYSQLSERVER_HOST',
:agt_svc_account => 'nexus\travis',
:agt_svc_password => 'P@ssword1',
:as_svc_account => 'analysisAccount',
:as_svc_password => 'CrazySimpleP@ssword',
:rs_svc_account => 'reportUserAccount', #always local user
:rs_svc_password => 'reportP@ssword1',
:sql_svc_account => 'NT Service\MSSQLSERVER',
:sql_sysadmin_accounts => ['localAdminAccount', 'nexus\domainUser']
}
let(:args) { @install_args }
end

def get_basic_args
return {
:source => 'C:\myinstallexecs',
:pid => 'areallyCrazyLongPid',
:features => %w(SQL AS RS),
:features => %w(SQL AS RS POLYBASE),
:name => 'MYSQLSERVER_HOST',
:agt_svc_account => 'nexus\travis',
:agt_svc_password => 'P@ssword1',
:as_svc_account => 'analysisAccount',
:as_svc_password => 'CrazySimpleP@ssword',
:rs_svc_account => 'reportUserAccount', #always local user
:rs_svc_password => 'reportP@ssword1',
:polybase_svc_account => 'nexus\polyuser',
:polybase_svc_password => 'P@ssword1',
:sql_svc_account => 'NT Service\MSSQLSERVER',
:sql_sysadmin_accounts => ['localAdminAccount', 'nexus\domainUser']
}
Expand Down
37 changes: 20 additions & 17 deletions spec/unit/puppet/type/sqlserver_instance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
end

# Failed validation examples
shared_examples 'fail validation' do #|args, messages = ['must be set'], error_class = Puppet::Error|
shared_examples 'fail validation' do
it 'should fail with' do
expect {
Puppet::Type.type(:sqlserver_instance).new(args)
Expand Down Expand Up @@ -54,27 +54,30 @@
end
end


describe 'should fail when rs_svc_account contains an invalid character' do
describe "rs_svc_account" do
%w(/ \ [ ] : ; | = , + * ? < > ).each do |v|
it_should_behave_like 'fail validation' do
args = get_basic_args
args[:rs_svc_account] = "crazy#{v}User"
let(:args) { args }
let(:messages) { ['rs_svc_account can not contain any of the special characters,'] }
context "contains invalid character #{v}" do
it_should_behave_like 'fail validation' do
args = get_basic_args
args[:rs_svc_account] = "crazy#{v}User"
let(:args) { args }
let(:messages) { ['rs_svc_account can not contain any of the special characters,'] }
end
end
end
end

context 'must be at least 8 characters long' do
it_behaves_like 'fail validation' do
args = get_basic_args
args[:rs_svc_password] = 'hrt'
let(:args) { args }
let(:messages) { ['must be at least 8 characters long', 'must contain uppercase letters',
'must contain numbers',
'must contain a special character'] }

describe "rs_svc_password" do
context 'when less than 8 characters long' do
it_behaves_like 'fail validation' do
args = get_basic_args
args[:rs_svc_password] = 'hrt'
let(:args) { args }
let(:messages) { ['must be at least 8 characters long',
'must contain uppercase letters',
'must contain numbers',
'must contain a special character'] }
end
end
end
end