Skip to content

Commit ce95060

Browse files
committed
Merge pull request #64 from cyberious/FM2110
FM-2110 Prep TSQL provider ...
2 parents 71f0870 + 3fd2931 commit ce95060

18 files changed

+77
-44
lines changed

CHANGELOG.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
1-
##2014-12-08 - 1.0.0
1+
##2015-01-xx - 1.1.0
2+
3+
###Summary
4+
Add sqlserver_tsql provider that to enable users to run sql against a given instance
5+
6+
###Features
7+
* sqlserver_tsql added
8+
* Better logging for ::login ::database and ::sp_configure
9+
10+
u#2014-12-08 - 1.0.0
211
Initial release
File renamed without changes.

lib/puppet/property/sqlserver_tsql.rb

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require 'puppet/property'
2+
3+
class Puppet::Property::SqlserverTsql < Puppet::Property
4+
desc 'TSQL property that we are going to wrap with a try catch'
5+
munge do |value|
6+
erb_template = <<-TEMPLATE
7+
BEGIN TRY
8+
#{value}
9+
END TRY
10+
BEGIN CATCH
11+
DECLARE @msg as VARCHAR(max);
12+
SELECT @msg = 'THROW CAUGHT: ' + ERROR_MESSAGE();
13+
THROW 51000, @msg, 10
14+
END CATCH
15+
TEMPLATE
16+
value = erb_template
17+
end
18+
19+
end

lib/puppet/provider/sqlserver.rb

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,12 @@ def self.run_authenticated_sqlcmd(query, opts)
5151
temp_ps1.write(ps1.result(b))
5252
temp_ps1.flush
5353
temp_ps1.close
54+
#We want to not fail the exec but fail the overall process once we get the clean result back, otherwise we report the temp file which is meaningless
5455
result = Puppet::Util::Execution.execute(['powershell.exe', '-noprofile', '-executionpolicy', 'unrestricted', temp_ps1.path], {:failonfail => false}) #We expect some things to fail in order to run as an only if
55-
debug("Return result #{result.exitstatus}")
56+
debug("Return result #{result}")
57+
if opts[:failonfail] && result.match(/ERROR/)
58+
fail(result)
59+
end
5660
return result
5761
ensure
5862
temp_ps1.close

lib/puppet/provider/sqlserver_tsql/mssql.rb

+5-9
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,15 @@
22

33
Puppet::Type::type(:sqlserver_tsql).provide(:mssql, :parent => Puppet::Provider::Sqlserver) do
44

5-
def run(query)
6-
debug("Running resource #{query} against #{resource[:instance]}")
7-
result = Puppet::Provider::Sqlserver.run_authenticated_sqlcmd(query, {:instance_name => resource[:instance]})
8-
return result
9-
end
10-
11-
def run_check
12-
result = self.run(resource[:onlyif])
5+
def run(query, opts)
6+
debug("Running resource #{query} against #{resource[:instance]} with failonfail set to #{opts[:failonfail]}")
7+
opts[:instance_name] = resource[:instance]
8+
result = Puppet::Provider::Sqlserver.run_authenticated_sqlcmd(query, opts)
139
return result
1410
end
1511

1612
def run_update
17-
result = self.run(resource[:command])
13+
result = self.run(resource[:command], {:failonfail => true})
1814
return result
1915
end
2016

lib/puppet/templates/authenticated_query.ps1.erb

+3-1
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ if (!(Get-Command 'sqlcmd.exe' -ErrorAction SilentlyContinue)){
2525

2626
$result = sqlcmd.exe -i '<%= input_file %>' -h-1 -W -s ',' <% if @instance != 'MSSQLSERVER' %>-S localhost\<%= @instance %><%end%>
2727
if($result -match "ERROR"){
28-
Write-Error -Message ($result | where {$_ -match "ERROR"} | select -First 1)
28+
Write-Host ($result | where {$_ -match "THROW CAUGHT"} | select -First 1)
29+
Write-Error -Message ($result | where {$_ -match "THROW CAUGHT"} | select -First 1)
2930
exit(10)
3031
}
3132
if($result -match "Incorrect syntax near "){
33+
Write-Host ($result | where {$_ -match "Incorrect syntax near"} | select -First 1)
3234
Write-Error -Message ($result | where {$_ -match "Incorrect syntax"} | select -First 1)
3335
exit(10)
3436
}

lib/puppet/type/sqlserver_features.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'property/login'))
1+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'property/sqlserver_login'))
22
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'puppet_x/sqlserver/server_helper'))
33

