Skip to content

FM-2110 Prep TSQL provider ... #64

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
Jan 18, 2015
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
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
##2014-12-08 - 1.0.0
##2015-01-xx - 1.1.0

###Summary
Add sqlserver_tsql provider that to enable users to run sql against a given instance

###Features
* sqlserver_tsql added
* Better logging for ::login ::database and ::sp_configure

u#2014-12-08 - 1.0.0
Initial release
File renamed without changes.
19 changes: 19 additions & 0 deletions lib/puppet/property/sqlserver_tsql.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'puppet/property'

class Puppet::Property::SqlserverTsql < Puppet::Property
desc 'TSQL property that we are going to wrap with a try catch'
munge do |value|
erb_template = <<-TEMPLATE
BEGIN TRY
#{value}
END TRY
BEGIN CATCH
DECLARE @msg as VARCHAR(max);
SELECT @msg = 'THROW CAUGHT: ' + ERROR_MESSAGE();
THROW 51000, @msg, 10
END CATCH
TEMPLATE
value = erb_template
end

end
6 changes: 5 additions & 1 deletion lib/puppet/provider/sqlserver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ def self.run_authenticated_sqlcmd(query, opts)
temp_ps1.write(ps1.result(b))
temp_ps1.flush
temp_ps1.close
#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
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
debug("Return result #{result.exitstatus}")
debug("Return result #{result}")
if opts[:failonfail] && result.match(/ERROR/)
fail(result)
end
return result
ensure
temp_ps1.close
Expand Down
14 changes: 5 additions & 9 deletions lib/puppet/provider/sqlserver_tsql/mssql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@

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

def run(query)
debug("Running resource #{query} against #{resource[:instance]}")
result = Puppet::Provider::Sqlserver.run_authenticated_sqlcmd(query, {:instance_name => resource[:instance]})
return result
end

def run_check
result = self.run(resource[:onlyif])
def run(query, opts)
debug("Running resource #{query} against #{resource[:instance]} with failonfail set to #{opts[:failonfail]}")
opts[:instance_name] = resource[:instance]
result = Puppet::Provider::Sqlserver.run_authenticated_sqlcmd(query, opts)
return result
end

def run_update
result = self.run(resource[:command])
result = self.run(resource[:command], {:failonfail => true})
return result
end

Expand Down
4 changes: 3 additions & 1 deletion lib/puppet/templates/authenticated_query.ps1.erb
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ if (!(Get-Command 'sqlcmd.exe' -ErrorAction SilentlyContinue)){

$result = sqlcmd.exe -i '<%= input_file %>' -h-1 -W -s ',' <% if @instance != 'MSSQLSERVER' %>-S localhost\<%= @instance %><%end%>
if($result -match "ERROR"){
Write-Error -Message ($result | where {$_ -match "ERROR"} | select -First 1)
Write-Host ($result | where {$_ -match "THROW CAUGHT"} | select -First 1)
Write-Error -Message ($result | where {$_ -match "THROW CAUGHT"} | select -First 1)
exit(10)
}
if($result -match "Incorrect syntax near "){
Write-Host ($result | where {$_ -match "Incorrect syntax near"} | select -First 1)
Write-Error -Message ($result | where {$_ -match "Incorrect syntax"} | select -First 1)
exit(10)
}
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/type/sqlserver_features.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'property/login'))
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'property/sqlserver_login'))
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'puppet_x/sqlserver/server_helper'))

Puppet::Type::newtype(:sqlserver_features) do
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/type/sqlserver_instance.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'property/login'))
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'property/sqlserver_login'))
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'puppet_x/sqlserver/server_helper'))

Puppet::Type::newtype(:sqlserver_instance) do
Expand Down
13 changes: 8 additions & 5 deletions lib/puppet/type/sqlserver_tsql.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'puppet'
require 'puppet/property/sqlserver_tsql'

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

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

end

desc 'requires the usage of sqlserver::config with the user and password'
newparam(:instance) do

munge do |value|
value.upcase
end
end

desc 'SQL Query to run and only run if exits with non-zero'
newcheck(:onlyif) do
# Return true if the command returns 0.
newcheck(:onlyif, :parent => Puppet::Property::SqlserverTsql) do
#Runs in the event that our TSQL exits with anything other than 0
def check(value)
begin
output = provider.run(value)
output = provider.run(value, :failonfail => false)
end
debug("OnlyIf returned exitstatus of #{output.exitstatus}")
output.exitstatus != 0
Expand Down
2 changes: 1 addition & 1 deletion metadata.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "puppetlabs-sqlserver",
"version": "1.0.0",
"version": "1.1.0",
"author": "puppetlabs",
"summary": "The `sqlserver` module installs and manages MS SQL Server 2012 and 2014 on Windows systems.",
"license": "PuppetLabs-Enterprise",
Expand Down
21 changes: 21 additions & 0 deletions spec/unit/puppet/property/tsql_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require 'spec_helper'

describe 'tsql' do

before :each do
@node = Puppet::Type.type(:sqlserver_tsql).new(:name => 'update user')
end

