Allow root mysql within environment

* Allow connections to mysql as root only
  from IP-addresses within environment
* Updated direct_networks function
* Provided and updated noop tests

Closes-Bug: 1471956
Change-Id: Ia873292d6b05f612642e055d1d0dc156a863bc34
This commit is contained in:
Oleksiy Molchanov 2015-07-13 13:56:36 +03:00
parent 99a4eafcb0
commit 91d2429d59
8 changed files with 164 additions and 108 deletions

View File

@ -4,19 +4,49 @@ directly attached to the host
EOS
) do |argv|
endpoints = argv[0]
filter = argv[1]
netmask = argv[2]
networks = []
endpoints.each{ |k,v|
if v.has_key?('IP') and v['IP'].is_a?(Array)
v['IP'].each { |ip|
networks << IPAddr.new(ip).to_s + "/" + ip.split('/')[1]
}
class IPAddr
def mask_length
@mask_addr.to_s(2).count '1'
end
if v.has_key?('routes') and v['routes'].is_a?(Array)
v['routes'].each { |route|
networks << route['net']
}
def cidr_to_netmask(cidr)
IPAddr.new('255.255.255.255').mask(cidr).to_s
end
}
def cidr
"#{to_s}/#{mask_length}"
end
def netmask
cidr = "#{mask_length}"
"#{to_s}/#{cidr_to_netmask(cidr)}"
end
end
endpoints.each do |interface, parameters|
next unless parameters.has_key? 'IP' and parameters['IP'].is_a? Array
next if filter and interface != filter
parameters['IP'].each do |ip|
next unless ip
if netmask and netmask == 'netmask'
networks << IPAddr.new(ip).netmask
else
networks << IPAddr.new(ip).cidr
end
end
next unless parameters.has_key? 'routes' and parameters['routes'].is_a? Array
parameters['routes'].each do |route|
next unless route.has_key? 'net'
if netmask and netmask == 'netmask'
networks << IPAddr.new(route['net']).netmask
else
networks << IPAddr.new(route['net']).cidr
end
end
end
return networks.join(' ')
end

View File

@ -0,0 +1,17 @@
# == Class definition osnailyfacter::mysql_grant
#
# Class for mysql grant permissions
#
# [*user*]
# Mysql username
#
# [*network*]
# Array of specific IPs or Networks or Hostnames
# to access the database with user
#
define osnailyfacter::mysql_grant ( $user = '',
$network = $name ) {
exec { "mysql_${user}_${network}":
command => "mysql -NBe \"grant all on *.* to \'${user}\'@\'${network}\' with grant option\"",
}
}

View File

@ -1,41 +0,0 @@
# == Class osnailyfacter::mysql_root
#
# Class for root grant permissions
#
# [*password*]
# Password to use with root user
#
class osnailyfacter::mysql_root (
$password = '',
) {
Exec {
path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
creates => '/root/.my.cnf',
}
exec { 'mysql_drop_test' :
command => "mysql -NBe \"drop database if exists test\"",
} ->
exec { 'mysql_root_%' :
command => "mysql -NBe \"grant all on *.* to 'root'@'%' with grant option\"",
} ->
exec { 'mysql_root_localhost' :
command => "mysql -NBe \"grant all on *.* to 'root'@'localhost' with grant option\"",
} ->
exec { 'mysql_root_127.0.0.1' :
command => "mysql -NBe \"grant all on *.* to 'root'@'127.0.0.1' with grant option\"",
} ->
exec { 'mysql_root_password' :
command => "mysql -NBe \"update mysql.user set password = password('${password}') where user = 'root'\"",
} ->
exec { 'mysql_flush_privileges' :
command => "mysql -NBe \"flush privileges\"",
}
}

View File

@ -0,0 +1,43 @@
# == Class osnailyfacter::mysql_user
#
# Class for mysql user creation and grant permissions
#
# [*user*]
# (optional) Mysql user name. Default 'root'
#
# [*password*]
# Password to use with mysql user
#
# [*access_networks*]
# Array of specific IPs or Networks or Hostnames
# to access the database with mysql user.
# Default '127.0.0.1'
#
class osnailyfacter::mysql_user (
$user = 'root',
$password = '',
$access_networks = '127.0.0.1',
) {
Exec {
path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
creates => '/root/.my.cnf',
}
exec { 'mysql_drop_test' :
command => "mysql -NBe \"drop database if exists test\"",
} ->
osnailyfacter::mysql_grant { $access_networks:
user => $user,
} ->
exec { "mysql_${user}_password" :
command => "mysql -NBe \"update mysql.user set password = password('${password}') where user = \'${user}\'\"",
} ->
exec { 'mysql_flush_privileges' :
command => "mysql -NBe \"flush privileges\"",
}
}

View File

