Class: JSS::APIConnection
- Inherits:
-
Object
- Object
- JSS::APIConnection
- Includes:
- Singleton
- Defined in:
- lib/jss/api_connection.rb,
lib/jss.rb
Overview
An API connection to the JSS.
This is a singleton class, only one can exist at a time. Its one instance is created automatically when the module loads, but it isn’t connected to anything at that time.
Use it via the API constant to call the #connect method, and the #get_rsrc, #put_rsrc, #post_rsrc, & #delete_rsrc methods, q.v. below.
To access the underlying RestClient::Resource instance, use JSS::API.cnx
Constant Summary collapse
- RSRC_BASE =
The base API path in the jss URL
"JSSResource"- TEST_PATH =
A url path to load to see if there’s an API available at a host. This just loads the API resource docs page
"#{RSRC_BASE}/accounts"- TEST_CONTENT =
If the test path loads correctly from a casper server, it’ll contain this text (this is what we get when we make an unauthenticated API call.)
"<p>The request requires user authentication</p>"- HTTP_PORT =
The Default port
9006- SSL_PORT =
The SSL port
8443- XML_HEADER =
The top line of an XML doc for submitting data via API
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>'- DFT_OPEN_TIMEOUT =
Default timeouts in seconds
60- DFT_TIMEOUT =
60- DFT_SSL_VERSION =
The Default SSL Version
'TLSv1'
Instance Attribute Summary collapse
-
#cnx ⇒ RestClient::Resource
readonly
The underlying connection resource.
-
#connected ⇒ Boolean
(also: #connected?)
readonly
Are we connected right now?.
-
#jss_user ⇒ String
readonly
The username who’s connected to the JSS API.
-
#server ⇒ JSS::Server
readonly
The details of the JSS to which we’re connected.
-
#server_host ⇒ String
readonly
The hostname of the JSS to which we’re connected.
Instance Method Summary collapse
-
#connect(args = {}) ⇒ true
Connect to the JSS API.
-
#delete_rsrc(rsrc) ⇒ String
Delete a resource from the JSS.
-
#disconnect ⇒ void
With a REST connection, there isn’t any real “connection” to disconnect from So to disconnect, we just unset all our credentials.
-
#get_rsrc(rsrc, format = :json) ⇒ Hash, String
Get an arbitrary JSS resource.
-
#hostname ⇒ String
The server to which we are connected, or will try connecting to if none is specified with the call to #connect.
-
#initialize ⇒ APIConnection
constructor
To connect, use JSS::APIConnection.instance.connect or a shortcut, JSS::API.connect.
-
#open_timeout=(timeout) ⇒ void
Reset the open-connection timeout for the rest connection.
-
#post_rsrc(rsrc, xml) ⇒ String
Create a new JSS resource.
-
#put_rsrc(rsrc, xml) ⇒ String
Change an existing JSS resource.
-
#timeout=(timeout) ⇒ void
Reset the response timeout for the rest connection.
-
#to_s ⇒ String
A useful string about this connection.
-
#valid_server?(server, port = SSL_PORT) ⇒ Boolean
Test that a given hostname & port is a JSS API server.
Constructor Details
#initialize ⇒ APIConnection
To connect, use JSS::APIConnection.instance.connect or a shortcut, JSS::API.connect
121 122 123 |
# File 'lib/jss/api_connection.rb', line 121 def initialize () @connected = false end |
Instance Attribute Details
#cnx ⇒ RestClient::Resource (readonly)
Returns the underlying connection resource.
102 103 104 |
# File 'lib/jss/api_connection.rb', line 102 def cnx @cnx end |
#connected ⇒ Boolean (readonly) Also known as: connected?
Returns are we connected right now?.
105 106 107 |
# File 'lib/jss/api_connection.rb', line 105 def connected @connected end |
#jss_user ⇒ String (readonly)
Returns the username who’s connected to the JSS API.
99 100 101 |
# File 'lib/jss/api_connection.rb', line 99 def jss_user @jss_user end |
#server ⇒ JSS::Server (readonly)
Returns the details of the JSS to which we’re connected.
108 109 110 |
# File 'lib/jss/api_connection.rb', line 108 def server @server end |
#server_host ⇒ String (readonly)
Returns the hostname of the JSS to which we’re connected.
111 112 113 |
# File 'lib/jss/api_connection.rb', line 111 def server_host @server_host end |
Instance Method Details
#connect(args = {}) ⇒ true
Connect to the JSS API.
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 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/jss/api_connection.rb', line 158 def connect (args = {}) # the server, if not specified, might come from a couple places. # see #hostname args[:server] ||= hostname # settings from config if they aren't in the args args[:server] ||= JSS::CONFIG.api_server_name args[:port] ||= JSS::CONFIG.api_server_port args[:user] ||= JSS::CONFIG.api_username args[:timeout] ||= JSS::CONFIG.api_timeout args[:open_timeout] ||= JSS::CONFIG.api_timeout_open args[:ssl_version] ||= JSS::CONFIG.api_ssl_version # if verify cert given was NOT in the args.... if args[:verify_cert].nil? # set it from the prefs args[:verify_cert] = JSS::CONFIG.api_verify_cert end # settings from client jamf plist if needed args[:port] ||= JSS::Client.jss_port # default settings if needed args[:port] ||= SSL_PORT args[:timeout] ||= DFT_TIMEOUT args[:open_timeout] ||= DFT_OPEN_TIMEOUT # As of Casper 9.61 we can't use SSL, must use TLS, since SSLv3 was susceptible to poodles. # NOTE - this requires rest-client v 1.7.0 or higher # which requires mime-types 2.0 or higher, which requires ruby 1.9.2 or higher! # That means that support for ruby 1.8.7 stops with Casper 9.6 args[:ssl_version] ||= DFT_SSL_VERSION # must have server, user, and pw raise JSS::MissingDataError, "No JSS :server specified, or in configuration." unless args[:server] raise JSS::MissingDataError, "No JSS :user specified, or in configuration." unless args[:user] raise JSS::MissingDataError, "Missing :pw for user '#{args[:user]}'" unless args[:pw] # we're using ssl if 1) args[:use_ssl] is anything but false # or 2) the port is the default casper ssl port. args[:use_ssl] = (not args[:use_ssl] == false) or (args[:port] == SSL_PORT) # and here's the URL ssl = args[:use_ssl] ? "s" : '' @rest_url = URI::encode "http#{ssl}://#{args[:server]}:#{args[:port]}/#{RSRC_BASE}" # prep the args for passing to RestClient::Resource # if verify_cert is anything but false, we will verify args[:verify_ssl] = (args[:verify_cert] == false) ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER args[:password] = if args[:pw] == :prompt JSS.prompt_for_password "Enter the password for JSS user #{args[:user]}@#{args[:server]}:" elsif args[:pw].is_a?(Symbol) and args[:pw].to_s.start_with?('stdin') args[:pw].to_s =~ /^stdin(\d+)$/ line = $1 line ||= 1 JSS.stdin line else args[:pw] end # heres our connection @cnx = RestClient::Resource.new("#{@rest_url}", args) @jss_user = args[:user] @server_host = args[:server] @connected = true @server = JSS::Server.new if @server.version < JSS.parse_jss_version(JSS::MINIMUM_SERVER_VERSION)[:version] raise JSS::UnsupportedError, "Your JSS Server version, #{@server.raw_version}, is to low. Must be #{JSS::MINIMUM_SERVER_VERSION} or higher." end return @connected ? @server_host : nil end |
#delete_rsrc(rsrc) ⇒ String
Delete a resource from the JSS
352 353 354 355 356 357 358 359 |
# File 'lib/jss/api_connection.rb', line 352 def delete_rsrc(rsrc) raise JSS::InvalidConnectionError, "Not Connected. Use JSS::API.connect first." unless @connected raise MissingDataError, "Missing :rsrc" if rsrc.nil? ### delete the resource @cnx[rsrc].delete end |
#disconnect ⇒ void
This method returns an undefined value.
With a REST connection, there isn’t any real “connection” to disconnect from So to disconnect, we just unset all our credentials.
274 275 276 277 278 279 280 |
# File 'lib/jss/api_connection.rb', line 274 def disconnect @jss_user = nil @rest_url = nil @server_host = nil @cnx = nil @connected = false end |
#get_rsrc(rsrc, format = :json) ⇒ Hash, String
Get an arbitrary JSS resource
The first argument is the resource to get (the part of the API url after the ‘JSSResource/’ )
By default we get the data in JSON, and parse it into a ruby data structure (arrays, hashes, strings, etc) with symbolized Hash keys.
300 301 302 303 304 305 306 |
# File 'lib/jss/api_connection.rb', line 300 def get_rsrc (rsrc, format = :json) raise JSS::InvalidConnectionError, "Not Connected. Use JSS::API.connect first." unless @connected rsrc = URI::encode rsrc data = @cnx[rsrc].get(:accept => format) return JSON.parse(data, :symbolize_names => true) if format == :json data end |
#hostname ⇒ String
The server to which we are connected, or will try connecting to if none is specified with the call to #connect
402 403 404 405 406 407 |
# File 'lib/jss/api_connection.rb', line 402 def hostname return @server_host if @server_host srvr = JSS::CONFIG.api_server_name srvr ||= JSS::Client.jss_server return srvr end |
#open_timeout=(timeout) ⇒ void
This method returns an undefined value.
Reset the open-connection timeout for the rest connection
263 264 265 |
# File 'lib/jss/api_connection.rb', line 263 def open_timeout= (timeout) @cnx.[:open_timeout] = timeout end |
#post_rsrc(rsrc, xml) ⇒ String
Create a new JSS resource
336 337 338 339 340 341 342 343 344 |
# File 'lib/jss/api_connection.rb', line 336 def post_rsrc(rsrc,xml) raise JSS::InvalidConnectionError, "Not Connected. Use JSS::API.connect first." unless @connected ### convert CRs & to xml.gsub!(/\r/, ' ') ### send the data @cnx[rsrc].post xml, :content_type => 'text/xml', :accept => :json end |
#put_rsrc(rsrc, xml) ⇒ String
Change an existing JSS resource
317 318 319 320 321 322 323 324 325 |
# File 'lib/jss/api_connection.rb', line 317 def put_rsrc(rsrc,xml) raise JSS::InvalidConnectionError, "Not Connected. Use JSS::API.connect first." unless @connected ### convert CRs & to xml.gsub!(/\r/, ' ') ### send the data @cnx[rsrc].put(xml, :content_type => 'text/xml') end |
#timeout=(timeout) ⇒ void
This method returns an undefined value.
Reset the response timeout for the rest connection
252 253 254 |
# File 'lib/jss/api_connection.rb', line 252 def timeout= (timeout) @cnx.[:timeout] = timeout end |
#to_s ⇒ String
A useful string about this connection
241 242 243 |
# File 'lib/jss/api_connection.rb', line 241 def to_s @connected ? "Using #{@rest_url} as user #{@jss_user}" : "not connected" end |
#valid_server?(server, port = SSL_PORT) ⇒ Boolean
Test that a given hostname & port is a JSS API server
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
# File 'lib/jss/api_connection.rb', line 370 def valid_server? (server, port = SSL_PORT) # cheating by shelling out to curl, because getting open-uri, or even net/http to use # ssl_options like :OP_NO_SSLv2 and :OP_NO_SSLv3 will take time to figure out.. return true if `/usr/bin/curl -s 'https://#{server}:#{port}/#{TEST_PATH}'`.include? TEST_CONTENT return true if `/usr/bin/curl -s 'http://#{server}:#{port}/#{TEST_PATH}'`.include? TEST_CONTENT return false # try ssl first # NOTE: doesn't work if we can't disallow SSLv3 or force TLSv1 # See cheat above. begin return true if open("https://#{server}:#{port}/#{TEST_PATH}", ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE).read.include? TEST_CONTENT rescue # then regular http begin return true if open("http://#{server}:#{port}/#{TEST_PATH}").read.include? TEST_CONTENT rescue # any errors = no API return false end # begin end #begin # if we're here, no API return false end |