@@ -48,8 +48,6 @@ import (
4848 "strings"
4949
5050 _ "embed"
51-
52- "github.com/deploymenttheory/go-api-http-client/internal/httpclient"
5351)
5452
5553// Endpoint constants represent the URL suffixes used for Jamf API token interactions.
@@ -104,9 +102,15 @@ type EndpointConfig struct {
104102
105103// JamfAPIHandler implements the APIHandler interface for the Jamf Pro API.
106104type JamfAPIHandler struct {
107- logger httpclient.Logger // logger is used to output logs for the API handling processes.
108- OverrideBaseDomain string // OverrideBaseDomain is used to override the base domain for URL construction.
109- InstanceName string // InstanceName is the name of the Jamf instance.
105+ OverrideBaseDomain string // OverrideBaseDomain is used to override the base domain for URL construction.
106+ InstanceName string // InstanceName is the name of the Jamf instance.
107+ }
108+
109+ type Logger interface {
110+ Debug (msg string , keysAndValues ... interface {})
111+ Info (msg string , keysAndValues ... interface {})
112+ Warn (msg string , keysAndValues ... interface {})
113+ Error (msg string , keysAndValues ... interface {})
110114}
111115
112116// Functions
@@ -121,18 +125,18 @@ func (j *JamfAPIHandler) GetBaseDomain() string {
121125}
122126
123127// ConstructAPIResourceEndpoint returns the full URL for a Jamf API resource endpoint path.
124- func (j * JamfAPIHandler ) ConstructAPIResourceEndpoint (endpointPath string ) string {
128+ func (j * JamfAPIHandler ) ConstructAPIResourceEndpoint (endpointPath string , logger Logger ) string {
125129 baseDomain := j .GetBaseDomain ()
126130 url := fmt .Sprintf ("https://%s%s%s" , j .InstanceName , baseDomain , endpointPath )
127- j . logger .Info ("Request will be made to API URL:" , "URL" , url )
131+ logger .Info ("Request will be made to API URL:" , "URL" , url )
128132 return url
129133}
130134
131135// ConstructAPIAuthEndpoint returns the full URL for a Jamf API auth endpoint path.
132- func (j * JamfAPIHandler ) ConstructAPIAuthEndpoint (endpointPath string ) string {
136+ func (j * JamfAPIHandler ) ConstructAPIAuthEndpoint (endpointPath string , logger Logger ) string {
133137 baseDomain := j .GetBaseDomain ()
134138 url := fmt .Sprintf ("https://%s%s%s" , j .InstanceName , baseDomain , endpointPath )
135- j . logger .Info ("Request will be made to API authentication URL:" , "URL" , url )
139+ logger .Info ("Request will be made to API authentication URL:" , "URL" , url )
136140 return url
137141}
138142
@@ -144,36 +148,36 @@ func (j *JamfAPIHandler) ConstructAPIAuthEndpoint(endpointPath string) string {
144148// - For url endpoints starting with "/api", it defaults to "application/json" for the JamfPro API.
145149// If the endpoint does not match any of the predefined patterns, "application/json" is used as a fallback.
146150// This method logs the decision process at various stages for debugging purposes.
147- func (u * JamfAPIHandler ) GetContentTypeHeader (endpoint string ) string {
151+ func (u * JamfAPIHandler ) GetContentTypeHeader (endpoint string , logger Logger ) string {
148152 // Dynamic lookup from configuration should be the first priority
149153 for key , config := range configMap {
150154 if strings .HasPrefix (endpoint , key ) {
151155 if config .ContentType != nil {
152- u . logger .Debug ("Content-Type for endpoint found in configMap" , "endpoint" , endpoint , "content_type" , * config .ContentType )
156+ logger .Debug ("Content-Type for endpoint found in configMap" , "endpoint" , endpoint , "content_type" , * config .ContentType )
153157 return * config .ContentType
154158 }
155- u . logger .Debug ("Content-Type for endpoint is nil in configMap, handling as special case" , "endpoint" , endpoint )
159+ logger .Debug ("Content-Type for endpoint is nil in configMap, handling as special case" , "endpoint" , endpoint )
156160 // If a nil ContentType is an expected case, do not set Content-Type header.
157161 return "" // Return empty to indicate no Content-Type should be set.
158162 }
159163 }
160164
161165 // If no specific configuration is found, then check for standard URL patterns.
162166 if strings .Contains (endpoint , "/JSSResource" ) {
163- u . logger .Debug ("Content-Type for endpoint defaulting to XML for Classic API" , "endpoint" , endpoint )
167+ logger .Debug ("Content-Type for endpoint defaulting to XML for Classic API" , "endpoint" , endpoint )
164168 return "application/xml" // Classic API uses XML
165169 } else if strings .Contains (endpoint , "/api" ) {
166- u . logger .Debug ("Content-Type for endpoint defaulting to JSON for JamfPro API" , "endpoint" , endpoint )
170+ logger .Debug ("Content-Type for endpoint defaulting to JSON for JamfPro API" , "endpoint" , endpoint )
167171 return "application/json" // JamfPro API uses JSON
168172 }
169173
170174 // Fallback to JSON if no other match is found.
171- u . logger .Debug ("Content-Type for endpoint not found in configMap or standard patterns, using default JSON" , "endpoint" , endpoint )
175+ logger .Debug ("Content-Type for endpoint not found in configMap or standard patterns, using default JSON" , "endpoint" , endpoint )
172176 return "application/json"
173177}
174178
175179// MarshalRequest encodes the request body according to the endpoint for the API.
176- func (u * JamfAPIHandler ) MarshalRequest (body interface {}, method string , endpoint string ) ([]byte , error ) {
180+ func (u * JamfAPIHandler ) MarshalRequest (body interface {}, method string , endpoint string , logger Logger ) ([]byte , error ) {
177181 var (
178182 data []byte
179183 err error
@@ -195,26 +199,26 @@ func (u *JamfAPIHandler) MarshalRequest(body interface{}, method string, endpoin
195199 }
196200
197201 if method == "POST" || method == "PUT" {
198- u . logger .Trace ("XML Request Body:" , "Body" , string (data ))
202+ logger .Debug ("XML Request Body:" , "Body" , string (data ))
199203 }
200204
201205 case "json" :
202206 data , err = json .Marshal (body )
203207 if err != nil {
204- u . logger .Error ("Failed marshaling JSON request" , "error" , err )
208+ logger .Error ("Failed marshaling JSON request" , "error" , err )
205209 return nil , err
206210 }
207211
208212 if method == "POST" || method == "PUT" || method == "PATCH" {
209- u . logger .Debug ("JSON Request Body:" , string (data ))
213+ logger .Debug ("JSON Request Body:" , string (data ))
210214 }
211215 }
212216
213217 return data , nil
214218}
215219
216220// UnmarshalResponse decodes the response body from XML or JSON format depending on the Content-Type header.
217- func (u * JamfAPIHandler ) UnmarshalResponse (resp * http.Response , out interface {}) error {
221+ func (u * JamfAPIHandler ) UnmarshalResponse (resp * http.Response , out interface {}, logger Logger ) error {
218222 // Handle DELETE method
219223 if resp .Request .Method == "DELETE" {
220224 if resp .StatusCode >= 200 && resp .StatusCode < 300 {
@@ -226,16 +230,16 @@ func (u *JamfAPIHandler) UnmarshalResponse(resp *http.Response, out interface{})
226230
227231 bodyBytes , err := io .ReadAll (resp .Body )
228232 if err != nil {
229- u . logger .Error ("Failed reading response body" , "error" , err )
233+ logger .Error ("Failed reading response body" , "error" , err )
230234 return err
231235 }
232236
233237 // Log the raw response body and headers
234- u . logger .Trace ("Raw HTTP Response:" , string (bodyBytes ))
235- u . logger .Debug ("Unmarshaling response" , "status" , resp .Status )
238+ logger .Trace ("Raw HTTP Response:" , string (bodyBytes ))
239+ logger .Debug ("Unmarshaling response" , "status" , resp .Status )
236240
237241 // Log headers when in debug mode
238- u . logger .Debug ("HTTP Response Headers:" , resp .Header )
242+ logger .Debug ("HTTP Response Headers:" , resp .Header )
239243
240244 // Check the Content-Type and Content-Disposition headers
241245 contentType := resp .Header .Get ("Content-Type" )
@@ -249,7 +253,7 @@ func (u *JamfAPIHandler) UnmarshalResponse(resp *http.Response, out interface{})
249253 // If content type is HTML, extract the error message
250254 if strings .Contains (contentType , "text/html" ) {
251255 errMsg := ExtractErrorMessageFromHTML (string (bodyBytes ))
252- u . logger .Warn ("Received HTML content" , "error_message" , errMsg , "status_code" , resp .StatusCode )
256+ logger .Warn ("Received HTML content" , "error_message" , errMsg , "status_code" , resp .StatusCode )
253257 return & APIError {
254258 StatusCode : resp .StatusCode ,
255259 Message : errMsg ,
@@ -289,12 +293,12 @@ func (u *JamfAPIHandler) UnmarshalResponse(resp *http.Response, out interface{})
289293 // If unmarshalling fails, check if the content might be HTML
290294 if strings .Contains (string (bodyBytes ), "<html>" ) {
291295 errMsg := ExtractErrorMessageFromHTML (string (bodyBytes ))
292- u . logger .Warn ("Received HTML content instead of expected format" , "error_message" , errMsg , "status_code" , resp .StatusCode )
296+ logger .Warn ("Received HTML content instead of expected format" , "error_message" , errMsg , "status_code" , resp .StatusCode )
293297 return fmt .Errorf (errMsg )
294298 }
295299
296300 // Log the error and return it
297- u . logger .Error ("Failed to unmarshal response" , "error" , err )
301+ logger .Error ("Failed to unmarshal response" , "error" , err )
298302 return fmt .Errorf ("failed to unmarshal response: %v" , err )
299303 }
300304
0 commit comments