Initial Chef repository

This commit is contained in:
Greg Karékinian
2015-07-21 19:45:23 +02:00
parent 7e5401fc71
commit ee4079fa85
1151 changed files with 185163 additions and 0 deletions

View File

@@ -0,0 +1,151 @@
#
# Author:: Douglas Thrift (<douglas.thrift@rightscale.com>)
# Cookbook Name:: database
# Library:: matchers
#
# Copyright 2014, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if defined?(ChefSpec)
# database
#
def create_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:database, :create, resource_name)
end
def drop_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:database, :drop, resource_name)
end
def query_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:database, :query, resource_name)
end
# database user
#
def create_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:database_user, :create, resource_name)
end
def drop_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:database_user, :drop, resource_name)
end
def grant_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:database_user, :grant, resource_name)
end
# mysql database
#
def create_mysql_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:mysql_database, :create, resource_name)
end
def drop_mysql_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:mysql_database, :drop, resource_name)
end
def query_mysql_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:mysql_database, :query, resource_name)
end
# mysql database user
#
def create_mysql_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:mysql_database_user, :create, resource_name)
end
def drop_mysql_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:mysql_database_user, :drop, resource_name)
end
def grant_mysql_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:mysql_database_user, :grant, resource_name)
end
# postgresql database
#
def create_postgresql_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database, :create, resource_name)
end
def drop_postgresql_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database, :drop, resource_name)
end
def query_postgresql_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database, :query, resource_name)
end
# postgresql database schema
#
def create_postgresql_database_schema(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database_schema, :create, resource_name)
end
def drop_postgresql_database_schema(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database_schema, :drop, resource_name)
end
# postgresql database user
#
def create_postgresql_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database_user, :create, resource_name)
end
def drop_postgresql_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database_user, :drop, resource_name)
end
def grant_postgresql_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database_user, :grant, resource_name)
end
def grant_schema_postgresql_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:postgresql_database_user, :grant_schema, resource_name)
end
# sql server database
#
def create_sql_server_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database, :create, resource_name)
end
def drop_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database, :drop, resource_name)
end
def query_database(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database, :query, resource_name)
end
# sql server database user
#
def create_sql_server_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database_user, :create, resource_name)
end
def drop_sql_server_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database_user, :drop, resource_name)
end
def grant_sql_server_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database_user, :grant, resource_name)
end
def alter_roles_sql_server_database_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:sql_server_database_user, :alter_roles, resource_name)
end
end

View File

