Skip to content

(CONT-490) - Add support for SQL Server 2022 #420

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 2 commits into from
Mar 6, 2023
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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

## Overview

The sqlserver module installs and manages Microsoft SQL Server 2012, 2014, 2016, 2017, 2019 on Windows systems.
The sqlserver module installs and manages Microsoft SQL Server 2012, 2014, 2016, 2017, 2019 and 2022 on Windows systems.

## Module Description

Expand Down Expand Up @@ -272,9 +272,9 @@ For information on the classes and types, see the [REFERENCE.md](https://github.

## Limitations

SQL 2017 and 2019 detection support has been added. This support is limited to functionality already present for other versions. No new SQL 2017 or above specific functionality has been added in this release.
SQL 2017, 2019 and 2022 detection support has been added. This support is limited to functionality already present for other versions.

This module can manage only a single version of SQL Server on a given host (one and only one of SQL Server 2012, 2014, 2016, 2017, or 2019). The module is able to manage multiple SQL Server instances of the same version.
This module can manage only a single version of SQL Server on a given host (one and only one of SQL Server 2012, 2014, 2016, 2017, 2019 or 2022). The module is able to manage multiple SQL Server instances of the same version.

This module cannot manage the SQL Server Native Client SDK (also known as SNAC_SDK). The SQL Server installation media can install the SDK, but it is not able to uninstall the SDK. Note that the 'sqlserver_features' fact detects the presence of the SDK.

Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/provider/sqlserver_features/mssql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def create
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?

install_net_35(@resource[:windows_feature_source]) unless [SQL_2016, SQL_2017, SQL_2019].include? instance_version
install_net_35(@resource[:windows_feature_source]) if [SQL_2012, SQL_2014].include? instance_version

debug "Installing features #{@resource[:features]}"
add_features(@resource[:features])
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/provider/sqlserver_instance/mssql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def create
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?

install_net_35(@resource[:windows_feature_source]) unless [SQL_2016, SQL_2017, SQL_2019].include? instance_version
install_net_35(@resource[:windows_feature_source]) if [SQL_2012, SQL_2014].include? instance_version

add_features(@resource[:features])
end
Expand Down
11 changes: 9 additions & 2 deletions lib/puppet_x/sqlserver/features.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
SQL_2016 ||= 'SQL_2016'
SQL_2017 ||= 'SQL_2017'
SQL_2019 ||= 'SQL_2019'
SQL_2022 ||= 'SQL_2022'

ALL_SQL_VERSIONS ||= [SQL_2012, SQL_2014, SQL_2016, SQL_2017, SQL_2019].freeze
ALL_SQL_VERSIONS ||= [SQL_2012, SQL_2014, SQL_2016, SQL_2017, SQL_2019, SQL_2022].freeze

# rubocop:disable Style/ClassAndModuleChildren
module PuppetX
Expand Down Expand Up @@ -39,6 +40,10 @@ class Features # rubocop:disable Style/Documentation
major_version: 15,
registry_path: '150',
},
SQL_2022 => {
major_version: 16,
registry_path: '160',
},
}.freeze

SQL_REG_ROOT ||= 'Software\Microsoft\Microsoft SQL Server'
Expand Down Expand Up @@ -145,6 +150,8 @@ def self.get_instance_features(reg_root, instance_name)

