lib/jss-api/api_connection.rb in jss-api-0.5.8 vs lib/jss-api/api_connection.rb in jss-api-0.6.1
- old
+ new
@@ -1,6 +1,6 @@
-### Copyright 2014 Pixar
+### Copyright 2016 Pixar
###
### Licensed under the Apache License, Version 2.0 (the "Apache License")
### with the following modification; you may not use this file except in
### compliance with the Apache License and the following modification to it:
### Section 6. Trademarks. is deleted and replaced with:
@@ -61,12 +61,20 @@
#####################################
### Class Constants
#####################################
### The base API path in the jss URL
- RSRC = "JSSResource"
-
+ RSRC_BASE = "JSSResource"
+
+ ### A url path to load to see if there's an API available at a host.
+ ### This just loads the API resource docs page
+ TEST_PATH = "api"
+
+ ### If the test path loads correctly from a casper server, it'll contain
+ ### this text
+ TEST_CONTENT = "<title>JSS REST API Resource Documentation</title>"
+
### The Default port
HTTP_PORT = 9006
### The SSL port
SSL_PORT = 8443
@@ -95,10 +103,13 @@
attr_reader :connected
### @return [JSS::Server] the details of the JSS to which we're connected.
attr_reader :server
+ ### @return [String] the hostname of the JSS to which we're connected.
+ attr_reader :server_host
+
#####################################
### Constructor
#####################################
###
@@ -120,10 +131,12 @@
###
### @option args :server[String] the hostname of the JSS API server, required if not defined in JSS::CONFIG
###
### @option args :port[Integer] the port number to connect with, defaults to 8443
###
+ ### @option args :use_ssl[Boolean] should the connection be made over SSL? Defaults to true.
+ ###
### @option args :verify_cert[Boolean] should HTTPS SSL certificates be verified. Defaults to true.
### If your connection raises RestClient::SSLCertificateNotVerified, and you don't care about the
### validity of the SSL cert. just set this explicitly to false.
###
### @option args :user[String] a JSS user who has API privs, required if not defined in JSS::CONFIG
@@ -139,11 +152,15 @@
### @option args :timeout[Integer] the number of seconds before an API call times out, defaults to 60
###
### @return [true]
###
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
@@ -153,11 +170,14 @@
# 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
@@ -171,17 +191,22 @@
# 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]
- # ssl or not?
- ssl = SSL_PORT == args[:port].to_i ? "s" : ''
- @rest_url = URI::encode "http#{ssl}://#{args[:server]}:#{args[:port]}/#{RSRC}"
+ # 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 nil (unset) or non-false, then we will verify
- args[:verify_ssl] = (args[:verify_cert].nil? or args[:verify_cert]) ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
+ # 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+)$/
@@ -190,24 +215,23 @@
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 true
+ return @connected ? @server_host : nil
end # connect
###
### Reset the response timeout for the rest connection
###
@@ -238,10 +262,11 @@
### @return [void]
###
def disconnect
@jss_user = nil
@rest_url = nil
+ @server_host = nil
@cnx = nil
@connected = false
end # disconnect
###
@@ -306,11 +331,10 @@
### send the data
@cnx[rsrc].post xml, :content_type => 'text/xml', :accept => :json
end #post_rsrc
- ###
### Delete a resource from the JSS
###
### @param rsrc[String] the resource to create, the URL part after 'JSSResource/'
###
### @return [String] the xml response from the server.
@@ -321,10 +345,49 @@
### delete the resource
@cnx[rsrc].delete
end #delete_rsrc
-
+
+
+ ### Test that a given hostname & port is a JSS API server
+ ###
+ ### @param server[String] The hostname to test,
+ ###
+ ### @param port[Integer] The port to try connecting on
+ ###
+ ### @return [Boolean] does the server host a JSS API?
+ ###
+ def valid_server? (server, port = SSL_PORT)
+ # try ssl first
+ 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
+
+ ### The server to which we are connected, or will
+ ### try connecting to if none is specified with the
+ ### call to #connect
+ ###
+ ### @return [String] the hostname of the server
+ ###
+ def hostname
+ return @server_host if @server_host
+ srvr = JSS::CONFIG.api_server_name
+ srvr ||= JSS::Client.jss_server
+ return srvr
+ end
+
### aliases
alias connected? connected
end # class JSSAPIConnection