@@ -0,0 +1,158 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Sean OMeara (<sean@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
class Provider
class Database
class Mysql < Chef::Provider::LWRPBase
use_inline_resources if defined?(use_inline_resources)
def whyrun_supported?
true
end
action :create do
# test
schema_present = nil
begin
test_sql = 'SHOW SCHEMAS;'
Chef::Log.debug("#{new_resource.name}: Performing query [#{test_sql}]")
test_sql_results = test_client.query(test_sql)
test_sql_results.each do |r|
schema_present = true if r['Database'] == new_resource.database_name
end
ensure
close_test_client
end
# repair
unless schema_present
converge_by "Creating schema '#{new_resource.database_name}'" do
begin
repair_sql = "CREATE SCHEMA IF NOT EXISTS `#{new_resource.database_name}`"
repair_sql += " CHARACTER SET = #{new_resource.encoding}" if new_resource.encoding
repair_sql += " COLLATE = #{new_resource.collation}" if new_resource.collation
Chef::Log.debug("#{new_resource.name}: Performing query [#{repair_sql}]")
repair_client.query(repair_sql)
ensure
close_repair_client
end
end
end
end
action :drop do
# test
schema_present = nil
begin
test_sql = 'SHOW SCHEMAS;'
Chef::Log.debug("Performing query [#{test_sql}]")
test_sql_results = test_client.query(test_sql)
test_sql_results.each do |r|
schema_present = true if r['Database'] == new_resource.database_name
end
ensure
close_test_client
end
# repair
if schema_present
converge_by "Dropping schema '#{new_resource.database_name}'" do
begin
repair_sql = "DROP SCHEMA IF EXISTS `#{new_resource.database_name}`"
Chef::Log.debug("Performing query [#{repair_sql}]")
repair_client.query(repair_sql)
ensure
close_repair_client
end
end
end
end
action :query do
begin
query_sql = new_resource.sql_query
Chef::Log.debug("Performing query [#{query_sql}]")
query_client.query(query_sql)
ensure
close_query_client
end
end
private
def test_client
require 'mysql2'
@test_client ||=
Mysql2::Client.new(
host: new_resource.connection[:host],
socket: new_resource.connection[:socket],
username: new_resource.connection[:username],
password: new_resource.connection[:password],
port: new_resource.connection[:port]
)
end
def close_test_client
@test_client.close if @test_client
rescue Mysql2::Error
@test_client = nil
end
def repair_client
require 'mysql2'
@repair_client ||=
Mysql2::Client.new(
host: new_resource.connection[:host],
socket: new_resource.connection[:socket],
username: new_resource.connection[:username],
password: new_resource.connection[:password],
port: new_resource.connection[:port]
)
end
def close_repair_client
@repair_client.close if @repair_client
rescue Mysql2::Error
@repair_client = nil
end
def query_client
require 'mysql2'
@query_client ||=
Mysql2::Client.new(
host: new_resource.connection[:host],
socket: new_resource.connection[:socket],
username: new_resource.connection[:username],
password: new_resource.connection[:password],
port: new_resource.connection[:port]
)
end
def close_query_client
@query_client.close
rescue Mysql2::Error
@query_client = nil
end
end
end
end
end

View File

@@ -0,0 +1,193 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Sean OMeara (<sean@chef.io>)
# Copyright:: 2011-2015 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'provider_database_mysql')
class Chef
class Provider
class Database
class MysqlUser < Chef::Provider::Database::Mysql
use_inline_resources if defined?(use_inline_resources)
def whyrun_supported?
true
end
action :create do
# test
user_present = nil
begin
test_sql = "SELECT User,Host from mysql.user WHERE User='#{new_resource.username}' AND Host='#{new_resource.host}';"
test_sql_results = test_client.query(test_sql)
test_sql_results.each do |r|
user_present = true if r['User'] == new_resource.username
end
ensure
close_test_client
end
# repair
unless user_present
converge_by "Creating user '#{new_resource.username}'@'#{new_resource.host}'" do
begin
repair_sql = "CREATE USER '#{new_resource.username}'@'#{new_resource.host}'"
repair_sql += " IDENTIFIED BY '#{new_resource.password}'" if new_resource.password
repair_client.query(repair_sql)
ensure
close_repair_client
end
end
end
end
action :drop do
# test
user_present = nil
begin
test_sql = 'SELECT User,Host'
test_sql += ' from mysql.user'
test_sql += " WHERE User='#{new_resource.username}'"
test_sql += " AND Host='#{new_resource.host}'"
test_sql_results = test_client.query test_sql
test_sql_results.each do |r|
user_present = true if r['User'] == new_resource.username
end
ensure
close_test_client
end
# repair
if user_present
converge_by "Dropping user '#{new_resource.username}'@'#{new_resource.host}'" do
begin
repair_sql = 'DROP USER'
repair_sql += " '#{new_resource.username}'@'#{new_resource.host}'"
repair_client.query repair_sql
ensure
close_repair_client
end
end
end
end
action :grant do
# gratuitous function
def ishash?
return true if (/(\A\*[0-9A-F]{40}\z)/i).match(new_resource.password)
end
db_name = new_resource.database_name ? "`#{new_resource.database_name}`" : '*'
tbl_name = new_resource.table ? new_resource.table : '*'
# Test
incorrect_privs = nil
begin
test_sql = 'SELECT * from mysql.db'
test_sql += " WHERE User='#{new_resource.username}'"
test_sql += " AND Host='#{new_resource.host}'"
test_sql += " AND Db='#{new_resource.database_name}'"
test_sql_results = test_client.query test_sql
incorrect_privs = true if test_sql_results.size == 0
# These should all by 'Y'
test_sql_results.each do |r|
new_resource.privileges.each do |p|
key = "#{p.capitalize}_priv"
incorrect_privs = true if r[key] != 'Y'
end
end
ensure
close_test_client
end
# Repair
if incorrect_privs
converge_by "Granting privs for '#{new_resource.username}'@'#{new_resource.host}'" do
begin
repair_sql = "GRANT #{new_resource.privileges.join(',')}"
repair_sql += " ON #{db_name}.#{tbl_name}"
repair_sql += " TO '#{new_resource.username}'@'#{new_resource.host}' IDENTIFIED BY"
repair_sql += " '#{new_resource.password}'"
repair_sql += ' REQUIRE SSL' if new_resource.require_ssl
repair_sql += ' WITH GRANT OPTION' if new_resource.grant_option
repair_client.query(repair_sql)
repair_client.query('FLUSH PRIVILEGES')
ensure
close_repair_client
end
end
end
end
def action_revoke
db_name = new_resource.database_name ? "`#{new_resource.database_name}`" : '*'
tbl_name = new_resource.table ? new_resource.table : '*'
revoke_statement = "REVOKE #{@new_resource.privileges.join(', ')}"
revoke_statement += " ON #{db_name}.#{tbl_name}"
revoke_statement += " FROM `#{@new_resource.username}`@`#{@new_resource.host}` "
Chef::Log.info("#{@new_resource}: revoking access with statement [#{revoke_statement}]")
db.query(revoke_statement)
@new_resource.updated_by_last_action(true)
ensure
close
end
private
def test_client
require 'mysql2'
@test_client ||=
Mysql2::Client.new(
host: new_resource.connection[:host],
socket: new_resource.connection[:socket],
username: new_resource.connection[:username],
password: new_resource.connection[:password],
port: new_resource.connection[:port]
)
end
def close_test_client
@test_client.close if @test_client
rescue Mysql2::Error
@test_client = nil
end
def repair_client
require 'mysql2'
@repair_client ||=
Mysql2::Client.new(
host: new_resource.connection[:host],
socket: new_resource.connection[:socket],
username: new_resource.connection[:username],
password: new_resource.connection[:password],
port: new_resource.connection[:port]
)
end
def close_repair_client
@repair_client.close if @repair_client
rescue Mysql2::Error
@repair_client = nil
end
end
end
end
end

View File

@@ -0,0 +1,144 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Lamont Granquist (<lamont@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/provider'
class Chef
class Provider
class Database
class Postgresql < Chef::Provider::LWRPBase
use_inline_resources if defined?(use_inline_resources)
def whyrun_supported?
true
end
def load_current_resource
Gem.clear_paths
require 'pg'
@current_resource = Chef::Resource::Database.new(@new_resource.name)
@current_resource.database_name(@new_resource.database_name)
@current_resource
end
action :create do
unless exists?
begin
encoding = @new_resource.encoding
if encoding != 'DEFAULT'
encoding = "'#{@new_resource.encoding}'"
end
Chef::Log.debug("#{@new_resource}: Creating database #{new_resource.database_name}")
create_sql = "CREATE DATABASE \"#{new_resource.database_name}\""
create_sql += " TEMPLATE = #{new_resource.template}" if new_resource.template
create_sql += " ENCODING = #{encoding}" if new_resource.encoding
create_sql += " TABLESPACE = #{new_resource.tablespace}" if new_resource.tablespace
create_sql += " LC_CTYPE = '#{new_resource.collation}' LC_COLLATE = '#{new_resource.collation}'" if new_resource.collation
create_sql += " CONNECTION LIMIT = #{new_resource.connection_limit}" if new_resource.connection_limit
create_sql += " OWNER = \"#{new_resource.owner}\"" if new_resource.owner
Chef::Log.debug("#{@new_resource}: Performing query [#{create_sql}]")
db('template1').query(create_sql)
@new_resource.updated_by_last_action(true)
ensure
close
end
end
end
action :drop do
if exists?
begin
Chef::Log.debug("#{@new_resource}: Dropping database #{new_resource.database_name}")
db('template1').query("DROP DATABASE \"#{new_resource.database_name}\"")
@new_resource.updated_by_last_action(true)
ensure
close
end
end
end
action :query do
if exists?
begin
Chef::Log.debug("#{@new_resource}: Performing query [#{new_resource.sql_query}]")
db(@new_resource.database_name).query(@new_resource.sql_query)
Chef::Log.debug("#{@new_resource}: query [#{new_resource.sql_query}] succeeded")
@new_resource.updated_by_last_action(true)
ensure
close
end
end
end
private
def exists?
begin
Chef::Log.debug("#{@new_resource}: checking if database #{@new_resource.database_name} exists")
ret = db('template1').query("SELECT * FROM pg_database where datname = '#{@new_resource.database_name}'").num_tuples != 0
ret ? Chef::Log.debug("#{@new_resource}: database #{@new_resource.database_name} exists") :
Chef::Log.debug("#{@new_resource}: database #{@new_resource.database_name} does not exist")
ensure
close
end
ret
end
# Test if text is psql keyword
def keyword?(text)
begin
result = db('template1').exec_params('select * from pg_get_keywords() where word = $1', [text.downcase]).num_tuples != 0
ensure
close
end
result
end
#
# Specifying the database in the connection parameter for the postgres resource is not recommended.
#
# - action_create/drop/exists will use the "template1" database to do work by default.
# - action_query will use the resource database_name.
# - specifying a database in the connection will override this behavior
#
def db(dbname = nil)
close if @db
dbname = @new_resource.connection[:database] if @new_resource.connection[:database]
host = @new_resource.connection[:host]
port = @new_resource.connection[:port] || 5432
user = @new_resource.connection[:username] || 'postgres'
Chef::Log.debug("#{@new_resource}: connecting to database #{dbname} on #{host}:#{port} as #{user}")
password = @new_resource.connection[:password] || node[:postgresql][:password][:postgres]
@db = ::PGconn.new(
host: host,
port: port,
dbname: dbname,
user: user,
password: password
)
end
def close
@db.close rescue nil
@db = nil
end
end
end
end
end

View File

@@ -0,0 +1,74 @@
#
# Author:: Marco Betti (<m.betti@gmail.com>)
# Copyright:: Copyright (c) 2013 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'provider_database_postgresql')
class Chef
class Provider
class Database
class PostgresqlSchema < Chef::Provider::Database::Postgresql
include Chef::Mixin::ShellOut
def load_current_resource
Gem.clear_paths
require 'pg'
@current_resource = Chef::Resource::PostgresqlDatabaseSchema.new(@new_resource.name)
@current_resource.schema_name(@new_resource.schema_name)
@current_resource
end
def action_create
unless exists?
begin
if new_resource.owner
db(@new_resource.database_name).query("CREATE SCHEMA \"#{@new_resource.schema_name}\" AUTHORIZATION \"#{@new_resource.owner}\"")
else
db(@new_resource.database_name).query("CREATE SCHEMA \"#{@new_resource.schema_name}\"")
end
@new_resource.updated_by_last_action(true)
ensure
close
end
end
end
def action_drop
if exists?
begin
db(@new_resource.database_name).query("DROP SCHEMA \"#{@new_resource.schema_name}\"")
@new_resource.updated_by_last_action(true)
ensure
close
end
end
end
private
def exists?
begin
exists = db(@new_resource.database_name).query("SELECT schema_name FROM information_schema.schemata WHERE schema_name='#{@new_resource.schema_name}'").num_tuples != 0
ensure
close
end
exists
end
end
end
end
end

View File

@@ -0,0 +1,103 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Lamont Granquist (<lamont@chef.io>)
# Author:: Marco Betti (<m.betti@gmail.com>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'provider_database_postgresql')
class Chef
class Provider
class Database
class PostgresqlUser < Chef::Provider::Database::Postgresql
include Chef::Mixin::ShellOut
def load_current_resource
Gem.clear_paths
require 'pg'
@current_resource = Chef::Resource::DatabaseUser.new(@new_resource.name)
@current_resource.username(@new_resource.name)
@current_resource
end
def action_create
unless exists?
begin
options = ''
options += " PASSWORD '#{@new_resource.password}'" if @new_resource.password
options += " #{@new_resource.createdb ? 'CREATEDB' : 'NOCREATEDB'}"
options += " #{@new_resource.createrole ? 'CREATEROLE' : 'NOCREATEROLE'}"
options += " #{@new_resource.login ? 'LOGIN' : 'NOLOGIN'}"
options += " #{@new_resource.replication ? 'REPLICATION' : 'NOREPLICATION'}" if keyword?('REPLICATION')
options += " #{@new_resource.superuser ? 'SUPERUSER' : 'NOSUPERUSER'}"
statement = "CREATE USER \"#{@new_resource.username}\""
if options.length > 0
statement += " WITH #{options}"
end
db('template1').query(statement)
@new_resource.updated_by_last_action(true)
ensure
close
end
end
end
def action_drop
if exists?
begin
db('template1').query("DROP USER \"#{@new_resource.username}\"")
@new_resource.updated_by_last_action(true)
ensure
close
end
end
end
def action_grant
grant_statement = "GRANT #{@new_resource.privileges.join(', ')} ON DATABASE \"#{@new_resource.database_name}\" TO \"#{@new_resource.username}\""
Chef::Log.info("#{@new_resource}: granting access with statement [#{grant_statement}]")
db(@new_resource.database_name).query(grant_statement)
@new_resource.updated_by_last_action(true)
ensure
close
end
def action_grant_schema
grant_statement = "GRANT #{@new_resource.privileges.join(', ')} ON SCHEMA \"#{@new_resource.schema_name}\" TO \"#{@new_resource.username}\""
Chef::Log.info("#{@new_resource}: granting access with statement [#{grant_statement}]")
db(@new_resource.database_name).query(grant_statement)
@new_resource.updated_by_last_action(true)
ensure
close
end
private
def exists?
begin
exists = db('template1').query("SELECT * FROM pg_user WHERE usename='#{@new_resource.username}'").num_tuples != 0
ensure
close
end
exists
end
end
end
end
end

View File

@@ -0,0 +1,111 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/provider'
class Chef
class Provider
class Database
class SqlServer < Chef::Provider
include Chef::Mixin::ShellOut
def load_current_resource
Gem.clear_paths
require 'tiny_tds'
@current_resource = Chef::Resource::Database.new(@new_resource.name)
@current_resource.database_name(@new_resource.database_name)
@current_resource
end
def action_create
unless exists?
begin
Chef::Log.debug("#{@new_resource}: Creating database #{new_resource.database_name}")
create_sql = "CREATE DATABASE [#{new_resource.database_name}]"
create_sql += " COLLATE #{new_resource.collation}" if new_resource.collation
db.execute(create_sql).do
@new_resource.updated_by_last_action(true)
ensure
close
end
end
end
def action_drop
if exists?
begin
Chef::Log.debug("#{@new_resource}: Dropping database #{new_resource.database_name}")
db.execute("DROP DATABASE [#{new_resource.database_name}]").do
@new_resource.updated_by_last_action(true)
ensure
close
end
end
end
def action_query
if exists?
begin
# db.select_db(@new_resource.database_name) if @new_resource.database_name
Chef::Log.debug("#{@new_resource}: Performing query [#{new_resource.sql_query}]")
db.execute(@new_resource.sql_query).do
@new_resource.updated_by_last_action(true)
ensure
close
end
end
end
private
def exists?
exists = false
begin
result = db.execute('SELECT name FROM sys.databases')
result.each do |row|
if row['name'] == @new_resource.database_name
exists = true
break
end
end
result.cancel
ensure
close
end
exists
end
def db
@db ||= begin
::TinyTds::Client.new(
host: @new_resource.connection[:host],
username: @new_resource.connection[:username],
password: @new_resource.connection[:password],
port: @new_resource.connection[:port] || 1433
)
end
end
def close
@db.close rescue nil
@db = nil
end
end
end
end
end

View File

@@ -0,0 +1,152 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'provider_database_sql_server')
class Chef
class Provider
class Database
class SqlServerUser < Chef::Provider::Database::SqlServer
include Chef::Mixin::ShellOut
def load_current_resource
Gem.clear_paths
require 'tiny_tds'
@current_resource = Chef::Resource::DatabaseUser.new(@new_resource.name)
@current_resource.username(@new_resource.name)
@current_resource
end
def action_create
unless exists?(:logins)
if @new_resource.windows_user
db.execute("CREATE LOGIN [#{@new_resource.username}] FROM WINDOWS").do
else
db.execute("CREATE LOGIN [#{@new_resource.username}] WITH PASSWORD = '#{@new_resource.password}', CHECK_POLICY = OFF").do
end
@new_resource.updated_by_last_action(true)
end
unless exists?(:users)
if @new_resource.database_name
Chef::Log.info("#{@new_resource} creating user in '#{@new_resource.database_name}' database context.")
db.execute("USE [#{@new_resource.database_name}]").do
else
Chef::Log.info("#{@new_resource} database_name not provided, creating user in global context.")
end
db.execute("CREATE USER [#{@new_resource.username}] FOR LOGIN [#{@new_resource.username}]").do
@new_resource.updated_by_last_action(true)
end
ensure
close
end
def action_drop
if exists?(:users)
db.execute("DROP USER [#{@new_resource.username}]").do
@new_resource.updated_by_last_action(true)
end
if exists?(:logins)
db.execute("DROP LOGIN [#{@new_resource.username}]").do
@new_resource.updated_by_last_action(true)
end
ensure
close
end
def action_grant
if @new_resource.password || (@new_resource.windows_user && !exists?(:logins))
action_create
end
Chef::Application.fatal!('Please provide a database_name, SQL Server does not support global GRANT statements.') unless @new_resource.database_name
grant_statement = "GRANT #{@new_resource.privileges.join(', ')} ON DATABASE::[#{@new_resource.database_name}] TO [#{@new_resource.username}]"
Chef::Log.info("#{@new_resource} granting access with statement [#{grant_statement}]")
db.execute("USE [#{@new_resource.database_name}]").do
db.execute(grant_statement).do
@new_resource.updated_by_last_action(true)
ensure
close
end
def action_alter_roles
if @new_resource.password || (@new_resource.windows_user && !exists?(:logins))
action_create
end
Chef::Application.fatal!('Please provide a database_name, SQL Server does not support global GRANT statements.') unless @new_resource.database_name
db.execute("USE [#{@new_resource.database_name}]").do
@new_resource.sql_roles.each do | sql_role, role_action |
alter_statement = "ALTER ROLE [#{sql_role}] #{role_action} MEMBER [#{@new_resource.username}]"
Chef::Log.info("#{@new_resource} granting access with statement [#{alter_statement}]")
db.execute(alter_statement).do
end
@new_resource.updated_by_last_action(true)
ensure
close
end
def action_alter_sys_roles
if @new_resource.password || (@new_resource.windows_user && !exists?(:logins))
action_create
end
server_version = db.execute("SELECT SERVERPROPERTY('productversion')").each.first.values.first
Chef::Log.info("SQL Server Version: #{server_version.inspect}")
db.execute('USE [master]').do
@new_resource.sql_sys_roles.each do | sql_sys_role, role_action |
case role_action
when 'ADD'
if server_version < '11.00.0000.00'
alter_statement = "EXEC sp_addsrvrolemember '#{@new_resource.username}', '#{sql_sys_role}'"
else
alter_statement = "ALTER SERVER ROLE #{sql_role} #{role_action} MEMBER [#{@new_resource.username}]"
end
Chef::Log.info("#{@new_resource} granting server role membership with statement [#{alter_statement}]")
when 'DROP'
if server_version < '11.00.0000.00'
alter_statement = "EXEC sp_dropsrvrolemember '#{@new_resource.username}', '#{sql_sys_role}'"
else
alter_statement = "ALTER SERVER ROLE #{sql_role} #{role_action} MEMBER [#{@new_resource.username}]"
end
Chef::Log.info("#{@new_resource} revoking server role membership with statement [#{alter_statement}]")
end
db.execute(alter_statement).do
end
@new_resource.updated_by_last_action(true)
ensure
close
end
private
def exists?(type = :users)
case type
when :users
table = 'database_principals'
if @new_resource.database_name
Chef::Log.debug("#{@new_resource} searching for existing user in '#{@new_resource.database_name}' database context.")
db.execute("USE [#{@new_resource.database_name}]").do
end
when :logins
table = 'server_principals'
end
result = db.execute("SELECT name FROM sys.#{table} WHERE name='#{@new_resource.username}'")
result.each.any?
end
end
end
end
end

View File

@@ -0,0 +1,118 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/resource'
class Chef
class Resource
class Database < Chef::Resource
def initialize(name, run_context = nil)
super
@resource_name = :database
@database_name = name
@allowed_actions.push(:create, :drop, :query)
@action = :create
end
def database_name(arg = nil)
set_or_return(
:database_name,
arg,
kind_of: String
)
end
def connection(arg = nil)
set_or_return(
:connection,
arg,
required: true
)
end
def sql(arg = nil, &block)
arg ||= block
set_or_return(
:sql,
arg,
kind_of: [String, Proc]
)
end
def sql_query
if sql.is_a?(Proc)
sql.call
else
sql
end
end
def template(arg = nil)
set_or_return(
:template,
arg,
kind_of: String,
default: 'DEFAULT'
)
end
def collation(arg = nil)
set_or_return(
:collation,
arg,
kind_of: String
)
end
def encoding(arg = nil)
set_or_return(
:encoding,
arg,
kind_of: String,
default: 'DEFAULT'
)
end
def tablespace(arg = nil)
set_or_return(
:tablespace,
arg,
kind_of: String,
default: 'DEFAULT'
)
end
def connection_limit(arg = nil)
set_or_return(
:connection_limit,
arg,
kind_of: String,
default: '-1'
)
end
def owner(arg = nil)
set_or_return(
:owner,
arg,
kind_of: String
)
end
end
end
end

View File

@@ -0,0 +1,105 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'resource_database')
class Chef
class Resource
class DatabaseUser < Chef::Resource::Database
def initialize(name, run_context = nil)
super
@resource_name = :database_user
@username = name
@database_name = nil
@table = nil
@host = 'localhost'
@privileges = [:all]
@grant_option = false
@require_ssl = false
@allowed_actions.push(:create, :drop, :grant, :revoke)
@action = :create
end
def database_name(arg = nil)
set_or_return(
:database_name,
arg,
kind_of: String
)
end
def username(arg = nil)
set_or_return(
:username,
arg,
kind_of: String
)
end
def require_ssl(arg = nil)
set_or_return(
:require_ssl,
arg,
kind_of: [TrueClass, FalseClass]
)
end
def password(arg = nil)
set_or_return(
:password,
arg,
kind_of: String
)
end
def table(arg = nil)
set_or_return(
:table,
arg,
kind_of: String
)
end
def host(arg = nil)
set_or_return(
:host,
arg,
kind_of: String
)
end
def privileges(arg = nil)
set_or_return(
:privileges,
arg,
kind_of: Array
)
end
def grant_option(arg = nil)
set_or_return(
:grant_option,
arg,
kind_of: [TrueClass, FalseClass], default: false
)
end
end
end
end