def self.get_shared_features(version)
shared_features = {
# Client tools support removed with SQLServer 2022
# (ref https://learn.microsoft.com/en-us/sql/database-engine/install-windows/install-sql-server-on-server-core?view=sql-server-ver16#BK_SupportedFeatures)
'Connectivity_Full' => 'Conn', # Client Tools Connectivity
'SDK_Full' => 'SDK', # Client Tools SDK
'MDSCoreFeature' => 'MDS', # Master Data Services
Expand All @@ -156,7 +163,7 @@ def self.get_shared_features(version)
'SQL_DReplay_Controller' => 'DREPLAY_CTLR', # Distributed Replay Controller
'SQL_DReplay_Client' => 'DREPLAY_CLT', # Distributed Replay Client
'sql_shared_mr' => 'SQL_SHARED_MR', # R Server (Standalone)

# SQL Client Connectivity SDK (Installed by default)
# also WMI: SqlService WHERE SQLServiceType = 4 # MsDtsServer
'SQL_DTS_Full' => 'IS', # Integration Services
# currently ignoring Reporting Services Shared
Expand Down
1 change: 1 addition & 0 deletions lib/puppet_x/sqlserver/server_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def self.sql_version_from_install_source(source_dir)
ver = content.match('"(.+)"')
return nil if ver.nil?

return SQL_2022 if ver[1].start_with?('16.')
return SQL_2019 if ver[1].start_with?('15.')
return SQL_2017 if ver[1].start_with?('14.')
return SQL_2016 if ver[1].start_with?('13.')
Expand Down
5 changes: 3 additions & 2 deletions metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "puppetlabs-sqlserver",
"version": "3.2.1",
"author": "puppetlabs",
"summary": "The `sqlserver` module installs and manages MS SQL Server 2012, 2014, 2016, 2017, and 2019 on Windows systems.",
"summary": "The `sqlserver` module installs and manages MS SQL Server 2012, 2014, 2016, 2017, 2019 and 2022 on Windows systems.",
"license": "proprietary",
"source": "https://github.com/puppetlabs/puppetlabs-sqlserver",
"project_page": "https://github.com/puppetlabs/puppetlabs-sqlserver",
Expand Down Expand Up @@ -44,7 +44,8 @@
"sql2014",
"sql2016",
"sql2017",
"sql2019",
"sql2019",
"sql2022",
"tsql",
"database"
],
Expand Down
51 changes: 35 additions & 16 deletions spec/acceptance/z_last_sqlserver_features_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ def ensure_sql_features(features, ensure_val = 'present')

