module Jamf::Connection::ClassicAPI
This module defines methods used for interacting with the Classic API. This includes creating the Faraday connection, sending HTTP requests and handling responses
Public Instance Methods
Delete a resource from the Classic API
@param rsrc the resource to create, the URL part after ‘JSSResource/’
@return [String] the xml response from the server.
# File lib/jamf/api/connection/classic_api.rb 162 def c_delete(rsrc) 163 validate_connected 164 raise MissingDataError, 'Missing :rsrc' if rsrc.nil? 165 166 rsrc = rsrc.delete_prefix Jamf::Connection::SLASH 167 168 # delete the resource 169 resp = 170 @c_cnx.delete(rsrc) do |req| 171 req.headers[Jamf::Connection::HTTP_CONTENT_TYPE_HEADER] = Jamf::Connection::MIME_XML 172 req.headers[Jamf::Connection::HTTP_ACCEPT_HEADER] = Jamf::Connection::MIME_XML 173 end 174 @last_http_response = resp 175 176 unless resp.success? 177 handle_classic_http_error resp 178 return 179 end 180 181 resp.body 182 end
Get a Classic API resource via GET
The first argument is the resource to get (the part of the API url after the ‘JSSResource/’ ) The resource must be properly URL escaped beforehand. Note: URL.encode is deprecated, use CGI.escape
By default we get the data in JSON, and parse it into a ruby Hash
with symbolized Hash
keys.
If the second parameter is :xml then the XML version is retrieved and returned as a String
.
To get the raw JSON string as it comes from the API, pass raw_json: true
@param rsrc the resource to get
(the part of the API url after the 'JSSResource/' )
@param format either ;json or :xml
If the second argument is :xml, the XML data is returned as a String.
@param raw_json When GETting JSON, return the raw unparsed string
(the XML is always returned as a raw string)
@return [Hash,String] the result of the get
# File lib/jamf/api/connection/classic_api.rb 61 def c_get(rsrc, format = :json, raw_json: false) 62 rsrc = rsrc.delete_prefix Jamf::Connection::SLASH 63 64 validate_connected 65 raise Jamf::InvalidDataError, 'format must be :json or :xml' unless Jamf::Connection::GET_FORMATS.include?(format) 66 67 resp = 68 @c_cnx.get(rsrc) do |req| 69 req.headers[Jamf::Connection::HTTP_ACCEPT_HEADER] = format == :json ? Jamf::Connection::MIME_JSON : Jamf::Connection::MIME_XML 70 # puts "Classic API Cookie is: #{req.headers['Cookie']}" 71 end 72 @last_http_response = resp 73 unless resp.success? 74 handle_classic_http_error resp 75 return 76 end 77 78 return JSON.parse(resp.body, symbolize_names: true) if format == :json && !raw_json 79 80 # the raw body, either json or xml 81 resp.body 82 end
Create a new Classic API resource via POST
@param rsrc the API resource being created, the URL part after ‘JSSResource/’
@param xml the xml specifying the new object.
@return [String] the xml response from the server.
# File lib/jamf/api/connection/classic_api.rb 94 def c_post(rsrc, xml) 95 validate_connected 96 97 rsrc = rsrc.delete_prefix Jamf::Connection::SLASH 98 99 # convert CRs & to 100 xml&.gsub!(/\r/, ' ') 101 102 # send the data 103 resp = 104 @c_cnx.post(rsrc) do |req| 105 req.headers[Jamf::Connection::HTTP_CONTENT_TYPE_HEADER] = Jamf::Connection::MIME_XML 106 req.headers[Jamf::Connection::HTTP_ACCEPT_HEADER] = Jamf::Connection::MIME_XML 107 req.body = xml 108 end 109 @last_http_response = resp 110 111 unless resp.success? 112 handle_classic_http_error resp 113 return 114 end 115 116 resp.body 117 end
Update an existing Classic API resource
@param rsrc the API resource being changed, the URL part after ‘JSSResource/’
@param xml the xml specifying the changes.
@return [String] the xml response from the server.
# File lib/jamf/api/connection/classic_api.rb 129 def c_put(rsrc, xml) 130 validate_connected 131 132 rsrc = rsrc.delete_prefix Jamf::Connection::SLASH 133 134 # convert CRs & to 135 xml.gsub!(/\r/, ' ') 136 137 # send the data 138 resp = 139 @c_cnx.put(rsrc) do |req| 140 req.headers[Jamf::Connection::HTTP_CONTENT_TYPE_HEADER] = Jamf::Connection::MIME_XML 141 req.headers[Jamf::Connection::HTTP_ACCEPT_HEADER] = Jamf::Connection::MIME_XML 142 req.body = xml 143 end 144 @last_http_response = resp 145 146 unless resp.success? 147 handle_classic_http_error resp 148 return 149 end 150 151 resp.body 152 end
Upload a file. This is really only used for the ‘fileuploads’ endpoint of the classic API, as implemented in the Uploadable
mixin module, q.v.
@param rsrc the API resource being uploadad-to,
the URL part after 'JSSResource/'
@param local_file[String, Pathname] the local file to upload
@return [String] the xml response from the server.
# File lib/jamf/api/connection/classic_api.rb 197 def upload(rsrc, local_file) 198 validate_connected 199 rsrc = rsrc.delete_prefix Jamf::Connection::SLASH 200 201 payload = {} 202 payload[:name] = Faraday::Multipart::FilePart.new(local_file.to_s, 'application/octet-stream') 203 204 resp = @c_cnx.post rsrc, payload 205 206 @last_http_response = resp 207 208 unless resp.success? 209 handle_classic_http_error resp 210 return false 211 end 212 213 true 214 end
Private Instance Methods
create the faraday CAPI connection object
# File lib/jamf/api/connection/classic_api.rb 220 def create_classic_connection 221 Faraday.new(@c_base_url, ssl: ssl_options) do |cnx| 222 # use a proc for the token value, so its looked up on every request 223 # meaning we don't have to validate that the token is still valid before every request 224 # because the Token instance will (usually) refresh it automatically. 225 cnx.request :authorization, 'Bearer', -> { @token.token } 226 227 cnx.options[:timeout] = @timeout 228 cnx.options[:open_timeout] = @open_timeout 229 230 cnx.request :multipart 231 cnx.request :url_encoded 232 233 cnx.adapter :net_http 234 end 235 end
Parses the given http response and raises a Jamf::APIError with a useful error message.
@return [void]
# File lib/jamf/api/connection/classic_api.rb 242 def handle_classic_http_error(resp) 243 return if resp.success? 244 245 case resp.status 246 when 404 247 err = Jamf::NoSuchItemError 248 msg = 'Not Found' 249 when 409 250 err = Jamf::ConflictError 251 252 # TODO: Clean this up 253 resp.body =~ /<p>(The server has not .*?)(<|$)/m 254 msg = Regexp.last_match(1) 255 256 unless msg 257 resp.body =~ %r{<p>Error: (.*?)</p>} 258 msg = Regexp.last_match(1) 259 end 260 261 unless msg 262 resp.body =~ /<p>(Unable to complete file upload.*?)(<|$)/m 263 msg = Regexp.last_match(1) 264 end 265 when 400 266 err = Jamf::BadRequestError 267 resp.body =~ %r{>Bad Request</p>\n<p>(.*?)</p>\n<p>You can get technical detail}m 268 msg = Regexp.last_match(1) 269 when 401 270 if resp.body.include? 'INVALID_TOKEN' 271 err = Jamf::InvalidConnectionError 272 msg = 'Connection token is not valid' 273 else 274 err = Jamf::AuthorizationError 275 msg = 'You are not authorized to do that.' 276 end 277 when (500..599) 278 err = Jamf::APIRequestError 279 msg = 'There was an internal server error' 280 else 281 err = Jamf::APIRequestError 282 msg = "There was a error processing your request, status: #{resp.status}" 283 end 284 raise err, msg 285 end