Class: Jamf::DBConnection
- Includes:
- Singleton
- Defined in:
- lib/jamf/db_connection.rb
Overview
A mysql connection to the JSS database.
This is a singleton class, only one can exist at a time, and it is created, but not connected, automatically when the module loads.
Use it via the Jamf::DB_CNX constant (for connection metadata) and the Jamf::DB_CNX.db attribute (which contains the actual mysql query interface) for making queries
Direct MySQL access is minimal and discouraged, since it bypasses the API, and can be very dangerous. However, it's necessary to overcome some limitations of the API or to access custom tables.
While a database connction isn't required for most things, warnings will be sent to stderr when functionality is limited due to a lack of a database connection i.e. when Jamf::DB_CNX.connected? == false
To make a connection with credentials, just call the #connect method thus:
Jamf::DB_CNX.connect :server => 'server.company.com', :user => "user", :pw => "pw"
Other options include:
:db_name => which database to connect to, defaults to 'jamfsoftware'
:port => tcp port for connection to server, defaults to the standard mysql port.
:connect_timeout => seconds to wait before giving up on connection, defaults to 120
:read_timeout => seconds to wait before giving up on recieving data, defaults to 120
:write_timeout => seconds to wait before giving up on sending data, defaults to 120
:timeout => sets all three timeouts to the same value, defaults to 120
Calling Jamf::DB_CNX.connect again will re-use any values not provided. but will create a new connection.
Constant Summary collapse
- DEFAULT_DB_NAME =
The name of the JSS database on the mysql server
'jamfsoftware'.freeze
- DFT_TIMEOUT =
give the connection a 60 second timeout, for really slow net connections (likeā¦ from airplanes)
60
- DFT_SOCKET =
'/var/mysql/mysql.sock'.freeze
- DFT_PORT =
the default MySQL port
3306
- DFT_CHARSET =
The default encoding in the tables - JAMF wisely uses UTF-8
'utf8'.freeze
- SQL_DATE_FORMAT =
the strftime format for reading/writing dates in the db
'%Y-%m-%d %H:%M:%S'.freeze
Instance Attribute Summary collapse
-
#connect_timeout ⇒ Object
readonly
Returns the value of attribute connect_timeout.
-
#connected ⇒ Object
(also: #connected?)
readonly
Returns the value of attribute connected.
-
#db_name ⇒ Object
readonly
Returns the value of attribute db_name.
-
#port ⇒ Object
readonly
Returns the value of attribute port.
-
#read_timeout ⇒ Object
readonly
Returns the value of attribute read_timeout.
-
#server ⇒ Object
readonly
Returns the value of attribute server.
-
#socket ⇒ Object
readonly
Returns the value of attribute socket.
-
#user ⇒ Object
readonly
Returns the value of attribute user.
-
#write_timeout ⇒ Object
readonly
Returns the value of attribute write_timeout.
Instance Method Summary collapse
-
#connect(**args) ⇒ true
Connect to the JSS MySQL database.
-
#db ⇒ Mysql
The mysql database connection itself.
-
#disconnect ⇒ Object
close the connection to the database it'll have to be re-connected before using again.
-
#hostname ⇒ String
The server to which we are connected, or will try connecting to if none is specified with the call to #connect.
-
#initialize ⇒ DBConnection
constructor
A new instance of DBConnection.
-
#valid_server?(server, port = DFT_PORT) ⇒ Boolean
Test that a given hostname is a MySQL server.
Constructor Details
#initialize ⇒ DBConnection
Returns a new instance of DBConnection.
99 100 101 102 |
# File 'lib/jamf/db_connection.rb', line 99 def initialize @mysql = Mysql.init @connected = false end |
Instance Attribute Details
#connect_timeout ⇒ Object (readonly)
Returns the value of attribute connect_timeout.
94 95 96 |
# File 'lib/jamf/db_connection.rb', line 94 def connect_timeout @connect_timeout end |
#connected ⇒ Object (readonly) Also known as: connected?
Returns the value of attribute connected.
97 98 99 |
# File 'lib/jamf/db_connection.rb', line 97 def connected @connected end |
#db_name ⇒ Object (readonly)
Returns the value of attribute db_name.
93 94 95 |
# File 'lib/jamf/db_connection.rb', line 93 def db_name @db_name end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
90 91 92 |
# File 'lib/jamf/db_connection.rb', line 90 def port @port end |
#read_timeout ⇒ Object (readonly)
Returns the value of attribute read_timeout.
95 96 97 |
# File 'lib/jamf/db_connection.rb', line 95 def read_timeout @read_timeout end |
#server ⇒ Object (readonly)
Returns the value of attribute server.
89 90 91 |
# File 'lib/jamf/db_connection.rb', line 89 def server @server end |
#socket ⇒ Object (readonly)
Returns the value of attribute socket.
91 92 93 |
# File 'lib/jamf/db_connection.rb', line 91 def socket @socket end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
92 93 94 |
# File 'lib/jamf/db_connection.rb', line 92 def user @user end |
#write_timeout ⇒ Object (readonly)
Returns the value of attribute write_timeout.
96 97 98 |
# File 'lib/jamf/db_connection.rb', line 96 def write_timeout @write_timeout end |
Instance Method Details
#connect(**args) ⇒ true
Connect to the JSS MySQL database.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/jamf/db_connection.rb', line 135 def connect(**args) begin disconnect if @connected rescue Mysql::ClientError::ServerGoneError @connected = false end # server might come frome several places # if not given in the args, use #hostname to figure out # which @server = args[:server] ? args[:server] : hostname # settings from config if they aren't in the args args[:port] ||= Jamf.config.db_server_port ? Jamf.config.db_server_port : Mysql::MYSQL_TCP_PORT args[:socket] ||= Jamf.config.db_server_socket ? Jamf.config.db_server_socket : DFT_SOCKET args[:db_name] ||= Jamf.config.db_name ? Jamf.config.db_name : DEFAULT_DB_NAME args[:user] ||= Jamf.config.db_username args[:connect_timeout] ||= Jamf.config.db_connect_timeout args[:read_timeout] ||= Jamf.config.db_read_timeout args[:write_timeout] ||= Jamf.config.db_write_timeout args[:charset] ||= DFT_CHARSET ### if one timeout was given, use it for all three args[:connect_timeout] ||= args[:timeout] ? args[:timeout] : DFT_TIMEOUT args[:read_timeout] ||= args[:timeout] ? args[:timeout] : DFT_TIMEOUT args[:write_timeout] ||= args[:timeout] ? args[:timeout] : DFT_TIMEOUT @port = args[:port] @socket = args[:socket] @mysql_name = args[:db_name] @user = args[:user] @connect_timeout = args[:connect_timeout] @read_timeout = args[:read_timeout] @write_timeout = args[:write_timeout] # make sure we have a user, pw, server raise Jamf::MissingDataError, 'No MySQL user specified, or defined in configuration.' unless args[:user] raise Jamf::MissingDataError, "Missing :pw (or :prompt/:stdin) for user '#{@user}'" unless args[:pw] raise Jamf::MissingDataError, 'No MySQL Server hostname specified, or listed in configuration.' unless @server @pw = if args[:pw] == :prompt JSS.prompt_for_password "Enter the password for the MySQL user #{@user}@#{@server}:" elsif args[:pw].is_a?(Symbol) && args[:pw].to_s.start_with?('stdin') args[:pw].to_s =~ /^stdin(\d+)$/ line = Regexp.last_match(1) line ||= 2 JSS.stdin line else args[:pw] end @mysql = Mysql.init @mysql. Mysql::OPT_CONNECT_TIMEOUT, @connect_timeout @mysql. Mysql::OPT_READ_TIMEOUT, @read_timeout @mysql. Mysql::OPT_WRITE_TIMEOUT, @write_timeout @mysql.charset = args[:charset] @mysql.connect @server, @user, @pw, @mysql_name, @port, @socket @connected = true @server rescue Mysql::ServerError::NotSupportedAuthMode => e raise Mysql::ServerError::AccessDeniedError, "Probable unknown MySQL user '#{@user}'. Original error was 'Mysql::ServerError::NotSupportedAuthMode: #{e}' which is sometimes raised when the user does not exist on the server." end |
#db ⇒ Mysql
Returns The mysql database connection itself.
204 205 206 207 |
# File 'lib/jamf/db_connection.rb', line 204 def db raise Jamf::InvalidConnectionError, 'No database connection. Please use Jamf::DB_CNX.connect' unless Jamf::DB_CNX.connected? @mysql end |
#disconnect ⇒ Object
close the connection to the database it'll have to be re-connected before using again
213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/jamf/db_connection.rb', line 213 def disconnect @mysql.close! if @mysql.protocol @server = nil @port = nil @socket = nil @user = nil @connection_timeout = DFT_TIMEOUT @read_timeout = DFT_TIMEOUT @write_timeout = DFT_TIMEOUT @connected = false nil end |
#hostname ⇒ String
The server to which we are connected, or will try connecting to if none is specified with the call to #connect
263 264 265 266 267 268 269 270 271 |
# File 'lib/jamf/db_connection.rb', line 263 def hostname # return it if already set return @server if @server # otherwise, from the config srvr = Jamf.config.db_server_name # otherwise, assume its on the JSS server to which this client talks srvr ||= Jamf::Client.jss_server srvr end |
#valid_server?(server, port = DFT_PORT) ⇒ Boolean
Test that a given hostname is a MySQL server
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/jamf/db_connection.rb', line 232 def valid_server?(server, port = DFT_PORT) mysql = Mysql.init mysql. Mysql::OPT_CONNECT_TIMEOUT, 60 mysql.charset = DFT_CHARSET begin # this connection should get an access denied error if there is # a mysql server there. I'm assuming no one will use this username # and pw for anything real # Also with newer versions of mysql, a Mysql instance that has # never authenticated will raise Mysql::ServerError::NotSupportedAuthMode # rather than Mysql::ServerError::AccessDeniedError, until a # successful connection is made. After that, re-connecting will # raise AccessDeniedError when credentials are invalid. mysql.connect server, 'notArealUser', "definatelyNotA#{$PROCESS_ID}password", 'not_a_db', port rescue Mysql::ServerError::AccessDeniedError, Mysql::ServerError::NotSupportedAuthMode return true rescue return false end false end |