View File

@@ -0,0 +1,32 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Sean OMeara (<sean@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'provider_database_mysql')
class Chef
class Resource
class MysqlDatabase < Chef::Resource::Database
def initialize(name, run_context = nil)
super
@resource_name = :mysql_database
@provider = Chef::Provider::Database::Mysql
end
end
end
end

View File

@@ -0,0 +1,32 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'resource_database_user')
require File.join(File.dirname(__FILE__), 'provider_database_mysql_user')
class Chef
class Resource
class MysqlDatabaseUser < Chef::Resource::DatabaseUser
def initialize(name, run_context = nil)
super
@resource_name = :mysql_database_user
@provider = Chef::Provider::Database::MysqlUser
end
end
end
end

View File

@@ -0,0 +1,33 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Lamont Granquist (<lamont@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'resource_database')
require File.join(File.dirname(__FILE__), 'provider_database_postgresql')
class Chef
class Resource
class PostgresqlDatabase < Chef::Resource::Database
def initialize(name, run_context = nil)
super
@resource_name = :postgresql_database
@provider = Chef::Provider::Database::Postgresql
end
end
end
end

View File

@@ -0,0 +1,43 @@
#
# Author:: Marco Betti (<m.betti@gmail.com>)
# Copyright:: Copyright (c) 2013 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'resource_database')
require File.join(File.dirname(__FILE__), 'provider_database_postgresql_schema')
class Chef
class Resource
class PostgresqlDatabaseSchema < Chef::Resource::Database
def initialize(name, run_context = nil)
super
@resource_name = :postgresql_database_schema
@schema_name = name
@allowed_actions.push(:create, :drop)
@action = :create
@provider = Chef::Provider::Database::PostgresqlSchema
end
def schema_name(arg = nil)
set_or_return(
:schema_name,
arg,
kind_of: String
)
end
end
end
end