pp = <<-MANIFEST
sqlserver::config{ 'MSSQLSERVER':
admin_pass => '<%= SQL_ADMIN_PASS %>',
admin_user => '<%= SQL_ADMIN_USER %>',
admin_pass => '<%= SQL_ADMIN_PASS %>',
admin_user => '<%= SQL_ADMIN_USER %>',
}
sqlserver_features{ 'MSSQLSERVER':
ensure => #{ensure_val},
Expand All @@ -35,8 +35,8 @@ def bind_and_apply_failing_manifest(features, ensure_val = 'present')
user = Helper.instance.run_shell('$env:UserName').stdout.chomp
pp = <<-MANIFEST
sqlserver::config{ 'MSSQLSERVER':
admin_pass => '<%= SQL_ADMIN_PASS %>',
admin_user => '<%= SQL_ADMIN_USER %>',
admin_pass => '<%= SQL_ADMIN_PASS %>',
admin_user => '<%= SQL_ADMIN_USER %>',
}
sqlserver_features{ 'MSSQLSERVER':
ensure => #{ensure_val},
Expand All @@ -50,7 +50,10 @@ def bind_and_apply_failing_manifest(features, ensure_val = 'present')
end

context 'can install' do
features = if version.to_i >= 2016
# Client Tools removed in Server2022 (Backwards Compatibility, Connectivity, SDK)
features = if version.to_i == 2022
['IS', 'MDS', 'DQC']
elsif version.to_i >= 2016 && version.to_i < 2022
['BC', 'Conn', 'SDK', 'IS', 'MDS', 'DQC']
else
['BC', 'Conn', 'SSMS', 'ADV_SSMS', 'SDK', 'IS', 'MDS', 'DQC']
Expand All @@ -64,17 +67,22 @@ def bind_and_apply_failing_manifest(features, ensure_val = 'present')
ensure_sql_features(features)

validate_sql_install(version: version) do |r|
expect(r.stdout).to match(%r{Client Tools Connectivity})
expect(r.stdout).to match(%r{Client Tools Backwards Compatibility})
expect(r.stdout).to match(%r{Client Tools SDK})
# Client Tools removed in Server2022
unless version.to_i == 2022
expect(r.stdout).to match(%r{Client Tools Connectivity})
expect(r.stdout).to match(%r{Client Tools Backwards Compatibility})
expect(r.stdout).to match(%r{Client Tools SDK})
end
expect(r.stdout).to match(%r{Integration Services})
expect(r.stdout).to match(%r{Master Data Services})
end
end
end

context 'can remove' do
features = if version.to_i >= 2016
features = if version.to_i == 2022
['IS', 'MDS', 'DQC']
elsif version.to_i >= 2016 && version.to_i < 2022
['BC', 'Conn', 'SDK', 'IS', 'MDS', 'DQC']
else
['BC', 'Conn', 'SSMS', 'ADV_SSMS', 'SDK', 'IS', 'MDS', 'DQC']
Expand All @@ -84,17 +92,22 @@ def bind_and_apply_failing_manifest(features, ensure_val = 'present')
ensure_sql_features(features, 'absent')

validate_sql_install(version: version) do |r|
expect(r.stdout).not_to match(%r{Client Tools Connectivity})
expect(r.stdout).not_to match(%r{Client Tools Backwards Compatibility})
expect(r.stdout).not_to match(%r{Client Tools SDK})
# Client Tools removed in Server2022
unless version.to_i == 2022
expect(r.stdout).not_to match(%r{Client Tools Connectivity})
expect(r.stdout).not_to match(%r{Client Tools Backwards Compatibility})
expect(r.stdout).not_to match(%r{Client Tools SDK})
end
expect(r.stdout).not_to match(%r{Integration Services})
expect(r.stdout).not_to match(%r{Master Data Services})
end
end
end

context 'can remove independent feature' do
features = if version.to_i >= 2016
features = if version.to_i == 2022
['IS', 'MDS', 'DQC']
elsif version.to_i >= 2016 && version.to_i < 2022
['BC', 'Conn', 'SDK', 'IS', 'MDS', 'DQC']
else
['BC', 'Conn', 'SSMS', 'ADV_SSMS', 'SDK', 'IS', 'MDS', 'DQC']
Expand All @@ -108,7 +121,7 @@ def bind_and_apply_failing_manifest(features, ensure_val = 'present')
ensure_sql_features(features, 'absent')
end

it "'BC'" do
it "'BC'", unless: version.to_i == 2022 do
ensure_sql_features(features - ['BC'])

validate_sql_install(version: version) do |r|
Expand All @@ -127,7 +140,7 @@ def bind_and_apply_failing_manifest(features, ensure_val = 'present')
end
end

it "'SDK' + 'IS" do
it "'SDK' + 'IS", unless: version.to_i == 2022 do
ensure_sql_features(features - ['SDK', 'IS'])

validate_sql_install(version: version) do |r|
Expand All @@ -152,7 +165,13 @@ def bind_and_apply_failing_manifest(features, ensure_val = 'present')
context 'with no installed instances' do
# Currently this test can only be run on a machine once and will error if run a second time
context 'can install' do
features = ['BC', 'Conn', 'SDK', 'IS', 'MDS', 'DQC']
features = if version.to_i == 2022
['IS', 'MDS', 'DQC']
elsif version.to_i >= 2016 && version.to_i < 2022
['BC', 'Conn', 'SDK', 'IS', 'MDS', 'DQC']
else
['BC', 'Conn', 'SSMS', 'ADV_SSMS', 'SDK', 'IS', 'MDS', 'DQC']
end

def remove_sql_instance
user = Helper.instance.run_shell('$env:UserName').stdout.chomp
Expand Down
11 changes: 10 additions & 1 deletion spec/spec_helper_acceptance_local.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Helper
WIN_ISO_ROOT = 'https://artifactory.delivery.puppetlabs.net/artifactory/generic__iso/iso/windows'
WIN_2019_ISO = 'en_windows_server_2019_updated_july_2020_x64_dvd_94453821.iso'
QA_RESOURCE_ROOT = 'https://artifactory.delivery.puppetlabs.net/artifactory/generic__iso/iso/SQLServer'
SQL_2022_ISO = 'SQLServer2022-x64-ENU-Dev.iso'
SQL_2019_ISO = 'SQLServer2019CTP2.4-x64-ENU.iso'
SQL_2017_ISO = 'SQLServer2017-x64-ENU.iso'
SQL_2016_ISO = 'en_sql_server_2016_enterprise_with_service_pack_1_x64_dvd_9542382.iso'
Expand Down Expand Up @@ -120,6 +121,12 @@ def base_install(sql_version)
file: SQL_2019_ISO,
drive_letter: 'H',
}
when 2022
iso_opts = {
folder: QA_RESOURCE_ROOT,
file: SQL_2022_ISO,
drive_letter: 'H'
}
end
# Mount the ISO on the agent
mount_iso(iso_opts)
Expand Down Expand Up @@ -217,12 +224,14 @@ def validate_sql_install(opts = {}, &block)
end

def get_install_paths(version)
vers = { '2012' => '110', '2014' => '120', '2016' => '130', '2017' => '140', '2019' => '150' }
vers = { '2012' => '110', '2014' => '120', '2016' => '130', '2017' => '140', '2019' => '150', '2022' => '160' }

raise _('Valid version must be specified') unless vers.keys.include?(version)

dir = "C://Program Files/Microsoft SQL Server/#{vers[version]}/Setup Bootstrap"
sql_directory = case version
when '2022'
"SQL#{version}"
when '2019'
"SQL#{version}CTP2.4"
when '2017'
Expand Down
26 changes: 20 additions & 6 deletions spec/sql_testing_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ def base_install(sql_version)
file: SQL_2019_ISO,
drive_letter: 'H',
}
when 2022
iso_opts = {
folder: QA_RESOURCE_ROOT,
file: SQL_2022_ISO,
drive_letter: 'H'
}
end
host = find_only_one('sql_host')
# Mount the ISO on the agent
Expand Down Expand Up @@ -162,15 +168,23 @@ def remove_sql_instances(host, opts = {})
end

