Skip to content

Commit

Permalink
add support for ProxySQL v2.x galera functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
unki authored and alexjfisher committed May 18, 2019
1 parent 028d97e commit 747421d
Show file tree
Hide file tree
Showing 10 changed files with 344 additions and 2 deletions.
63 changes: 61 additions & 2 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@

The proxysql module installs, configures and manages the [ProxySQL](https://github.com/sysown/proxysql) service.

This module will install the ProxySQL and manage it's configuration. It also extends Puppet to be able to manage `mysql_users`, `mysql_servers`, `mysql_replication_hostgroups`, `mysql_query_rules`, `proxysql_servers`, `scheduler` and `global_variables`.

This module will install the ProxySQL and manage it's configuration. It also extends Puppet to be able to manage `mysql_users`, `mysql_servers`, `mysql_replication_hostgroups`, `mysql_galera_hostgroups`, `mysql_query_rules`, `proxysql_servers`, `scheduler` and `global_variables`.

## Setup

Expand Down Expand Up @@ -96,6 +95,16 @@ You can configure users\hostgroups\rules\schedulers using class parameters
}
},
],
mysql_galera_hostgroups => [
{
'galera hostgroup 1' => {
'writer_hostgroup' => 1,
'backup_writer_hostgroup' => 2,
'reader_hostgroup' => 3,
'offline_hostgroup' => 4,
}
},
],
mysql_rules => [
{
'mysql_query_rule-1' => {
Expand Down Expand Up @@ -169,6 +178,13 @@ Or by using individual resources:
offline_hostgroup => 11,
}
proxy_mysql_galera_hostgroup { '1-2-3-4':
writer_hostgroup => 1,
backup_writer_hostgroup => 2,
reader_hostgroup => 3,
offline_hostgroup => 4,
}
proxy_mysql_user { 'tester':
password => 'testerpwd',
default_hostgroup => 30,
Expand Down Expand Up @@ -231,6 +247,7 @@ You can override any configuration setting by using the `override_config_setting
mysql_query_rules => { ... },
scheduler => { ... },
mysql_replication_hostgroups => { ... },
mysql_galera_hostgroups => { ... },
}
```
Expand Down Expand Up @@ -485,6 +502,48 @@ Specifies how many transactions a resource can be behind the "master" until shun
##### `comment`
Optional comment.

#### proxy_mysql_galera_hostgroup
`proxy_mysql_galera_hostgroup` manages an entry in the ProxySQL `mysql_galera_hostgroups` admin table.

##### `ensure`
Whether the resource is present. Valid values are 'present', 'absent'. Defaults to 'present'.

##### `name`
Name to describe the hostgroup config. Must be in a '`writer_hostgroup`-`backup_writer_hostgroup`-`reader_hostgroup`-`offline_hostgroup`' format.

##### `load_to_runtime`
Specifies wheter the resource should be immediately loaded to the active runtime. Boolean, defaults to 'true'.

##### `save_to_disk`
Specifies wheter the resource should be immediately save to disk. Boolean, defaults to 'true'.

##### `writer_hostgroup`
Id of the writer hostgroup. Required.

##### `backup_writer_hostgroup`
Id of the backup writer hostgroup. Required.

##### `reader_hostgroup`
Id of the reader hostgroup. Required.

##### `offline_hostgroup`
Id of the offline hostgroup. Required.

##### `active`
Specifies wheter the resource is active or not. Integer, defaults to 1.

##### `max_writers`
Specifies how many active writers the resource has. Integer, defaults to 1.

##### `writer_is_also_reader`
Specifies if the writer is also a reader. Integer, defaults to 0.

##### `max_transactions_behind`
Specifies how many transactions a resource can be behind the "master" until shunned. Integer, defaults to 0.

##### `comment`
Optional comment.

#### proxy_mysql_server
`proxy_mysql_server` manages an entry in the ProxySQL `mysql_servers` admin table.

Expand Down
20 changes: 20 additions & 0 deletions examples/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
'backup_writer_hostgroup' => 2,
'offline_hostgroup' => 11, } },
],
mysql_galera_hostgroups => [ { 'hostgroup 2' => { 'reader_hostgroup' => 10,
'writer_hostgroup' => 5,
'backup_writer_hostgroup' => 2,
'offline_hostgroup' => 11, } },
],
mysql_rules => [ { 'testable to test DB' => { 'rule_id' => 1,
'match_pattern' => 'testtable',
'replace_pattern' => 'test.newtable',
Expand Down Expand Up @@ -84,6 +89,21 @@
offline_hostgroup => 11,
}

proxy_mysql_galera_hostgroup { '1-2-3-4':
writer_hostgroup => 1,
backup_writer_hostgroup => 2,
reader_hostgroup => 3,
offline_hostgroup => 4,
comment => 'Galera Replication Group 1',
}
proxy_mysql_galera_hostgroup { '5-6-7-8':
writer_hostgroup => 5,
backup_writer_hostgroup => 6,
reader_hostgroup => 7,
offline_hostgroup => 8,
comment => 'Galera Replication Group 2',
}

proxy_mysql_user { 'tester':
password => 'testerpwd',
default_hostgroup => 30,
Expand Down
108 changes: 108 additions & 0 deletions lib/puppet/provider/proxy_mysql_galera_hostgroup/proxysql.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'proxysql'))
Puppet::Type.type(:proxy_mysql_galera_hostgroup).provide(:proxysql, parent: Puppet::Provider::Proxysql) do
desc 'Manage galera hostgroup for a ProxySQL instance.'
commands mysql: 'mysql'

# Build a property_hash containing all the discovered information about MySQL
# Galera servers.
def self.instances
instances = []
hostgroups = mysql([defaults_file, '-NBe',
'SELECT `writer_hostgroup`, `backup_writer_hostgroup`, `reader_hostgroup`, `offline_hostgroup`, `active`,`max_writers`,`writer_is_also_reader`,`max_transactions_behind`, `comment` FROM `mysql_galera_hostgroups`'].compact).split(%r{\n})

# To reduce the number of calls to MySQL we collect all the properties in
# one big swoop.
hostgroups.each do |line|
writer_hostgroup, backup_writer_hostgroup, reader_hostgroup, offline_hostgroup, active, max_writers, writer_is_also_reader, max_transactions_behind, comment = line.split(%r{\t})
name = "#{writer_hostgroup}-#{backup_writer_hostgroup}-#{reader_hostgroup}-#{offline_hostgroup}"

instances << new(
name: name,
ensure: :present,
writer_hostgroup: writer_hostgroup,
backup_writer_hostgroup: backup_writer_hostgroup,
reader_hostgroup: reader_hostgroup,
offline_hostgroup: offline_hostgroup,
active: active,
max_writers: max_writers,
writer_is_also_reader: writer_is_also_reader,
max_transactions_behind: max_transactions_behind,
comment: comment
)
end
instances
end

# We iterate over each proxy_mysql_galera_hostgroup entry in the catalog and compare it against
# the contents of the property_hash generated by self.instances
def self.prefetch(resources)
hostgroups = instances
resources.keys.each do |name|
provider = hostgroups.find { |hostgroup| hostgroup.name == name }
resources[name].provider = provider if provider
end
end

def create
_name = @resource[:name]
writer_hostgroup = @resource.value(:writer_hostgroup)
backup_writer_hostgroup = @resource.value(:backup_writer_hostgroup)
reader_hostgroup = @resource.value(:reader_hostgroup)
offline_hostgroup = @resource.value(:offline_hostgroup)
active = @resource.value(:active)
max_writers = @resource.value(:max_writers)
writer_is_also_reader = @resource.value(:writer_is_also_reader)
max_transactions_behind = @resource.value(:max_transactions_behind)
comment = @resource.value(:comment) || ''

query = 'INSERT INTO `mysql_galera_hostgroups` (`writer_hostgroup`, `backup_writer_hostgroup`, `reader_hostgroup`, `offline_hostgroup`, `active`,`max_writers`,`writer_is_also_reader`,`max_transactions_behind`, `comment`)'
query << " VALUES (#{writer_hostgroup}, #{backup_writer_hostgroup}, #{reader_hostgroup}, #{offline_hostgroup}, #{active}, #{max_writers}, #{writer_is_also_reader}, #{max_transactions_behind}, '#{comment}')"
mysql([defaults_file, '-e', query].compact)
@property_hash[:ensure] = :present

exists? ? (return true) : (return false)
end

def destroy
writer_hostgroup = @resource.value(:writer_hostgroup)
backup_writer_hostgroup = @resource.value(:backup_writer_hostgroup)
reader_hostgroup = @resource.value(:reader_hostgroup)
offline_hostgroup = @resource.value(:offline_hostgroup)
query = 'DELETE FROM `mysql_galera_hostgroups`'
query << " WHERE `writer_hostgroup` = #{writer_hostgroup} AND `backup_writer_hostgroup` = #{backup_writer_hostgroup} `reader_hostgroup` = #{reader_hostgroup} AND `offline_hostgroup` = #{offline_hostgroup}"
mysql([defaults_file, '-e', query].compact)

@property_hash.clear
exists? ? (return false) : (return true)
end

def exists?
@property_hash[:ensure] == :present || false
end

def flush
@property_hash.clear
load_to_runtime = @resource[:load_to_runtime]
mysql([defaults_file, '-NBe', 'LOAD MYSQL SERVERS TO RUNTIME'].compact) if load_to_runtime == :true

save_to_disk = @resource[:save_to_disk]
mysql([defaults_file, '-NBe', 'SAVE MYSQL SERVERS TO DISK'].compact) if save_to_disk == :true
end

# Generates method for all properties of the property_hash
mk_resource_methods

def comment=(value)
writer_hostgroup = @resource.value(:writer_hostgroup)
backup_writer_hostgroup = @resource.value(:backup_writer_hostgroup)
reader_hostgroup = @resource.value(:reader_hostgroup)
offline_hostgroup = @resource.value(:offline_hostgroup)

query = "UPDATE mysql_galera_hostgroups SET `comment` = '#{value}'"
query << " WHERE `writer_hostgroup` = #{writer_hostgroup} AND `backup_writer_hostgroup` = #{backup_writer_hostgroup}AND `reader_hostgroup` = #{reader_hostgroup} AND `offline_hostgroup` = #{offline_hostgroup}"
mysql([defaults_file, '-e', query].compact)

@property_hash.clear
exists? ? (return false) : (return true)
end
end
79 changes: 79 additions & 0 deletions lib/puppet/type/proxy_mysql_galera_hostgroup.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# This has to be a separate type to enable collecting
Puppet::Type.newtype(:proxy_mysql_galera_hostgroup) do
@doc = 'Manage a ProxySQL mysql_galera_hostgroup.'

ensurable

autorequire(:file) { '/root/.my.cnf' }
autorequire(:class) { 'mysql::client' }
autorequire(:service) { 'proxysql' }

validate do
raise('writer_hostgroup parameter is required.') if (self[:ensure] == :present) && self[:writer_hostgroup].nil?
raise('backup_writer_hostgroup parameter is required.') if (self[:ensure] == :present) && self[:backup_writer_hostgroup].nil?
raise('reader_hostgroup parameter is required.') if (self[:ensure] == :present) && self[:reader_hostgroup].nil?
raise('offline_hostgroup parameter is required.') if (self[:ensure] == :present) && self[:offline_hostgroup].nil?
raise('name must match writer_hostgroup-backup_writer_hostgroup-reader_hostgroup-offline_hostgroup parameters') if self[:name] != "#{self[:writer_hostgroup]}-#{self[:backup_writer_hostgroup]}-#{self[:reader_hostgroup]}-#{self[:offline_hostgroup]}"
end

newparam(:name, namevar: true) do
desc 'name to describe the hostgroup config'
end

newparam(:load_to_runtime) do
desc 'Load this entry to the active runtime.'
defaultto :true
newvalues(:true, :false)
end

newparam(:save_to_disk) do
desc 'Perist this entry to the disk.'
defaultto :true
newvalues(:true, :false)
end

newproperty(:writer_hostgroup) do
desc 'Writer hostgroup.'
newvalue(%r{\d+})
end

newproperty(:backup_writer_hostgroup) do
desc 'Backup Writer hostgroup.'
newvalue(%r{\d+})
end

newproperty(:reader_hostgroup) do
desc 'Reader hostgroup.'
newvalue(%r{\d+})
end

newproperty(:offline_hostgroup) do
desc 'Offline hostgroup.'
newvalue(%r{\d+})
end

newproperty(:active) do
desc 'active'
newvalue(%r{\d+})
end

newproperty(:max_writers) do
desc 'Maximum Writers'
newvalue(%r{\d+})
end

newproperty(:writer_is_also_reader) do
desc 'A writer is also used for reading'
newvalue(%r{\d+})
end

newproperty(:max_transactions_behind) do
desc 'Maximum Transaction Galera Node out-of-sync'
newvalue(%r{\d+})
end

newproperty(:comment) do
desc 'text field can be used to store any arbitrary data.'
newvalue(%r{[\w+]})
end
end
28 changes: 28 additions & 0 deletions manifests/configure.pp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,34 @@
}
}