@ -8,6 +8,10 @@ $mysql_hash = hiera_hash('mysql', {})
$management_vip = hiera('management_vip')
$database_vip = hiera('database_vip', $management_vip)
$network_scheme = hiera('network_scheme', {})
$direct_networks = split(direct_networks($network_scheme['endpoints'], 'br-mgmt', 'netmask'), ' ')
$access_networks = flatten(['localhost', '127.0.0.1', $direct_networks])
$haproxy_stats_port = '10000'
$haproxy_stats_url = "http://${database_vip}:${haproxy_stats_port}/;csv"
@ -71,8 +75,9 @@ if $enabled {
config_hash => $config_hash_real,
}
class { 'osnailyfacter::mysql_root':
password => $mysql_database_password,
class { 'osnailyfacter::mysql_user':
password => $mysql_database_password,
access_networks => $direct_networks,
}
exec { 'initial_access_config':
@ -114,7 +119,7 @@ if $enabled {
Package['socat'] ->
Class['mysql::server'] ->
Class['osnailyfacter::mysql_root'] ->
Class['osnailyfacter::mysql_user'] ->
Exec['initial_access_config'] ->
Class['openstack::galera::status'] ->
Haproxy_backend_status['mysql'] ->

View File

@ -4,44 +4,27 @@ manifest = 'cluster-haproxy/cluster-haproxy.pp'
describe manifest do
shared_examples 'catalog' do
let(:endpoints) do
Noop.hiera('network_scheme', {}).fetch('endpoints', {})
end
networks = []
endpoints = Noop.hiera_structure 'network_scheme/endpoints'
management_vip = Noop.hiera 'management_vip'
endpoints.each{ |k,v|
if v['IP'].is_a?(Array)
v['IP'].each { |ip|
networks << IPAddr.new(ip).to_s + '/' + ip.split('/')[1]
}
end
if v.has_key?('routes') and v['routes'].is_a?(Array)
v['routes'].each { |route|
networks << route['net']
}
end
}
let(:scope) do
scope = PuppetlabsSpec::PuppetInternals.scope
Puppet::Parser::Functions.autoloader.loadall unless scope.respond_to? :function_direct_networks
scope
end
it "should delcare cluster::haproxy with other_networks set to #{networks.join(' ')}" do
should contain_class('cluster::haproxy').with(
'other_networks' => networks.join(' '),
let(:other_networks) do
scope.function_direct_networks [endpoints]
end
it "should delcare cluster::haproxy with correct other_networks" do
expect(subject).to contain_class('cluster::haproxy').with(
'other_networks' => other_networks,
)
end
it "should contain stats fragment and listen only on lo and #{management_vip}" do
should contain_concat__fragment('haproxy-stats').with_content(
%r{\n\s*bind\s+127\.0\.0\.1:10000\s*$\n}
)
should contain_concat__fragment('haproxy-stats').with_content(
%r{\n\s*bind\s+#{management_vip}:10000\s*\n}
)
end
it "should not contain stats enable for defaults and global section" do
should contain_concat__fragment('haproxy-base').without_content(
%r{\n\s*stats\s+enable\s*$\n}
)
end
end
test_ubuntu_and_centos manifest
end

View File

@ -3,25 +3,25 @@ require 'shared-examples'
manifest = 'cluster-vrouter/cluster-vrouter.pp'
describe manifest do
shared_examples 'puppet catalogue' do
settings = Noop.fuel_settings
networks = []
settings['network_scheme']['endpoints'].each{ |k,v|
if v['IP'].is_a?(Array)
v['IP'].each { |ip|
networks << IPAddr.new(ip).to_s + "/" + ip.split('/')[1]
}
end
if v.has_key?('routes') and v['routes'].is_a?(Array)
v['routes'].each { |route|
networks << route['net']
}
end
}
it "should delcare cluster::vrouter_ocf with other_networks set to #{networks.join(' ')}" do
should contain_class('cluster::vrouter_ocf').with(
'other_networks' => networks.join(' '),
shared_examples 'catalog' do
let(:endpoints) do
Noop.hiera('network_scheme', {}).fetch('endpoints', {})
end
let(:scope) do
scope = PuppetlabsSpec::PuppetInternals.scope
Puppet::Parser::Functions.autoloader.loadall unless scope.respond_to? :function_direct_networks
scope
end
let(:other_networks) do
scope.function_direct_networks [endpoints]
end
it "should delcare cluster::vrouter_ocf with correct other_networks" do
expect(subject).to contain_class('cluster::vrouter_ocf').with(
'other_networks' => other_networks,
)
end

View File

@ -4,15 +4,34 @@ manifest = 'database/database.pp'
describe manifest do
shared_examples 'catalog' do
#nodes = Noop.hiera 'nodes'
it { should contain_class('mysql::server').that_comes_before('Class[osnailyfacter::mysql_root]') }
let(:endpoints) do
Noop.hiera('network_scheme', {}).fetch('endpoints', {})
end
let(:scope) do
scope = PuppetlabsSpec::PuppetInternals.scope
Puppet::Parser::Functions.autoloader.loadall unless scope.respond_to? :function_direct_networks
scope
end
let(:other_networks) do
scope.function_direct_networks [endpoints, 'br-mgmt', 'netmask']
end
it "should delcare osnailyfacter::mysql_user with correct other_networks" do
expect(subject).to contain_class('osnailyfacter::mysql_user').with(
'user' => 'root',
'access_networks' => other_networks,
).that_comes_before('Exec[initial_access_config]')
end
it { should contain_class('mysql::server').that_comes_before('Osnailyfacter::Mysql_user') }
it { should contain_class('osnailyfacter::mysql_access') }
it { should contain_class('osnailyfacter::mysql_root').that_comes_before('Exec[initial_access_config]') }
it { should contain_class('openstack::galera::status').that_comes_before('Haproxy_backend_status[mysql]') }
it { should contain_haproxy_backend_status('mysql').that_comes_before('Class[osnailyfacter::mysql_access]') }
it { should contain_package('socat').that_comes_before('Class[mysql::server]') }
end
end
test_ubuntu_and_centos manifest
end