def get_install_paths(version)
vers = { '2012' => '110', '2014' => '120', '2016' => '130', '2017' => '140', '2019' => '150' }
vers = { '2012' => '110', '2014' => '120', '2016' => '130', '2017' => '140', '2019' => '150', '2022' => '160' }

raise _('Valid version must be specified') unless vers.keys.include?(version)

dir = "%ProgramFiles%\\Microsoft SQL Server\\#{vers[version]}\\Setup Bootstrap"
sql_directory = 'SQL'
sql_directory += 'Server' if version != '2017'

[dir, "#{dir}\\#{sql_directory}#{version}"]
dir = "C://Program Files/Microsoft SQL Server/#{vers[version]}/Setup Bootstrap"
sql_directory = case version
when '2022'
"SQL#{version}"
when '2019'
"SQL#{version}CTP2.4"
when '2017'
"SQL#{version}"
else
"SQLServer#{version}"
end

[dir, "#{dir}\\#{sql_directory}"]
end

def install_pe_license(host)
Expand Down
2 changes: 1 addition & 1 deletion spec/unit/puppet_x/sql_connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def stub_connection
context 'command execution' do
before :each do
stub_connection
allow(@connection).to receive(:Open).with('Provider=MSOLEDBSQL;Initial Catalog=master;Application Name=Puppet;Data Source=.;DataTypeComptibility=80;User ID=sa;Password=Pupp3t1@')
allow(@connection).to receive(:Open).with('Provider=MSOLEDBSQL;Initial Catalog=master;Application Name=Puppet;Data Source=.;DataTypeComptibility=80;UID=sa;PWD=Pupp3t1@')
end
it 'does not raise an error but populate has_errors with message' do
allow(@connection.Errors).to receive(:count).and_return(2)
Expand Down