/* ** Copyright (C) 2001-2025 Zabbix SIA ** ** This program is free software: you can redistribute it and/or modify it under the terms of ** the GNU Affero General Public License as published by the Free Software Foundation, version 3. ** ** This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU Affero General Public License for more details. ** ** You should have received a copy of the GNU Affero General Public License along with this program. ** If not, see <https://www.gnu.org/licenses/>. **/ package mysql import ( "context" "golang.zabbix.com/sdk/errs" "golang.zabbix.com/sdk/metric" "golang.zabbix.com/sdk/plugin" "golang.zabbix.com/sdk/uri" ) const ( keyCustomQuery = "mysql.custom.query" keyDatabasesDiscovery = "mysql.db.discovery" keyDatabaseSize = "mysql.db.size" keyPing = "mysql.ping" keyReplicationDiscovery = "mysql.replication.discovery" keyReplicationSlaveStatus = "mysql.replication.get_slave_status" keyStatusVars = "mysql.get_status_variables" keyVersion = "mysql.version" uriParam = "URI" tlsConnectParam = "TLSConnect" tlsCAParam = "TLSCAFile" tlsCertParam = "TLSCertFile" tlsKeyParam = "TLSKeyFile" masterHostParam = "Master" ) var ( uriDefaults = &uri.Defaults{Scheme: "tcp", Port: "3306"} // Common params: [URI|Session][,User][,Password] paramURI = metric.NewConnParam(uriParam, "URI to connect or session name."). WithDefault(uriDefaults.Scheme + "://localhost:" + uriDefaults.Port).WithSession(). WithValidator(uri.URIValidator{Defaults: uriDefaults, AllowedSchemes: []string{"tcp", "unix"}}) paramUsername = metric.NewConnParam("User", "MySQL user.").WithDefault("root") paramPassword = metric.NewConnParam("Password", "User's password.").WithDefault("") paramTLSConnect = metric.NewSessionOnlyParam("TLSConnect", "DB connection encryption type.").WithDefault("") paramTLSCaFile = metric.NewSessionOnlyParam("TLSCAFile", "TLS ca file path.").WithDefault("") paramTLSCertFile = metric.NewSessionOnlyParam("TLSCertFile", "TLS cert file path.").WithDefault("") paramTLSKeyFile = metric.NewSessionOnlyParam("TLSKeyFile", "TLS key file path.").WithDefault("") metrics = metric.MetricSet{ keyCustomQuery: metric.New("Returns result of a custom query.", []*metric.Param{ paramURI, paramUsername, paramPassword, metric.NewParam("QueryName", "Name of a custom query "+ "(must be equal to a name of an SQL file without an extension).").SetRequired(), paramTLSConnect, paramTLSCaFile, paramTLSCertFile, paramTLSKeyFile, }, true), keyDatabasesDiscovery: metric.New("Returns list of databases in LLD format.", []*metric.Param{ paramURI, paramUsername, paramPassword, paramTLSConnect, paramTLSCaFile, paramTLSCertFile, paramTLSKeyFile, }, false), keyDatabaseSize: metric.New("Returns size of given database in bytes.", []*metric.Param{ paramURI, paramUsername, paramPassword, metric.NewParam("Database", "Database name.").SetRequired(), paramTLSConnect, paramTLSCaFile, paramTLSCertFile, paramTLSKeyFile, }, false), keyPing: metric.New("Tests if connection is alive or not.", []*metric.Param{ paramURI, paramUsername, paramPassword, paramTLSConnect, paramTLSCaFile, paramTLSCertFile, paramTLSKeyFile, }, false), keyReplicationDiscovery: metric.New("Returns replication information in LLD format.", []*metric.Param{ paramURI, paramUsername, paramPassword, paramTLSConnect, paramTLSCaFile, paramTLSCertFile, paramTLSKeyFile, }, false), keyReplicationSlaveStatus: metric.New("Returns replication status.", []*metric.Param{ paramURI, paramUsername, paramPassword, metric.NewParam(masterHostParam, "Master host."), paramTLSConnect, paramTLSCaFile, paramTLSCertFile, paramTLSKeyFile, }, false), keyStatusVars: metric.New("Returns values of global status variables.", []*metric.Param{ paramURI, paramUsername, paramPassword, paramTLSConnect, paramTLSCaFile, paramTLSCertFile, paramTLSKeyFile, }, false), keyVersion: metric.New("Returns MySQL version.", []*metric.Param{ paramURI, paramUsername, paramPassword, paramTLSConnect, paramTLSCaFile, paramTLSCertFile, paramTLSKeyFile, }, false), } ) // handlerFunc defines an interface must be implemented by handlers. type handlerFunc func( ctx context.Context, conn MyClient, params map[string]string, extraParams ...string, ) (res interface{}, err error) func init() { err := plugin.RegisterMetrics(&impl, pluginName, metrics.List()...) if err != nil { panic(errs.Wrap(err, "failed to register metrics")) } } // getHandlerFunc returns a handlerFunc related to a given key. func getHandlerFunc(key string) handlerFunc { switch key { case keyCustomQuery: return customQueryHandler case keyDatabasesDiscovery: return databasesDiscoveryHandler case keyDatabaseSize: return databaseSizeHandler case keyPing: return pingHandler case keyReplicationDiscovery: return replicationDiscoveryHandler case keyReplicationSlaveStatus: return replicationSlaveStatusHandler case keyStatusVars: return statusVarsHandler case keyVersion: return versionHandler default: return nil } }