diff --git a/.gitignore b/.gitignore index 10fcfcbd5..348badbd1 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ go.work # macOS File System .DS_Store + +clientconfig.json \ No newline at end of file diff --git a/README.md b/README.md index 33cf6abdb..1fa325ebd 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ For those who prefer using configuration files for setting up the client, the SD "log_export_path": "/your/log/path/", // optional, ensure permissions to file path "export_logs": true, // or false "hide_sensitive_data": false, // redact sensitive data from logs - "instance_domain": "https://lbgsandbox.jamfcloud.com", + "instance_domain": "https://yourinstance.jamfcloud.com", "auth_method": "oauth2", // or "basic" "client_id": "your_client_id", // Required if using oauth2 "client_secret": "your_client_secret", // Required if using oauth2 @@ -1129,44 +1129,57 @@ This documentation provides details on the API endpoints available for managing - Total Operations Covered: 8 -### Jamf Pro Classic API - Distribution Points +### Jamf Pro API - Distribution Points This documentation outlines the operations available for managing Distribution Points within Jamf Pro using the Classic API, which supports XML data structures. + + ## Operations -- [x] ✅ **GET** `/JSSResource/distributionpoints` +- [x] ✅ **GET** `/v1/distribution-points` - `GetDistributionPoints` operation retrieves a serialized list of all distribution points. -- [x] ✅ **GET** `/JSSResource/distributionpoints/id/{id}` +- [x] ✅ **GET** `/v1/distribution-points/{id}` - `GetDistributionPointByID` operation fetches a single distribution point by its ID. -- [x] ✅ **GET** `/JSSResource/distributionpoints/name/{name}` - - `GetDistributionPointByName` operation retrieves a distribution point by its name. + -- [x] ✅ **POST** `/JSSResource/distributionpoints/id/0` - - `CreateDistributionPoint` operation creates a new distribution point with the provided details. The ID `0` in the endpoint indicates creation. +- [x] ✅ **POST** `/v1/distribution-points` + - `CreateDistributionPoint` operation creates a new distribution point with the provided details. -- [x] ✅ **PUT** `/JSSResource/distributionpoints/id/{id}` +- [x] ✅ **PUT** `/v1/distribution-points/{id}` - `UpdateDistributionPointByID` operation updates an existing distribution point by its ID. -- [x] ✅ **PUT** `/JSSResource/distributionpoints/name/{name}` - - `UpdateDistributionPointByName` operation updates an existing distribution point by its name. + -- [x] ✅ **DELETE** `/JSSResource/distributionpoints/id/{id}` +- [x] ✅ **DELETE** `/v1/distribution-points/{id}` - `DeleteDistributionPointByID` operation deletes a distribution point by its ID. -- [x] ✅ **DELETE** `/JSSResource/distributionpoints/name/{name}` - - `DeleteDistributionPointByName` operation deletes a distribution point by its name. + + +- [] ❌ **POST** `/v1/distribution-points/delete-multiple` + - Currently not implemented + +- [] ❌ **PATCH** `/v1/distribution-points/{id}` + - Currently not implemented + +- [] ❌ **GET** `/v1/distribution-points/{id}/history` + - Currently not implemented + +- [] ❌ **POST** `/v1/distribution-points/{id}/history` + - Currently not implemented ## Summary - Total Endpoints Covered: 3 - - `/JSSResource/distributionpoints` - - `/JSSResource/distributionpoints/id/{id}` - - `/JSSResource/distributionpoints/name/{name}` + - `/v1/distribution-points` + - `/v1/distribution-points/{id}` -- Total Operations Covered: 8 +- Total Operations Covered: 5 ### Jamf Pro Classic API - Directory Bindings diff --git a/sdk/jamfpro/classicapi_file_share_distribution_points.go b/deprecated/sdk/classicapi_file_share_distribution_points.go.deprecated similarity index 100% rename from sdk/jamfpro/classicapi_file_share_distribution_points.go rename to deprecated/sdk/classicapi_file_share_distribution_points.go.deprecated diff --git a/deprecated/sdk/jamfproapi_jamf_protect.go b/deprecated/sdk/jamfproapi_jamf_protect.go.deprecated similarity index 100% rename from deprecated/sdk/jamfproapi_jamf_protect.go rename to deprecated/sdk/jamfproapi_jamf_protect.go.deprecated diff --git a/deprecated/sdk/jamfproapi_sso_settings.go b/deprecated/sdk/jamfproapi_sso_settings.go.deprecated similarity index 100% rename from deprecated/sdk/jamfproapi_sso_settings.go rename to deprecated/sdk/jamfproapi_sso_settings.go.deprecated diff --git a/examples/file_share_distribution_points/CreateFileShareDistributionPoint/CreateFileShareDistributionPoint.go b/examples/file_share_distribution_points/CreateFileShareDistributionPoint/CreateFileShareDistributionPoint.go index a54f48c5c..2aca3dee7 100644 --- a/examples/file_share_distribution_points/CreateFileShareDistributionPoint/CreateFileShareDistributionPoint.go +++ b/examples/file_share_distribution_points/CreateFileShareDistributionPoint/CreateFileShareDistributionPoint.go @@ -1,7 +1,7 @@ package main import ( - "encoding/xml" + "encoding/json" "fmt" "log" @@ -10,51 +10,70 @@ import ( func main() { // Define the path to the JSON configuration file - configFilePath := "/Users/dafyddwatkins/localtesting/jamfpro/clientconfig.json" - + configFilePath := "/Users/work/Documents/clientconfig.json" // Initialize the Jamf Pro client with the HTTP client configuration client, err := jamfpro.BuildClientWithConfigFile(configFilePath) if err != nil { log.Fatalf("Failed to initialize Jamf Pro client: %v", err) } - // New distribution point to create - newDistributionPoint := jamfpro.ResourceFileShareDistributionPoint{ - Name: "New York Share", - IPAddress: "ny.company.com", - IsMaster: true, - EnableLoadBalancing: false, - SSHUsername: "casperadmin", - Password: "password", - ConnectionType: "SMB", - ShareName: "Caspershare", - WorkgroupOrDomain: "COMPANY", - SharePort: 139, - ReadOnlyUsername: "casperinstall", - ReadOnlyPassword: "password", - ReadWriteUsername: "casperwrite", - ReadWritePassword: "password", - HTTPDownloadsEnabled: true, - HTTPURL: "http://ny.company.com/CasperShare", - Context: "CasperShare", - Protocol: "http", - Port: 80, - NoAuthenticationRequired: false, - UsernamePasswordRequired: true, - HTTPUsername: "casperinstall", - HTTPPassword: "password", + // Define variables for pointer fields + + // List of distribution points to create + distributionPoints := []jamfpro.ResourceFileShareDistributionPoint{ + { + Name: "example-distribution-point-min", + ServerName: "servername", + FileSharingConnectionType: "NONE", + HTTPSEnabled: true, + HTTPSPort: 443, + HTTPSSecurityType: "NONE", + }, + { + Name: "example-distribution-point-max-smb", + ServerName: "servername", + Principal: false, + // If EnableLoadBalancing is true, BackupDistributionPointID needs to have the + // valid ID if another distribution point + EnableLoadBalancing: true, + BackupDistributionPointID: "108", + FileSharingConnectionType: "SMB", + HTTPSEnabled: true, + HTTPSPort: 443, + HTTPSSecurityType: "USERNAME_PASSWORD", + HTTPSContext: "context", + HTTPSUsername: "username", + HTTPSPassword: "password", + ShareName: "sharename", + Workgroup: "workgroup", + Port: 443, + ReadWriteUsername: "username", + ReadWritePassword: "password", + ReadOnlyUsername: "username", + ReadOnlyPassword: "password", + SSHUsername: "username", + SSHPassword: "password", + LocalPathToShare: "parf", + }, + } + + // Loop through the list and create each distribution point + for _, distributionPoint := range distributionPoints { + createDistributionPointandLog(client, distributionPoint) } +} + +func createDistributionPointandLog(client *jamfpro.Client, newDistributionPoint jamfpro.ResourceFileShareDistributionPoint) { // Call CreateDistributionPoint function createdDistributionPoint, err := client.CreateDistributionPoint(&newDistributionPoint) if err != nil { - log.Fatalf("Error creating distribution point: %v", err) + log.Fatalf("Error creating distribution point: %v, %v", err, newDistributionPoint) } - // Pretty print the newly created distribution point in XML - createdDistributionPointXML, err := xml.MarshalIndent(createdDistributionPoint, "", " ") + createdDistributionPointJSON, err := json.MarshalIndent(createdDistributionPoint, "", " ") if err != nil { log.Fatalf("Error marshaling created distribution point data: %v", err) } - fmt.Println("Created Distribution Point:\n", string(createdDistributionPointXML)) + fmt.Println("Created Distribution Point:\n", string(createdDistributionPointJSON)) } diff --git a/examples/file_share_distribution_points/DeleteFileShareDistributionPointByID/DeleteFileShareDistributionPointByID.go b/examples/file_share_distribution_points/DeleteFileShareDistributionPointByID/DeleteFileShareDistributionPointByID.go index 5eb14cdce..38d70a766 100644 --- a/examples/file_share_distribution_points/DeleteFileShareDistributionPointByID/DeleteFileShareDistributionPointByID.go +++ b/examples/file_share_distribution_points/DeleteFileShareDistributionPointByID/DeleteFileShareDistributionPointByID.go @@ -9,7 +9,7 @@ import ( func main() { // Define the path to the JSON configuration file - configFilePath := "/Users/dafyddwatkins/localtesting/jamfpro/clientconfig.json" + configFilePath := "/Users/work/Documents/clientconfig.json" // Initialize the Jamf Pro client with the HTTP client configuration client, err := jamfpro.BuildClientWithConfigFile(configFilePath) @@ -18,7 +18,7 @@ func main() { } // ID of the distribution point to delete - distributionPointID := "1" // Replace with the actual ID + distributionPointID := "136" // Replace with the actual ID // Call DeleteDistributionPointByID function err = client.DeleteDistributionPointByID(distributionPointID) diff --git a/examples/file_share_distribution_points/DeleteFileShareDistributionPointByName/DeleteFileShareDistributionPointByName.go b/examples/file_share_distribution_points/DeleteFileShareDistributionPointByName/DeleteFileShareDistributionPointByName.go deleted file mode 100644 index 9311b82a3..000000000 --- a/examples/file_share_distribution_points/DeleteFileShareDistributionPointByName/DeleteFileShareDistributionPointByName.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import ( - "fmt" - "log" - - "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" -) - -func main() { - // Define the path to the JSON configuration file - configFilePath := "/Users/dafyddwatkins/localtesting/jamfpro/clientconfig.json" - - // Initialize the Jamf Pro client with the HTTP client configuration - client, err := jamfpro.BuildClientWithConfigFile(configFilePath) - if err != nil { - log.Fatalf("Failed to initialize Jamf Pro client: %v", err) - } - - // Name of the distribution point to delete - distributionPointName := "New York Share" // Replace with the actual name - - // Call DeleteDistributionPointByName function - err = client.DeleteDistributionPointByName(distributionPointName) - if err != nil { - log.Fatalf("Error deleting distribution point by name '%s': %v", distributionPointName, err) - } - - fmt.Printf("Distribution Point '%s' deleted successfully\n", distributionPointName) -} diff --git a/examples/file_share_distribution_points/GetFileShareDistributionPointByID/GetFileShareDistributionPointByID.go b/examples/file_share_distribution_points/GetFileShareDistributionPointByID/GetFileShareDistributionPointByID.go index e84edfa0d..db306301c 100644 --- a/examples/file_share_distribution_points/GetFileShareDistributionPointByID/GetFileShareDistributionPointByID.go +++ b/examples/file_share_distribution_points/GetFileShareDistributionPointByID/GetFileShareDistributionPointByID.go @@ -1,7 +1,7 @@ package main import ( - "encoding/xml" + "encoding/json" "fmt" "log" @@ -10,7 +10,7 @@ import ( func main() { // Define the path to the JSON configuration file - configFilePath := "/Users/dafyddwatkins/localtesting/jamfpro/clientconfig.json" + configFilePath := "/Users/work/Documents/clientconfig.json" // Initialize the Jamf Pro client with the HTTP client configuration client, err := jamfpro.BuildClientWithConfigFile(configFilePath) @@ -18,8 +18,8 @@ func main() { log.Fatalf("Failed to initialize Jamf Pro client: %v", err) } - // ID of the distribution point to fetch - distributionPointID := "1" // Replace with actual ID + // ID of the distribution point to delete + distributionPointID := "135" // Replace with the actual ID // Call GetDistributionPointByID function distributionPoint, err := client.GetDistributionPointByID(distributionPointID) @@ -27,10 +27,12 @@ func main() { log.Fatalf("Error fetching distribution point: %v", err) } - // Pretty print the distribution point in XML - distributionPointXML, err := xml.MarshalIndent(distributionPoint, "", " ") + // Pretty print the newly created distribution point in XML + distributionPointJSON, err := json.MarshalIndent(distributionPoint, "", " ") if err != nil { - log.Fatalf("Error marshaling distribution point data: %v", err) + log.Fatalf("Error marshaling created distribution point data: %v", err) } - fmt.Println("Fetched Distribution Point:\n", string(distributionPointXML)) + fmt.Println("Retrieved Distribution Point:\n", string(distributionPointJSON)) + + fmt.Println("Distribution Point retrieved successfully") } diff --git a/examples/file_share_distribution_points/GetFileShareDistributionPointByName/GetFileShareDistributionPointByName.go b/examples/file_share_distribution_points/GetFileShareDistributionPointByName/GetFileShareDistributionPointByName.go deleted file mode 100644 index 358f32a15..000000000 --- a/examples/file_share_distribution_points/GetFileShareDistributionPointByName/GetFileShareDistributionPointByName.go +++ /dev/null @@ -1,36 +0,0 @@ -package main - -import ( - "encoding/xml" - "fmt" - "log" - - "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" -) - -func main() { - // Define the path to the JSON configuration file - configFilePath := "/Users/dafyddwatkins/localtesting/jamfpro/clientconfig.json" - - // Initialize the Jamf Pro client with the HTTP client configuration - client, err := jamfpro.BuildClientWithConfigFile(configFilePath) - if err != nil { - log.Fatalf("Failed to initialize Jamf Pro client: %v", err) - } - - // Name of the distribution point to fetch - distributionPointName := "New York Share" // Replace with the actual name - - // Call GetDistributionPointByName function - distributionPoint, err := client.GetDistributionPointByName(distributionPointName) - if err != nil { - log.Fatalf("Error fetching distribution point: %v", err) - } - - // Pretty print the distribution point in XML - distributionPointXML, err := xml.MarshalIndent(distributionPoint, "", " ") - if err != nil { - log.Fatalf("Error marshaling distribution point data: %v", err) - } - fmt.Println("Fetched Distribution Point:\n", string(distributionPointXML)) -} diff --git a/examples/file_share_distribution_points/GetFileShareDistributionPoints/GetFileShareDistributionPoints.go b/examples/file_share_distribution_points/GetFileShareDistributionPoints/GetFileShareDistributionPoints.go index 0ed830acb..00ccfe732 100644 --- a/examples/file_share_distribution_points/GetFileShareDistributionPoints/GetFileShareDistributionPoints.go +++ b/examples/file_share_distribution_points/GetFileShareDistributionPoints/GetFileShareDistributionPoints.go @@ -1,7 +1,7 @@ package main import ( - "encoding/xml" + "encoding/json" "fmt" "log" @@ -10,7 +10,7 @@ import ( func main() { // Define the path to the JSON configuration file - configFilePath := "/Users/dafyddwatkins/localtesting/jamfpro/clientconfig.json" + configFilePath := "/Users/work/Documents/clientconfig.json" // Initialize the Jamf Pro client with the HTTP client configuration client, err := jamfpro.BuildClientWithConfigFile(configFilePath) @@ -18,16 +18,18 @@ func main() { log.Fatalf("Failed to initialize Jamf Pro client: %v", err) } - // Call GetDistributionPoints function - distributionPoints, err := client.GetDistributionPoints() + // Call GetDistributionPointByID function + distributionPoint, err := client.GetDistributionPoints() if err != nil { - log.Fatalf("Error fetching distribution points: %v", err) + log.Fatalf("Error fetching distribution point: %v", err) } - // Pretty print the distribution points in XML - distributionPointsXML, err := xml.MarshalIndent(distributionPoints, "", " ") // Indent with 4 spaces + // Pretty print the newly created distribution point in XML + distributionPointJSON, err := json.MarshalIndent(distributionPoint, "", " ") if err != nil { - log.Fatalf("Error marshaling distribution points data: %v", err) + log.Fatalf("Error marshaling created distribution point data: %v", err) } - fmt.Println("Fetched Distribution Points:\n", string(distributionPointsXML)) + fmt.Println("Retrieved Distribution Point:\n", string(distributionPointJSON)) + + fmt.Println("Distribution Point retrieved successfully") } diff --git a/examples/file_share_distribution_points/UpdateFileShareDistributionPointByID/UpdateFileShareDistributionPointByID.go b/examples/file_share_distribution_points/UpdateFileShareDistributionPointByID/UpdateFileShareDistributionPointByID.go index ab793a63b..0cac53f41 100644 --- a/examples/file_share_distribution_points/UpdateFileShareDistributionPointByID/UpdateFileShareDistributionPointByID.go +++ b/examples/file_share_distribution_points/UpdateFileShareDistributionPointByID/UpdateFileShareDistributionPointByID.go @@ -1,7 +1,7 @@ package main import ( - "encoding/xml" + "encoding/json" "fmt" "log" @@ -10,54 +10,62 @@ import ( func main() { // Define the path to the JSON configuration file - configFilePath := "/Users/dafyddwatkins/localtesting/jamfpro/clientconfig.json" - + configFilePath := "/Users/work/Documents/clientconfig.json" // Initialize the Jamf Pro client with the HTTP client configuration client, err := jamfpro.BuildClientWithConfigFile(configFilePath) if err != nil { log.Fatalf("Failed to initialize Jamf Pro client: %v", err) } - // New distribution point to create - updateDistributionPoint := jamfpro.ResourceFileShareDistributionPoint{ - Name: "Tokyo Share", - IPAddress: "tokyo.company.com", - IsMaster: true, - EnableLoadBalancing: false, - SSHUsername: "casperadmin", - Password: "password", - ConnectionType: "SMB", - ShareName: "Caspershare", - WorkgroupOrDomain: "COMPANY", - SharePort: 139, - ReadOnlyUsername: "casperinstall", - ReadOnlyPassword: "password", - ReadWriteUsername: "casperwrite", - ReadWritePassword: "password", - HTTPDownloadsEnabled: true, - HTTPURL: "http://ny.company.com/CasperShare", - Context: "CasperShare", - Protocol: "http", - Port: 80, - NoAuthenticationRequired: false, - UsernamePasswordRequired: true, - HTTPUsername: "casperinstall", - HTTPPassword: "password", + // Define variables for pointer fields + + // List of distribution points to create + updatedDistributionPoint := jamfpro.ResourceFileShareDistributionPoint{ + + Name: "example-updated-distribution-pointss", + ServerName: "servername", + Principal: false, + // If EnableLoadBalancing is true, BackupDistributionPointID needs to have the + // valid ID if another distribution point + EnableLoadBalancing: true, + BackupDistributionPointID: "108", + FileSharingConnectionType: "SMB", + HTTPSEnabled: true, + HTTPSPort: 443, + HTTPSSecurityType: "USERNAME_PASSWORD", + HTTPSContext: "context", + HTTPSUsername: "username", + HTTPSPassword: "password", + ShareName: "sharename", + Workgroup: "workgroup", + Port: 443, + ReadWriteUsername: "username", + ReadWritePassword: "password", + ReadOnlyUsername: "username", + ReadOnlyPassword: "password", + SSHUsername: "username", + SSHPassword: "password", + LocalPathToShare: "parf", } - // ID of the distribution point to update - distributionPointID := "1" // Replace with the actual ID + targetDistributionPoint := "135" + + // Loop through the list and create each distribution point + updateDistributionPointandLog(client, updatedDistributionPoint, targetDistributionPoint) + +} - // Call UpdateDistributionPointByID function - updatedDistributionPoint, err := client.UpdateDistributionPointByID(distributionPointID, &updateDistributionPoint) +func updateDistributionPointandLog(client *jamfpro.Client, distributionPointUpdateData jamfpro.ResourceFileShareDistributionPoint, id string) { + // Call CreateDistributionPoint function + updatedDistributionPoint, err := client.UpdateDistributionPointByID(id, &distributionPointUpdateData) if err != nil { - log.Fatalf("Error updating distribution point: %v", err) + log.Fatalf("Error creating distribution point: %v, %v", err, distributionPointUpdateData) } - // Pretty print the updated distribution point in XML - updatedDistributionPointXML, err := xml.MarshalIndent(updatedDistributionPoint, "", " ") + // Pretty print the newly created distribution point in XML + updatedDistributionPointJSON, err := json.MarshalIndent(updatedDistributionPoint, "", " ") if err != nil { - log.Fatalf("Error marshaling updated distribution point data: %v", err) + log.Fatalf("Error marshaling created distribution point data: %v", err) } - fmt.Println("Updated Distribution Point:\n", string(updatedDistributionPointXML)) + fmt.Println("Updated Distribution Point:\n", string(updatedDistributionPointJSON)) } diff --git a/examples/file_share_distribution_points/UpdateFileShareDistributionPointByName/UpdateFileShareDistributionPointByName.go b/examples/file_share_distribution_points/UpdateFileShareDistributionPointByName/UpdateFileShareDistributionPointByName.go deleted file mode 100644 index 8d2e6d100..000000000 --- a/examples/file_share_distribution_points/UpdateFileShareDistributionPointByName/UpdateFileShareDistributionPointByName.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "encoding/xml" - "fmt" - "log" - - "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" -) - -func main() { - // Define the path to the JSON configuration file - configFilePath := "/Users/dafyddwatkins/localtesting/jamfpro/clientconfig.json" - - // Initialize the Jamf Pro client with the HTTP client configuration - client, err := jamfpro.BuildClientWithConfigFile(configFilePath) - if err != nil { - log.Fatalf("Failed to initialize Jamf Pro client: %v", err) - } - - // New distribution point to create - updateDistributionPoint := jamfpro.ResourceFileShareDistributionPoint{ - Name: "New York Share", - IPAddress: "ny.company.com", - IsMaster: true, - EnableLoadBalancing: false, - SSHUsername: "casperadmin", - Password: "password", - ConnectionType: "SMB", - ShareName: "Caspershare", - WorkgroupOrDomain: "COMPANY", - SharePort: 139, - ReadOnlyUsername: "casperinstall", - ReadOnlyPassword: "password", - ReadWriteUsername: "casperwrite", - ReadWritePassword: "password", - HTTPDownloadsEnabled: true, - HTTPURL: "http://ny.company.com/CasperShare", - Context: "CasperShare", - Protocol: "http", - Port: 80, - NoAuthenticationRequired: false, - UsernamePasswordRequired: true, - HTTPUsername: "casperinstall", - HTTPPassword: "password", - } - - // Name of the distribution point to update - distributionPointName := "Tokyo Share" // Replace with the actual name - - // Call UpdateDistributionPointByName function - updatedDistributionPoint, err := client.UpdateDistributionPointByName(distributionPointName, &updateDistributionPoint) - if err != nil { - log.Fatalf("Error updating distribution point: %v", err) - } - - // Pretty print the updated distribution point in XML - updatedDistributionPointXML, err := xml.MarshalIndent(updatedDistributionPoint, "", " ") - if err != nil { - log.Fatalf("Error marshaling updated distribution point data: %v", err) - } - fmt.Println("Updated Distribution Point:\n", string(updatedDistributionPointXML)) -} diff --git a/examples/macos_configuration_profiles/UpdateMacOSConfigurationProfileByIDWithFileUpload/DOCK.mobileconfig b/examples/macos_configuration_profiles/UpdateMacOSConfigurationProfileByIDWithFileUpload/DOCK.mobileconfig index ac01b92bb..d045745ef 100644 --- a/examples/macos_configuration_profiles/UpdateMacOSConfigurationProfileByIDWithFileUpload/DOCK.mobileconfig +++ b/examples/macos_configuration_profiles/UpdateMacOSConfigurationProfileByIDWithFileUpload/DOCK.mobileconfig @@ -14,7 +14,7 @@ PayloadIdentifier 6756212F-E97A-4EEF-91C1-F8C5CD3A11F9 PayloadOrganization - Lloyds Bank + DeploymentTheory PayloadType com.apple.dock PayloadUUID @@ -76,7 +76,7 @@ PayloadIdentifier 2359960C-3E2F-4159-B3D2-90D7804AEFF2 PayloadOrganization - Lloyds Bank + DeploymentTheory PayloadRemovalDisallowed PayloadScope diff --git a/examples/support_files/accessibility-chara-sub-test.mobileconfig b/examples/support_files/accessibility-chara-sub-test.mobileconfig index 31b274a1d..ed47e053f 100644 --- a/examples/support_files/accessibility-chara-sub-test.mobileconfig +++ b/examples/support_files/accessibility-chara-sub-test.mobileconfig @@ -1 +1 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1"><dict><key>PayloadUUID</key><string>5D73158F-BAD0-4D93-9D32-DC4837D6A6AC</string><key>PayloadType</key><string>Configuration</string><key>PayloadOrganization</key><string>Lloyds Bank</string><key>PayloadIdentifier</key><string>5D73158F-BAD0-4D93-9D32-DC4837D6A6AC</string><key>PayloadDisplayName</key><string>accessibility</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>PayloadRemovalDisallowed</key><true/><key>PayloadScope</key><string>System</string><key>PayloadContent</key><array><dict><key>PayloadUUID</key><string>955481F6-5C70-40F7-A96B-78AF47E9C3AA</string><key>PayloadType</key><string>com.apple.universalaccess</string><key>PayloadOrganization</key><string>Lloyds Bank</string><key>PayloadIdentifier</key><string>955481F6-5C70-40F7-A96B-78AF47E9C3AA</string><key>PayloadDisplayName</key><string>Accessibility</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>closeViewScrollWheelToggle</key><true/><key>closeViewHotkeysEnabled</key><true/><key>closeViewNearPoint</key><integer>10</integer><key>closeViewFarPoint</key><integer>1</integer><key>closeViewShowPreview</key><true/><key>closeViewSmoothImages</key><true/><key>whiteOnBlack</key><true/><key>grayscale</key><true/><key>contrast</key><integer>0</integer><key>mouseDriverCursorSize</key><integer>1</integer><key>voiceOverOnOffKey</key><true/><key>flashScreen</key><true/><key>stereoAsMono</key><true/><key>stickyKey</key><true/><key>stickyKeyBeepOnModifier</key><true/><key>stickyKeyShowWindow</key><true/><key>slowKey</key><true/><key>slowKeyBeepOn</key><true/><key>slowKeyDelay</key><integer>0</integer><key>mouseDriver</key><true/><key>mouseDriverInitialDelay</key><real>1.0</real><key>mouseDriverMaxSpeed</key><integer>3</integer><key>mouseDriverIgnoreTrackpad</key><false/></dict></array></dict></plist> \ No newline at end of file +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1"><dict><key>PayloadUUID</key><string>5D73158F-BAD0-4D93-9D32-DC4837D6A6AC</string><key>PayloadType</key><string>Configuration</string><key>PayloadOrganization</key><string>DeploymentTheory</string><key>PayloadIdentifier</key><string>5D73158F-BAD0-4D93-9D32-DC4837D6A6AC</string><key>PayloadDisplayName</key><string>accessibility</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>PayloadRemovalDisallowed</key><true/><key>PayloadScope</key><string>System</string><key>PayloadContent</key><array><dict><key>PayloadUUID</key><string>955481F6-5C70-40F7-A96B-78AF47E9C3AA</string><key>PayloadType</key><string>com.apple.universalaccess</string><key>PayloadOrganization</key><string>DeploymentTheory</string><key>PayloadIdentifier</key><string>955481F6-5C70-40F7-A96B-78AF47E9C3AA</string><key>PayloadDisplayName</key><string>Accessibility</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>closeViewScrollWheelToggle</key><true/><key>closeViewHotkeysEnabled</key><true/><key>closeViewNearPoint</key><integer>10</integer><key>closeViewFarPoint</key><integer>1</integer><key>closeViewShowPreview</key><true/><key>closeViewSmoothImages</key><true/><key>whiteOnBlack</key><true/><key>grayscale</key><true/><key>contrast</key><integer>0</integer><key>mouseDriverCursorSize</key><integer>1</integer><key>voiceOverOnOffKey</key><true/><key>flashScreen</key><true/><key>stereoAsMono</key><true/><key>stickyKey</key><true/><key>stickyKeyBeepOnModifier</key><true/><key>stickyKeyShowWindow</key><true/><key>slowKey</key><true/><key>slowKeyBeepOn</key><true/><key>slowKeyDelay</key><integer>0</integer><key>mouseDriver</key><true/><key>mouseDriverInitialDelay</key><real>1.0</real><key>mouseDriverMaxSpeed</key><integer>3</integer><key>mouseDriverIgnoreTrackpad</key><false/></dict></array></dict></plist> \ No newline at end of file diff --git a/examples/support_files/configprofile_export/Test from iMazing JL Friday 19.mobileconfig b/examples/support_files/configprofile_export/Test from iMazing JL Friday 19.mobileconfig index c384299b3..a19d4a72d 100644 --- a/examples/support_files/configprofile_export/Test from iMazing JL Friday 19.mobileconfig +++ b/examples/support_files/configprofile_export/Test from iMazing JL Friday 19.mobileconfig @@ -1 +1 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1"><dict><key>PayloadUUID</key><string>04fdf599-0c06-4564-a996-5954c30c0491</string><key>PayloadType</key><string>Configuration</string><key>PayloadOrganization</key><string>Lloyds Bank</string><key>PayloadIdentifier</key><string>04fdf599-0c06-4564-a996-5954c30c0491</string><key>PayloadDisplayName</key><string>Test from iMazing JL Friday 19</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>PayloadRemovalDisallowed</key><true/><key>PayloadScope</key><string>System</string><key>PayloadContent</key><array><dict><key>PayloadUUID</key><string>2F65D244-8BFC-46CE-8FC3-8222EE47F57D</string><key>PayloadType</key><string>com.apple.shareddeviceconfiguration</string><key>PayloadOrganization</key><string>Lloyds Bank</string><key>PayloadIdentifier</key><string>com.apple.shareddeviceconfiguration.2F65D244-8BFC-46CE-8FC3-8222EE47F57D</string><key>PayloadDisplayName</key><string>Lock Screen Message</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>LockScreenFootnote</key><string>Look up</string><key>IfLostReturnToMessage</key><string>If lost make this script work before returning</string></dict></array></dict></plist> \ No newline at end of file +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1"><dict><key>PayloadUUID</key><string>04fdf599-0c06-4564-a996-5954c30c0491</string><key>PayloadType</key><string>Configuration</string><key>PayloadOrganization</key><string>DeploymentTheory</string><key>PayloadIdentifier</key><string>04fdf599-0c06-4564-a996-5954c30c0491</string><key>PayloadDisplayName</key><string>Test from iMazing JL Friday 19</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>PayloadRemovalDisallowed</key><true/><key>PayloadScope</key><string>System</string><key>PayloadContent</key><array><dict><key>PayloadUUID</key><string>2F65D244-8BFC-46CE-8FC3-8222EE47F57D</string><key>PayloadType</key><string>com.apple.shareddeviceconfiguration</string><key>PayloadOrganization</key><string>DeploymentTheory</string><key>PayloadIdentifier</key><string>com.apple.shareddeviceconfiguration.2F65D244-8BFC-46CE-8FC3-8222EE47F57D</string><key>PayloadDisplayName</key><string>Lock Screen Message</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>LockScreenFootnote</key><string>Look up</string><key>IfLostReturnToMessage</key><string>If lost make this script work before returning</string></dict></array></dict></plist> \ No newline at end of file diff --git a/examples/support_files/sec-baseline-test.mobileconfig b/examples/support_files/sec-baseline-test.mobileconfig index da3c9473f..3d17f0207 100644 --- a/examples/support_files/sec-baseline-test.mobileconfig +++ b/examples/support_files/sec-baseline-test.mobileconfig @@ -1 +1 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1"><dict><key>PayloadUUID</key><string>76e6fef7-dd98-491e-9cb8-30e2b8bbec6c</string><key>PayloadType</key><string>Configuration</string><key>PayloadOrganization</key><string>macOS Security Compliance Project</string><key>PayloadIdentifier</key><string>76e6fef7-dd98-491e-9cb8-30e2b8bbec6c</string><key>PayloadDisplayName</key><string>WiFi Test</string><key>PayloadDescription</key><string>Created: 2023-11-16Configuration settings for the com.apple.loginwindow preference domain.</string><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>ConsentText</key><dict><key>default</key><string>THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.</string></dict><key>PayloadRemovalDisallowed</key><true/><key>PayloadScope</key><string>System</string><key>PayloadContent</key><array><dict><key>PayloadUUID</key><string>681643d5-68a3-4e14-9978-155e1ecf8c0c</string><key>PayloadType</key><string>com.apple.loginwindow</string><key>PayloadOrganization</key><string>Lloyds Bank</string><key>PayloadIdentifier</key><string>alacarte.macOS.cis_lvl1.681643d5-68a3-4e14-9978-155e1ecf8c0c</string><key>PayloadDisplayName</key><string>Login Window</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>LoginwindowText</key><string>Center for Internet Security Test Message</string><key>SHOWFULLNAME</key><true/><key>HideLocalUsers</key><false/><key>HideMobileAccounts</key><false/><key>IncludeNetworkUser</key><false/><key>HideAdminUsers</key><false/><key>SHOWOTHERUSERS_MANAGED</key><true/><key>ShutDownDisabled</key><true/><key>UseComputerNameForComputerRecordName</key><false/><key>EnableExternalAccounts</key><true/><key>DisableConsoleAccess</key><false/><key>com.apple.login.mcx.DisableAutoLoginClient</key><true/><key>AdminMayDisableMCX</key><false/><key>LocalUserLoginEnabled</key><true/><key>LocalUsersHaveWorkgroups</key><false/><key>FlattenUserWorkgroups</key><false/><key>CombineUserWorkgroups</key><true/><key>AlwaysShowWorkgroupDialog</key><false/><key>RetriesUntilHint</key><integer>0</integer><key>AllowList</key><array/><key>DenyList</key><array/></dict></array></dict></plist> \ No newline at end of file +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1"><dict><key>PayloadUUID</key><string>76e6fef7-dd98-491e-9cb8-30e2b8bbec6c</string><key>PayloadType</key><string>Configuration</string><key>PayloadOrganization</key><string>macOS Security Compliance Project</string><key>PayloadIdentifier</key><string>76e6fef7-dd98-491e-9cb8-30e2b8bbec6c</string><key>PayloadDisplayName</key><string>WiFi Test</string><key>PayloadDescription</key><string>Created: 2023-11-16Configuration settings for the com.apple.loginwindow preference domain.</string><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>ConsentText</key><dict><key>default</key><string>THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.</string></dict><key>PayloadRemovalDisallowed</key><true/><key>PayloadScope</key><string>System</string><key>PayloadContent</key><array><dict><key>PayloadUUID</key><string>681643d5-68a3-4e14-9978-155e1ecf8c0c</string><key>PayloadType</key><string>com.apple.loginwindow</string><key>PayloadOrganization</key><string>DeploymentTheory</string><key>PayloadIdentifier</key><string>alacarte.macOS.cis_lvl1.681643d5-68a3-4e14-9978-155e1ecf8c0c</string><key>PayloadDisplayName</key><string>Login Window</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>LoginwindowText</key><string>Center for Internet Security Test Message</string><key>SHOWFULLNAME</key><true/><key>HideLocalUsers</key><false/><key>HideMobileAccounts</key><false/><key>IncludeNetworkUser</key><false/><key>HideAdminUsers</key><false/><key>SHOWOTHERUSERS_MANAGED</key><true/><key>ShutDownDisabled</key><true/><key>UseComputerNameForComputerRecordName</key><false/><key>EnableExternalAccounts</key><true/><key>DisableConsoleAccess</key><false/><key>com.apple.login.mcx.DisableAutoLoginClient</key><true/><key>AdminMayDisableMCX</key><false/><key>LocalUserLoginEnabled</key><true/><key>LocalUsersHaveWorkgroups</key><false/><key>FlattenUserWorkgroups</key><false/><key>CombineUserWorkgroups</key><true/><key>AlwaysShowWorkgroupDialog</key><false/><key>RetriesUntilHint</key><integer>0</integer><key>AllowList</key><array/><key>DenyList</key><array/></dict></array></dict></plist> \ No newline at end of file diff --git a/sdk/jamfpro/classicapi_command_flush.go b/sdk/jamfpro/classicapi_command_flush.go index 8abae47fa..f05672c8f 100644 --- a/sdk/jamfpro/classicapi_command_flush.go +++ b/sdk/jamfpro/classicapi_command_flush.go @@ -145,7 +145,7 @@ func (c *Client) ClearPendingMobileDeviceMDMCommandsByMobileDeviceGroupID(mobile // ClearFailedAndPendingMDMCommandsByComputerID clears all failed & pending MDM commands for a specific computer. func (c *Client) ClearFailedAndPendingComputerMDMCommandsByComputerID(computerId string) error { - endpoint := fmt.Sprintf("%s/computers/id/%s/status/Pending%2BFailed", uriCommandFlush, computerId) + endpoint := fmt.Sprintf("%s/computers/id/%s/status/Pending+Failed", uriCommandFlush, computerId) resp, err := c.HTTP.DoRequest("DELETE", endpoint, nil, nil) if err != nil { @@ -162,7 +162,7 @@ func (c *Client) ClearFailedAndPendingComputerMDMCommandsByComputerID(computerId // ClearFailedAndPendingComputerMDMCommandsByComputerGroupID clears all failed & pending MDM commands for a specific // smart or static computer group. func (c *Client) ClearFailedAndPendingComputerMDMCommandsByComputerGroupID(computerGroupId string) error { - endpoint := fmt.Sprintf("%s/computergroups/id/%s/status/Pending%2BFailed", uriCommandFlush, computerGroupId) + endpoint := fmt.Sprintf("%s/computergroups/id/%s/status/Pending+Failed", uriCommandFlush, computerGroupId) resp, err := c.HTTP.DoRequest("DELETE", endpoint, nil, nil) if err != nil { @@ -179,7 +179,7 @@ func (c *Client) ClearFailedAndPendingComputerMDMCommandsByComputerGroupID(compu // ClearFailedAndPendingMobileDeviceMDMCommandsByMobileDeviceID clears all failed & pending MDM commands // for a specific mobile device. func (c *Client) ClearFailedAndPendingMobileDeviceMDMCommandsByMobileDeviceID(mobileDeviceID string) error { - endpoint := fmt.Sprintf("%s/mobiledevices/id/%s/status/Pending%2BFailed", uriCommandFlush, mobileDeviceID) + endpoint := fmt.Sprintf("%s/mobiledevices/id/%s/status/Pending+Failed", uriCommandFlush, mobileDeviceID) resp, err := c.HTTP.DoRequest("DELETE", endpoint, nil, nil) if err != nil { @@ -196,7 +196,7 @@ func (c *Client) ClearFailedAndPendingMobileDeviceMDMCommandsByMobileDeviceID(mo // ClearFailedAndPendingMobileDeviceMDMCommandsByMobileDeviceGroupID clears all failed MDM commands // for a specific mobile device group. func (c *Client) ClearFailedAndPendingMobileDeviceMDMCommandsByMobileDeviceGroupID(mobileDeviceGroupId string) error { - endpoint := fmt.Sprintf("%s/mobiledevicegroups/id/%s/status/Pending%2BFailed", uriCommandFlush, mobileDeviceGroupId) + endpoint := fmt.Sprintf("%s/mobiledevicegroups/id/%s/status/Pending+Failed", uriCommandFlush, mobileDeviceGroupId) resp, err := c.HTTP.DoRequest("DELETE", endpoint, nil, nil) if err != nil { diff --git a/sdk/jamfpro/jamfproapi_file_share_distribution_points.go b/sdk/jamfpro/jamfproapi_file_share_distribution_points.go new file mode 100644 index 000000000..687a4864c --- /dev/null +++ b/sdk/jamfpro/jamfproapi_file_share_distribution_points.go @@ -0,0 +1,124 @@ +package jamfpro + +import ( + "fmt" +) + +const uriDistributionPoints = "/api/v1/distribution-points" + +type ResponseDistributionPointList struct { + TotalCount int `json:"totalCount"` + Results []ResourceFileShareDistributionPoint `json:"results"` +} + +type ResourceFileShareDistributionPoint struct { + ShareName string `json:"shareName,omitempty"` + Workgroup string `json:"workgroup,omitempty"` + Port int `json:"port,omitempty"` + ReadWriteUsername string `json:"readWriteUsername,omitempty"` + ReadWritePassword string `json:"readWritePassword,omitempty"` + ReadOnlyUsername string `json:"readOnlyUsername,omitempty"` + ReadOnlyPassword string `json:"readOnlyPassword,omitempty"` + ID string `json:"id,omitempty"` + Name string `json:"name"` + ServerName string `json:"serverName"` + Principal bool `json:"principal,omitempty"` + BackupDistributionPointID string `json:"backupDistributionPointId,omitempty"` + SSHUsername string `json:"sshUsername,omitempty"` + SSHPassword string `json:"sshPassword,omitempty"` + LocalPathToShare string `json:"localPathToShare,omitempty"` + FileSharingConnectionType string `json:"fileSharingConnectionType"` + HTTPSEnabled bool `json:"httpsEnabled"` + HTTPSPort int `json:"httpsPort"` + HTTPSContext string `json:"httpsContext,omitempty"` + HTTPSSecurityType string `json:"httpsSecurityType"` + HTTPSUsername string `json:"httpsUsername,omitempty"` + HTTPSPassword string `json:"httpsPassword,omitempty"` + EnableLoadBalancing bool `json:"enableLoadBalancing,omitempty"` +} + +type ResponseFileShareDistributionPointCreatedAndUpdated struct { + ID string `json:"id,omitempty"` + Href string `json:"href,omitempty"` +} + +func (c *Client) GetDistributionPoints() (*ResponseDistributionPointList, error) { + endpoint := uriDistributionPoints + + var distributionPoints ResponseDistributionPointList + + _, err := c.HTTP.DoRequest("GET", endpoint, nil, &distributionPoints) + + if err != nil { + return nil, fmt.Errorf(errMsgFailedGet, "file share distribution point", err) + } + + return &distributionPoints, nil +} + +// GetDistributionPointByID retrieves a single distribution point by its ID. +func (c *Client) CreateDistributionPoint(payload *ResourceFileShareDistributionPoint) (*ResponseFileShareDistributionPointCreatedAndUpdated, error) { + endpoint := uriDistributionPoints + var createdResponseObject ResponseFileShareDistributionPointCreatedAndUpdated + + resp, err := c.HTTP.DoRequest("POST", endpoint, payload, &createdResponseObject) + if err != nil { + return nil, fmt.Errorf(errMsgFailedCreate, "file share distribution point", err) + } + + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } + + return &createdResponseObject, nil + // return nil, nil +} + +func (c *Client) GetDistributionPointByID(id string) (*ResourceFileShareDistributionPoint, error) { + var out ResourceFileShareDistributionPoint + endpoint := fmt.Sprintf("%s/%s", uriDistributionPoints, id) + + resp, err := c.HTTP.DoRequest("GET", endpoint, nil, &out) + + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } + + if err != nil { + fmt.Printf(errMsgFailedGetByID, "file share distribution point", id, err) + return nil, err + } + + return &out, nil +} + +func (c *Client) UpdateDistributionPointByID(id string, distributionPointUpdate *ResourceFileShareDistributionPoint) (*ResourceFileShareDistributionPoint, error) { + endpoint := fmt.Sprintf("%s/%s", uriDistributionPoints, id) + + var response ResourceFileShareDistributionPoint + resp, err := c.HTTP.DoRequest("PUT", endpoint, distributionPointUpdate, &response) + if err != nil { + return nil, fmt.Errorf(errMsgFailedUpdateByID, "file share distribution point", id, err) + } + + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } + + return &response, nil +} + +func (c *Client) DeleteDistributionPointByID(id string) error { + endpoint := fmt.Sprintf("%s/%s", uriDistributionPoints, id) + + resp, err := c.HTTP.DoRequest("DELETE", endpoint, nil, nil) + if err != nil { + return fmt.Errorf(errMsgFailedDeleteByID, "file share distribution point", id, err) + } + + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } + + return nil +} diff --git a/sdk/jamfpro/jamfproapi_file_share_distribution_points_test.go b/sdk/jamfpro/jamfproapi_file_share_distribution_points_test.go new file mode 100644 index 000000000..43e47bb7b --- /dev/null +++ b/sdk/jamfpro/jamfproapi_file_share_distribution_points_test.go @@ -0,0 +1,182 @@ +package jamfpro + +import ( + "encoding/json" + "reflect" + "testing" +) + +// This testing function could be done better, as marshalling in an out of maps can cause formatting differences +// which will not be representative of how the api would recieve the unmarshalled struct. +// @TODO: make use of jsonfiles in the mocks folder to import and export configurations. +func TestResourceFileShareDistributionPoint_MarshalJSON(t *testing.T) { + tests := []struct { + name string + input ResourceFileShareDistributionPoint + expected map[string]any + }{ + { + name: "Full struct with all fields", + input: ResourceFileShareDistributionPoint{ + ShareName: "TestShare", + Workgroup: "TestWorkgroup", + Port: 445, + ReadWriteUsername: "rwuser", + ReadWritePassword: "rwpass", + ReadOnlyUsername: "rouser", + ReadOnlyPassword: "ropass", + ID: "1", + Name: "Test Distribution Point", + ServerName: "server.example.com", + Principal: true, + BackupDistributionPointID: "2", + SSHUsername: "sshuser", + SSHPassword: "sshpass", + LocalPathToShare: "/path/to/share", + FileSharingConnectionType: "SMB", + HTTPSEnabled: true, + HTTPSPort: 443, + HTTPSContext: "context", + HTTPSSecurityType: "BASIC", + HTTPSUsername: "httpsuser", + HTTPSPassword: "httpspass", + EnableLoadBalancing: true, + }, + expected: map[string]any{ + "shareName": "TestShare", + "workgroup": "TestWorkgroup", + "port": float64(445), + "readWriteUsername": "rwuser", + "readWritePassword": "rwpass", + "readOnlyUsername": "rouser", + "readOnlyPassword": "ropass", + "id": "1", + "name": "Test Distribution Point", + "serverName": "server.example.com", + "principal": true, + "backupDistributionPointId": "2", + "sshUsername": "sshuser", + "sshPassword": "sshpass", + "localPathToShare": "/path/to/share", + "fileSharingConnectionType": "SMB", + "httpsEnabled": true, + "httpsPort": float64(443), + "httpsContext": "context", + "httpsSecurityType": "BASIC", + "httpsUsername": "httpsuser", + "httpsPassword": "httpspass", + "enableLoadBalancing": true, + }, + }, + { + name: "Required keys are correctly zeroed and present", + input: ResourceFileShareDistributionPoint{ + + }, + expected: map[string]any{ + "fileSharingConnectionType":"", + "httpsEnabled": false, + "httpsPort": float64(0), + "httpsSecurityType": "", + "name": "", + "serverName": "", + }, + }, + { + name: "Minimal required fields only", + input: ResourceFileShareDistributionPoint{ + Name: "Minimal DP", + ServerName: "minimal.example.com", + FileSharingConnectionType: "NONE", + HTTPSEnabled: false, + HTTPSPort: 443, + HTTPSSecurityType: "NONE", + }, + // expected: "{\"name\":\"Minimal DP\",\"serverName\":\"minimal.example.com\",\"fileSharingConnectionType\":\"NONE\",\"httpsEnabled\":false,\"httpsPort\":443,\"httpsSecurityType\":\"NONE\"}", + expected: map[string]any{ + "name": "Minimal DP", + "serverName": "minimal.example.com", + "fileSharingConnectionType": "NONE", + "httpsEnabled": false, + "httpsPort": float64(443), + "httpsSecurityType": "NONE", + }, + }, + { + name: "Maximal fields for SMB", + input: ResourceFileShareDistributionPoint{ + Principal: true, + BackupDistributionPointID: "3", + FileSharingConnectionType: "SMB", + Port: 139, + HTTPSEnabled: true, + HTTPSPort: 443, + HTTPSSecurityType: "USERNAME_PASSWORD", + EnableLoadBalancing: true, + Name: "distributionpointname", + ServerName: "servername", + SSHUsername: "sshusername1", + SSHPassword: "sshpassword1", + LocalPathToShare: "/path/dir/file", + ShareName: "sharename", + Workgroup: "workgroupname", + ReadWriteUsername: "readusername", + ReadWritePassword: "readpassword1", + ReadOnlyUsername: "readonlyusername", + ReadOnlyPassword: "readonlypassword", + HTTPSContext: "httpcontext", + HTTPSUsername: "httpsusername", + HTTPSPassword: "httpspassword", + }, + expected: map[string]any{ + "principal": true, + "backupDistributionPointId": "3", + "fileSharingConnectionType": "SMB", + "port": float64(139), + "httpsEnabled": true, + "httpsPort": float64(443), + "httpsSecurityType": "USERNAME_PASSWORD", + "enableLoadBalancing": true, + "name": "distributionpointname", + "serverName": "servername", + "sshUsername": "sshusername1", + "sshPassword": "sshpassword1", + "localPathToShare": "/path/dir/file", + "shareName": "sharename", + "workgroup": "workgroupname", + "readWriteUsername": "readusername", + "readWritePassword": "readpassword1", + "readOnlyUsername": "readonlyusername", + "readOnlyPassword": "readonlypassword", + "httpsContext": "httpcontext", + "httpsUsername": "httpsusername", + "httpsPassword": "httpspassword", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Marshal the input struct + actualBytes, err := json.Marshal(tt.input) + if err != nil { + t.Errorf("Failed to marshal struct: %v", err) + return + } + + // Unmarshal actual result back to map for comparison + var actualMap map[string]any + if err := json.Unmarshal(actualBytes, &actualMap); err != nil { + t.Errorf("Failed to unmarshal actual result: %v", err) + return + } + + // Compare the maps directly (order-independent) + if !reflect.DeepEqual(actualMap, tt.expected) { + actualJSON, _ := json.MarshalIndent(actualMap, "", " ") + expectedJSON, _ := json.MarshalIndent(tt.expected, "", " ") + t.Errorf("JSON marshalling mismatch:\nwant: %s\ngot: %s", expectedJSON, actualJSON) + } + }) + } +} \ No newline at end of file