44
Puppet::Type::newtype(:sqlserver_features) do

lib/puppet/type/sqlserver_instance.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'property/login'))
1+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'property/sqlserver_login'))
22
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'puppet_x/sqlserver/server_helper'))
33

44
Puppet::Type::newtype(:sqlserver_instance) do

lib/puppet/type/sqlserver_tsql.rb

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'puppet'
2+
require 'puppet/property/sqlserver_tsql'
23

34
Puppet::Type::newtype(:sqlserver_tsql) do
45
newparam :name, :namevar => true
@@ -15,21 +16,23 @@ def self.checks
1516
end
1617

1718
desc 'command to run against an instance with the authenticated credentials used in sqlserver::config'
18-
newparam(:command) do
19+
newparam(:command, :parent => Puppet::Property::SqlserverTsql) do
1920

2021
end
2122

2223
desc 'requires the usage of sqlserver::config with the user and password'
2324
newparam(:instance) do
24-
25+
munge do |value|
26+
value.upcase
27+
end
2528
end
2629

2730
desc 'SQL Query to run and only run if exits with non-zero'
28-
newcheck(:onlyif) do
29-
# Return true if the command returns 0.
31+
newcheck(:onlyif, :parent => Puppet::Property::SqlserverTsql) do
32+
#Runs in the event that our TSQL exits with anything other than 0
3033
def check(value)
3134
begin
32-
output = provider.run(value)
35+
output = provider.run(value, :failonfail => false)
3336
end
3437
debug("OnlyIf returned exitstatus of #{output.exitstatus}")
3538
output.exitstatus != 0

metadata.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "puppetlabs-sqlserver",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"author": "puppetlabs",
55
"summary": "The `sqlserver` module installs and manages MS SQL Server 2012 and 2014 on Windows systems.",
66
"license": "PuppetLabs-Enterprise",
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
require 'spec_helper'
2+
3+
describe 'tsql' do
4+
5+
before :each do
6+
@node = Puppet::Type.type(:sqlserver_tsql).new(:name => 'update user')
7+
end
8+
9+
it {
10+
@node[:command] = 'UPDATE [my_login] SET PASSWORD = "MYSillyPassword"'
11+
expect(@node[:command]).to match(/BEGIN TRY/)
12+
expect(@node[:command]).to include('UPDATE [my_login] SET PASSWORD = "MYSillyPassword"')
13+
}
14+
it 'should munge value to have begin and end try' do
15+
@node[:command] = 'function foo'
16+
@node[:onlyif] = 'exec bar'
17+
expect(@node[:onlyif]).to match(/BEGIN TRY\n\s+exec bar\nEND TRY/)
18+
expect(@node[:command]).to match(/BEGIN TRY\n\s+function foo\nEND TRY/)
19+
end
20+
21+
end

templates/create/database.sql.erb

-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
BEGIN TRY
21
USE master
32
DECLARE @default_db_path as nvarchar(max),
43
@default_log_path as varchar(max)
@@ -116,5 +115,3 @@ END
116115

117116
IF NOT EXISTS (select * from sys.databases WHERE name = '<%= @db_name %>')
118117
THROW 51000, 'DATABASE CREATION FAILED', 10
119-
END TRY
120-
<%= scope.function_template(['sqlserver/snippets/begin_catch.sql.erb']) %>

templates/create/login.sql.erb