if $proxysql::mysql_galera_hostgroups {
$proxysql::mysql_galera_hostgroups.each |$hostgroup| {
$hostgroup.each |$k,$v| {
$comment = $k
$reader = $hostgroup[$k][reader]
$backup = $hostgroup[$k][backup]
$writer = $hostgroup[$k][writer]
$offline = $hostgroup[$k][offline]
$active = $hostgroup[$k][active]
$writers = $hostgroup[$k][writers]
$writer_is_reader = $hostgroup[$k][writer_is_reader]
$max_transactions = $hostgroup[$k][max_transactions]

proxy_mysql_galera_hostgroup { "${writer}-${backup}-${reader}-${offline}":
writer_hostgroup => $writer,
backup_writer_hostgroup => $backup,
reader_hostgroup => $reader,
offline_hostgroup => $offline,
active => $active,
max_writers => $writers,
writer_is_also_reader => $writer_is_reader,
max_transactions_behind => $max_transactions,
comment => $k,
}
}
}
}

if $proxysql::mysql_rules {
$proxysql::mysql_rules.each |$rule| {
$rule.each |$k,$v| {
Expand Down
1 change: 1 addition & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@
Optional[Proxysql::User] $mysql_users = undef,
Optional[Proxysql::Hostgroup] $mysql_hostgroups = undef,
Optional[Proxysql::GroupReplicationHostgroup] $mysql_group_replication_hostgroups = undef,
Optional[Proxysql::GaleraHostgroup] $mysql_galera_hostgroups = undef,
Optional[Proxysql::Rule] $mysql_rules = undef,
Optional[Proxysql::Scheduler] $schedulers = undef,
) inherits ::proxysql::params {
Expand Down
1 change: 1 addition & 0 deletions manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@
scheduler => {},
mysql_replication_hostgroups => {},
mysql_group_replication_hostgroups => {},
mysql_galera_hostgroups => {},
}

}
Loading

0 comments on commit 747421d

Please sign in to comment.