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.
91 92 93 94 |
# File 'lib/jamf/db_connection.rb', line 91 def initialize @mysql = Mysql.init @connected = false end |
Instance Attribute Details
#connect_timeout ⇒ Object (readonly)
Returns the value of attribute connect_timeout.
89 90 91 |
# File 'lib/jamf/db_connection.rb', line 89 def connect_timeout @connect_timeout end |
#connected ⇒ Object (readonly) Also known as: connected?
Returns the value of attribute connected.
89 90 91 |
# File 'lib/jamf/db_connection.rb', line 89 def connected @connected end |
#db_name ⇒ Object (readonly)
Returns the value of attribute db_name.
89 90 91 |
# File 'lib/jamf/db_connection.rb', line 89 def db_name @db_name end |
#port ⇒ Object (readonly)
Returns the value of attribute port.
89 90 91 |
# File 'lib/jamf/db_connection.rb', line 89 def port @port end |
#read_timeout ⇒ Object (readonly)
Returns the value of attribute read_timeout.
89 90 91 |
# File 'lib/jamf/db_connection.rb', line 89 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.
89 90 91 |
# File 'lib/jamf/db_connection.rb', line 89 def socket @socket end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
89 90 91 |
# File 'lib/jamf/db_connection.rb', line 89 def user @user end |
#write_timeout ⇒ Object (readonly)
Returns the value of attribute write_timeout.
89 90 91 |
# File 'lib/jamf/db_connection.rb', line 89 def write_timeout @write_timeout end |
Instance Method Details
#connect(**args) ⇒ true
Connect to the JSS MySQL database.
127 128 129 130 131 132 133 134 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 |
# File 'lib/jamf/db_connection.rb', line 127 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] || hostname # settings from config if they aren't in the args args[:port] ||= Jamf.config.db_server_port || Mysql::MYSQL_TCP_PORT args[:socket] ||= Jamf.config.db_server_socket || DFT_SOCKET args[: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] || DFT_TIMEOUT args[:read_timeout] ||= args[:timeout] || DFT_TIMEOUT args[:write_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.
197 198 199 200 201 |
# File 'lib/jamf/db_connection.rb', line 197 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
207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/jamf/db_connection.rb', line 207 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
256 257 258 259 260 261 262 263 264 265 |
# File 'lib/jamf/db_connection.rb', line 256 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
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/jamf/db_connection.rb', line 226 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 |