-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
GO
21
DECLARE
32
@login as varchar(255) = '<%= @login %>',
43
@is_disabled as tinyint = <%= @disabled ? 1 : 0 %>;
@@ -47,6 +46,5 @@ BEGIN
4746
<% end -%>
4847
<% end -%>
4948
END
50-
GO
5149

5250

templates/create/sp_configure.sql.erb

-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
BEGIN TRY
21
DECLARE @return_value INT
32
EXECUTE @return_value = sp_configure @configname = N'<%= @config_name %>', @configvalue = <%= @value %>
43
IF @return_value != 0
@@ -7,5 +6,3 @@ IF @return_value != 0
76
ELSE
87
RECONFIGURE <% if @with_override %>WITH OVERRIDE<% end %>
98
<% end -%>
10-
END TRY
11-
<%= scope.function_template(['sqlserver/snippets/begin_catch.sql.erb']) %>

templates/query/database_exists.sql.erb

-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
BEGIN TRY
21
-- QUICK CHECK before most costly query
32
IF <% if @ensure == 'present' %>NOT<% end %> EXISTS(SELECT name from sys.databases WHERE name = '<%= @db_name %>')
43
THROW 51000, 'The database does <% if @ensure == 'present' %>not<% end %> exist', 10
@@ -23,5 +22,3 @@ IF <% if @ensure == 'present' %>NOT<% end %> EXISTS(SELECT name from sys.databas
2322
<% end
2423
#end ensure present section
2524
-%>
26-
END TRY
27-
<%= scope.function_template(['sqlserver/snippets/begin_catch.sql.erb']) %>

templates/query/login_exists.sql.erb

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
GO
31
DECLARE
42
@login as varchar(255) = '<%= @login %>',
53
@is_disabled as tinyint = <%= @disabled ? 1 : 0 %>,
@@ -9,7 +7,7 @@ DECLARE
97
@default_db as varchar(255) = '<%= @default_database %>',
108
@default_lang as varchar(50) = '<%= @default_language %>'
119
IF <% if @ensure == 'present' %>NOT<% end %> EXISTS(SELECT name FROM sys.server_principals WHERE name = '<%= @login %>')
12-
THROW 51000, 'ERROR: the login is not <%= @ensure %>', 10
10+
THROW 51000, 'The login is not <%= @ensure %>', 10
1311

1412
<% if @ensure == 'present' %>
1513
BEGIN
@@ -26,10 +24,10 @@ IF NOT EXISTS(
2624
AND is_policy_checked = @check_policy
2725
AND is_expiration_checked = @check_expiration
2826
<% end %>
29-
) THROW 51000, 'ERROR: the login is not in the correct state', 10
27+
) THROW 51000, 'The login is not in the correct state', 10
3028
/* If it does exist check for each role is in the correct state */
3129
<% @svrroles.each do |role, enable_bit| %>
32-
IF IS_SRVROLEMEMBER('<%= role %>','<%= @login %>') != <%= enable_bit %> THROW 51000, 'ERROR: a role is not correct for <%= role %>', 10
30+
IF IS_SRVROLEMEMBER('<%= role %>','<%= @login %>') != <%= enable_bit %> THROW 51000, 'A svrrole is not correct for <%= role %>', 10
3331
<% end %>
3432

3533
<% end %>

templates/query/sp_configure.sql.erb

-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
BEGIN TRY
21
USE master;
32
DECLARE @sp_conf TABLE
43
(
@@ -11,5 +10,3 @@ DECLARE @sp_conf TABLE
1110
INSERT INTO @sp_conf EXECUTE sp_configure @configname = N'<%= @config_name %>'
1211
IF EXISTS(select * from @sp_conf where name = '<%= @config_name %>' AND run_value != <%= @value %>)
1312
THROW 51000, 'sp_configure `<%= @config_name %>` is not in the correct state', 10
14-
END TRY
15-
<%= scope.function_template(['sqlserver/snippets/begin_catch.sql.erb']) %>

templates/snippets/begin_catch.sql.erb

-5
This file was deleted.

0 commit comments

Comments
 (0)