From 4dd7d1a46ca2a67f151702d2153a15bd76e9429d Mon Sep 17 00:00:00 2001 From: Jesse Peterson Date: Mon, 8 Sep 2025 12:26:53 -0700 Subject: [PATCH 1/7] abm structs generated from apple-device-services repo --- goaxm/abm.go | 15 +++ goaxm/abm/abm.go | 245 ++++++++++++++++++++++++++++++++++++++++++ goaxm/abm/generate.go | 3 + 3 files changed, 263 insertions(+) create mode 100644 goaxm/abm.go create mode 100644 goaxm/abm/abm.go create mode 100644 goaxm/abm/generate.go diff --git a/goaxm/abm.go b/goaxm/abm.go new file mode 100644 index 0000000..5ba5972 --- /dev/null +++ b/goaxm/abm.go @@ -0,0 +1,15 @@ +package goaxm + +import ( + "context" + + "github.com/micromdm/nanoaxm/goaxm/abm" +) + +// ABMv1MDMServers calls the Apple Business Manager API "v1" to +// Get a list of device management services in an organization. +// See https://developer.apple.com/documentation/applebusinessmanagerapi/get-mdm-servers +func (c *Client) ABMv1MDMServers(ctx context.Context, axmName string) (*abm.MdmServersResponseJson, error) { + out := new(abm.MdmServersResponseJson) + return out, c.Do(ctx, axmName, "GET", "https://api-business.apple.com/v1/mdmServers", nil, out) +} diff --git a/goaxm/abm/abm.go b/goaxm/abm/abm.go new file mode 100644 index 0000000..10e3749 --- /dev/null +++ b/goaxm/abm/abm.go @@ -0,0 +1,245 @@ +// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. + +package abm + +import "time" + +// Attributes that describe a device management service resource. +type MdmServerAttributesJson struct { + // The date and time of the creation of the resource. + CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` + + // The device management service’s name. + ServerName *string `json:"serverName,omitempty"` + + // The type of device management service: MDM, APPLE_CONFIGURATOR, APPLE_MDM + ServerType *MdmServerAttributesJsonServerType `json:"serverType,omitempty"` + + // The date and time of the most-recent update for the resource. + UpdatedDateTime *time.Time `json:"updatedDateTime,omitempty"` +} + +type MdmServerAttributesJsonServerType string + +const MdmServerAttributesJsonServerTypeAPPLECONFIGURATOR MdmServerAttributesJsonServerType = "APPLE_CONFIGURATOR" +const MdmServerAttributesJsonServerTypeAPPLEMDM MdmServerAttributesJsonServerType = "APPLE_MDM" +const MdmServerAttributesJsonServerTypeMDM MdmServerAttributesJsonServerType = "MDM" + +// The data structure that represents a device management service resource in an +// organization. +type MdmServerJson struct { + // The resource’s attributes. + Attributes *MdmServerAttributesJson `json:"attributes,omitempty"` + + // The opaque resource ID that uniquely identifies the resource. + Id string `json:"id"` + + // Navigational links to related data and included resource types and IDs. + Relationships *MdmServerRelationshipsJson `json:"relationships,omitempty"` + + // The resource type. + Type string `json:"type"` +} + +// The type and ID of a related resource. +type MdmServerRelationshipsDevicesDataJson struct { + // The opaque resource ID that uniquely identifies the resource. + Id string `json:"id"` + + // The resource type. + Type interface{} `json:"type"` +} + +// The data and links that describe the relationship between the resources. +type MdmServerRelationshipsDevicesJson struct { + // Data corresponds to the JSON schema field "data". + Data []MdmServerRelationshipsDevicesDataJson `json:"data,omitempty"` + + // Links corresponds to the JSON schema field "links". + Links *RelationshipLinksJson `json:"links,omitempty"` + + // Meta corresponds to the JSON schema field "meta". + Meta *PagingInformationJson `json:"meta,omitempty"` +} + +// The relationships you include in the request, and those that you can operate on. +type MdmServerRelationshipsJson struct { + // The devices in the device management service. + Devices *MdmServerRelationshipsDevicesJson `json:"devices,omitempty"` +} + +// A response that contains a list of device management service resources. +type MdmServersResponseJson struct { + // The resource data. + Data []MdmServerJson `json:"data"` + + // Included corresponds to the JSON schema field "included". + Included []OrgDeviceJson `json:"included,omitempty"` + + // Navigational links that include the self-link. + Links PagedDocumentLinksJson `json:"links"` + + // Paging information. + Meta *PagingInformationJson `json:"meta,omitempty"` +} + +// Attributes that describe an organization device resource. +type OrgDeviceAttributesJson struct { + // The date and time of adding the device to an organization. + AddedToOrgDateTime *time.Time `json:"addedToOrgDateTime,omitempty"` + + // The device’s Bluetooth MAC address. + BluetoothMacAddress *string `json:"bluetoothMacAddress,omitempty"` + + // The color of the device. + Color *string `json:"color,omitempty"` + + // The capacity of the device. + DeviceCapacity *string `json:"deviceCapacity,omitempty"` + + // The model name. + DeviceModel *string `json:"deviceModel,omitempty"` + + // The device’s EID (if available). + Eid *string `json:"eid,omitempty"` + + // The device’s IMEI (if available). + Imei *string `json:"imei,omitempty"` + + // The device’s MEID (if available). + Meid *string `json:"meid,omitempty"` + + // The date and time of placing the device’s order. + OrderDateTime *time.Time `json:"orderDateTime,omitempty"` + + // The order number of the device. + OrderNumber *string `json:"orderNumber,omitempty"` + + // The part number of the device. + PartNumber *string `json:"partNumber,omitempty"` + + // The device’s Apple product family: iPhone, iPad,Mac, AppleTV, Watch, or Vision + ProductFamily *OrgDeviceAttributesJsonProductFamily `json:"productFamily,omitempty"` + + // The device’s product type: (examples: iPhone14,3, iPad13,4, MacBookPro14,2) + ProductType *string `json:"productType,omitempty"` + + // The unique ID of the purchase source type: Apple Customer Number or Reseller + // Number + PurchaseSourceId *string `json:"purchaseSourceId,omitempty"` + + // The device’s purchase source type: APPLE, RESELLER, or MANUALLY_ADDED + PurchaseSourceType *OrgDeviceAttributesJsonPurchaseSourceType `json:"purchaseSourceType,omitempty"` + + // The device’s serial number. + SerialNumber *string `json:"serialNumber,omitempty"` + + // The devices status: ASSIGNED or UNASSIGNED. If ASSIGNED, use a separate API to + // get the information of the assigned server. + Status *OrgDeviceAttributesJsonStatus `json:"status,omitempty"` + + // The date and time of the most-recent update for the device. + UpdatedDateTime *time.Time `json:"updatedDateTime,omitempty"` + + // The device’s Wi-Fi MAC address. + WifiMacAddress *string `json:"wifiMacAddress,omitempty"` +} + +type OrgDeviceAttributesJsonProductFamily string + +const OrgDeviceAttributesJsonProductFamilyAppleTV OrgDeviceAttributesJsonProductFamily = "AppleTV" +const OrgDeviceAttributesJsonProductFamilyIPad OrgDeviceAttributesJsonProductFamily = "iPad" +const OrgDeviceAttributesJsonProductFamilyIPhone OrgDeviceAttributesJsonProductFamily = "iPhone" +const OrgDeviceAttributesJsonProductFamilyMac OrgDeviceAttributesJsonProductFamily = "Mac" +const OrgDeviceAttributesJsonProductFamilyVision OrgDeviceAttributesJsonProductFamily = "Vision" +const OrgDeviceAttributesJsonProductFamilyWatch OrgDeviceAttributesJsonProductFamily = "Watch" + +type OrgDeviceAttributesJsonPurchaseSourceType string + +const OrgDeviceAttributesJsonPurchaseSourceTypeAPPLE OrgDeviceAttributesJsonPurchaseSourceType = "APPLE" +const OrgDeviceAttributesJsonPurchaseSourceTypeMANUALLYADDED OrgDeviceAttributesJsonPurchaseSourceType = "MANUALLY_ADDED" +const OrgDeviceAttributesJsonPurchaseSourceTypeRESELLER OrgDeviceAttributesJsonPurchaseSourceType = "RESELLER" + +type OrgDeviceAttributesJsonStatus string + +const OrgDeviceAttributesJsonStatusASSIGNED OrgDeviceAttributesJsonStatus = "ASSIGNED" +const OrgDeviceAttributesJsonStatusUNASSIGNED OrgDeviceAttributesJsonStatus = "UNASSIGNED" + +// The data structure that represents an organization device resource. +type OrgDeviceJson struct { + // The resource’s attributes. + Attributes *OrgDeviceAttributesJson `json:"attributes,omitempty"` + + // The opaque resource ID that uniquely identifies the resource. + Id string `json:"id"` + + // Navigational links that include the self-link. + Links *ResourceLinksJson `json:"links,omitempty"` + + // Navigational links to related data and included resource types and IDs. + Relationships *OrgDeviceRelationshipsJson `json:"relationships,omitempty"` + + // The resource type. + Type string `json:"type"` +} + +// The links that describe the relationship between the resources. +type OrgDeviceRelationshipsAssignedServerJson struct { + // Links corresponds to the JSON schema field "links". + Links *RelationshipLinksJson `json:"links,omitempty"` +} + +// The relationships you include in the request, and those that you can operate on. +type OrgDeviceRelationshipsJson struct { + // The relationship representing a device and its assigned device management + // service. + AssignedServer *OrgDeviceRelationshipsAssignedServerJson `json:"assignedServer,omitempty"` +} + +// Links related to the response document, including paging links. +type PagedDocumentLinksJson struct { + // The link to the first page of documents. + First *string `json:"first,omitempty"` + + // The link to the next page of documents. + Next *string `json:"next,omitempty"` + + // The link that produces the current document. + Self string `json:"self"` +} + +// Paging information for data responses. +type PagingInformationJson struct { + // The paging information details. + Paging PagingInformationPagingJson `json:"paging"` +} + +// Paging details, such as the total number of resources and the per-page limit. +type PagingInformationPagingJson struct { + // The maximum number of resources to return per page. + Limit int `json:"limit"` + + // The cursor to use for the next request, in case of pagination. + NextCursor *string `json:"nextCursor,omitempty"` + + // The total number of resources to return. + Total *int `json:"total,omitempty"` +} + +// Links related to the response document, including self-links. +type RelationshipLinksJson struct { + // Include corresponds to the JSON schema field "include". + Include *string `json:"include,omitempty"` + + // The link to the related documents. + Related *string `json:"related,omitempty"` + + // The link that produces the current document. + Self *string `json:"self,omitempty"` +} + +// Self-links to requested resources. +type ResourceLinksJson struct { + // The link to the resource. + Self *string `json:"self,omitempty"` +} diff --git a/goaxm/abm/generate.go b/goaxm/abm/generate.go new file mode 100644 index 0000000..1627722 --- /dev/null +++ b/goaxm/abm/generate.go @@ -0,0 +1,3 @@ +package abm + +//go:generate go-jsonschema -p abm --tags json --only-models --output abm.go apple-device-services/abm/schemas/MdmServersResponse.json From 220538537c873bb55a7fa728f0b4955fb5726977 Mon Sep 17 00:00:00 2001 From: Jesse Peterson Date: Mon, 8 Sep 2025 13:24:51 -0700 Subject: [PATCH 2/7] add values --- goaxm/abm.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/goaxm/abm.go b/goaxm/abm.go index 5ba5972..0473f2d 100644 --- a/goaxm/abm.go +++ b/goaxm/abm.go @@ -2,14 +2,20 @@ package goaxm import ( "context" + "net/url" "github.com/micromdm/nanoaxm/goaxm/abm" ) // ABMv1MDMServers calls the Apple Business Manager API "v1" to // Get a list of device management services in an organization. +// Query parameters may be provided in v, otherwise nil. // See https://developer.apple.com/documentation/applebusinessmanagerapi/get-mdm-servers -func (c *Client) ABMv1MDMServers(ctx context.Context, axmName string) (*abm.MdmServersResponseJson, error) { +func (c *Client) ABMv1MDMServers(ctx context.Context, axmName string, v url.Values) (*abm.MdmServersResponseJson, error) { + var q string + if v != nil { + q = "?" + v.Encode() + } out := new(abm.MdmServersResponseJson) - return out, c.Do(ctx, axmName, "GET", "https://api-business.apple.com/v1/mdmServers", nil, out) + return out, c.Do(ctx, axmName, "GET", "https://api-business.apple.com/v1/mdmServers"+q, nil, out) } From dd6d9ee4b3d1a354b5259bbed5f7a89978417867 Mon Sep 17 00:00:00 2001 From: Jesse Peterson Date: Mon, 8 Sep 2025 14:06:38 -0700 Subject: [PATCH 3/7] add error generation --- goaxm/abm/abm.go | 61 +++++++++++++++++++++++++++++++++++++++++++ goaxm/abm/generate.go | 2 +- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/goaxm/abm/abm.go b/goaxm/abm/abm.go index 10e3749..f81ac48 100644 --- a/goaxm/abm/abm.go +++ b/goaxm/abm/abm.go @@ -4,6 +4,61 @@ package abm import "time" +type ErrorLinksJson struct { + // About corresponds to the JSON schema field "about". + About *string `json:"about,omitempty"` + + // Associated corresponds to the JSON schema field "associated". + Associated interface{} `json:"associated,omitempty"` +} + +// The details about an error that returns when an API request isn’t successful. +type ErrorResponseErrorsJson struct { + // A machine-readable code indicating the type of error. The code is a + // hierarchical value with levels of specificity separated by a period (.). This + // value is parseable for programmatic error handling in code. + Code string `json:"code"` + + // A detailed explanation of the error. Don’t use this field for programmatic + // error handling. + Detail string `json:"detail"` + + // The unique ID of a specific instance of an error, request, and response. Use + // this ID when providing feedback to, or debugging issues with, Apple. + Id *string `json:"id,omitempty"` + + // Links corresponds to the JSON schema field "links". + Links *ErrorLinksJson `json:"links,omitempty"` + + // Meta corresponds to the JSON schema field "meta". + Meta map[string]interface{} `json:"meta,omitempty"` + + // One of two possible types of values — source.Parameter when a query parameter + // produces the error, or source.JsonPointer when a problem with the entity + // produces the error. + Source interface{} `json:"source,omitempty"` + + // The HTTP status code of the error. This status code usually matches the + // response’s status code. However, if the request produces multiple errors, these + // two codes may differ. + Status string `json:"status"` + + // A summary of the error. Don’t use this field for programmatic error handling. + Title string `json:"title"` +} + +// A response that contains a list of device management service resources. +type ErrorResponseJson struct { + // An array of one or more errors. + Errors []ErrorResponseErrorsJson `json:"errors,omitempty"` +} + +// A response that contains a list of device management service resources. +type JsonPointerJson struct { + // A JSON pointer that indicates the location of the error in the request entity. + Pointer string `json:"pointer"` +} + // Attributes that describe a device management service resource. type MdmServerAttributesJson struct { // The date and time of the creation of the resource. @@ -226,6 +281,12 @@ type PagingInformationPagingJson struct { Total *int `json:"total,omitempty"` } +// An object that contains the query parameter that produces the error. +type ParameterJson struct { + // The query parameter that produces the error. + Parameter string `json:"parameter"` +} + // Links related to the response document, including self-links. type RelationshipLinksJson struct { // Include corresponds to the JSON schema field "include". diff --git a/goaxm/abm/generate.go b/goaxm/abm/generate.go index 1627722..df47694 100644 --- a/goaxm/abm/generate.go +++ b/goaxm/abm/generate.go @@ -1,3 +1,3 @@ package abm -//go:generate go-jsonschema -p abm --tags json --only-models --output abm.go apple-device-services/abm/schemas/MdmServersResponse.json +//go:generate go-jsonschema -p abm --tags json --only-models --output abm.go apple-device-services/abm/schemas/ErrorResponse.json apple-device-services/abm/schemas/Parameter.json apple-device-services/abm/schemas/JsonPointer.json apple-device-services/abm/schemas/MdmServersResponse.json From 8257c79b527702fe938faf10174104d945407f9f Mon Sep 17 00:00:00 2001 From: Jesse Peterson Date: Thu, 11 Sep 2025 14:14:43 -0700 Subject: [PATCH 4/7] add OrgDeviceActivities and Error JSON parsing --- goaxm/abm/{abm.go => schema.go} | 0 goaxm/error.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) rename goaxm/abm/{abm.go => schema.go} (100%) create mode 100644 goaxm/error.go diff --git a/goaxm/abm/abm.go b/goaxm/abm/schema.go similarity index 100% rename from goaxm/abm/abm.go rename to goaxm/abm/schema.go diff --git a/goaxm/error.go b/goaxm/error.go new file mode 100644 index 0000000..f75db56 --- /dev/null +++ b/goaxm/error.go @@ -0,0 +1,32 @@ +package goaxm + +import ( + "fmt" + "strings" + + "github.com/micromdm/nanoaxm/goaxm/abm" +) + +type ABMErrorResponseError struct { + abm.ErrorResponseJson +} + +func (e *ABMErrorResponseError) Error() string { + if e == nil { + return "nil *ABMErrorResponseError" + } + if len(e.Errors) < 1 { + return "empty ABM errors" + } + + var errStrs []string + for i, e := range e.Errors { + errStr := fmt.Sprintf("error %d: %s: %s: %s", i+1, e.Detail, e.Code, e.Status) + if e.Id != nil { + errStr += ": " + *e.Id + } + errStrs = append(errStrs, errStr) + } + + return "ABM error response: " + strings.Join(errStrs, ", ") +} From 9dc9d15f65cbccab9666b89a0b2b83bc81d69aab Mon Sep 17 00:00:00 2001 From: Jesse Peterson Date: Thu, 11 Sep 2025 14:15:23 -0700 Subject: [PATCH 5/7] add OrgDeviceActivities and Error JSON parsing --- goaxm/abm/generate.go | 2 +- goaxm/abm/schema.go | 154 ++++++++++++++++++++++++++++++++++++++---- goaxm/client.go | 50 +++++++++++--- goaxm/error.go | 30 +++++++- goaxm/goaxm_test.go | 3 +- 5 files changed, 215 insertions(+), 24 deletions(-) diff --git a/goaxm/abm/generate.go b/goaxm/abm/generate.go index df47694..4f8b5ad 100644 --- a/goaxm/abm/generate.go +++ b/goaxm/abm/generate.go @@ -1,3 +1,3 @@ package abm -//go:generate go-jsonschema -p abm --tags json --only-models --output abm.go apple-device-services/abm/schemas/ErrorResponse.json apple-device-services/abm/schemas/Parameter.json apple-device-services/abm/schemas/JsonPointer.json apple-device-services/abm/schemas/MdmServersResponse.json +//go:generate go-jsonschema -p $GOPACKAGE --tags json --only-models --output schema.go apple-device-services/abm/schemas/ErrorResponse.json apple-device-services/abm/schemas/MdmServersResponse.json apple-device-services/abm/schemas/OrgDeviceActivityCreateRequest.json apple-device-services/abm/schemas/OrgDeviceActivityResponse.json diff --git a/goaxm/abm/schema.go b/goaxm/abm/schema.go index f81ac48..50b908b 100644 --- a/goaxm/abm/schema.go +++ b/goaxm/abm/schema.go @@ -4,6 +4,12 @@ package abm import "time" +// Self-links to documents that can contain information for one or more resources. +type DocumentLinksJson struct { + // The link that produces the current + Self string `json:"self"` +} + type ErrorLinksJson struct { // About corresponds to the JSON schema field "about". About *string `json:"about,omitempty"` @@ -47,18 +53,13 @@ type ErrorResponseErrorsJson struct { Title string `json:"title"` } -// A response that contains a list of device management service resources. +// The error details that an API returns in the response body whenever the API +// request isn’t successful. type ErrorResponseJson struct { // An array of one or more errors. Errors []ErrorResponseErrorsJson `json:"errors,omitempty"` } -// A response that contains a list of device management service resources. -type JsonPointerJson struct { - // A JSON pointer that indicates the location of the error in the request entity. - Pointer string `json:"pointer"` -} - // Attributes that describe a device management service resource. type MdmServerAttributesJson struct { // The date and time of the creation of the resource. @@ -138,6 +139,139 @@ type MdmServersResponseJson struct { Meta *PagingInformationJson `json:"meta,omitempty"` } +// Attributes that describe an organization device activity resource. +type OrgDeviceActivityAttributesJson struct { + // The date and time of the completion of organization device activity. This is + // available only when an activity is in a COMPLETED status. + CompletedDateTime *time.Time `json:"completedDateTime,omitempty"` + + // The date and time of the creation of organization device activity. + CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` + + // A presigned URL for downloading activity logs in a CSV format. This is + // available only when an activity is in a COMPLETED status. + DownloadUrl *string `json:"downloadUrl,omitempty"` + + // The top-level status of an activity. For more details, see the table below. + // Possible values: COMPLETED, IN_PROGRESS, STOPPED, FAILED + Status *OrgDeviceActivityAttributesJsonStatus `json:"status,omitempty"` + + // The low-level status of an activity. For more details, see the table below. + // Possible values: SUBMITTED,PRE_PROCESSING,PENDING,PROCESSING,POST_PROCESSING, + // STOPPING,COMPLETED_WITH_SUCCESS,COMPLETED_WITH_ERROR,COMPLETED_WITH_FAILURE,COMPLETED_POST_PROCESSING_FAILED + SubStatus *OrgDeviceActivityAttributesJsonSubStatus `json:"subStatus,omitempty"` +} + +type OrgDeviceActivityAttributesJsonStatus string + +const OrgDeviceActivityAttributesJsonStatusCOMPLETED OrgDeviceActivityAttributesJsonStatus = "COMPLETED" +const OrgDeviceActivityAttributesJsonStatusFAILED OrgDeviceActivityAttributesJsonStatus = "FAILED" +const OrgDeviceActivityAttributesJsonStatusINPROGRESS OrgDeviceActivityAttributesJsonStatus = "IN_PROGRESS" +const OrgDeviceActivityAttributesJsonStatusSTOPPED OrgDeviceActivityAttributesJsonStatus = "STOPPED" + +type OrgDeviceActivityAttributesJsonSubStatus string + +const OrgDeviceActivityAttributesJsonSubStatusCOMPLETEDPOSTPROCESSINGFAILED OrgDeviceActivityAttributesJsonSubStatus = "COMPLETED_POST_PROCESSING_FAILED" +const OrgDeviceActivityAttributesJsonSubStatusCOMPLETEDWITHERROR OrgDeviceActivityAttributesJsonSubStatus = "COMPLETED_WITH_ERROR" +const OrgDeviceActivityAttributesJsonSubStatusCOMPLETEDWITHFAILURE OrgDeviceActivityAttributesJsonSubStatus = "COMPLETED_WITH_FAILURE" +const OrgDeviceActivityAttributesJsonSubStatusCOMPLETEDWITHSUCCESS OrgDeviceActivityAttributesJsonSubStatus = "COMPLETED_WITH_SUCCESS" +const OrgDeviceActivityAttributesJsonSubStatusPENDING OrgDeviceActivityAttributesJsonSubStatus = "PENDING" +const OrgDeviceActivityAttributesJsonSubStatusPOSTPROCESSING OrgDeviceActivityAttributesJsonSubStatus = "POST_PROCESSING" +const OrgDeviceActivityAttributesJsonSubStatusPREPROCESSING OrgDeviceActivityAttributesJsonSubStatus = "PRE_PROCESSING" +const OrgDeviceActivityAttributesJsonSubStatusPROCESSING OrgDeviceActivityAttributesJsonSubStatus = "PROCESSING" +const OrgDeviceActivityAttributesJsonSubStatusSTOPPING OrgDeviceActivityAttributesJsonSubStatus = "STOPPING" +const OrgDeviceActivityAttributesJsonSubStatusSUBMITTED OrgDeviceActivityAttributesJsonSubStatus = "SUBMITTED" + +// Attributes with values that you’re changing as part of the create request. +type OrgDeviceActivityCreateRequestDataAttributesJson struct { + // The type of activity you want to create. + ActivityType OrgDeviceActivityTypeJson `json:"activityType"` +} + +// The request body you use to update the device management service for a device. +type OrgDeviceActivityCreateRequestDataJson struct { + // The resource’s attributes. + Attributes OrgDeviceActivityCreateRequestDataAttributesJson `json:"attributes"` + + // The types and IDs of the related data to update. + Relationships OrgDeviceActivityCreateRequestDataRelationshipsJson `json:"relationships"` + + // The resource type. + Type string `json:"type"` +} + +// The type and ID of a related resource. +type OrgDeviceActivityCreateRequestDataRelationshipsDevicesDataJson struct { + // The opaque resource ID that uniquely identifies the resource. + Id string `json:"id"` + + // The resource type. + Type string `json:"type"` +} + +// The data that describe the relationship between the resources. +type OrgDeviceActivityCreateRequestDataRelationshipsDevicesJson struct { + // Data corresponds to the JSON schema field "data". + Data []OrgDeviceActivityCreateRequestDataRelationshipsDevicesDataJson `json:"data"` +} + +// The relationships you include in the request, and those that you can operate on. +type OrgDeviceActivityCreateRequestDataRelationshipsJson struct { + // Devices corresponds to the JSON schema field "devices". + Devices OrgDeviceActivityCreateRequestDataRelationshipsDevicesJson `json:"devices"` + + // MdmServer corresponds to the JSON schema field "mdmServer". + MdmServer *OrgDeviceActivityCreateRequestDataRelationshipsMdmServerJson `json:"mdmServer,omitempty"` +} + +// The type and ID of a related resource. +type OrgDeviceActivityCreateRequestDataRelationshipsMdmServerDataJson struct { + // The opaque resource ID that uniquely identifies the resource. + Id string `json:"id"` + + // The resource type. + Type string `json:"type"` +} + +// The data that describe the relationship between the resources. +type OrgDeviceActivityCreateRequestDataRelationshipsMdmServerJson struct { + // Data corresponds to the JSON schema field "data". + Data OrgDeviceActivityCreateRequestDataRelationshipsMdmServerDataJson `json:"data"` +} + +// The request body you use to update the device management service for a device. +type OrgDeviceActivityCreateRequestJson struct { + // The resource data. + Data OrgDeviceActivityCreateRequestDataJson `json:"data"` +} + +// The data structure that represents an organization device activity resource. +type OrgDeviceActivityJson struct { + // The resource’s attributes. + Attributes *OrgDeviceActivityAttributesJson `json:"attributes,omitempty"` + + // The opaque resource ID that uniquely identifies the resource. + Id string `json:"id"` + + // Navigational links that include the self-link. + Links *ResourceLinksJson `json:"links,omitempty"` + + // The resource type. + Type string `json:"type"` +} + +// A response that contains a single organization device activity resource. +type OrgDeviceActivityResponseJson struct { + // The resource data. + Data OrgDeviceActivityJson `json:"data"` + + // Navigational links that include the self-link. + Links DocumentLinksJson `json:"links"` +} + +// Strings that represent organization device activities. +type OrgDeviceActivityTypeJson string + // Attributes that describe an organization device resource. type OrgDeviceAttributesJson struct { // The date and time of adding the device to an organization. @@ -281,12 +415,6 @@ type PagingInformationPagingJson struct { Total *int `json:"total,omitempty"` } -// An object that contains the query parameter that produces the error. -type ParameterJson struct { - // The query parameter that produces the error. - Parameter string `json:"parameter"` -} - // Links related to the response document, including self-links. type RelationshipLinksJson struct { // Include corresponds to the JSON schema field "include". diff --git a/goaxm/client.go b/goaxm/client.go index f78e6c2..0cb4358 100644 --- a/goaxm/client.go +++ b/goaxm/client.go @@ -6,7 +6,6 @@ import ( "context" "encoding/json" "errors" - "fmt" "io" "net/http" @@ -90,11 +89,18 @@ func WithJTI(jtiFn func() string) Option { } } -// Do executes the AxM HTTP call against using method and url. -// OAuth utilizes credentials of axmName. +// defaultOutStatus is the "success" HTTP status that will allow parsing of the "out." +var defaultOutStatus = http.StatusOK + +// Do executes the AxM HTTP call against url using method. +// OAuth credentials are looked-up and used by axmName. // JSON is marshaled and decoded from the HTTP request and response // bodies using in and out respectively. -func (c *Client) Do(ctx context.Context, axmName, method, url string, in, out any) error { +// A successful HTTP code is specified in outStatus. +// A default status will be used if outStatus is 0. +// To parse potential errors as the AxM Error value, specify them with errStatuses. +// A default set will be used if errStatuses is empty. +func (c *Client) Do(ctx context.Context, axmName, method, url string, in, out any, outStatus int, errStatuses []int) error { if c.doer == nil { return errors.New("nil client") } @@ -128,10 +134,11 @@ func (c *Client) Do(ctx context.Context, axmName, method, url string, in, out an } defer resp.Body.Close() - if resp.StatusCode == http.StatusUnauthorized { - return fmt.Errorf("unhandled auth error: %w", client.NewHTTPError(resp)) - } else if resp.StatusCode != http.StatusOK { - return client.NewHTTPError(resp) + if outStatus < 1 { + outStatus = defaultOutStatus + } + if resp.StatusCode != outStatus { + return ABMError(resp, errStatuses) } if out != nil { @@ -143,3 +150,30 @@ func (c *Client) Do(ctx context.Context, axmName, method, url string, in, out an return nil } + +// defaultErrStatuses is the default set of HTTP statuses that will generate HTTP errors. +var defaultErrStatuses = []int{ + http.StatusBadRequest, + http.StatusUnauthorized, + http.StatusForbidden, + http.StatusTooManyRequests, +} + +// ABMError searches errStatuses for the response code in r and returns a +// [ABMErrorResponseError] if found, otherwise an HTTP error. +func ABMError(r *http.Response, errStatuses []int) error { + if errStatuses == nil { + errStatuses = defaultErrStatuses + } + foundErrStatus := false + for _, e := range errStatuses { + if r.StatusCode == e { + foundErrStatus = true + break + } + } + if foundErrStatus { + return NewABMErrorResponseErrorFromReader(r.Body) + } + return client.NewHTTPError(r) +} diff --git a/goaxm/error.go b/goaxm/error.go index f75db56..8260f84 100644 --- a/goaxm/error.go +++ b/goaxm/error.go @@ -1,20 +1,48 @@ package goaxm import ( + "encoding/json" + "errors" "fmt" + "io" "strings" "github.com/micromdm/nanoaxm/goaxm/abm" ) +// ABMErrorResponseError is an error wraps an ABM ErrorResponse JSON struct. +// See https://developer.apple.com/documentation/applebusinessmanagerapi/errorresponse type ABMErrorResponseError struct { - abm.ErrorResponseJson + *abm.ErrorResponseJson } +// NewABMErrorResponseError creates the error from the ABM ErrorResponse JSON struct. +func NewABMErrorResponseError(errorResponse *abm.ErrorResponseJson) *ABMErrorResponseError { + return &ABMErrorResponseError{ErrorResponseJson: errorResponse} +} + +// NewABMErrorResponseErrorFromReader decodes the ABM ErrorResponse JSON from jsonReader. +// A new [ABMErrorResponseError] is returned or an error decoding the JSON. +func NewABMErrorResponseErrorFromReader(jsonReader io.Reader) error { + if jsonReader == nil { + return errors.New("nil reader") + } + abmErr := new(abm.ErrorResponseJson) + err := json.NewDecoder(jsonReader).Decode(abmErr) + if err != nil { + return fmt.Errorf("decoding ABM error response: %w", err) + } + return NewABMErrorResponseError(abmErr) +} + +// Error generates an error string based on the embedded ErrorResponse JSON struct. func (e *ABMErrorResponseError) Error() string { if e == nil { return "nil *ABMErrorResponseError" } + if e.ErrorResponseJson == nil { + return "nil *ErrorResponseJson" + } if len(e.Errors) < 1 { return "empty ABM errors" } diff --git a/goaxm/goaxm_test.go b/goaxm/goaxm_test.go index 575d112..42b1ce4 100644 --- a/goaxm/goaxm_test.go +++ b/goaxm/goaxm_test.go @@ -9,6 +9,7 @@ import ( "github.com/micromdm/nanoaxm/storage/inmem" ) +// Example of directly using the `client.Do()` method. func Example() { ctx := context.Background() @@ -18,7 +19,7 @@ func Example() { var output struct{ Item string } - err := client.Do(ctx, "test-axm-name", http.MethodGet, "https://api-business.apple.com/v1/mdmServers", nil, output) + err := client.Do(ctx, "test-axm-name", http.MethodGet, "https://api-business.apple.com/v1/mdmServers", nil, output, 0, nil) if err != nil { log.Fatal(err) } From d2cc5d86167410dc354f605d31d79192ff35d983 Mon Sep 17 00:00:00 2001 From: Jesse Peterson Date: Thu, 11 Sep 2025 14:17:33 -0700 Subject: [PATCH 6/7] add OrgDeviceActivities and Error JSON parsing --- goaxm/abm.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/goaxm/abm.go b/goaxm/abm.go index 0473f2d..339e5d2 100644 --- a/goaxm/abm.go +++ b/goaxm/abm.go @@ -2,6 +2,7 @@ package goaxm import ( "context" + "net/http" "net/url" "github.com/micromdm/nanoaxm/goaxm/abm" @@ -17,5 +18,10 @@ func (c *Client) ABMv1MDMServers(ctx context.Context, axmName string, v url.Valu q = "?" + v.Encode() } out := new(abm.MdmServersResponseJson) - return out, c.Do(ctx, axmName, "GET", "https://api-business.apple.com/v1/mdmServers"+q, nil, out) + return out, c.Do(ctx, axmName, "GET", "https://api-business.apple.com/v1/mdmServers"+q, nil, out, 0, nil) +} + +func (c *Client) ABMv1OrgDeviceActivities(ctx context.Context, axmName string, req *abm.OrgDeviceActivityCreateRequestJson) (*abm.OrgDeviceActivityResponseJson, error) { + out := new(abm.OrgDeviceActivityResponseJson) + return out, c.Do(ctx, axmName, http.MethodPost, "https://api-business.apple.com/v1/orgDeviceActivities", req, out, 201, []int{400, 401, 403, 409, 422, 429}) } From fbc8141b6eb28b581c953317f105ed10055015ef Mon Sep 17 00:00:00 2001 From: Jesse Peterson Date: Mon, 15 Sep 2025 09:25:46 -0700 Subject: [PATCH 7/7] re-gen schema from latest --- goaxm/abm/schema.go | 219 +++++++++++++++++++++++--------------------- 1 file changed, 116 insertions(+), 103 deletions(-) diff --git a/goaxm/abm/schema.go b/goaxm/abm/schema.go index 50b908b..54eccbd 100644 --- a/goaxm/abm/schema.go +++ b/goaxm/abm/schema.go @@ -6,10 +6,23 @@ import "time" // Self-links to documents that can contain information for one or more resources. type DocumentLinksJson struct { - // The link that produces the current + // The link that produces the current document. Self string `json:"self"` } +type ErrorLinksAssociated struct { + // Href corresponds to the JSON schema field "href". + Href *string `json:"href,omitempty"` + + // Meta corresponds to the JSON schema field "meta". + Meta *ErrorLinksAssociatedMeta `json:"meta,omitempty"` +} + +type ErrorLinksAssociatedMeta struct { + // Source corresponds to the JSON schema field "source". + Source *string `json:"source,omitempty"` +} + type ErrorLinksJson struct { // About corresponds to the JSON schema field "about". About *string `json:"about,omitempty"` @@ -19,7 +32,7 @@ type ErrorLinksJson struct { } // The details about an error that returns when an API request isn’t successful. -type ErrorResponseErrorsJson struct { +type ErrorResponseErrors struct { // A machine-readable code indicating the type of error. The code is a // hierarchical value with levels of specificity separated by a period (.). This // value is parseable for programmatic error handling in code. @@ -57,11 +70,11 @@ type ErrorResponseErrorsJson struct { // request isn’t successful. type ErrorResponseJson struct { // An array of one or more errors. - Errors []ErrorResponseErrorsJson `json:"errors,omitempty"` + Errors []ErrorResponseErrors `json:"errors,omitempty"` } // Attributes that describe a device management service resource. -type MdmServerAttributesJson struct { +type MdmServerAttributes struct { // The date and time of the creation of the resource. CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` @@ -69,47 +82,44 @@ type MdmServerAttributesJson struct { ServerName *string `json:"serverName,omitempty"` // The type of device management service: MDM, APPLE_CONFIGURATOR, APPLE_MDM - ServerType *MdmServerAttributesJsonServerType `json:"serverType,omitempty"` + ServerType *MdmServerAttributesServerType `json:"serverType,omitempty"` // The date and time of the most-recent update for the resource. UpdatedDateTime *time.Time `json:"updatedDateTime,omitempty"` } -type MdmServerAttributesJsonServerType string +type MdmServerAttributesServerType string -const MdmServerAttributesJsonServerTypeAPPLECONFIGURATOR MdmServerAttributesJsonServerType = "APPLE_CONFIGURATOR" -const MdmServerAttributesJsonServerTypeAPPLEMDM MdmServerAttributesJsonServerType = "APPLE_MDM" -const MdmServerAttributesJsonServerTypeMDM MdmServerAttributesJsonServerType = "MDM" +const MdmServerAttributesServerTypeAPPLECONFIGURATOR MdmServerAttributesServerType = "APPLE_CONFIGURATOR" +const MdmServerAttributesServerTypeAPPLEMDM MdmServerAttributesServerType = "APPLE_MDM" +const MdmServerAttributesServerTypeMDM MdmServerAttributesServerType = "MDM" // The data structure that represents a device management service resource in an // organization. type MdmServerJson struct { // The resource’s attributes. - Attributes *MdmServerAttributesJson `json:"attributes,omitempty"` + Attributes *MdmServerAttributes `json:"attributes,omitempty"` // The opaque resource ID that uniquely identifies the resource. Id string `json:"id"` // Navigational links to related data and included resource types and IDs. - Relationships *MdmServerRelationshipsJson `json:"relationships,omitempty"` + Relationships *MdmServerRelationships `json:"relationships,omitempty"` // The resource type. Type string `json:"type"` } -// The type and ID of a related resource. -type MdmServerRelationshipsDevicesDataJson struct { - // The opaque resource ID that uniquely identifies the resource. - Id string `json:"id"` - - // The resource type. - Type interface{} `json:"type"` +// The relationships you include in the request, and those that you can operate on. +type MdmServerRelationships struct { + // The devices in the device management service. + Devices *MdmServerRelationshipsDevices `json:"devices,omitempty"` } // The data and links that describe the relationship between the resources. -type MdmServerRelationshipsDevicesJson struct { +type MdmServerRelationshipsDevices struct { // Data corresponds to the JSON schema field "data". - Data []MdmServerRelationshipsDevicesDataJson `json:"data,omitempty"` + Data []MdmServerRelationshipsDevicesData `json:"data,omitempty"` // Links corresponds to the JSON schema field "links". Links *RelationshipLinksJson `json:"links,omitempty"` @@ -118,10 +128,13 @@ type MdmServerRelationshipsDevicesJson struct { Meta *PagingInformationJson `json:"meta,omitempty"` } -// The relationships you include in the request, and those that you can operate on. -type MdmServerRelationshipsJson struct { - // The devices in the device management service. - Devices *MdmServerRelationshipsDevicesJson `json:"devices,omitempty"` +// The type and ID of a related resource. +type MdmServerRelationshipsDevicesData struct { + // The opaque resource ID that uniquely identifies the resource. + Id string `json:"id"` + + // The resource type. + Type interface{} `json:"type"` } // A response that contains a list of device management service resources. @@ -140,7 +153,7 @@ type MdmServersResponseJson struct { } // Attributes that describe an organization device activity resource. -type OrgDeviceActivityAttributesJson struct { +type OrgDeviceActivityAttributes struct { // The date and time of the completion of organization device activity. This is // available only when an activity is in a COMPLETED status. CompletedDateTime *time.Time `json:"completedDateTime,omitempty"` @@ -154,78 +167,69 @@ type OrgDeviceActivityAttributesJson struct { // The top-level status of an activity. For more details, see the table below. // Possible values: COMPLETED, IN_PROGRESS, STOPPED, FAILED - Status *OrgDeviceActivityAttributesJsonStatus `json:"status,omitempty"` + Status *OrgDeviceActivityAttributesStatus `json:"status,omitempty"` // The low-level status of an activity. For more details, see the table below. // Possible values: SUBMITTED,PRE_PROCESSING,PENDING,PROCESSING,POST_PROCESSING, // STOPPING,COMPLETED_WITH_SUCCESS,COMPLETED_WITH_ERROR,COMPLETED_WITH_FAILURE,COMPLETED_POST_PROCESSING_FAILED - SubStatus *OrgDeviceActivityAttributesJsonSubStatus `json:"subStatus,omitempty"` + SubStatus *OrgDeviceActivityAttributesSubStatus `json:"subStatus,omitempty"` } -type OrgDeviceActivityAttributesJsonStatus string - -const OrgDeviceActivityAttributesJsonStatusCOMPLETED OrgDeviceActivityAttributesJsonStatus = "COMPLETED" -const OrgDeviceActivityAttributesJsonStatusFAILED OrgDeviceActivityAttributesJsonStatus = "FAILED" -const OrgDeviceActivityAttributesJsonStatusINPROGRESS OrgDeviceActivityAttributesJsonStatus = "IN_PROGRESS" -const OrgDeviceActivityAttributesJsonStatusSTOPPED OrgDeviceActivityAttributesJsonStatus = "STOPPED" +type OrgDeviceActivityAttributesStatus string -type OrgDeviceActivityAttributesJsonSubStatus string +const OrgDeviceActivityAttributesStatusCOMPLETED OrgDeviceActivityAttributesStatus = "COMPLETED" +const OrgDeviceActivityAttributesStatusFAILED OrgDeviceActivityAttributesStatus = "FAILED" +const OrgDeviceActivityAttributesStatusINPROGRESS OrgDeviceActivityAttributesStatus = "IN_PROGRESS" +const OrgDeviceActivityAttributesStatusSTOPPED OrgDeviceActivityAttributesStatus = "STOPPED" -const OrgDeviceActivityAttributesJsonSubStatusCOMPLETEDPOSTPROCESSINGFAILED OrgDeviceActivityAttributesJsonSubStatus = "COMPLETED_POST_PROCESSING_FAILED" -const OrgDeviceActivityAttributesJsonSubStatusCOMPLETEDWITHERROR OrgDeviceActivityAttributesJsonSubStatus = "COMPLETED_WITH_ERROR" -const OrgDeviceActivityAttributesJsonSubStatusCOMPLETEDWITHFAILURE OrgDeviceActivityAttributesJsonSubStatus = "COMPLETED_WITH_FAILURE" -const OrgDeviceActivityAttributesJsonSubStatusCOMPLETEDWITHSUCCESS OrgDeviceActivityAttributesJsonSubStatus = "COMPLETED_WITH_SUCCESS" -const OrgDeviceActivityAttributesJsonSubStatusPENDING OrgDeviceActivityAttributesJsonSubStatus = "PENDING" -const OrgDeviceActivityAttributesJsonSubStatusPOSTPROCESSING OrgDeviceActivityAttributesJsonSubStatus = "POST_PROCESSING" -const OrgDeviceActivityAttributesJsonSubStatusPREPROCESSING OrgDeviceActivityAttributesJsonSubStatus = "PRE_PROCESSING" -const OrgDeviceActivityAttributesJsonSubStatusPROCESSING OrgDeviceActivityAttributesJsonSubStatus = "PROCESSING" -const OrgDeviceActivityAttributesJsonSubStatusSTOPPING OrgDeviceActivityAttributesJsonSubStatus = "STOPPING" -const OrgDeviceActivityAttributesJsonSubStatusSUBMITTED OrgDeviceActivityAttributesJsonSubStatus = "SUBMITTED" +type OrgDeviceActivityAttributesSubStatus string -// Attributes with values that you’re changing as part of the create request. -type OrgDeviceActivityCreateRequestDataAttributesJson struct { - // The type of activity you want to create. - ActivityType OrgDeviceActivityTypeJson `json:"activityType"` -} +const OrgDeviceActivityAttributesSubStatusCOMPLETEDPOSTPROCESSINGFAILED OrgDeviceActivityAttributesSubStatus = "COMPLETED_POST_PROCESSING_FAILED" +const OrgDeviceActivityAttributesSubStatusCOMPLETEDWITHERROR OrgDeviceActivityAttributesSubStatus = "COMPLETED_WITH_ERROR" +const OrgDeviceActivityAttributesSubStatusCOMPLETEDWITHFAILURE OrgDeviceActivityAttributesSubStatus = "COMPLETED_WITH_FAILURE" +const OrgDeviceActivityAttributesSubStatusCOMPLETEDWITHSUCCESS OrgDeviceActivityAttributesSubStatus = "COMPLETED_WITH_SUCCESS" +const OrgDeviceActivityAttributesSubStatusPENDING OrgDeviceActivityAttributesSubStatus = "PENDING" +const OrgDeviceActivityAttributesSubStatusPOSTPROCESSING OrgDeviceActivityAttributesSubStatus = "POST_PROCESSING" +const OrgDeviceActivityAttributesSubStatusPREPROCESSING OrgDeviceActivityAttributesSubStatus = "PRE_PROCESSING" +const OrgDeviceActivityAttributesSubStatusPROCESSING OrgDeviceActivityAttributesSubStatus = "PROCESSING" +const OrgDeviceActivityAttributesSubStatusSTOPPING OrgDeviceActivityAttributesSubStatus = "STOPPING" +const OrgDeviceActivityAttributesSubStatusSUBMITTED OrgDeviceActivityAttributesSubStatus = "SUBMITTED" // The request body you use to update the device management service for a device. -type OrgDeviceActivityCreateRequestDataJson struct { +type OrgDeviceActivityCreateRequestData struct { // The resource’s attributes. - Attributes OrgDeviceActivityCreateRequestDataAttributesJson `json:"attributes"` + Attributes OrgDeviceActivityCreateRequestDataAttributes `json:"attributes"` // The types and IDs of the related data to update. - Relationships OrgDeviceActivityCreateRequestDataRelationshipsJson `json:"relationships"` + Relationships OrgDeviceActivityCreateRequestDataRelationships `json:"relationships"` // The resource type. Type string `json:"type"` } -// The type and ID of a related resource. -type OrgDeviceActivityCreateRequestDataRelationshipsDevicesDataJson struct { - // The opaque resource ID that uniquely identifies the resource. - Id string `json:"id"` - - // The resource type. - Type string `json:"type"` -} - -// The data that describe the relationship between the resources. -type OrgDeviceActivityCreateRequestDataRelationshipsDevicesJson struct { - // Data corresponds to the JSON schema field "data". - Data []OrgDeviceActivityCreateRequestDataRelationshipsDevicesDataJson `json:"data"` +// Attributes with values that you’re changing as part of the create request. +type OrgDeviceActivityCreateRequestDataAttributes struct { + // The type of activity you want to create. + ActivityType OrgDeviceActivityTypeJson `json:"activityType"` } // The relationships you include in the request, and those that you can operate on. -type OrgDeviceActivityCreateRequestDataRelationshipsJson struct { +type OrgDeviceActivityCreateRequestDataRelationships struct { // Devices corresponds to the JSON schema field "devices". - Devices OrgDeviceActivityCreateRequestDataRelationshipsDevicesJson `json:"devices"` + Devices OrgDeviceActivityCreateRequestDataRelationshipsDevices `json:"devices"` // MdmServer corresponds to the JSON schema field "mdmServer". - MdmServer *OrgDeviceActivityCreateRequestDataRelationshipsMdmServerJson `json:"mdmServer,omitempty"` + MdmServer *OrgDeviceActivityCreateRequestDataRelationshipsMdmServer `json:"mdmServer,omitempty"` +} + +// The data that describe the relationship between the resources. +type OrgDeviceActivityCreateRequestDataRelationshipsDevices struct { + // Data corresponds to the JSON schema field "data". + Data []OrgDeviceActivityCreateRequestDataRelationshipsDevicesData `json:"data"` } // The type and ID of a related resource. -type OrgDeviceActivityCreateRequestDataRelationshipsMdmServerDataJson struct { +type OrgDeviceActivityCreateRequestDataRelationshipsDevicesData struct { // The opaque resource ID that uniquely identifies the resource. Id string `json:"id"` @@ -234,21 +238,30 @@ type OrgDeviceActivityCreateRequestDataRelationshipsMdmServerDataJson struct { } // The data that describe the relationship between the resources. -type OrgDeviceActivityCreateRequestDataRelationshipsMdmServerJson struct { +type OrgDeviceActivityCreateRequestDataRelationshipsMdmServer struct { // Data corresponds to the JSON schema field "data". - Data OrgDeviceActivityCreateRequestDataRelationshipsMdmServerDataJson `json:"data"` + Data OrgDeviceActivityCreateRequestDataRelationshipsMdmServerData `json:"data"` +} + +// The type and ID of a related resource. +type OrgDeviceActivityCreateRequestDataRelationshipsMdmServerData struct { + // The opaque resource ID that uniquely identifies the resource. + Id string `json:"id"` + + // The resource type. + Type string `json:"type"` } // The request body you use to update the device management service for a device. type OrgDeviceActivityCreateRequestJson struct { // The resource data. - Data OrgDeviceActivityCreateRequestDataJson `json:"data"` + Data OrgDeviceActivityCreateRequestData `json:"data"` } // The data structure that represents an organization device activity resource. type OrgDeviceActivityJson struct { // The resource’s attributes. - Attributes *OrgDeviceActivityAttributesJson `json:"attributes,omitempty"` + Attributes *OrgDeviceActivityAttributes `json:"attributes,omitempty"` // The opaque resource ID that uniquely identifies the resource. Id string `json:"id"` @@ -273,7 +286,7 @@ type OrgDeviceActivityResponseJson struct { type OrgDeviceActivityTypeJson string // Attributes that describe an organization device resource. -type OrgDeviceAttributesJson struct { +type OrgDeviceAttributes struct { // The date and time of adding the device to an organization. AddedToOrgDateTime *time.Time `json:"addedToOrgDateTime,omitempty"` @@ -308,7 +321,7 @@ type OrgDeviceAttributesJson struct { PartNumber *string `json:"partNumber,omitempty"` // The device’s Apple product family: iPhone, iPad,Mac, AppleTV, Watch, or Vision - ProductFamily *OrgDeviceAttributesJsonProductFamily `json:"productFamily,omitempty"` + ProductFamily *OrgDeviceAttributesProductFamily `json:"productFamily,omitempty"` // The device’s product type: (examples: iPhone14,3, iPad13,4, MacBookPro14,2) ProductType *string `json:"productType,omitempty"` @@ -318,14 +331,14 @@ type OrgDeviceAttributesJson struct { PurchaseSourceId *string `json:"purchaseSourceId,omitempty"` // The device’s purchase source type: APPLE, RESELLER, or MANUALLY_ADDED - PurchaseSourceType *OrgDeviceAttributesJsonPurchaseSourceType `json:"purchaseSourceType,omitempty"` + PurchaseSourceType *OrgDeviceAttributesPurchaseSourceType `json:"purchaseSourceType,omitempty"` // The device’s serial number. SerialNumber *string `json:"serialNumber,omitempty"` // The devices status: ASSIGNED or UNASSIGNED. If ASSIGNED, use a separate API to // get the information of the assigned server. - Status *OrgDeviceAttributesJsonStatus `json:"status,omitempty"` + Status *OrgDeviceAttributesStatus `json:"status,omitempty"` // The date and time of the most-recent update for the device. UpdatedDateTime *time.Time `json:"updatedDateTime,omitempty"` @@ -334,30 +347,30 @@ type OrgDeviceAttributesJson struct { WifiMacAddress *string `json:"wifiMacAddress,omitempty"` } -type OrgDeviceAttributesJsonProductFamily string +type OrgDeviceAttributesProductFamily string -const OrgDeviceAttributesJsonProductFamilyAppleTV OrgDeviceAttributesJsonProductFamily = "AppleTV" -const OrgDeviceAttributesJsonProductFamilyIPad OrgDeviceAttributesJsonProductFamily = "iPad" -const OrgDeviceAttributesJsonProductFamilyIPhone OrgDeviceAttributesJsonProductFamily = "iPhone" -const OrgDeviceAttributesJsonProductFamilyMac OrgDeviceAttributesJsonProductFamily = "Mac" -const OrgDeviceAttributesJsonProductFamilyVision OrgDeviceAttributesJsonProductFamily = "Vision" -const OrgDeviceAttributesJsonProductFamilyWatch OrgDeviceAttributesJsonProductFamily = "Watch" +const OrgDeviceAttributesProductFamilyAppleTV OrgDeviceAttributesProductFamily = "AppleTV" +const OrgDeviceAttributesProductFamilyIPad OrgDeviceAttributesProductFamily = "iPad" +const OrgDeviceAttributesProductFamilyIPhone OrgDeviceAttributesProductFamily = "iPhone" +const OrgDeviceAttributesProductFamilyMac OrgDeviceAttributesProductFamily = "Mac" +const OrgDeviceAttributesProductFamilyVision OrgDeviceAttributesProductFamily = "Vision" +const OrgDeviceAttributesProductFamilyWatch OrgDeviceAttributesProductFamily = "Watch" -type OrgDeviceAttributesJsonPurchaseSourceType string +type OrgDeviceAttributesPurchaseSourceType string -const OrgDeviceAttributesJsonPurchaseSourceTypeAPPLE OrgDeviceAttributesJsonPurchaseSourceType = "APPLE" -const OrgDeviceAttributesJsonPurchaseSourceTypeMANUALLYADDED OrgDeviceAttributesJsonPurchaseSourceType = "MANUALLY_ADDED" -const OrgDeviceAttributesJsonPurchaseSourceTypeRESELLER OrgDeviceAttributesJsonPurchaseSourceType = "RESELLER" +const OrgDeviceAttributesPurchaseSourceTypeAPPLE OrgDeviceAttributesPurchaseSourceType = "APPLE" +const OrgDeviceAttributesPurchaseSourceTypeMANUALLYADDED OrgDeviceAttributesPurchaseSourceType = "MANUALLY_ADDED" +const OrgDeviceAttributesPurchaseSourceTypeRESELLER OrgDeviceAttributesPurchaseSourceType = "RESELLER" -type OrgDeviceAttributesJsonStatus string +type OrgDeviceAttributesStatus string -const OrgDeviceAttributesJsonStatusASSIGNED OrgDeviceAttributesJsonStatus = "ASSIGNED" -const OrgDeviceAttributesJsonStatusUNASSIGNED OrgDeviceAttributesJsonStatus = "UNASSIGNED" +const OrgDeviceAttributesStatusASSIGNED OrgDeviceAttributesStatus = "ASSIGNED" +const OrgDeviceAttributesStatusUNASSIGNED OrgDeviceAttributesStatus = "UNASSIGNED" // The data structure that represents an organization device resource. type OrgDeviceJson struct { // The resource’s attributes. - Attributes *OrgDeviceAttributesJson `json:"attributes,omitempty"` + Attributes *OrgDeviceAttributes `json:"attributes,omitempty"` // The opaque resource ID that uniquely identifies the resource. Id string `json:"id"` @@ -366,23 +379,23 @@ type OrgDeviceJson struct { Links *ResourceLinksJson `json:"links,omitempty"` // Navigational links to related data and included resource types and IDs. - Relationships *OrgDeviceRelationshipsJson `json:"relationships,omitempty"` + Relationships *OrgDeviceRelationships `json:"relationships,omitempty"` // The resource type. Type string `json:"type"` } -// The links that describe the relationship between the resources. -type OrgDeviceRelationshipsAssignedServerJson struct { - // Links corresponds to the JSON schema field "links". - Links *RelationshipLinksJson `json:"links,omitempty"` -} - // The relationships you include in the request, and those that you can operate on. -type OrgDeviceRelationshipsJson struct { +type OrgDeviceRelationships struct { // The relationship representing a device and its assigned device management // service. - AssignedServer *OrgDeviceRelationshipsAssignedServerJson `json:"assignedServer,omitempty"` + AssignedServer *OrgDeviceRelationshipsAssignedServer `json:"assignedServer,omitempty"` +} + +// The links that describe the relationship between the resources. +type OrgDeviceRelationshipsAssignedServer struct { + // Links corresponds to the JSON schema field "links". + Links *RelationshipLinksJson `json:"links,omitempty"` } // Links related to the response document, including paging links. @@ -400,11 +413,11 @@ type PagedDocumentLinksJson struct { // Paging information for data responses. type PagingInformationJson struct { // The paging information details. - Paging PagingInformationPagingJson `json:"paging"` + Paging PagingInformationPaging `json:"paging"` } // Paging details, such as the total number of resources and the per-page limit. -type PagingInformationPagingJson struct { +type PagingInformationPaging struct { // The maximum number of resources to return per page. Limit int `json:"limit"`