common refactor for Pike and Chef 13
- changed the default RDBMS to MariaDB in accordance with install docs[0] - removed deprecated database, apt and yum cookbooks - incorporated `database' and MySQL-specific abstractions from database cookbook - implemented foodcritic and cookstyle corrections - deprecated node.foo.bar method access for node['foo']['bar'] bracket syntax - updated default recipe for core apt resource - use /etc/apt/apt.conf.d on Ubuntu instead of passing the dpkg overrides as command line options in every cookbook [0]: https://docs.openstack.org/install-guide/environment-sql-database.html Implements blueprint modern-chef Change-Id: I143e0ed0a2bdd76269fc0c402052696426d96d81 Depends-On: I00e2237cef0c9aa35f78d3ccec04a1c7b9271ce8 Depends-On: I7ee0f5eae4e79e5c70ee8de4a0094a7c34fdd18f
This commit is contained in:
parent
ea0365d79a
commit
b2881c3a80
@ -1,6 +1,6 @@
|
|||||||
# This configuration was generated by
|
# This configuration was generated by
|
||||||
# `rubocop --auto-gen-config`
|
# `rubocop --auto-gen-config`
|
||||||
# on 2017-08-17 14:16:01 +0200 using RuboCop version 0.47.1.
|
# on 2017-11-26 11:38:53 -0800 using RuboCop version 0.49.1.
|
||||||
# The point is for the user to remove these configuration records
|
# The point is for the user to remove these configuration records
|
||||||
# one by one as the offenses are removed from the code base.
|
# one by one as the offenses are removed from the code base.
|
||||||
# Note that changes in the inspected code, or installation of new
|
# Note that changes in the inspected code, or installation of new
|
||||||
@ -11,30 +11,17 @@ Lint/NestedMethodDefinition:
|
|||||||
Exclude:
|
Exclude:
|
||||||
- 'libraries/matchers.rb'
|
- 'libraries/matchers.rb'
|
||||||
|
|
||||||
# Offense count: 11
|
|
||||||
Metrics/AbcSize:
|
|
||||||
Max: 39
|
|
||||||
|
|
||||||
# Offense count: 44
|
|
||||||
# Configuration parameters: CountComments, ExcludedMethods.
|
|
||||||
Metrics/BlockLength:
|
|
||||||
Max: 203
|
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 1
|
||||||
Metrics/PerceivedComplexity:
|
# Cop supports --auto-correct.
|
||||||
Max: 13
|
# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles.
|
||||||
|
# SupportedStyles: predicate, comparison
|
||||||
# Offense count: 9
|
Style/NumericPredicate:
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
|
||||||
# SupportedStyles: nested, compact
|
|
||||||
Style/ClassAndModuleChildren:
|
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'libraries/cli.rb'
|
- 'spec/**/*'
|
||||||
- 'libraries/config_helpers.rb'
|
- 'libraries/provider_database_mysql_user.rb'
|
||||||
- 'libraries/endpoints.rb'
|
|
||||||
- 'libraries/network.rb'
|
# Offense count: 2
|
||||||
- 'libraries/parse.rb'
|
# Cop supports --auto-correct.
|
||||||
- 'libraries/passwords.rb'
|
Style/ZeroLengthPredicate:
|
||||||
- 'libraries/search.rb'
|
Exclude:
|
||||||
- 'libraries/uri.rb'
|
- 'libraries/provider_database_mysql_user.rb'
|
||||||
- 'libraries/wrappers.rb'
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
source "https://supermarket.chef.io"
|
source 'https://supermarket.chef.io'
|
||||||
|
|
||||||
metadata
|
metadata
|
||||||
|
|
||||||
|
32
Rakefile
32
Rakefile
@ -1,41 +1,41 @@
|
|||||||
task default: ["test"]
|
task default: ['test']
|
||||||
|
|
||||||
task :test => [:syntax, :lint, :unit]
|
task test: [:syntax, :lint, :unit]
|
||||||
|
|
||||||
desc "Vendor the cookbooks in the Berksfile"
|
desc 'Vendor the cookbooks in the Berksfile'
|
||||||
task :berks_prep do
|
task :berks_prep do
|
||||||
sh %{chef exec berks vendor}
|
sh %(chef exec berks vendor)
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Run FoodCritic (syntax) tests"
|
desc 'Run FoodCritic (syntax) tests'
|
||||||
task :syntax do
|
task :syntax do
|
||||||
sh %{chef exec foodcritic --exclude spec -f any .}
|
sh %(chef exec foodcritic --exclude spec -f any .)
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Run RuboCop (lint) tests"
|
desc 'Run RuboCop (lint) tests'
|
||||||
task :lint do
|
task :lint do
|
||||||
sh %{chef exec cookstyle}
|
sh %(chef exec cookstyle)
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Run RSpec (unit) tests"
|
desc 'Run RSpec (unit) tests'
|
||||||
task :unit => :berks_prep do
|
task unit: :berks_prep do
|
||||||
sh %{chef exec rspec --format documentation}
|
sh %(chef exec rspec --format documentation)
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Remove the berks-cookbooks directory and the Berksfile.lock"
|
desc 'Remove the berks-cookbooks directory and the Berksfile.lock'
|
||||||
task :clean do
|
task :clean do
|
||||||
rm_rf [
|
rm_rf [
|
||||||
'berks-cookbooks',
|
'berks-cookbooks',
|
||||||
'Berksfile.lock'
|
'Berksfile.lock',
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "All-in-One Neutron build"
|
desc 'All-in-One Neutron build'
|
||||||
task :integration => :common_integration do
|
task integration: :common_integration do
|
||||||
# Noop
|
# Noop
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Common task used by all cookbooks for integration test"
|
desc 'Common task used by all cookbooks for integration test'
|
||||||
task :common_integration do
|
task :common_integration do
|
||||||
# Use the berksfile support to make use of the existing patch clones.
|
# Use the berksfile support to make use of the existing patch clones.
|
||||||
# Make a sym link from workspace/gate-cookbook-openstack-common-chef-rake-integration
|
# Make a sym link from workspace/gate-cookbook-openstack-common-chef-rake-integration
|
||||||
|
@ -109,7 +109,6 @@ default['openstack']['db']['options'] = {
|
|||||||
mysql: "?charset=#{node['openstack']['db']['charset']['mysql']}",
|
mysql: "?charset=#{node['openstack']['db']['charset']['mysql']}",
|
||||||
'percona-cluster' => "?charset=#{node['openstack']['db']['charset']['percona-cluster']}",
|
'percona-cluster' => "?charset=#{node['openstack']['db']['charset']['percona-cluster']}",
|
||||||
mariadb: "?charset=#{node['openstack']['db']['charset']['mariadb']}",
|
mariadb: "?charset=#{node['openstack']['db']['charset']['mariadb']}",
|
||||||
postgresql: '',
|
|
||||||
sqlite: '',
|
sqlite: '',
|
||||||
nosql: '',
|
nosql: '',
|
||||||
galera: "?charset=#{node['openstack']['db']['charset']['galera']}",
|
galera: "?charset=#{node['openstack']['db']['charset']['galera']}",
|
||||||
@ -117,7 +116,7 @@ default['openstack']['db']['options'] = {
|
|||||||
|
|
||||||
# platform and DBMS-specific python client packages
|
# platform and DBMS-specific python client packages
|
||||||
default['openstack']['db']['python_packages'] = {
|
default['openstack']['db']['python_packages'] = {
|
||||||
postgresql: ['python-psycopg2'],
|
postgresql: [],
|
||||||
sqlite: [],
|
sqlite: [],
|
||||||
}
|
}
|
||||||
case node['platform_family']
|
case node['platform_family']
|
||||||
@ -128,7 +127,7 @@ when 'rhel'
|
|||||||
default['openstack']['db']['python_packages']['percona-cluster'] = ['MySQL-python']
|
default['openstack']['db']['python_packages']['percona-cluster'] = ['MySQL-python']
|
||||||
default['openstack']['db']['python_packages']['galera'] = ['MySQL-python']
|
default['openstack']['db']['python_packages']['galera'] = ['MySQL-python']
|
||||||
when 'debian'
|
when 'debian'
|
||||||
default['openstack']['db']['service_type'] = 'mysql'
|
default['openstack']['db']['service_type'] = 'mariadb'
|
||||||
default['openstack']['db']['python_packages']['mysql'] = ['python-mysqldb']
|
default['openstack']['db']['python_packages']['mysql'] = ['python-mysqldb']
|
||||||
default['openstack']['db']['python_packages']['mariadb'] = ['python-mysqldb']
|
default['openstack']['db']['python_packages']['mariadb'] = ['python-mysqldb']
|
||||||
default['openstack']['db']['python_packages']['percona-cluster'] = ['python-mysqldb']
|
default['openstack']['db']['python_packages']['percona-cluster'] = ['python-mysqldb']
|
||||||
@ -140,7 +139,7 @@ case node['platform_family']
|
|||||||
when 'rhel'
|
when 'rhel'
|
||||||
default['openstack']['db']['socket'] = '/var/lib/mysql/mysql.sock'
|
default['openstack']['db']['socket'] = '/var/lib/mysql/mysql.sock'
|
||||||
when 'debian'
|
when 'debian'
|
||||||
default['openstack']['db']['socket'] = '/run/mysql-default/mysqld.sock'
|
default['openstack']['db']['socket'] = '/var/run/mysqld/mysqld.sock'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Database used by the OpenStack services
|
# Database used by the OpenStack services
|
||||||
|
@ -292,11 +292,13 @@ default['openstack']['sysctl']['net.ipv4.conf.default.rp_filter'] = 0
|
|||||||
case node['platform_family']
|
case node['platform_family']
|
||||||
when 'rhel'
|
when 'rhel'
|
||||||
default['openstack']['common']['platform'] = {
|
default['openstack']['common']['platform'] = {
|
||||||
|
'common_client_packages' => ['python-openstackclient'],
|
||||||
'package_overrides' => '',
|
'package_overrides' => '',
|
||||||
}
|
}
|
||||||
when 'debian'
|
when 'debian'
|
||||||
default['openstack']['common']['platform'] = {
|
default['openstack']['common']['platform'] = {
|
||||||
'package_overrides' => "-o Dpkg::Options::='--force-confold' -o Dpkg::Options::='--force-confdef'",
|
'common_client_packages' => ['python-openstackclient'],
|
||||||
|
'package_overrides' => '',
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -68,8 +68,6 @@ module ::Openstack
|
|||||||
|
|
||||||
# Normalize to the SQLAlchemy standard db type identifier
|
# Normalize to the SQLAlchemy standard db type identifier
|
||||||
case type
|
case type
|
||||||
when 'pgsql'
|
|
||||||
type = 'postgresql'
|
|
||||||
when 'mariadb', 'galera', 'percona-cluster'
|
when 'mariadb', 'galera', 'percona-cluster'
|
||||||
type = 'mysql'
|
type = 'mysql'
|
||||||
end
|
end
|
||||||
@ -91,7 +89,7 @@ module ::Openstack
|
|||||||
# Find the specific endpoint type ('internal', 'admin' or
|
# Find the specific endpoint type ('internal', 'admin' or
|
||||||
# 'public') for the given service.
|
# 'public') for the given service.
|
||||||
%w(public internal admin).each do |ep_type|
|
%w(public internal admin).each do |ep_type|
|
||||||
define_method "#{ep_type}_endpoint" do |service|
|
define_method("#{ep_type}_endpoint") do |service|
|
||||||
uri_from_hash(node['openstack']['endpoints'][ep_type][service])
|
uri_from_hash(node['openstack']['endpoints'][ep_type][service])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
52
libraries/hashed_password.rb
Normal file
52
libraries/hashed_password.rb
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#
|
||||||
|
# Author:: Maksim Horbul (<max@gorbul.net>)
|
||||||
|
# Cookbook:: openstack-common
|
||||||
|
# Library:: hashed_password
|
||||||
|
#
|
||||||
|
# Copyright:: 2016, Eligible, 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.
|
||||||
|
|
||||||
|
# this file is originally from the database cookbook, preserved for legacy
|
||||||
|
# purposes until the functionality can be refactored into a custom resource.
|
||||||
|
# Original: https://github.com/chef-boneyard/database
|
||||||
|
|
||||||
|
require File.join(File.dirname(__FILE__), 'resource_mysql_database_user')
|
||||||
|
|
||||||
|
class HashedPassword
|
||||||
|
# Initializes an object of the MysqlPassword type
|
||||||
|
# @param [String] hashed_password mysql native hashed password
|
||||||
|
# @return [MysqlPassword]
|
||||||
|
def initialize(hashed_password)
|
||||||
|
@hashed_password = hashed_password
|
||||||
|
end
|
||||||
|
|
||||||
|
# String representation of the object
|
||||||
|
# @return [String] hashed password string
|
||||||
|
def to_s
|
||||||
|
@hashed_password
|
||||||
|
end
|
||||||
|
|
||||||
|
module Helpers
|
||||||
|
# helper method wrappers the string into a MysqlPassword object
|
||||||
|
# @param [String] hashed_password mysql native hashed password
|
||||||
|
# @return [MysqlPassword] object
|
||||||
|
def hashed_password(hashed_password)
|
||||||
|
HashedPassword.new hashed_password
|
||||||
|
end
|
||||||
|
# For backward compatibility, because method was renamed
|
||||||
|
alias_method :mysql_hashed_password, :hashed_password
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
::Chef::Resource::MysqlDatabaseUser.send(:include, HashedPassword::Helpers)
|
@ -95,4 +95,68 @@ if defined?(ChefSpec)
|
|||||||
def create_openstack_common_database(resource_name)
|
def create_openstack_common_database(resource_name)
|
||||||
ChefSpec::Matchers::ResourceMatcher.new(:openstack_common_database, :create, resource_name)
|
ChefSpec::Matchers::ResourceMatcher.new(:openstack_common_database, :create, resource_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# database
|
||||||
|
#
|
||||||
|
ChefSpec.define_matcher :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
|
||||||
|
#
|
||||||
|
ChefSpec.define_matcher :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
|
||||||
|
#
|
||||||
|
ChefSpec.define_matcher :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
|
||||||
|
#
|
||||||
|
ChefSpec.define_matcher :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
|
||||||
end
|
end
|
||||||
|
@ -43,13 +43,13 @@ module ::Openstack
|
|||||||
def encrypted_secret(bag_name, index)
|
def encrypted_secret(bag_name, index)
|
||||||
key_path = node['openstack']['secret']['key_path']
|
key_path = node['openstack']['secret']['key_path']
|
||||||
::Chef::Log.info "Loading encrypted databag #{bag_name}.#{index} using key at #{key_path}"
|
::Chef::Log.info "Loading encrypted databag #{bag_name}.#{index} using key at #{key_path}"
|
||||||
secret = ::Chef::EncryptedDataBagItem.load_secret key_path
|
secret = ::Chef::EncryptedDataBagItem.load_secret key_path # ~FC086
|
||||||
::Chef::EncryptedDataBagItem.load(bag_name, index, secret)[index]
|
::Chef::EncryptedDataBagItem.load(bag_name, index, secret)[index] # ~FC086
|
||||||
end
|
end
|
||||||
|
|
||||||
def standard_secret(bag_name, index)
|
def standard_secret(bag_name, index)
|
||||||
::Chef::Log.info "Loading databag #{bag_name}.#{index}"
|
::Chef::Log.info "Loading databag #{bag_name}.#{index}"
|
||||||
::Chef::DataBagItem.load(bag_name, index)[index]
|
::Chef::DataBagItem.load(bag_name, index)[index] # ~FC086
|
||||||
end
|
end
|
||||||
|
|
||||||
def vault_secret(bag_name, index)
|
def vault_secret(bag_name, index)
|
||||||
|
170
libraries/provider_database_mysql.rb
Normal file
170
libraries/provider_database_mysql.rb
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
#
|
||||||
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
||||||
|
# Author:: Sean OMeara (<sean@sean.io>)
|
||||||
|
# Copyright:: 2011-2016, 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# this file is originally from the database cookbook, preserved for legacy
|
||||||
|
# purposes until the functionality can be refactored into a custom resource.
|
||||||
|
# Original: https://github.com/chef-boneyard/database
|
||||||
|
|
||||||
|
class Chef
|
||||||
|
class Provider
|
||||||
|
class Database
|
||||||
|
class Mysql < Chef::Provider::LWRPBase
|
||||||
|
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],
|
||||||
|
default_file: new_resource.connection[:default_file],
|
||||||
|
default_group: new_resource.connection[:default_group]
|
||||||
|
)
|
||||||
|
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],
|
||||||
|
default_file: new_resource.connection[:default_file],
|
||||||
|
default_group: new_resource.connection[:default_group]
|
||||||
|
)
|
||||||
|
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],
|
||||||
|
default_file: new_resource.connection[:default_file],
|
||||||
|
default_group: new_resource.connection[:default_group],
|
||||||
|
flags: new_resource.connection[:flags],
|
||||||
|
database: new_resource.database_name
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def close_query_client
|
||||||
|
@query_client.close if @query_client
|
||||||
|
rescue Mysql2::Error
|
||||||
|
@query_client = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
388
libraries/provider_database_mysql_user.rb
Normal file
388
libraries/provider_database_mysql_user.rb
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
#
|
||||||
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
||||||
|
# Author:: Sean OMeara (<sean@sean.io>)
|
||||||
|
# Copyright:: 2011-2016, 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# this file is originally from the database cookbook, preserved for legacy
|
||||||
|
# purposes until the functionality can be refactored into a custom resource.
|
||||||
|
# Original: https://github.com/chef-boneyard/database
|
||||||
|
|
||||||
|
require File.join(File.dirname(__FILE__), 'provider_database_mysql')
|
||||||
|
|
||||||
|
class Chef
|
||||||
|
class Provider
|
||||||
|
class Database
|
||||||
|
class MysqlUser < Chef::Provider::Database::Mysql
|
||||||
|
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
|
||||||
|
|
||||||
|
password_up_to_date = !user_present || test_user_password
|
||||||
|
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}'"
|
||||||
|
if new_resource.password
|
||||||
|
repair_sql += ' IDENTIFIED BY '
|
||||||
|
repair_sql += if new_resource.password.is_a?(HashedPassword)
|
||||||
|
" PASSWORD '#{new_resource.password}'"
|
||||||
|
else
|
||||||
|
" '#{new_resource.password}'"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
repair_client.query(repair_sql)
|
||||||
|
ensure
|
||||||
|
close_repair_client
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
update_user_password unless password_up_to_date
|
||||||
|
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 =~ new_resource.password
|
||||||
|
end
|
||||||
|
|
||||||
|
db_name = new_resource.database_name ? "`#{new_resource.database_name}`" : '*'
|
||||||
|
tbl_name = new_resource.table ? new_resource.table : '*'
|
||||||
|
test_table = new_resource.database_name ? 'mysql.db' : 'mysql.user'
|
||||||
|
|
||||||
|
# Test
|
||||||
|
incorrect_privs = nil
|
||||||
|
begin
|
||||||
|
test_sql = "SELECT * from #{test_table}"
|
||||||
|
test_sql += " WHERE User='#{new_resource.username}'"
|
||||||
|
test_sql += " AND Host='#{new_resource.host}'"
|
||||||
|
test_sql += " AND Db='#{new_resource.database_name}'" if new_resource.database_name
|
||||||
|
test_sql_results = test_client.query test_sql
|
||||||
|
|
||||||
|
incorrect_privs = true if test_sql_results.size.zero?
|
||||||
|
# These should all be 'Y'
|
||||||
|
test_sql_results.each do |r|
|
||||||
|
desired_privs.each do |p|
|
||||||
|
key = p.to_s.capitalize.tr(' ', '_').gsub('Replication_', 'Repl_').gsub('Create_temporary_tables', 'Create_tmp_table').gsub('Show_databases', 'Show_db')
|
||||||
|
key = "#{key}_priv"
|
||||||
|
incorrect_privs = true if r[key] != 'Y'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
password_up_to_date = incorrect_privs || test_user_password
|
||||||
|
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 += if new_resource.password.is_a?(HashedPassword)
|
||||||
|
" PASSWORD '#{new_resource.password}'"
|
||||||
|
else
|
||||||
|
" '#{new_resource.password}'"
|
||||||
|
end
|
||||||
|
repair_sql += ' REQUIRE SSL' if new_resource.require_ssl
|
||||||
|
repair_sql += ' REQUIRE X509' if new_resource.require_x509
|
||||||
|
repair_sql += ' WITH GRANT OPTION' if new_resource.grant_option
|
||||||
|
|
||||||
|
redacted_sql = redact_password(repair_sql, new_resource.password)
|
||||||
|
Chef::Log.debug("#{@new_resource}: granting with sql [#{redacted_sql}]")
|
||||||
|
repair_client.query(repair_sql)
|
||||||
|
repair_client.query('FLUSH PRIVILEGES')
|
||||||
|
ensure
|
||||||
|
close_repair_client
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
# The grants are correct, but perhaps the password needs updating?
|
||||||
|
update_user_password unless password_up_to_date
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
action :revoke do
|
||||||
|
db_name = new_resource.database_name ? "`#{new_resource.database_name}`" : '*'
|
||||||
|
tbl_name = new_resource.table ? new_resource.table : '*'
|
||||||
|
test_table = new_resource.database_name ? 'mysql.db' : 'mysql.user'
|
||||||
|
|
||||||
|
privs_to_revoke = []
|
||||||
|
begin
|
||||||
|
test_sql = "SELECT * from #{test_table}"
|
||||||
|
test_sql += " WHERE User='#{new_resource.username}'"
|
||||||
|
test_sql += " AND Host='#{new_resource.host}'"
|
||||||
|
test_sql += " AND Db='#{new_resource.database_name}'" if new_resource.database_name
|
||||||
|
test_sql_results = test_client.query test_sql
|
||||||
|
|
||||||
|
# These should all be 'N'
|
||||||
|
test_sql_results.each do |r|
|
||||||
|
desired_privs.each do |p|
|
||||||
|
key = p.to_s.capitalize.tr(' ', '_').gsub('Replication_', 'Repl_').gsub('Create_temporary_tables', 'Create_tmp_table').gsub('Show_databases', 'Show_db')
|
||||||
|
key = "#{key}_priv"
|
||||||
|
privs_to_revoke << revokify_key(p) if r[key] != 'N'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
close_test_client
|
||||||
|
end
|
||||||
|
|
||||||
|
# Repair
|
||||||
|
unless privs_to_revoke.empty?
|
||||||
|
converge_by "Revoking privs for '#{new_resource.username}'@'#{new_resource.host}'" do
|
||||||
|
begin
|
||||||
|
revoke_statement = "REVOKE #{privs_to_revoke.join(',')}"
|
||||||
|
revoke_statement += " ON #{db_name}.#{tbl_name}"
|
||||||
|
revoke_statement += " FROM `#{@new_resource.username}`@`#{@new_resource.host}` "
|
||||||
|
|
||||||
|
Chef::Log.debug("#{@new_resource}: revoking access with statement [#{revoke_statement}]")
|
||||||
|
repair_client.query(revoke_statement)
|
||||||
|
repair_client.query('FLUSH PRIVILEGES')
|
||||||
|
ensure
|
||||||
|
close_repair_client
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def desired_privs
|
||||||
|
possible_global_privs = [
|
||||||
|
:select,
|
||||||
|
:insert,
|
||||||
|
:update,
|
||||||
|
:delete,
|
||||||
|
:create,
|
||||||
|
:drop,
|
||||||
|
:references,
|
||||||
|
:index,
|
||||||
|
:alter,
|
||||||
|
:create_tmp_table,
|
||||||
|
:lock_tables,
|
||||||
|
:create_view,
|
||||||
|
:show_view,
|
||||||
|
:create_routine,
|
||||||
|
:alter_routine,
|
||||||
|
:execute,
|
||||||
|
:event,
|
||||||
|
:trigger,
|
||||||
|
:reload,
|
||||||
|
:shutdown,
|
||||||
|
:process,
|
||||||
|
:file,
|
||||||
|
:show_db,
|
||||||
|
:super,
|
||||||
|
:repl_slave,
|
||||||
|
:repl_client,
|
||||||
|
:create_user,
|
||||||
|
]
|
||||||
|
possible_db_privs = [
|
||||||
|
:select,
|
||||||
|
:insert,
|
||||||
|
:update,
|
||||||
|
:delete,
|
||||||
|
:create,
|
||||||
|
:drop,
|
||||||
|
:references,
|
||||||
|
:index,
|
||||||
|
:alter,
|
||||||
|
:create_tmp_table,
|
||||||
|
:lock_tables,
|
||||||
|
:create_view,
|
||||||
|
:show_view,
|
||||||
|
:create_routine,
|
||||||
|
:alter_routine,
|
||||||
|
:execute,
|
||||||
|
:event,
|
||||||
|
:trigger,
|
||||||
|
]
|
||||||
|
|
||||||
|
# convert :all to the individual db or global privs
|
||||||
|
desired_privs = if new_resource.privileges == [:all] && new_resource.database_name
|
||||||
|
possible_db_privs
|
||||||
|
elsif new_resource.privileges == [:all]
|
||||||
|
possible_global_privs
|
||||||
|
else
|
||||||
|
new_resource.privileges
|
||||||
|
end
|
||||||
|
desired_privs
|
||||||
|
end
|
||||||
|
|
||||||
|
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],
|
||||||
|
default_file: new_resource.connection[:default_file],
|
||||||
|
default_group: new_resource.connection[:default_group]
|
||||||
|
)
|
||||||
|
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],
|
||||||
|
default_file: new_resource.connection[:default_file],
|
||||||
|
default_group: new_resource.connection[:default_group]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def close_repair_client
|
||||||
|
@repair_client.close if @repair_client
|
||||||
|
rescue Mysql2::Error
|
||||||
|
@repair_client = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def revokify_key(key)
|
||||||
|
return '' if key.nil?
|
||||||
|
|
||||||
|
# Some keys need to be translated as outlined by the table found here:
|
||||||
|
# https://dev.mysql.com/doc/refman/5.7/en/privileges-provided.html
|
||||||
|
result = key.to_s.downcase.tr('_', ' ').gsub('repl ', 'replication ').gsub('create tmp table', 'create temporary tables').gsub('show db', 'show databases')
|
||||||
|
result = result.gsub(/ priv$/, '')
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_user_password
|
||||||
|
if database_has_password_column(test_client)
|
||||||
|
test_sql = 'SELECT User,Host,Password FROM mysql.user ' \
|
||||||
|
"WHERE User='#{new_resource.username}' AND Host='#{new_resource.host}' "
|
||||||
|
test_sql += if new_resource.password.is_a? HashedPassword
|
||||||
|
"AND Password='#{new_resource.password}'"
|
||||||
|
else
|
||||||
|
"AND Password=PASSWORD('#{new_resource.password}')"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
test_sql = 'SELECT User,Host,authentication_string FROM mysql.user ' \
|
||||||
|
"WHERE User='#{new_resource.username}' AND Host='#{new_resource.host}' " \
|
||||||
|
"AND plugin='mysql_native_password' "
|
||||||
|
test_sql += if new_resource.password.is_a? HashedPassword
|
||||||
|
"AND authentication_string='#{new_resource.password}'"
|
||||||
|
else
|
||||||
|
"AND authentication_string=PASSWORD('#{new_resource.password}')"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
test_client.query(test_sql).size > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_user_password
|
||||||
|
converge_by "Updating password of user '#{new_resource.username}'@'#{new_resource.host}'" do
|
||||||
|
begin
|
||||||
|
if database_has_password_column(repair_client)
|
||||||
|
repair_sql = "SET PASSWORD FOR '#{new_resource.username}'@'#{new_resource.host}' = "
|
||||||
|
repair_sql += if new_resource.password.is_a? HashedPassword
|
||||||
|
"'#{new_resource.password}'"
|
||||||
|
else
|
||||||
|
" PASSWORD('#{new_resource.password}')"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
# "ALTER USER is now the preferred statement for assigning passwords."
|
||||||
|
# http://dev.mysql.com/doc/refman/5.7/en/set-password.html
|
||||||
|
repair_sql = "ALTER USER '#{new_resource.username}'@'#{new_resource.host}' "
|
||||||
|
repair_sql += if new_resource.password.is_a? HashedPassword
|
||||||
|
"IDENTIFIED WITH mysql_native_password AS '#{new_resource.password}'"
|
||||||
|
else
|
||||||
|
"IDENTIFIED BY '#{new_resource.password}'"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
repair_client.query(repair_sql)
|
||||||
|
ensure
|
||||||
|
close_repair_client
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def database_has_password_column(client)
|
||||||
|
client.query('SHOW COLUMNS FROM mysql.user WHERE Field="Password"').size > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def redact_password(query, password)
|
||||||
|
if password.nil? || password == ''
|
||||||
|
query
|
||||||
|
else
|
||||||
|
query.gsub(password, 'REDACTED')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
122
libraries/resource_database.rb
Normal file
122
libraries/resource_database.rb
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#
|
||||||
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
||||||
|
# Copyright:: 2011-2016, 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# this file is originally from the database cookbook, preserved for legacy
|
||||||
|
# purposes until the functionality can be refactored into a custom resource.
|
||||||
|
# Original: https://github.com/chef-boneyard/database
|
||||||
|
|
||||||
|
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
|
118
libraries/resource_database_user.rb
Normal file
118
libraries/resource_database_user.rb
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#
|
||||||
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
||||||
|
# Copyright:: 2011-2016, 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# this file is originally from the database cookbook, preserved for legacy
|
||||||
|
# purposes until the functionality can be refactored into a custom resource.
|
||||||
|
# Original: https://github.com/chef-boneyard/database
|
||||||
|
|
||||||
|
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
|
||||||
|
@require_x509 = 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 require_x509(arg = nil)
|
||||||
|
set_or_return(
|
||||||
|
:require_x509,
|
||||||
|
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
|
36
libraries/resource_mysql_database.rb
Normal file
36
libraries/resource_mysql_database.rb
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#
|
||||||
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
||||||
|
# Author:: Sean OMeara (<sean@sean.io>)
|
||||||
|
# Copyright:: 2011-2016, 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# this file is originally from the database cookbook, preserved for legacy
|
||||||
|
# purposes until the functionality can be refactored into a custom resource.
|
||||||
|
# Original: https://github.com/chef-boneyard/database
|
||||||
|
|
||||||
|
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
|
44
libraries/resource_mysql_database_user.rb
Normal file
44
libraries/resource_mysql_database_user.rb
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#
|
||||||
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
||||||
|
# Copyright:: 2011-2016, 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# this file is originally from the database cookbook, preserved for legacy
|
||||||
|
# purposes until the functionality can be refactored into a custom resource.
|
||||||
|
# Original: https://github.com/chef-boneyard/database
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def password(arg = nil)
|
||||||
|
set_or_return(
|
||||||
|
:password,
|
||||||
|
arg,
|
||||||
|
kind_of: [String, HashedPassword]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,7 +1,7 @@
|
|||||||
name 'openstack-common'
|
name 'openstack-common'
|
||||||
maintainer 'openstack-chef'
|
maintainer 'openstack-chef'
|
||||||
maintainer_email 'openstack-dev@lists.openstack.org'
|
maintainer_email 'openstack-dev@lists.openstack.org'
|
||||||
license 'Apache 2.0'
|
license 'Apache-2.0'
|
||||||
description 'Common OpenStack attributes, libraries and recipes.'
|
description 'Common OpenStack attributes, libraries and recipes.'
|
||||||
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
|
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
|
||||||
version '16.0.0'
|
version '16.0.0'
|
||||||
@ -14,14 +14,12 @@ recipe 'openstack-common::sysctl', 'Configures sysctl settings'
|
|||||||
supports os
|
supports os
|
||||||
end
|
end
|
||||||
|
|
||||||
depends 'apt', '~> 5.0'
|
|
||||||
depends 'database', '~> 6.1'
|
|
||||||
depends 'etcd', '~> 3.0'
|
depends 'etcd', '~> 3.0'
|
||||||
depends 'mariadb', '~> 1.5'
|
depends 'mariadb', '~> 1.5'
|
||||||
|
depends 'memcached', '~> 4.1'
|
||||||
depends 'mysql', '~> 8.2'
|
depends 'mysql', '~> 8.2'
|
||||||
depends 'yum', '~> 3.13'
|
|
||||||
depends 'yum-epel', '~> 2.0'
|
|
||||||
depends 'poise-python', '~> 1.5'
|
depends 'poise-python', '~> 1.5'
|
||||||
|
depends 'selinux'
|
||||||
|
|
||||||
issues_url 'https://launchpad.net/openstack-chef' if respond_to?(:issues_url)
|
issues_url 'https://launchpad.net/openstack-chef' if respond_to?(:issues_url)
|
||||||
source_url 'https://github.com/openstack/cookbook-openstack-common' if respond_to?(:source_url)
|
source_url 'https://github.com/openstack/cookbook-openstack-common' if respond_to?(:source_url)
|
||||||
|
@ -38,10 +38,6 @@ end
|
|||||||
|
|
||||||
def db_types
|
def db_types
|
||||||
case @db_type
|
case @db_type
|
||||||
when 'postgresql', 'pgsql'
|
|
||||||
@db_prov = ::Chef::Provider::Database::Postgresql
|
|
||||||
@user_prov = ::Chef::Provider::Database::PostgresqlUser
|
|
||||||
@super_user = 'postgres'
|
|
||||||
when 'mysql', 'mariadb', 'percona-cluster', 'galera'
|
when 'mysql', 'mariadb', 'percona-cluster', 'galera'
|
||||||
@db_prov = ::Chef::Provider::Database::Mysql
|
@db_prov = ::Chef::Provider::Database::Mysql
|
||||||
@user_prov = ::Chef::Provider::Database::MysqlUser
|
@user_prov = ::Chef::Provider::Database::MysqlUser
|
||||||
|
@ -19,4 +19,10 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
package 'python-openstackclient'
|
platform_options = node['openstack']['common']['platform']
|
||||||
|
platform_options['common_client_packages'].each do |pkg|
|
||||||
|
package pkg do
|
||||||
|
options platform_options['package_overrides']
|
||||||
|
action :upgrade
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@ -22,9 +22,26 @@ platform_options = node['openstack']['common']['platform']
|
|||||||
case node['platform_family']
|
case node['platform_family']
|
||||||
when 'debian'
|
when 'debian'
|
||||||
if node['openstack']['apt']['update_apt_cache']
|
if node['openstack']['apt']['update_apt_cache']
|
||||||
# Ensure we've done an apt-update first or packages won't be found.
|
# update the apt cache before installing anything
|
||||||
include_recipe 'apt'
|
apt_update 'default' do
|
||||||
|
action :update
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# populate the necessary apt options
|
||||||
|
# by default, do not overwrite existing configuration files
|
||||||
|
# this alleviates the need to populate package_overrides in every cookbook
|
||||||
|
file '/etc/apt/apt.conf.d/confdef' do
|
||||||
|
owner 'root'
|
||||||
|
group 'root'
|
||||||
|
mode 00644
|
||||||
|
content 'Dpkg::Options {
|
||||||
|
"--force-confdef";
|
||||||
|
"--force-confold";
|
||||||
|
}'
|
||||||
|
action :create
|
||||||
|
end
|
||||||
|
|
||||||
package 'ubuntu-cloud-keyring' do
|
package 'ubuntu-cloud-keyring' do
|
||||||
options platform_options['package_overrides']
|
options platform_options['package_overrides']
|
||||||
action :upgrade
|
action :upgrade
|
||||||
@ -36,6 +53,7 @@ when 'debian'
|
|||||||
uri node['openstack']['apt']['uri']
|
uri node['openstack']['apt']['uri']
|
||||||
distribution "#{node['lsb']['codename']}-updates/#{node['openstack']['release']}"
|
distribution "#{node['lsb']['codename']}-updates/#{node['openstack']['release']}"
|
||||||
components apt_components
|
components apt_components
|
||||||
|
cache_rebuild true # update the cache after a new repo is added
|
||||||
end
|
end
|
||||||
|
|
||||||
# add in the proposed repo, but only if we're in development
|
# add in the proposed repo, but only if we're in development
|
||||||
@ -50,18 +68,17 @@ when 'debian'
|
|||||||
distribution "#{node['lsb']['codename']}-proposed/#{node['openstack']['release']}"
|
distribution "#{node['lsb']['codename']}-proposed/#{node['openstack']['release']}"
|
||||||
components apt_components
|
components apt_components
|
||||||
action proposed_action
|
action proposed_action
|
||||||
|
cache_rebuild true # update the cache after a new repo is added
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
when 'rhel'
|
|
||||||
include_recipe 'yum' if node['openstack']['yum']['update_yum_cache']
|
|
||||||
|
|
||||||
if node['openstack']['yum']['rdo_enabled']
|
when 'rhel'
|
||||||
repo_action = :add
|
repo_action = if node['openstack']['yum']['rdo_enabled']
|
||||||
include_recipe 'yum-epel'
|
:add
|
||||||
elsif FileTest.exist? "/etc/yum.repos.d/RDO-#{node['openstack']['release']}.repo"
|
elsif FileTest.exist? "/etc/yum.repos.d/RDO-#{node['openstack']['release']}.repo"
|
||||||
repo_action = :remove
|
:remove
|
||||||
else
|
else
|
||||||
repo_action = :nothing
|
:nothing
|
||||||
end
|
end
|
||||||
|
|
||||||
yum_repository "RDO-#{node['openstack']['release']}" do
|
yum_repository "RDO-#{node['openstack']['release']}" do
|
||||||
|
@ -23,9 +23,8 @@ describe 'openstack-common::default' do
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
it 'returns cli enviroment' do
|
it 'returns cli enviroment' do
|
||||||
allow(subject).to receive(:get_password)
|
allow(subject).to receive(:get_password).with(
|
||||||
.with('user', 'name')
|
'user', 'name').and_return('pass')
|
||||||
.and_return('pass')
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
subject.openstack_command_env('name', 'project', 'default', 'default')
|
subject.openstack_command_env('name', 'project', 'default', 'default')
|
||||||
@ -112,9 +111,10 @@ describe 'openstack-common::default' do
|
|||||||
'OS_AUTH_URL' => 'http://127.0.0.1:35357/v3',
|
'OS_AUTH_URL' => 'http://127.0.0.1:35357/v3',
|
||||||
'OS_IDENTITY_API_VERSION' => 3,
|
'OS_IDENTITY_API_VERSION' => 3,
|
||||||
}
|
}
|
||||||
allow(subject).to receive(:openstack_command).with('openstack', 'user list', env, {})
|
allow(subject).to receive(:openstack_command).with(
|
||||||
allow(subject).to receive(:prettytable_to_array)
|
'openstack', 'user list', env, {})
|
||||||
.and_return([{ 'name' => 'user1', 'id' => '1234567890ABCDEFGH' }])
|
allow(subject).to receive(:prettytable_to_array).and_return(
|
||||||
|
[{ 'name' => 'user1', 'id' => '1234567890ABCDEFGH' }])
|
||||||
|
|
||||||
result = subject.identity_uuid('user', 'name', 'user1', env)
|
result = subject.identity_uuid('user', 'name', 'user1', env)
|
||||||
expect(result).to eq('1234567890ABCDEFGH')
|
expect(result).to eq('1234567890ABCDEFGH')
|
||||||
@ -135,17 +135,19 @@ describe 'openstack-common::default' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'runs glance command to query valid id' do
|
it 'runs glance command to query valid id' do
|
||||||
allow(subject).to receive(:openstack_command).with('openstack', 'image list', :env, {})
|
allow(subject).to receive(:openstack_command).with(
|
||||||
allow(subject).to receive(:prettytable_to_array)
|
'openstack', 'image list', :env, {})
|
||||||
.and_return([{ 'ID' => '87f38e15-9737-46cc-a612-7c67ee29a24f', 'Name' => 'cirros' }])
|
allow(subject).to receive(:prettytable_to_array).and_return(
|
||||||
|
[{ 'ID' => '87f38e15-9737-46cc-a612-7c67ee29a24f', 'Name' => 'cirros' }])
|
||||||
|
|
||||||
result = subject.image_id('cirros', :env)
|
result = subject.image_id('cirros', :env)
|
||||||
expect(result).to eq('87f38e15-9737-46cc-a612-7c67ee29a24f')
|
expect(result).to eq('87f38e15-9737-46cc-a612-7c67ee29a24f')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'runs glance command to query invalid id' do
|
it 'runs glance command to query invalid id' do
|
||||||
allow(subject).to receive(:openstack_command).with('openstack', 'image list', :env, {})
|
allow(subject).to receive(:openstack_command).with(
|
||||||
.and_raise("No image with a name or ID of 'test' exists. (1)")
|
'openstack', 'image list', :env, {}).and_raise(
|
||||||
|
"No image with a name or ID of 'test' exists. (1)")
|
||||||
|
|
||||||
expect { subject.image_id('test', :env) }.to raise_error(RuntimeError)
|
expect { subject.image_id('test', :env) }.to raise_error(RuntimeError)
|
||||||
end
|
end
|
||||||
@ -163,9 +165,10 @@ describe 'openstack-common::default' do
|
|||||||
'OS_AUTH_URL' => 'http://127.0.0.1:35357/v3',
|
'OS_AUTH_URL' => 'http://127.0.0.1:35357/v3',
|
||||||
'OS_IDENTITY_API_VERSION' => 3,
|
'OS_IDENTITY_API_VERSION' => 3,
|
||||||
}
|
}
|
||||||
allow(subject).to receive(:openstack_command).with('openstack', 'network list', env, {})
|
allow(subject).to receive(:openstack_command).with(
|
||||||
allow(subject).to receive(:prettytable_to_array)
|
'openstack', 'network list', env, {})
|
||||||
.and_return([{ 'name' => 'net1', 'id' => '1234567890ABCDEFGH' }])
|
allow(subject).to receive(:prettytable_to_array).and_return(
|
||||||
|
[{ 'name' => 'net1', 'id' => '1234567890ABCDEFGH' }])
|
||||||
|
|
||||||
result = subject.network_uuid('network', 'name', 'net1', env)
|
result = subject.network_uuid('network', 'name', 'net1', env)
|
||||||
expect(result).to eq('1234567890ABCDEFGH')
|
expect(result).to eq('1234567890ABCDEFGH')
|
||||||
|
@ -10,7 +10,7 @@ describe 'openstack-common::client' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it do
|
it do
|
||||||
expect(chef_run).to install_package('python-openstackclient')
|
expect(chef_run).to upgrade_package('python-openstackclient')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -30,7 +30,7 @@ describe 'test-openstack-common-database::default' do
|
|||||||
expect(chef_run).to create_database('create database service_db')
|
expect(chef_run).to create_database('create database service_db')
|
||||||
.with(
|
.with(
|
||||||
provider: ::Chef::Provider::Database::Mysql,
|
provider: ::Chef::Provider::Database::Mysql,
|
||||||
connection: { host: 'localhost123', port: 3306, username: 'root', password: 'root_pass', socket: '/run/mysql-default/mysqld.sock' },
|
connection: { host: 'localhost123', port: 3306, username: 'root', password: 'root_pass', socket: '/var/run/mysqld/mysqld.sock' },
|
||||||
database_name: 'service_db',
|
database_name: 'service_db',
|
||||||
encoding: 'utf8'
|
encoding: 'utf8'
|
||||||
)
|
)
|
||||||
@ -41,7 +41,7 @@ describe 'test-openstack-common-database::default' do
|
|||||||
expect(chef_run).to create_database('create database service_db')
|
expect(chef_run).to create_database('create database service_db')
|
||||||
.with(
|
.with(
|
||||||
provider: ::Chef::Provider::Database::Mysql,
|
provider: ::Chef::Provider::Database::Mysql,
|
||||||
connection: { host: 'localhost', port: 3306, username: 'root', password: 'root_pass', socket: '/run/mysql-default/mysqld.sock' },
|
connection: { host: 'localhost', port: 3306, username: 'root', password: 'root_pass', socket: '/var/run/mysqld/mysqld.sock' },
|
||||||
database_name: 'service_db',
|
database_name: 'service_db',
|
||||||
encoding: 'utf8'
|
encoding: 'utf8'
|
||||||
)
|
)
|
||||||
@ -51,7 +51,7 @@ describe 'test-openstack-common-database::default' do
|
|||||||
expect(chef_run).to create_database_user('create database user db_user')
|
expect(chef_run).to create_database_user('create database user db_user')
|
||||||
.with(
|
.with(
|
||||||
provider: ::Chef::Provider::Database::MysqlUser,
|
provider: ::Chef::Provider::Database::MysqlUser,
|
||||||
connection: { host: 'localhost', port: 3306, username: 'root', password: 'root_pass', socket: '/run/mysql-default/mysqld.sock' },
|
connection: { host: 'localhost', port: 3306, username: 'root', password: 'root_pass', socket: '/var/run/mysqld/mysqld.sock' },
|
||||||
username: 'db_user',
|
username: 'db_user',
|
||||||
password: 'db_pass'
|
password: 'db_pass'
|
||||||
)
|
)
|
||||||
@ -61,7 +61,7 @@ describe 'test-openstack-common-database::default' do
|
|||||||
expect(chef_run).to grant_database_user('grant database user db_user')
|
expect(chef_run).to grant_database_user('grant database user db_user')
|
||||||
.with(
|
.with(
|
||||||
provider: ::Chef::Provider::Database::MysqlUser,
|
provider: ::Chef::Provider::Database::MysqlUser,
|
||||||
connection: { host: 'localhost', port: 3306, username: 'root', password: 'root_pass', socket: '/run/mysql-default/mysqld.sock' },
|
connection: { host: 'localhost', port: 3306, username: 'root', password: 'root_pass', socket: '/var/run/mysqld/mysqld.sock' },
|
||||||
username: 'db_user',
|
username: 'db_user',
|
||||||
password: 'db_pass',
|
password: 'db_pass',
|
||||||
database_name: 'service_db',
|
database_name: 'service_db',
|
||||||
|
@ -19,7 +19,6 @@ describe 'openstack-common::default' do
|
|||||||
before do
|
before do
|
||||||
node.set['openstack']['yum']['rdo_enabled'] = true
|
node.set['openstack']['yum']['rdo_enabled'] = true
|
||||||
node.set['openstack']['yum']['gpgcheck'] = true
|
node.set['openstack']['yum']['gpgcheck'] = true
|
||||||
node.set['openstack']['yum']['update_yum_cache'] = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds RDO yum repository' do
|
it 'adds RDO yum repository' do
|
||||||
@ -29,12 +28,12 @@ describe 'openstack-common::default' do
|
|||||||
.with(gpgcheck: true)
|
.with(gpgcheck: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'includes yum recipe' do
|
it 'does not include yum recipe' do
|
||||||
expect(chef_run).to include_recipe('yum')
|
expect(chef_run).to_not include_recipe('yum')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'includes yum-epel recipe' do
|
it 'does not include yum-epel recipe' do
|
||||||
expect(chef_run).to include_recipe('yum-epel')
|
expect(chef_run).to_not include_recipe('yum-epel')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -49,8 +48,8 @@ describe 'openstack-common::default' do
|
|||||||
.with(gpgcheck: false)
|
.with(gpgcheck: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'includes yum-epel recipe' do
|
it 'does not include yum-epel recipe' do
|
||||||
expect(chef_run).to include_recipe('yum-epel')
|
expect(chef_run).to_not include_recipe('yum-epel')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -10,13 +10,13 @@ describe 'openstack-common::default' do
|
|||||||
runner.converge(described_recipe)
|
runner.converge(described_recipe)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'includes apt for apt-get update' do
|
it 'does not include apt for apt-get update' do
|
||||||
node.set['openstack']['apt']['update_apt_cache'] = 'true'
|
expect(chef_run).to_not include_recipe 'apt'
|
||||||
expect(chef_run).to include_recipe 'apt'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'doesnt include apt for apt-get update' do
|
it 'updates apt cache before installing packages' do
|
||||||
expect(chef_run).to_not include_recipe 'apt'
|
node.override['openstack']['apt']['update_apt_cache'] = true
|
||||||
|
expect(chef_run).to update_apt_update 'default'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'upgrades ubuntu-cloud-keyring package' do
|
it 'upgrades ubuntu-cloud-keyring package' do
|
||||||
@ -30,7 +30,8 @@ describe 'openstack-common::default' do
|
|||||||
expect(chef_run).to add_apt_repository('openstack-ppa').with(
|
expect(chef_run).to add_apt_repository('openstack-ppa').with(
|
||||||
uri: 'http://ubuntu-cloud.archive.canonical.com/ubuntu',
|
uri: 'http://ubuntu-cloud.archive.canonical.com/ubuntu',
|
||||||
distribution: 'xenial-updates/pike',
|
distribution: 'xenial-updates/pike',
|
||||||
components: ['main']
|
components: ['main'],
|
||||||
|
cache_rebuild: true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -47,7 +48,8 @@ describe 'openstack-common::default' do
|
|||||||
expect(chef_run).to add_apt_repository('openstack-ppa-proposed').with(
|
expect(chef_run).to add_apt_repository('openstack-ppa-proposed').with(
|
||||||
uri: 'http://ubuntu-cloud.archive.canonical.com/ubuntu',
|
uri: 'http://ubuntu-cloud.archive.canonical.com/ubuntu',
|
||||||
distribution: 'xenial-proposed/pike',
|
distribution: 'xenial-proposed/pike',
|
||||||
components: ['main']
|
components: ['main'],
|
||||||
|
cache_rebuild: true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -16,8 +16,10 @@ describe 'openstack-common::default' do
|
|||||||
describe '#secret' do
|
describe '#secret' do
|
||||||
it 'returns databag' do
|
it 'returns databag' do
|
||||||
value = { 'nova' => 'this' }
|
value = { 'nova' => 'this' }
|
||||||
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with('/etc/chef/openstack_data_bag_secret').and_return('secret')
|
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with(
|
||||||
allow(Chef::EncryptedDataBagItem).to receive(:load).with('passwords', 'nova', 'secret').and_return(value)
|
'/etc/chef/openstack_data_bag_secret').and_return('secret')
|
||||||
|
allow(Chef::EncryptedDataBagItem).to receive(:load).with(
|
||||||
|
'passwords', 'nova', 'secret').and_return(value)
|
||||||
expect(subject.secret('passwords', 'nova')).to eq('this')
|
expect(subject.secret('passwords', 'nova')).to eq('this')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -27,7 +29,8 @@ describe 'openstack-common::default' do
|
|||||||
node.set['openstack']['databag_type'] = 'vault'
|
node.set['openstack']['databag_type'] = 'vault'
|
||||||
end
|
end
|
||||||
it 'returns the data from a chef vault item' do
|
it 'returns the data from a chef vault item' do
|
||||||
allow(ChefVault::Item).to receive(:load).with('vault_passwords', 'nova')
|
allow(ChefVault::Item).to receive(:load)
|
||||||
|
.with('vault_passwords', 'nova')
|
||||||
.and_return('nova' => 'novapassword')
|
.and_return('nova' => 'novapassword')
|
||||||
expect(subject.secret('passwords', 'nova')).to eq('novapassword')
|
expect(subject.secret('passwords', 'nova')).to eq('novapassword')
|
||||||
end
|
end
|
||||||
@ -37,8 +40,10 @@ describe 'openstack-common::default' do
|
|||||||
%w(service db user).each do |type|
|
%w(service db user).each do |type|
|
||||||
it "returns databag value for #{type}" do
|
it "returns databag value for #{type}" do
|
||||||
value = { 'nova' => 'this' }
|
value = { 'nova' => 'this' }
|
||||||
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with('/etc/chef/openstack_data_bag_secret').and_return('secret')
|
allow(Chef::EncryptedDataBagItem).to receive(:load_secret).with(
|
||||||
allow(Chef::EncryptedDataBagItem).to receive(:load).with("#{type}_passwords", 'nova', 'secret').and_return(value)
|
'/etc/chef/openstack_data_bag_secret').and_return('secret')
|
||||||
|
allow(Chef::EncryptedDataBagItem).to receive(:load).with(
|
||||||
|
"#{type}_passwords", 'nova', 'secret').and_return(value)
|
||||||
expect(subject.get_password(type, 'nova')).to eq('this')
|
expect(subject.get_password(type, 'nova')).to eq('this')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -65,7 +70,8 @@ describe 'openstack-common::default' do
|
|||||||
describe '#secret' do
|
describe '#secret' do
|
||||||
it 'returns databag' do
|
it 'returns databag' do
|
||||||
value = { 'nova' => 'this' }
|
value = { 'nova' => 'this' }
|
||||||
allow(Chef::DataBagItem).to receive(:load).with('passwords', 'nova').and_return(value)
|
allow(Chef::DataBagItem).to receive(:load)
|
||||||
|
.with('passwords', 'nova').and_return(value)
|
||||||
expect(subject.secret('passwords', 'nova')).to eq('this')
|
expect(subject.secret('passwords', 'nova')).to eq('this')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -74,7 +80,8 @@ describe 'openstack-common::default' do
|
|||||||
%w(service db user).each do |type|
|
%w(service db user).each do |type|
|
||||||
it "returns databag value for #{type}" do
|
it "returns databag value for #{type}" do
|
||||||
value = { 'nova' => 'this' }
|
value = { 'nova' => 'this' }
|
||||||
allow(Chef::DataBagItem).to receive(:load).with("#{type}_passwords", 'nova').and_return(value)
|
allow(Chef::DataBagItem).to receive(:load).with(
|
||||||
|
"#{type}_passwords", 'nova').and_return(value)
|
||||||
expect(subject.get_password(type, 'nova')).to eq('this')
|
expect(subject.get_password(type, 'nova')).to eq('this')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -12,7 +12,7 @@ UBUNTU_OPTS = {
|
|||||||
}.freeze
|
}.freeze
|
||||||
REDHAT_OPTS = {
|
REDHAT_OPTS = {
|
||||||
platform: 'redhat',
|
platform: 'redhat',
|
||||||
version: '7.1',
|
version: '7.3',
|
||||||
log_level: LOG_LEVEL,
|
log_level: LOG_LEVEL,
|
||||||
}.freeze
|
}.freeze
|
||||||
# We set a default platform for non-platform specific test cases
|
# We set a default platform for non-platform specific test cases
|
||||||
|
Loading…
Reference in New Issue
Block a user