it {
@node[:command] = 'UPDATE [my_login] SET PASSWORD = "MYSillyPassword"'
expect(@node[:command]).to match(/BEGIN TRY/)
expect(@node[:command]).to include('UPDATE [my_login] SET PASSWORD = "MYSillyPassword"')
}
it 'should munge value to have begin and end try' do
@node[:command] = 'function foo'
@node[:onlyif] = 'exec bar'
expect(@node[:onlyif]).to match(/BEGIN TRY\n\s+exec bar\nEND TRY/)
expect(@node[:command]).to match(/BEGIN TRY\n\s+function foo\nEND TRY/)
end

end
3 changes: 0 additions & 3 deletions templates/create/database.sql.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
BEGIN TRY
USE master
DECLARE @default_db_path as nvarchar(max),
@default_log_path as varchar(max)
Expand Down Expand Up @@ -116,5 +115,3 @@ END

IF NOT EXISTS (select * from sys.databases WHERE name = '<%= @db_name %>')
THROW 51000, 'DATABASE CREATION FAILED', 10
END TRY
<%= scope.function_template(['sqlserver/snippets/begin_catch.sql.erb']) %>
2 changes: 0 additions & 2 deletions templates/create/login.sql.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
GO
DECLARE
@login as varchar(255) = '<%= @login %>',
@is_disabled as tinyint = <%= @disabled ? 1 : 0 %>;
Expand Down Expand Up @@ -47,6 +46,5 @@ BEGIN
<% end -%>
<% end -%>
END
GO


3 changes: 0 additions & 3 deletions templates/create/sp_configure.sql.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
BEGIN TRY
DECLARE @return_value INT
EXECUTE @return_value = sp_configure @configname = N'<%= @config_name %>', @configvalue = <%= @value %>
IF @return_value != 0
Expand All @@ -7,5 +6,3 @@ IF @return_value != 0
ELSE
RECONFIGURE <% if @with_override %>WITH OVERRIDE<% end %>
<% end -%>
END TRY
<%= scope.function_template(['sqlserver/snippets/begin_catch.sql.erb']) %>
3 changes: 0 additions & 3 deletions templates/query/database_exists.sql.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
BEGIN TRY
-- QUICK CHECK before most costly query
IF <% if @ensure == 'present' %>NOT<% end %> EXISTS(SELECT name from sys.databases WHERE name = '<%= @db_name %>')
THROW 51000, 'The database does <% if @ensure == 'present' %>not<% end %> exist', 10
Expand All @@ -23,5 +22,3 @@ IF <% if @ensure == 'present' %>NOT<% end %> EXISTS(SELECT name from sys.databas
<% end
#end ensure present section
-%>
END TRY
<%= scope.function_template(['sqlserver/snippets/begin_catch.sql.erb']) %>
8 changes: 3 additions & 5 deletions templates/query/login_exists.sql.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@

GO
DECLARE
@login as varchar(255) = '<%= @login %>',
@is_disabled as tinyint = <%= @disabled ? 1 : 0 %>,
Expand All @@ -9,7 +7,7 @@ DECLARE
@default_db as varchar(255) = '<%= @default_database %>',
@default_lang as varchar(50) = '<%= @default_language %>'
IF <% if @ensure == 'present' %>NOT<% end %> EXISTS(SELECT name FROM sys.server_principals WHERE name = '<%= @login %>')
THROW 51000, 'ERROR: the login is not <%= @ensure %>', 10
THROW 51000, 'The login is not <%= @ensure %>', 10

<% if @ensure == 'present' %>
BEGIN
Expand All @@ -26,10 +24,10 @@ IF NOT EXISTS(
AND is_policy_checked = @check_policy
AND is_expiration_checked = @check_expiration
<% end %>
) THROW 51000, 'ERROR: the login is not in the correct state', 10
) THROW 51000, 'The login is not in the correct state', 10
/* If it does exist check for each role is in the correct state */
<% @svrroles.each do |role, enable_bit| %>
IF IS_SRVROLEMEMBER('<%= role %>','<%= @login %>') != <%= enable_bit %> THROW 51000, 'ERROR: a role is not correct for <%= role %>', 10
IF IS_SRVROLEMEMBER('<%= role %>','<%= @login %>') != <%= enable_bit %> THROW 51000, 'A svrrole is not correct for <%= role %>', 10
<% end %>

<% end %>
Expand Down
3 changes: 0 additions & 3 deletions templates/query/sp_configure.sql.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
BEGIN TRY
USE master;
DECLARE @sp_conf TABLE
(
Expand All @@ -11,5 +10,3 @@ DECLARE @sp_conf TABLE
INSERT INTO @sp_conf EXECUTE sp_configure @configname = N'<%= @config_name %>'
IF EXISTS(select * from @sp_conf where name = '<%= @config_name %>' AND run_value != <%= @value %>)
THROW 51000, 'sp_configure `<%= @config_name %>` is not in the correct state', 10
END TRY
<%= scope.function_template(['sqlserver/snippets/begin_catch.sql.erb']) %>
5 changes: 0 additions & 5 deletions templates/snippets/begin_catch.sql.erb

This file was deleted.