Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support to add resource via class parameters. Add manage_hostgroup_fo… #62

Merged
merged 5 commits into from
Sep 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 120 additions & 3 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ The module requires Puppet 4.x and currently supports only Debian 8 "Jessie" (an
### Beginning with proxysql

To install the ProxySQL software with all the default options:
```
```puppet
include ::proxysql
```

You can customize options such as (but not limited to) `listen_port`, `admin_password`, `monitor_password`, ...
```
```puppet
class { '::proxysql':
listen_port => 3306,
admin_password => '654321',
Expand All @@ -48,6 +48,104 @@ You can customize options such as (but not limited to) `listen_port`, `admin_pas
}
```

You can configure users\hostgroups\rules\schedulers using class parameters
```puppet
class { '::proxysql':
mysql_servers => [ { 'db1' => { 'port' => 3306,
'hostgroup_id' => 1, } },
{ 'db2' => { 'hostgroup_id' => 2, } },
],
mysql_users => [ { 'app' => { 'password' => '*92C74DFBDA5D60ABD41EFD7EB0DAE389F4646ABB',
'default_hostgroup' => 1, } },
{ 'ro' => { 'password' => '*86935F2843252CFAAC4CE713C0D5FF80CF444F3B',
' default_hostgroup' => 2, } },
],
mysql_hostgroups => [ { 'hostgroup 1' => { 'writer_hostgroup' => 1,
'reader_hostgroup' => 2, } },
],
mysql_rules => [ { 'testable to test DB' => { 'rule_id' => 1,
'match_pattern' => 'testtable',
'replace_pattern' => 'test.newtable',
'apply' => 1,
'active' => 1, } },
],
schedulers => [ { 'test scheduler' => { 'scheduler_id' => 1,
'active' => 0,
'filename' => '/usr/bin/whoami', } },
],
```

Or by using individual resources:
```puppet
class { '::proxysql':
listen_port => 3306,
admin_password => 'SuperSecretPassword',
}

proxy_mysql_server { '192.168.33.31:3306-31':
hostname => '192.168.33.31',
port => 3306,
hostgroup_id => 31,
}
proxy_mysql_server { '192.168.33.32:3306-31':
hostname => '192.168.33.32',
port => 3306,
hostgroup_id => 31,
}
proxy_mysql_server { '192.168.33.33:3306-31':
hostname => '192.168.33.33',
port => 3306,
hostgroup_id => 31,
}
proxy_mysql_server { '192.168.33.34:3306-31':
hostname => '192.168.33.34',
port => 3306,
hostgroup_id => 31,
}
proxy_mysql_server { '192.168.33.35:3306-31':
hostname => '192.168.33.35',
port => 3306,
hostgroup_id => 31,
}

proxy_mysql_replication_hostgroup { '30-31':
writer_hostgroup => 30,
reader_hostgroup => 31,
comment => 'Replication Group 1',
}
proxy_mysql_replication_hostgroup { '20-21':
writer_hostgroup => 20,
reader_hostgroup => 21,
comment => 'Replication Group 2',
}

proxy_mysql_user { 'tester':
password => 'testerpwd',
default_hostgroup => 30,
}

proxy_mysql_query_rule { 'mysql_query_rule-1':
rule_id => 1,
match_pattern => '^SELECT',
apply => 1,
active => 1,
destination_hostgroup => 31,
}

proxy_scheduler { 'scheduler-1':
scheduler_id => 1,
active => 0,
filename => '/usr/bin/whoami',
}

proxy_scheduler { 'scheduler-2':
scheduler_id => 2,
active => 0,
interval_ms => 1000,
filename => '/usr/bin/id',
}
```

## Usage

Configuration is done by the `proxysql` class.
Expand All @@ -56,7 +154,7 @@ Configuration is done by the `proxysql` class.

You can override any configuration setting by using the `override_config_settings` hash. This hash resembles the structure of the `proxysql.cnf` file

```
```puppet
{
admin_variables => {
refresh_interval => 2000,
Expand Down Expand Up @@ -205,6 +303,25 @@ The password ProxySQL will use to connect to the configured mysql_clusters. Defa
##### `mysql_client_package_name`
The name of the mysql client package in your package manager. Defaults to undef

##### `manage_hostgroup_for_servers`
Determines wheter this module will manage hostgroup_id for mysql_servers.
If false - it will skip difference in this value between manifest and defined in ProxySQL. Defaults to 'true'

##### `mysql_servers`
Array of mysql_servers, that will be created in ProxySQL. Defaults to undef

##### `mysql_users`
Array of mysql_users, that will be created in ProxySQL. Defaults to undef

#####` mysql_hostgroups`
Array of mysql_hostgroups, that will be created in ProxySQL. Defaults to undef

##### `mysql_rules`
Array of mysql_rules, that will be created in ProxySQL. Defaults to undef

##### `schedulers`
Array of schedulers, that will be created in ProxySQL. Defaults to undef

## Types
#### proxy_global_variable
`proxy_global_variable` manages a variable in the ProxySQL `global_variables` admin table.
Expand Down
30 changes: 30 additions & 0 deletions examples/init.pp
Original file line number Diff line number Diff line change
@@ -1,4 +1,34 @@
# lint:ignore:80chars
# lint:ignore:2sp_soft_tabs
# variant 1

class { '::proxysql':
MaxFedotov marked this conversation as resolved.
Show resolved Hide resolved
mysql_servers => [ { 'db1' => { 'port' => 3306,
'hostgroup_id' => 1, } },
{ 'db2' => { 'hostgroup_id' => 2, } },
],
mysql_users => [ { 'app' => { 'password' => '*92C74DFBDA5D60ABD41EFD7EB0DAE389F4646ABB',
'default_hostgroup' => 1, } },
{ 'ro' => { 'password' => '*86935F2843252CFAAC4CE713C0D5FF80CF444F3B',
' default_hostgroup' => 2, } },
],
mysql_hostgroups => [ { 'hostgroup 1' => { 'writer_hostgroup' => 1,
'reader_hostgroup' => 2, } },
],
mysql_rules => [ { 'testable to test DB' => { 'rule_id' => 1,
'match_pattern' => 'testtable',
'replace_pattern' => 'test.newtable',
'apply' => 1,
'active' => 1, } },
],
schedulers => [ { 'test scheduler' => { 'scheduler_id' => 1,
'active' => 0,
'filename' => '/usr/bin/whoami', } },
],
}
# lint:endignore

# variant 2

class { '::proxysql':
listen_port => 3306,
Expand Down
166 changes: 166 additions & 0 deletions lib/puppet/provider/proxy_mysql_server_no_hostgroup/proxysql.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'proxysql'))
Puppet::Type.type(:proxy_mysql_server_no_hostgroup).provide(:proxysql, parent: Puppet::Provider::Proxysql) do
desc 'Manage servers for a ProxySQL instance.'
commands mysql: 'mysql'

# Build a property_hash containing all the discovered information about MySQL
# servers.
def self.instances
instances = []
servers = mysql([defaults_file, '-NBe',
'SELECT `hostname`, `port` FROM `mysql_servers`'].compact).split(%r{\n})

# To reduce the number of calls to MySQL we collect all the properties in
# one big swoop.
servers.each do |line|
hostname, port = line.split(%r{\t})
query = 'SELECT `hostname`, `port`, `hostgroup_id`, `status`, `weight`, `compression`, '
query << ' `max_connections`, `max_replication_lag`, `use_ssl`, `max_latency_ms`, `comment` '
query << ' FROM `mysql_servers`'
query << " WHERE `hostname` = '#{hostname}' AND `port` = #{port}"

@hostname, @port, @hostgroup_id, @status, @weight, @compression,
@max_connections, @max_replication_lag, @use_ssl, @max_latency_ms,
@comment = mysql([defaults_file, '-NBe', query].compact).chomp.split(%r{\t})
name = "#{hostname}:#{port}"

instances << new(
name: name,
ensure: :present,
hostname: @hostname,
port: @port,
hostgroup_id: @hostgroup_id,
status: @status,
weight: @weight,
compression: @compression,
max_connections: @max_connections,
max_replication_lag: @max_replication_lag,
use_ssl: @use_ssl,
max_latency_ms: @max_latency_ms,
comment: @comment
)
end
instances
end

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

def create
_name = @resource[:name]
hostname = @resource.value(:hostname)
port = @resource.value(:port) || 3306
hostgroup_id = @resource.value(:hostgroup_id) || 0
status = @resource.value(:status) || 'ONLINE'
weight = @resource.value(:weight) || 1
compression = @resource.value(:compression) || 0
max_connections = @resource.value(:max_connections) || 1000
max_replication_lag = @resource.value(:max_replication_lag) || 0
use_ssl = @resource.value(:use_ssl) || 0
max_latency_ms = @resource.value(:max_latency_ms) || 0
comment = @resource.value(:comment) || ''

query = 'INSERT INTO mysql_servers (`hostname`, `port`, `hostgroup_id`, `status`, `weight`, `compression`, '
query << ' `max_connections`, `max_replication_lag`, `use_ssl`, `max_latency_ms`, `comment`)'
query << " VALUES ('#{hostname}', #{port}, #{hostgroup_id}, '#{status}', #{weight}, #{compression}, "
query << " #{max_connections}, #{max_replication_lag}, #{use_ssl}, #{max_latency_ms}, '#{comment}')"
mysql([defaults_file, '-e', query].compact)
@property_hash[:ensure] = :present

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

def destroy
hostname = @resource.value(:hostname)
port = @resource.value(:port)

query = 'DELETE FROM `mysql_servers`'
query << " WHERE `hostname` = '#{hostname}' AND `port` = #{port}"
mysql([defaults_file, '-e', query].compact)

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

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

def initialize(value = {})
super(value)
@property_flush = {}
end

def flush
update_server(@property_flush) if @property_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

def update_server(properties)
hostname = @resource.value(:hostname)
port = @resource.value(:port)

return false if properties.empty?

values = []
properties.each do |field, value|
values.push("`#{field}` = '#{value}'")
end

query = 'UPDATE mysql_servers SET '
query << values.join(', ')
query << " WHERE `hostname` = '#{hostname}' AND `port` = #{port}"
mysql([defaults_file, '-e', query].compact)

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

# Generates method for all properties of the property_hash
mk_resource_methods

def status=(value)
@property_flush[:status] = value
end

def weight=(value)
@property_flush[:weight] = value
end

def compression=(value)
@property_flush[:compression] = value
end

def max_connections=(value)
@property_flush[:max_connections] = value
end

def max_replication_lag=(value)
@property_flush[:max_replication_lag] = value
end

def use_ssl=(value)
@property_flush[:use_ssl] = value
end

def max_latency_ms=(value)
@property_flush[:max_latency_ms] = value
end

def comment=(value)
@property_flush[:comment] = value
end
end
Loading