View File

@@ -0,0 +1,89 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Author:: Lamont Granquist (<lamont@chef.io>)
# Author:: Marco Betti (<m.betti@gmail.com>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'resource_database_user')
require File.join(File.dirname(__FILE__), 'provider_database_postgresql_user')
class Chef
class Resource
class PostgresqlDatabaseUser < Chef::Resource::DatabaseUser
def initialize(name, run_context = nil)
super
@resource_name = :postgresql_database_user
@provider = Chef::Provider::Database::PostgresqlUser
@createdb = false
@createrole = false
@login = true
@replication = false
@superuser = false
@schema_name = nil
@allowed_actions.push(:create, :drop, :grant, :grant_schema)
end
def createdb(arg = nil)
set_or_return(
:createdb,
arg,
equal_to: [true, false]
)
end
def createrole(arg = nil)
set_or_return(
:createrole,
arg,
equal_to: [true, false]
)
end
def login(arg = nil)
set_or_return(
:login,
arg,
equal_to: [true, false]
)
end
def replication(arg = nil)
set_or_return(
:replication,
arg,
equal_to: [true, false]
)
end
def schema_name(arg = nil)
set_or_return(
:schema_name,
arg,
kind_of: String
)
end
def superuser(arg = nil)
set_or_return(
:superuser,
arg,
equal_to: [true, false]
)
end
end
end
end

