diff --git a/README.markdown b/README.markdown index 24e2b652..31c11df2 100644 --- a/README.markdown +++ b/README.markdown @@ -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', @@ -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. @@ -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, @@ -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. diff --git a/examples/init.pp b/examples/init.pp index 2a136308..7a5ce518 100644 --- a/examples/init.pp +++ b/examples/init.pp @@ -1,4 +1,34 @@ # lint:ignore:80chars +# lint:ignore:2sp_soft_tabs +# variant 1 + +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', } }, + ], +} +# lint:endignore + +# variant 2 class { '::proxysql': listen_port => 3306, diff --git a/lib/puppet/provider/proxy_mysql_server_no_hostgroup/proxysql.rb b/lib/puppet/provider/proxy_mysql_server_no_hostgroup/proxysql.rb new file mode 100644 index 00000000..feb336e0 --- /dev/null +++ b/lib/puppet/provider/proxy_mysql_server_no_hostgroup/proxysql.rb @@ -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 diff --git a/lib/puppet/type/proxy_mysql_server_no_hostgroup.rb b/lib/puppet/type/proxy_mysql_server_no_hostgroup.rb new file mode 100644 index 00000000..c082d2f7 --- /dev/null +++ b/lib/puppet/type/proxy_mysql_server_no_hostgroup.rb @@ -0,0 +1,91 @@ +# This has to be a separate type to enable collecting +Puppet::Type.newtype(:proxy_mysql_server_no_hostgroup) do + @doc = 'Manage a ProxySQL mysql_server.' + + ensurable + + autorequire(:file) { '/root/.my.cnf' } + autorequire(:class) { 'mysql::client' } + autorequire(:service) { 'proxysql' } + + validate do + raise('hostname parameter is required.') if (self[:ensure] == :present) && self[:hostname].nil? + raise('port parameter is required.') if (self[:ensure] == :present) && self[:port].nil? + raise('hostgroup_id parameter is required.') if (self[:ensure] == :present) && self[:hostgroup_id].nil? + raise('name must match hostname and port') if self[:name] != "#{self[:hostname]}:#{self[:port]}" + end + + newparam(:name, namevar: true) do + desc 'name for server to manage.' + 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 + + newparam(:hostgroup_id) do + desc 'The hostgroup of the server.' + defaultto 0 + newvalues(%r{\d+}) + end + + newproperty(:hostname) do + desc 'The hostname of the server.' + defaultto :localhost + newvalue(%r{\w+}) + end + + newproperty(:port) do + desc 'The port of the server.' + defaultto 3306 + newvalue(%r{\d+}) + end + + newproperty(:status) do + desc 'Server status.' + newvalues(:ONLINE, :SHUNNED, :OFFLINE_SOFT, :OFFLINE_HARD) + end + + newproperty(:weight) do + desc 'the bigger the weight of a server relative to other weights, the higher the probability of the server to be chosen from a hostgroup' + newvalue(%r{\d+}) + end + + newproperty(:compression) do + desc 'if the value is greater than 0, new connections to that server will use compression' + newvalue(%r{\d+}) + end + + newproperty(:max_connections) do + desc 'the maximum number of connections ProxySQL will open to this backend server. Even though this server will have the highest weight, no new connections will be opened to it once this limit is hit. Please ensure that the backend is configured with a correct value of max_connections to avoid that ProxySQL will try to go beyond that limit' + newvalue(%r{\d+}) + end + + newproperty(:max_replication_lag) do + desc 'if greater and 0, ProxySQL will reguarly monitor replication lag and if it goes beyond such threshold it will temporary shun the host until replication catch ups' + newvalue(%r{\d+}) + end + + newproperty(:use_ssl) do + desc 'if set to 1, connections to the backend will use SSL' + newvalue(%r{[01]}) + end + + newproperty(:max_latency_ms) do + desc 'ping time is regularly monitored. If a host has a ping time greater than max_latency_ms it is excluded from the connection pool (although the server stays ONLINE)' + newvalue(%r{[\d+]}) + end + + newproperty(:comment) do + desc 'text field that can be used for any purposed defined by the user. Could be a description of what the host stores, a reminder of when the host was added or disabled, or a JSON processed by some checker script.' + newvalue(%r{[\w+]}) + end +end diff --git a/manifests/configure.pp b/manifests/configure.pp new file mode 100644 index 00000000..30c73299 --- /dev/null +++ b/manifests/configure.pp @@ -0,0 +1,86 @@ +# == Class proxysql::configure +# +# This class is called from proxysql for all proxy configuration. +# +class proxysql::configure { + + if $proxysql::mysql_servers { + $proxysql::mysql_servers.each |$server| { + $server.each |$k,$v| { + $hostname = $k + $port = $server[$k][port] ? { undef => 3306, + default => $server[$k][port], } + $hostgroup_id = $server[$k][hostgroup_id] + + if $proxysql::manage_hostgroup_for_servers { + proxy_mysql_server { "${hostname}:${port}-${hostgroup_id}": + hostname => $hostname, + * => $server[$k], + } + } else { + proxy_mysql_server_no_hostgroup { "${hostname}:${port}": + hostname => $hostname, + * => $server[$k], + } + } + } + } + } + + if $proxysql::mysql_users { + $proxysql::mysql_users.each |$user| { + $user.each |$k,$v| { + $username = $k + + proxy_mysql_user { $username: + * => $user[$k], + } + } + } + } + + if $proxysql::mysql_hostgroups { + $proxysql::mysql_hostgroups.each |$hostgroup| { + $hostgroup.each |$k,$v| { + $comment = $k + $reader = $hostgroup[$k][reader] + $writer = $hostgroup[$k][writer] + + proxy_mysql_replication_hostgroup { "${writer}-${reader}": + writer_hostgroup => $writer, + reader_hostgroup => $reader, + comment => $k, + } + } + } + } + + if $proxysql::mysql_rules { + $proxysql::mysql_rules.each |$rule| { + $rule.each |$k,$v| { + $comment = $k + $rule_id = $rule[$k][rule_id] + + proxy_mysql_query_rule { "mysql_query_rule-${rule_id}": + comment => $k, + * => $rule[$k], + } + } + } + } + + if $proxysql::schedulers { + $proxysql::schedulers.each |$scheduler| { + $scheduler.each |$k,$v| { + $comment = $k + $scheduler_id = $scheduler[$k][scheduler_id] + + proxy_scheduler { "scheduler-${scheduler_id}": + comment => $k, + * => $scheduler[$k], + } + } + } + } +} + diff --git a/manifests/init.pp b/manifests/init.pp index 8c645fdd..6d0eccf8 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -115,19 +115,24 @@ # * `mysql_client_package_name` # The name of the mysql client package in your package manager. Defaults to undef # -# * `cluster_name` -# If set, proxysql_servers with the same cluster_name will be automatically added to the same cluster and will -# synchronize their configuration parameters. 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' # -# * `cluster_username` -# The username ProxySQL will use to connect to the configured mysql_clusters -# Defaults to 'cluster' +# * `mysql_servers` +# Array of mysql_servers, that will be created in ProxySQL. Defaults to undef # -# * `cluster_password` -# The password ProxySQL will use to connect to the configured mysql_clusters. Defaults to 'cluster' +# * `mysql_users` +# Array of mysql_users, that will be created in ProxySQL. Defaults to undef # -# * `mysql_client_package_name` -# The name of the mysql client package in your package manager. 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 # class proxysql ( Optional[String] $cluster_name = $proxysql::params::cluster_name, @@ -182,6 +187,12 @@ Hash $override_config_settings = {}, String $node_name = "${facts['fqdn']}:${admin_listen_port}", + Boolean $manage_hostgroup_for_servers = $proxysql::params::manage_hostgroup_for_servers, + Optional[Proxysql::Server] $mysql_servers = undef, + Optional[Proxysql::User] $mysql_users = undef, + Optional[Proxysql::Hostgroup] $mysql_hostgroups = undef, + Optional[Proxysql::Rule] $mysql_rules = undef, + Optional[Proxysql::Scheduler] $schedulers = undef, ) inherits ::proxysql::params { # lint:ignore:80chars @@ -221,6 +232,7 @@ -> class { 'proxysql::config':} -> class { 'proxysql::service':} -> class { 'proxysql::admin_credentials':} + -> class { 'proxysql::configure':} -> anchor { 'proxysql::end': } Class['proxysql::install'] diff --git a/manifests/params.pp b/manifests/params.pp index bbe1fcd3..0bfa2714 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -131,6 +131,7 @@ $cluster_name = undef $cluster_username = 'cluster' $cluster_password = Sensitive('cluster') + $manage_hostgroup_for_servers = true $config_settings = { datadir => $datadir, diff --git a/spec/classes/proxysql_spec.rb b/spec/classes/proxysql_spec.rb index d0acff44..8499ba8d 100644 --- a/spec/classes/proxysql_spec.rb +++ b/spec/classes/proxysql_spec.rb @@ -18,13 +18,13 @@ it { is_expected.to contain_class('proxysql::install').that_comes_before('Class[proxysql::config]') } it { is_expected.to contain_class('proxysql::config').that_comes_before('Class[proxysql::service]') } it { is_expected.to contain_class('proxysql::service').that_comes_before('Class[proxysql::admin_credentials]') } - it { is_expected.to contain_class('proxysql::admin_credentials').that_comes_before('Anchor[proxysql::end]') } - - it { is_expected.to contain_class('proxysql::service').that_subscribes_to('Class[proxysql::install]') } + it { is_expected.to contain_class('proxysql::admin_credentials').that_comes_before('Class[proxysql::configure]') } + it { is_expected.to contain_class('proxysql::configure').that_comes_before('Anchor[proxysql::end]') } it { is_expected.to contain_anchor('proxysql::end') } it { is_expected.to contain_class('proxysql::install').that_notifies('Class[proxysql::service]') } + it { is_expected.to contain_class('proxysql::service').that_subscribes_to('Class[proxysql::install]') } it { is_expected.to contain_class('mysql::client').with(bindings_enable: false) } diff --git a/types/hostgroup.pp b/types/hostgroup.pp new file mode 100644 index 00000000..b24128e6 --- /dev/null +++ b/types/hostgroup.pp @@ -0,0 +1,4 @@ +# lint:ignore:2sp_soft_tabs +type Proxysql::Hostgroup = Array[Hash[String, Struct[{ writer => Integer, + reader => Integer, }],1,1]] +# lint:endignore diff --git a/types/rule.pp b/types/rule.pp new file mode 100644 index 00000000..4aa3787b --- /dev/null +++ b/types/rule.pp @@ -0,0 +1,27 @@ +# lint:ignore:2sp_soft_tabs +type Proxysql::Rule = Array[Hash[String, Struct[{ rule_id => Integer, + active => Integer, + Optional[username] => String[1], + Optional[schemaname] => String[1], + Optional[flag_in] => Integer, + Optional[flag_out] => Integer, + Optional[apply] => Integer, + Optional[client_addr] => String[1], + Optional[proxy_addr] => String[1], + Optional[proxy_port] => Integer, + Optional[digest] => String[1], + Optional[match_digest] => String[1], + Optional[match_pattern] => String[1], + Optional[replace_pattern] => String[1], + Optional[negate_match_pattern] => Boolean, + Optional[destination_hostgroup] => Integer, + Optional[cache_ttl] => Integer, + Optional[reconnect] => Boolean, + Optional[timeout] => Integer, + Optional[retries] => Integer, + Optional[delay] => Integer, + Optional[error_msg] => String[1], + Optional[log] => Boolean, + Optional[mirror_hostgroup] => Integer, + Optional[mirror_flag_out] => Integer, }],1,1]] +# lint:endignore diff --git a/types/scheduler.pp b/types/scheduler.pp new file mode 100644 index 00000000..fb47907c --- /dev/null +++ b/types/scheduler.pp @@ -0,0 +1,11 @@ +# lint:ignore:2sp_soft_tabs +type Proxysql::Scheduler = Array[Hash[String, Struct[{ scheduler_id => Integer, + active => Integer, + Optional[interval_ms] => Integer, + filename => String[1], + Optional[arg1] => String[1], + Optional[arg2] => String[1], + Optional[arg3] => String[1], + Optional[arg4] => String[1], + Optional[arg5] => String[1] }],1,1]] +# lint:endignore diff --git a/types/server.pp b/types/server.pp new file mode 100644 index 00000000..7e789818 --- /dev/null +++ b/types/server.pp @@ -0,0 +1,12 @@ +# lint:ignore:2sp_soft_tabs +type Proxysql::Server = Array[Hash[String, Struct[{ Optional[port] => Integer, + hostgroup_id => Integer, + Optional[status] => String[1], + Optional[weight] => Integer, + Optional[compression] => Integer, + Optional[max_connections] => Integer, + Optional[max_replication_lag] => Integer, + Optional[use_ssl] => Boolean, + Optional[max_latency_ms] => Integer, + Optional[comment] => String[1], }],1,1]] +# lint:endignore diff --git a/types/user.pp b/types/user.pp new file mode 100644 index 00000000..54424fff --- /dev/null +++ b/types/user.pp @@ -0,0 +1,13 @@ +# lint:ignore:2sp_soft_tabs +type Proxysql::User = Array[Hash[String, Struct[{ password => String[1], + default_hostgroup => Integer, + Optional[active] => Boolean, + Optional[use_ssl] => Boolean, + Optional[default_schema] => String[1], + Optional[schema_locked] => Boolean, + Optional[transaction_persistent] => Boolean, + Optional[fast_forward] => Boolean, + Optional[backend] => Boolean, + Optional[frontend] => Boolean, + Optional[max_connections] => Integer, }],1,1]] +# lint:endignore