View File

@@ -0,0 +1,32 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'resource_database')
require File.join(File.dirname(__FILE__), 'provider_database_sql_server')
class Chef
class Resource
class SqlServerDatabase < Chef::Resource::Database
def initialize(name, run_context = nil)
super
@resource_name = :sql_server_database
@provider = Chef::Provider::Database::SqlServer
end
end
end
end

View File

@@ -0,0 +1,63 @@
#
# Author:: Seth Chisamore (<schisamo@chef.io>)
# Copyright:: Copyright (c) 2011 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require File.join(File.dirname(__FILE__), 'resource_database_user')
require File.join(File.dirname(__FILE__), 'provider_database_sql_server_user')
class Chef
class Resource
class SqlServerDatabaseUser < Chef::Resource::DatabaseUser
def initialize(name, run_context = nil)
super
@sql_roles = {}
@sql_sys_roles = {}
@resource_name = :sql_server_database_user
@provider = Chef::Provider::Database::SqlServerUser
@allowed_actions.push(:alter_roles, :alter_sys_roles)
@windows_user = false
end
end
def windows_user(arg = nil)
set_or_return(
:windows_user,
arg,
kind_of: [TrueClass, FalseClass],
default: false
)
end
def sql_roles(arg = nil)
Chef::Log.debug("Received roles: #{arg.inspect}")
set_or_return(
:sql_roles,
arg,
kind_of: Hash
)
end
def sql_sys_roles(arg = nil)
Chef::Log.debug("Received Server roles: #{arg.inspect}")
set_or_return(
:sql_sys_roles,
arg,
kind_of: Hash
)
end
end
end