From fd958d0d4fe2da95b497e3252b36a1082bba4767 Mon Sep 17 00:00:00 2001 From: ShocOne Date: Sat, 28 Oct 2023 19:11:28 +0100 Subject: [PATCH 1/4] 1st itteratiion of computer prestages --- .../GetComputerPrestageByID.go | 51 ++++++ .../GetComputerPrestageNameByID.go | 45 +++++ .../GetComputerPrestages.go | 48 +++++ sdk/jamfpro/jamfproapi_categories.go | 2 +- sdk/jamfpro/jamfproapi_computer_prestages.go | 169 ++++++++++++++++++ 5 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 examples/computer_prestages/GetComputerPrestageByID/GetComputerPrestageByID.go create mode 100644 examples/computer_prestages/GetComputerPrestageNameByID/GetComputerPrestageNameByID.go create mode 100644 examples/computer_prestages/GetComputerPrestages/GetComputerPrestages.go create mode 100644 sdk/jamfpro/jamfproapi_computer_prestages.go diff --git a/examples/computer_prestages/GetComputerPrestageByID/GetComputerPrestageByID.go b/examples/computer_prestages/GetComputerPrestageByID/GetComputerPrestageByID.go new file mode 100644 index 00000000..05feffb9 --- /dev/null +++ b/examples/computer_prestages/GetComputerPrestageByID/GetComputerPrestageByID.go @@ -0,0 +1,51 @@ +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 inside the main function + configFilePath := "/Users/dafyddwatkins/GitHub/deploymenttheory/go-api-sdk-jamfpro/clientauth.json" + + // Load the client OAuth credentials from the configuration file + authConfig, err := jamfpro.LoadClientAuthConfig(configFilePath) + if err != nil { + log.Fatalf("Failed to load client OAuth configuration: %v", err) + } + + // Configuration for the jamfpro + config := jamfpro.Config{ + InstanceName: authConfig.InstanceName, + DebugMode: true, + Logger: jamfpro.NewDefaultLogger(), + ClientID: authConfig.ClientID, + ClientSecret: authConfig.ClientSecret, + } + + // Create a new jamfpro client instance + client, err := jamfpro.NewClient(config) + if err != nil { + log.Fatalf("Failed to create Jamf Pro client: %v", err) + } + + // Define the ID of the Computer Prestage you want to fetch as a string + prestageID := "1" // Replace with the actual prestage ID as a string + + // Call GetComputerPrestageByID function + prestage, err := client.GetComputerPrestageByID(prestageID) + if err != nil { + log.Fatalf("Error fetching Computer Prestage by ID: %v", err) + } + + // Pretty print the prestage in XML + prestageXML, err := xml.MarshalIndent(prestage, "", " ") // Indent with 4 spaces + if err != nil { + log.Fatalf("Error marshaling Computer Prestage data: %v", err) + } + fmt.Println("Fetched Computer Prestage:\n", string(prestageXML)) +} diff --git a/examples/computer_prestages/GetComputerPrestageNameByID/GetComputerPrestageNameByID.go b/examples/computer_prestages/GetComputerPrestageNameByID/GetComputerPrestageNameByID.go new file mode 100644 index 00000000..a5510588 --- /dev/null +++ b/examples/computer_prestages/GetComputerPrestageNameByID/GetComputerPrestageNameByID.go @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" + "log" + + "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" +) + +func main() { + // Define the path to the JSON configuration file inside the main function + configFilePath := "/Users/dafyddwatkins/GitHub/deploymenttheory/go-api-sdk-jamfpro/clientauth.json" + + // Load the client OAuth credentials from the configuration file + authConfig, err := jamfpro.LoadClientAuthConfig(configFilePath) + if err != nil { + log.Fatalf("Failed to load client OAuth configuration: %v", err) + } + + // Configuration for the jamfpro + config := jamfpro.Config{ + InstanceName: authConfig.InstanceName, + DebugMode: true, + Logger: jamfpro.NewDefaultLogger(), + ClientID: authConfig.ClientID, + ClientSecret: authConfig.ClientSecret, + } + + // Create a new jamfpro client instance + client, err := jamfpro.NewClient(config) + if err != nil { + log.Fatalf("Failed to create Jamf Pro client: %v", err) + } + + // Define the NAME of the Computer Prestage you want to fetch + prestageName := "YourComputerPrestageName" // Replace with the actual prestage name + + // Call GetComputerPrestageIDByName function + prestageID, err := client.GetComputerPrestageIDByName(prestageName) + if err != nil { + log.Fatalf("Error fetching Computer Prestage ID by Name: %v", err) + } + + fmt.Println("Fetched Computer Prestage ID for Name", prestageName, "is:", prestageID) +} diff --git a/examples/computer_prestages/GetComputerPrestages/GetComputerPrestages.go b/examples/computer_prestages/GetComputerPrestages/GetComputerPrestages.go new file mode 100644 index 00000000..6273c2e8 --- /dev/null +++ b/examples/computer_prestages/GetComputerPrestages/GetComputerPrestages.go @@ -0,0 +1,48 @@ +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 inside the main function + configFilePath := "/Users/dafyddwatkins/GitHub/deploymenttheory/go-api-sdk-jamfpro/clientauth.json" + + // Load the client OAuth credentials from the configuration file + authConfig, err := jamfpro.LoadClientAuthConfig(configFilePath) + if err != nil { + log.Fatalf("Failed to load client OAuth configuration: %v", err) + } + + // Configuration for the jamfpro + config := jamfpro.Config{ + InstanceName: authConfig.InstanceName, + DebugMode: true, + Logger: jamfpro.NewDefaultLogger(), + ClientID: authConfig.ClientID, + ClientSecret: authConfig.ClientSecret, + } + + // Create a new jamfpro client instance + client, err := jamfpro.NewClient(config) + if err != nil { + log.Fatalf("Failed to create Jamf Pro client: %v", err) + } + + // Call GetComputerPrestages function + prestages, err := client.GetComputerPrestages() + if err != nil { + log.Fatalf("Error fetching Computer Prestages: %v", err) + } + + // Pretty print the prestages in XML + prestagesXML, err := xml.MarshalIndent(prestages, "", " ") // Indent with 4 spaces + if err != nil { + log.Fatalf("Error marshaling Computer Prestages data: %v", err) + } + fmt.Println("Fetched Computer Prestages:\n", string(prestagesXML)) +} diff --git a/sdk/jamfpro/jamfproapi_categories.go b/sdk/jamfpro/jamfproapi_categories.go index cd41693e..ad2f87ed 100644 --- a/sdk/jamfpro/jamfproapi_categories.go +++ b/sdk/jamfpro/jamfproapi_categories.go @@ -1,4 +1,4 @@ -// classicapi_categories.go +// jamfproapi_categories.go // Jamf Pro Api - osx configuration profiles // api reference: https://developer.jamf.com/jamf-pro/reference/get_v1-categories // Jamf Pro API requires the structs to support a JSON data structure. diff --git a/sdk/jamfpro/jamfproapi_computer_prestages.go b/sdk/jamfpro/jamfproapi_computer_prestages.go new file mode 100644 index 00000000..5ec2b406 --- /dev/null +++ b/sdk/jamfpro/jamfproapi_computer_prestages.go @@ -0,0 +1,169 @@ +// jamfproapi_computer_prestages.go + +package jamfpro + +import ( + "fmt" +) + +const uriComputerPrestagesV3 = "/api/v3/computer-prestages" + +// ResponseComputerPrestages represents the structure of the response for fetching computer pre-stages +type ResponseComputerPrestages struct { + TotalCount int `json:"totalCount"` + Results []ComputerPrestage `json:"results"` +} + +// ComputerPrestage represents the top-level structure for a computer prestage response. +type ComputerPrestage struct { + DisplayName string `json:"displayName"` + Mandatory bool `json:"mandatory"` + MdmRemovable bool `json:"mdmRemovable"` + SupportPhoneNumber string `json:"supportPhoneNumber"` + SupportEmailAddress string `json:"supportEmailAddress"` + Department string `json:"department"` + DefaultPrestage bool `json:"defaultPrestage"` + EnrollmentSiteId string `json:"enrollmentSiteId"` + KeepExistingSiteMembership bool `json:"keepExistingSiteMembership"` + KeepExistingLocationInformation bool `json:"keepExistingLocationInformation"` + RequireAuthentication bool `json:"requireAuthentication"` + AuthenticationPrompt string `json:"authenticationPrompt"` + PreventActivationLock bool `json:"preventActivationLock"` + EnableDeviceBasedActivationLock bool `json:"enableDeviceBasedActivationLock"` + DeviceEnrollmentProgramInstanceId string `json:"deviceEnrollmentProgramInstanceId"` + SkipSetupItems SkipSetupItems `json:"skipSetupItems"` + LocationInformation LocationInformation `json:"locationInformation"` + PurchasingInformation PurchasingInformation `json:"purchasingInformation"` + AnchorCertificates []string `json:"anchorCertificates"` + EnrollmentCustomizationId string `json:"enrollmentCustomizationId"` + Language string `json:"language"` + Region string `json:"region"` + AutoAdvanceSetup bool `json:"autoAdvanceSetup"` + InstallProfilesDuringSetup bool `json:"installProfilesDuringSetup"` + PrestageInstalledProfileIds []string `json:"prestageInstalledProfileIds"` + CustomPackageIds []string `json:"customPackageIds"` + CustomPackageDistributionPointId string `json:"customPackageDistributionPointId"` + EnableRecoveryLock bool `json:"enableRecoveryLock"` + RecoveryLockPasswordType string `json:"recoveryLockPasswordType"` + RotateRecoveryLockPassword bool `json:"rotateRecoveryLockPassword"` + ID string `json:"id"` + ProfileUuid string `json:"profileUuid"` + SiteId string `json:"siteId"` + VersionLock int `json:"versionLock"` + AccountSettings AccountSettings `json:"accountSettings"` +} + +// SkipSetupItems represents the structure for skipping setup items. +type SkipSetupItems struct { + Biometric bool `json:"Biometric"` + TermsOfAddress bool `json:"TermsOfAddress"` + FileVault bool `json:"FileVault"` + ICloudDiagnostics bool `json:"iCloudDiagnostics"` + Diagnostics bool `json:"Diagnostics"` + Accessibility bool `json:"Accessibility"` + AppleID bool `json:"AppleID"` + ScreenTime bool `json:"ScreenTime"` + Siri bool `json:"Siri"` + DisplayTone bool `json:"DisplayTone"` + Restore bool `json:"Restore"` + Appearance bool `json:"Appearance"` + Privacy bool `json:"Privacy"` + Payment bool `json:"Payment"` + Registration bool `json:"Registration"` + TOS bool `json:"TOS"` + ICloudStorage bool `json:"iCloudStorage"` + Location bool `json:"Location"` +} + +// LocationInformation represents the structure for location information. +type LocationInformation struct { + Username string `json:"username"` + RealName string `json:"realname"` + Phone string `json:"phone"` + Email string `json:"email"` + Room string `json:"room"` + Position string `json:"position"` + DepartmentId string `json:"departmentId"` + BuildingId string `json:"buildingId"` + ID string `json:"id"` + VersionLock int `json:"versionLock"` +} + +// PurchasingInformation represents the structure for purchasing information. +type PurchasingInformation struct { + ID string `json:"id"` + Leased bool `json:"leased"` + Purchased bool `json:"purchased"` + AppleCareId string `json:"appleCareId"` + PoNumber string `json:"poNumber"` + Vendor string `json:"vendor"` + PurchasePrice string `json:"purchasePrice"` + LifeExpectancy int `json:"lifeExpectancy"` + WarrantyExpires string `json:"warrantyExpires"` + LeaseExpires string `json:"leaseExpires"` + PurchaseDate string `json:"purchaseDate"` + PoDate string `json:"poDate"` + VersionLock int `json:"versionLock"` + IsPurchased bool `json:"isPurchased"` + IsLeased bool `json:"isLeased"` + PurchasingAccount string `json:"purchasingAccount"` + WarrantyDaysLeft int `json:"warrantyDaysLeft"` + LeaseDaysLeft int `json:"leaseDaysLeft"` + Attachments []struct { + ID string `json:"id"` + Filename string `json:"filename"` + Filetype string `json:"filetype"` + Filesize int `json:"filesize"` + VersionLock int `json:"versionLock"` + DownloadLink string `json:"downloadLink"` + } `json:"attachments"` +} + +// AccountSettings represents the structure for account settings. +type AccountSettings struct { + ID string `json:"id"` + PayloadConfigured bool `json:"payloadConfigured"` + LocalAdminAccountEnabled bool `json:"localAdminAccountEnabled"` + AdminUsername string `json:"adminUsername"` + HiddenAdminAccount bool `json:"hiddenAdminAccount"` + LocalUserManaged bool `json:"localUserManaged"` + UserAccountType string `json:"userAccountType"` + VersionLock int `json:"versionLock"` + PrefillPrimaryAccountInfoFeatureEnabled bool `json:"prefillPrimaryAccountInfoFeatureEnabled"` + PrefillType string `json:"prefillType"` + PrefillAccountFullName string `json:"prefillAccountFullName"` + PrefillAccountUserName string `json:"prefillAccountUserName"` + PreventPrefillInfoFromModification bool `json:"preventPrefillInfoFromModification"` +} + +// GetComputerPrestages fetches all computer pre-stages +func (c *Client) GetComputerPrestages() (*ResponseComputerPrestages, error) { + var preStagesList ResponseComputerPrestages + resp, err := c.HTTP.DoRequest("GET", uriComputerPrestagesV3, nil, &preStagesList) + if err != nil { + return nil, fmt.Errorf("failed to fetch Jamf computer pre-stages: %v", err) + } + + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } + + return &preStagesList, nil +} + +// GetComputerPrestageByID fetches a computer pre-stage by its ID +func (c *Client) GetComputerPrestageByID(id string) (*ComputerPrestage, error) { + endpoint := fmt.Sprintf(uriComputerPrestagesV3+"/%s", id) + + var preStage ComputerPrestage + resp, err := c.HTTP.DoRequest("GET", endpoint, nil, &preStage) + if err != nil { + return nil, fmt.Errorf("failed to fetch Jamf computer pre-stage ID %s: %v", id, err) + } + + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } + + return &preStage, nil +} From af5fe2258250c4348f53152ffa562d625a41a7f7 Mon Sep 17 00:00:00 2001 From: ShocOne Date: Sun, 29 Oct 2023 15:33:06 +0000 Subject: [PATCH 2/4] added funcs --- .../GetComputerPrestageByID.go | 2 +- .../GetComputerPrestageNameByID.go | 23 ++- sdk/jamfpro/jamfproapi_computer_prestages.go | 177 ++++++++---------- 3 files changed, 98 insertions(+), 104 deletions(-) diff --git a/examples/computer_prestages/GetComputerPrestageByID/GetComputerPrestageByID.go b/examples/computer_prestages/GetComputerPrestageByID/GetComputerPrestageByID.go index 05feffb9..200f14b5 100644 --- a/examples/computer_prestages/GetComputerPrestageByID/GetComputerPrestageByID.go +++ b/examples/computer_prestages/GetComputerPrestageByID/GetComputerPrestageByID.go @@ -34,7 +34,7 @@ func main() { } // Define the ID of the Computer Prestage you want to fetch as a string - prestageID := "1" // Replace with the actual prestage ID as a string + prestageID := "2" // Replace with the actual prestage ID as a string // Call GetComputerPrestageByID function prestage, err := client.GetComputerPrestageByID(prestageID) diff --git a/examples/computer_prestages/GetComputerPrestageNameByID/GetComputerPrestageNameByID.go b/examples/computer_prestages/GetComputerPrestageNameByID/GetComputerPrestageNameByID.go index a5510588..ee16896c 100644 --- a/examples/computer_prestages/GetComputerPrestageNameByID/GetComputerPrestageNameByID.go +++ b/examples/computer_prestages/GetComputerPrestageNameByID/GetComputerPrestageNameByID.go @@ -1,12 +1,17 @@ package main import ( + "encoding/json" "fmt" "log" "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" ) +const ( + prestageName = "pse-ade_lbgstaging_Jamf_Connect_New_Config-1.1-0000" // Replace with the actual prestage name you want to fetch +) + func main() { // Define the path to the JSON configuration file inside the main function configFilePath := "/Users/dafyddwatkins/GitHub/deploymenttheory/go-api-sdk-jamfpro/clientauth.json" @@ -26,20 +31,22 @@ func main() { ClientSecret: authConfig.ClientSecret, } - // Create a new jamfpro client instance + // Create a new jamfpro client instance, client, err := jamfpro.NewClient(config) if err != nil { log.Fatalf("Failed to create Jamf Pro client: %v", err) } - // Define the NAME of the Computer Prestage you want to fetch - prestageName := "YourComputerPrestageName" // Replace with the actual prestage name - - // Call GetComputerPrestageIDByName function - prestageID, err := client.GetComputerPrestageIDByName(prestageName) + // Call GetComputerPrestageByNameByID function + prestage, err := client.GetComputerPrestageByNameByID(prestageName) if err != nil { - log.Fatalf("Error fetching Computer Prestage ID by Name: %v", err) + log.Fatalf("Error fetching Jamf computer prestage by name: %v", err) } - fmt.Println("Fetched Computer Prestage ID for Name", prestageName, "is:", prestageID) + // Pretty print the prestage in JSON + prestageJSON, err := json.MarshalIndent(prestage, "", " ") // Indent with 4 spaces + if err != nil { + log.Fatalf("Error marshaling Jamf computer prestage data: %v", err) + } + fmt.Println("Fetched Jamf computer prestage:\n", string(prestageJSON)) } diff --git a/sdk/jamfpro/jamfproapi_computer_prestages.go b/sdk/jamfpro/jamfproapi_computer_prestages.go index 5ec2b406..db00dc0a 100644 --- a/sdk/jamfpro/jamfproapi_computer_prestages.go +++ b/sdk/jamfpro/jamfproapi_computer_prestages.go @@ -6,79 +6,61 @@ import ( "fmt" ) +const uriComputerPrestagesV2 = "/api/v2/computer-prestages/scope" const uriComputerPrestagesV3 = "/api/v3/computer-prestages" // ResponseComputerPrestages represents the structure of the response for fetching computer pre-stages type ResponseComputerPrestages struct { - TotalCount int `json:"totalCount"` - Results []ComputerPrestage `json:"results"` + TotalCount *int `json:"totalCount,omitempty"` + Results []ComputerPrestage `json:"results,omitempty"` } -// ComputerPrestage represents the top-level structure for a computer prestage response. type ComputerPrestage struct { - DisplayName string `json:"displayName"` - Mandatory bool `json:"mandatory"` - MdmRemovable bool `json:"mdmRemovable"` - SupportPhoneNumber string `json:"supportPhoneNumber"` - SupportEmailAddress string `json:"supportEmailAddress"` - Department string `json:"department"` - DefaultPrestage bool `json:"defaultPrestage"` - EnrollmentSiteId string `json:"enrollmentSiteId"` - KeepExistingSiteMembership bool `json:"keepExistingSiteMembership"` - KeepExistingLocationInformation bool `json:"keepExistingLocationInformation"` - RequireAuthentication bool `json:"requireAuthentication"` - AuthenticationPrompt string `json:"authenticationPrompt"` - PreventActivationLock bool `json:"preventActivationLock"` - EnableDeviceBasedActivationLock bool `json:"enableDeviceBasedActivationLock"` - DeviceEnrollmentProgramInstanceId string `json:"deviceEnrollmentProgramInstanceId"` - SkipSetupItems SkipSetupItems `json:"skipSetupItems"` - LocationInformation LocationInformation `json:"locationInformation"` - PurchasingInformation PurchasingInformation `json:"purchasingInformation"` - AnchorCertificates []string `json:"anchorCertificates"` - EnrollmentCustomizationId string `json:"enrollmentCustomizationId"` - Language string `json:"language"` - Region string `json:"region"` - AutoAdvanceSetup bool `json:"autoAdvanceSetup"` - InstallProfilesDuringSetup bool `json:"installProfilesDuringSetup"` - PrestageInstalledProfileIds []string `json:"prestageInstalledProfileIds"` - CustomPackageIds []string `json:"customPackageIds"` - CustomPackageDistributionPointId string `json:"customPackageDistributionPointId"` - EnableRecoveryLock bool `json:"enableRecoveryLock"` - RecoveryLockPasswordType string `json:"recoveryLockPasswordType"` - RotateRecoveryLockPassword bool `json:"rotateRecoveryLockPassword"` - ID string `json:"id"` - ProfileUuid string `json:"profileUuid"` - SiteId string `json:"siteId"` - VersionLock int `json:"versionLock"` - AccountSettings AccountSettings `json:"accountSettings"` + DisplayName string `json:"displayName"` + Mandatory bool `json:"mandatory"` + MdmRemovable bool `json:"mdmRemovable"` + SupportPhoneNumber string `json:"supportPhoneNumber"` + SupportEmailAddress string `json:"supportEmailAddress"` + Department string `json:"department"` + DefaultPrestage bool `json:"defaultPrestage"` + EnrollmentSiteId string `json:"enrollmentSiteId"` + KeepExistingSiteMembership bool `json:"keepExistingSiteMembership"` + KeepExistingLocationInformation bool `json:"keepExistingLocationInformation"` + RequireAuthentication bool `json:"requireAuthentication"` + AuthenticationPrompt string `json:"authenticationPrompt"` + PreventActivationLock bool `json:"preventActivationLock"` + EnableDeviceBasedActivationLock bool `json:"enableDeviceBasedActivationLock"` + DeviceEnrollmentProgramInstanceId string `json:"deviceEnrollmentProgramInstanceId"` + SkipSetupItems *[]ComputerPrestageDataSubsetSkipSetupItems `json:"skipSetupItems"` + LocationInformation *[]ComputerPrestageDataSubsetLocationInformation `json:"locationInformation"` + PurchasingInformation *[]ComputerPrestageDataSubsetPurchasingInformation `json:"purchasingInformation"` + AnchorCertificates []string `json:"anchorCertificates"` + EnrollmentCustomizationId string `json:"enrollmentCustomizationId"` + Language string `json:"language"` + Region string `json:"region"` + AutoAdvanceSetup bool `json:"autoAdvanceSetup"` + InstallProfilesDuringSetup *bool `json:"installProfilesDuringSetup"` + PrestageInstalledProfileIds []string `json:"prestageInstalledProfileIds"` + CustomPackageIds []string `json:"customPackageIds"` + CustomPackageDistributionPointId string `json:"customPackageDistributionPointId"` + EnableRecoveryLock *bool `json:"enableRecoveryLock"` + RecoveryLockPasswordType *string `json:"recoveryLockPasswordType"` + RotateRecoveryLockPassword *bool `json:"rotateRecoveryLockPassword"` + ID string `json:"id"` + ProfileUuid string `json:"profileUuid"` + SiteId string `json:"siteId"` + VersionLock int `json:"versionLock"` + AccountSettings *[]ComputerPrestageDataSubsetAccountSettings `json:"accountSettings"` } -// SkipSetupItems represents the structure for skipping setup items. -type SkipSetupItems struct { - Biometric bool `json:"Biometric"` - TermsOfAddress bool `json:"TermsOfAddress"` - FileVault bool `json:"FileVault"` - ICloudDiagnostics bool `json:"iCloudDiagnostics"` - Diagnostics bool `json:"Diagnostics"` - Accessibility bool `json:"Accessibility"` - AppleID bool `json:"AppleID"` - ScreenTime bool `json:"ScreenTime"` - Siri bool `json:"Siri"` - DisplayTone bool `json:"DisplayTone"` - Restore bool `json:"Restore"` - Appearance bool `json:"Appearance"` - Privacy bool `json:"Privacy"` - Payment bool `json:"Payment"` - Registration bool `json:"Registration"` - TOS bool `json:"TOS"` - ICloudStorage bool `json:"iCloudStorage"` - Location bool `json:"Location"` +type ComputerPrestageDataSubsetSkipSetupItems struct { + Location bool `json:"Location"` + Privacy bool `json:"Privacy"` } -// LocationInformation represents the structure for location information. -type LocationInformation struct { +type ComputerPrestageDataSubsetLocationInformation struct { Username string `json:"username"` - RealName string `json:"realname"` + Realname string `json:"realname"` Phone string `json:"phone"` Email string `json:"email"` Room string `json:"room"` @@ -89,8 +71,7 @@ type LocationInformation struct { VersionLock int `json:"versionLock"` } -// PurchasingInformation represents the structure for purchasing information. -type PurchasingInformation struct { +type ComputerPrestageDataSubsetPurchasingInformation struct { ID string `json:"id"` Leased bool `json:"leased"` Purchased bool `json:"purchased"` @@ -99,47 +80,35 @@ type PurchasingInformation struct { Vendor string `json:"vendor"` PurchasePrice string `json:"purchasePrice"` LifeExpectancy int `json:"lifeExpectancy"` - WarrantyExpires string `json:"warrantyExpires"` - LeaseExpires string `json:"leaseExpires"` - PurchaseDate string `json:"purchaseDate"` + PurchasingAccount string `json:"purchasingAccount"` + PurchasingContact string `json:"purchasingContact"` + LeaseDate string `json:"leaseDate"` PoDate string `json:"poDate"` + WarrantyDate string `json:"warrantyDate"` VersionLock int `json:"versionLock"` - IsPurchased bool `json:"isPurchased"` - IsLeased bool `json:"isLeased"` - PurchasingAccount string `json:"purchasingAccount"` - WarrantyDaysLeft int `json:"warrantyDaysLeft"` - LeaseDaysLeft int `json:"leaseDaysLeft"` - Attachments []struct { - ID string `json:"id"` - Filename string `json:"filename"` - Filetype string `json:"filetype"` - Filesize int `json:"filesize"` - VersionLock int `json:"versionLock"` - DownloadLink string `json:"downloadLink"` - } `json:"attachments"` } -// AccountSettings represents the structure for account settings. -type AccountSettings struct { - ID string `json:"id"` - PayloadConfigured bool `json:"payloadConfigured"` - LocalAdminAccountEnabled bool `json:"localAdminAccountEnabled"` - AdminUsername string `json:"adminUsername"` - HiddenAdminAccount bool `json:"hiddenAdminAccount"` - LocalUserManaged bool `json:"localUserManaged"` - UserAccountType string `json:"userAccountType"` - VersionLock int `json:"versionLock"` - PrefillPrimaryAccountInfoFeatureEnabled bool `json:"prefillPrimaryAccountInfoFeatureEnabled"` - PrefillType string `json:"prefillType"` - PrefillAccountFullName string `json:"prefillAccountFullName"` - PrefillAccountUserName string `json:"prefillAccountUserName"` - PreventPrefillInfoFromModification bool `json:"preventPrefillInfoFromModification"` +type ComputerPrestageDataSubsetAccountSettings struct { + ID *string `json:"id"` + PayloadConfigured *bool `json:"payloadConfigured"` + LocalAdminAccountEnabled *bool `json:"localAdminAccountEnabled"` + AdminUsername *string `json:"adminUsername"` + AdminPassword *string `json:"adminPassword"` + HiddenAdminAccount *bool `json:"hiddenAdminAccount"` + LocalUserManaged *bool `json:"localUserManaged"` + UserAccountType *string `json:"userAccountType"` + VersionLock *int `json:"versionLock"` + PrefillPrimaryAccountInfoFeatureEnabled *bool `json:"prefillPrimaryAccountInfoFeatureEnabled"` + PrefillType *string `json:"prefillType"` + PrefillAccountFullName *string `json:"prefillAccountFullName"` + PrefillAccountUserName *string `json:"prefillAccountUserName"` + PreventPrefillInfoFromModification *bool `json:"preventPrefillInfoFromModification"` } // GetComputerPrestages fetches all computer pre-stages func (c *Client) GetComputerPrestages() (*ResponseComputerPrestages, error) { var preStagesList ResponseComputerPrestages - resp, err := c.HTTP.DoRequest("GET", uriComputerPrestagesV3, nil, &preStagesList) + resp, err := c.HTTP.DoRequest("GET", uriComputerPrestagesV2, nil, &preStagesList) if err != nil { return nil, fmt.Errorf("failed to fetch Jamf computer pre-stages: %v", err) } @@ -167,3 +136,21 @@ func (c *Client) GetComputerPrestageByID(id string) (*ComputerPrestage, error) { return &preStage, nil } + +// GetComputerPrestageByNameByID fetches a Jamf computer pre-stage by its display name and then retrieves its details using its ID +func (c *Client) GetComputerPrestageByNameByID(name string) (*ComputerPrestage, error) { + preStagesList, err := c.GetComputerPrestages() + if err != nil { + return nil, fmt.Errorf("failed to fetch all Jamf computer pre-stages: %v", err) + } + + // Search for the pre-stage with the given name + for _, preStage := range preStagesList.Results { + fmt.Printf("Comparing desired name '%s' with pre-stage name '%s'\n", name, preStage.DisplayName) // Debug log + if preStage.DisplayName == name { + return c.GetComputerPrestageByID(preStage.ID) + } + } + + return nil, fmt.Errorf("no Jamf computer pre-stage found with the name %s", name) +} From ae6f7ef7315fe7226952346dd421658162bfcdf8 Mon Sep 17 00:00:00 2001 From: ShocOne Date: Sun, 29 Oct 2023 16:09:19 +0000 Subject: [PATCH 3/4] added tests for classicapi_computer_extension_atts --- ...capi_computer_extension_attributes_test.go | 243 ++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 sdk/jamfpro/classicapi_computer_extension_attributes_test.go diff --git a/sdk/jamfpro/classicapi_computer_extension_attributes_test.go b/sdk/jamfpro/classicapi_computer_extension_attributes_test.go new file mode 100644 index 00000000..cc563064 --- /dev/null +++ b/sdk/jamfpro/classicapi_computer_extension_attributes_test.go @@ -0,0 +1,243 @@ +package jamfpro_test + +import ( + "os" + "testing" + "time" + + "github.com/deploymenttheory/go-api-sdk-jamfpro/sdk/jamfpro" +) + +const helloWorldScript = `#!/bin/bash\n` + + `echo "Hello World"\n` + +// TestCreateBasicComputerExtensionAttribute tests the creation of a basic computer extension attribute +func TestCreatePopUpMenuComputerExtensionAttribute_Basic(t *testing.T) { + client := getClient(t) + + // Define a basic computer extension attribute + attribute := &jamfpro.ComputerExtensionAttributeResponse{ + Name: "Basic Pop Up Menu Test", + InputType: jamfpro.ComputerExtensionAttributeInputType{Type: "Pop Up Menu", Choices: []string{"Option 1", "Option 2"}}, + } + + // Call CreateComputerExtensionAttribute function + _, err := client.CreateComputerExtensionAttribute(attribute) + if err != nil { + t.Errorf("Error creating basic Computer Extension Attribute: %v", err) + } +} + +// TestCreateDetailedComputerExtensionAttribute tests the creation of a detailed computer extension attribute +func TestCreatePopUpMenuComputerExtensionAttribute_Full(t *testing.T) { + client := getClient(t) + + // Define a detailed computer extension attribute + attribute := &jamfpro.ComputerExtensionAttributeResponse{ + Name: "Detailed Pop Up Menu Test", + Description: "A detailed pop up menu for testing", + DataType: "String", + InputType: jamfpro.ComputerExtensionAttributeInputType{Type: "Pop Up Menu", Choices: []string{"Choice 1", "Choice 2", "Choice 3"}}, + InventoryDisplay: "General", + ReconDisplay: "Extension Attributes", + } + + // Call CreateComputerExtensionAttribute function + _, err := client.CreateComputerExtensionAttribute(attribute) + if err != nil { + t.Errorf("Error creating detailed Computer Extension Attribute: %v", err) + } +} + +// TestCreateBasicScriptComputerExtensionAttribute tests the creation of a basic script-based computer extension attribute +func TestCreateScriptComputerExtensionAttribute_Basic(t *testing.T) { + client := getClient(t) + + // Define a basic computer extension attribute using the embedded script + attribute := &jamfpro.ComputerExtensionAttributeResponse{ + Name: "Basic Script Test", + DataType: "String", + InputType: jamfpro.ComputerExtensionAttributeInputType{ + Type: "Script", + Script: helloWorldScript, + }, + } + + // Call CreateComputerExtensionAttribute function + _, err := client.CreateComputerExtensionAttribute(attribute) + if err != nil { + t.Errorf("Error creating basic script-based Computer Extension Attribute: %v", err) + } +} + +// TestCreateDetailedScriptComputerExtensionAttribute tests the creation of a detailed script-based computer extension attribute +func TestCreateScriptComputerExtensionAttribute_Full(t *testing.T) { + client := getClient(t) + + // Define a detailed computer extension attribute using the embedded script + attribute := &jamfpro.ComputerExtensionAttributeResponse{ + Name: "Detailed Script Test", + Description: "A detailed script for testing", + DataType: "String", + InputType: jamfpro.ComputerExtensionAttributeInputType{ + Type: "Script", + Script: helloWorldScript, + Platform: "Mac", + }, + InventoryDisplay: "General", + ReconDisplay: "Extension Attributes", + } + + // Call CreateComputerExtensionAttribute function + _, err := client.CreateComputerExtensionAttribute(attribute) + if err != nil { + t.Errorf("Error creating detailed script-based Computer Extension Attribute: %v", err) + } +} + +// TestCreateBasicTextComputerExtensionAttribute tests the creation of a basic text-based computer extension attribute +func TestCreateTextComputerExtensionAttribute_Basic(t *testing.T) { + client := getClient(t) + + // Define a basic computer extension attribute with a text field + attribute := &jamfpro.ComputerExtensionAttributeResponse{ + Name: "Basic Text Field Test", + DataType: "String", + InputType: jamfpro.ComputerExtensionAttributeInputType{ + Type: "Text Field", + }, + } + + // Call CreateComputerExtensionAttribute function + _, err := client.CreateComputerExtensionAttribute(attribute) + if err != nil { + t.Errorf("Error creating basic text-based Computer Extension Attribute: %v", err) + } +} + +// TestCreateDetailedTextComputerExtensionAttribute tests the creation of a detailed text-based computer extension attribute +func TestCreateTextComputerExtensionAttribute_Full(t *testing.T) { + client := getClient(t) + + // Define a detailed computer extension attribute with a text field + attribute := &jamfpro.ComputerExtensionAttributeResponse{ + Name: "Detailed Text Field Test", + Description: "A detailed text field for testing", + DataType: "String", + InputType: jamfpro.ComputerExtensionAttributeInputType{ + Type: "Text Field", + }, + InventoryDisplay: "General", + ReconDisplay: "Extension Attributes", + } + + // Call CreateComputerExtensionAttribute function + _, err := client.CreateComputerExtensionAttribute(attribute) + if err != nil { + t.Errorf("Error creating detailed text-based Computer Extension Attribute: %v", err) + } +} + +// TestGetComputerExtensionAttributes tests the retrieval of all computer extension attributes. +func TestGetComputerExtensionAttributes(t *testing.T) { + client := getClient(t) + + attributes, err := client.GetComputerExtensionAttributes() + if err != nil { + t.Errorf("Error retrieving Computer Extension Attributes: %v", err) + } + + if len(attributes.Results) == 0 { + t.Error("No Computer Extension Attributes found") + } +} + +// TestGetComputerExtensionAttributeByID tests the retrieval of a computer extension attribute by its ID. +func TestGetComputerExtensionAttributeByID(t *testing.T) { + client := getClient(t) + + // First, retrieve all attributes to get a valid ID + allAttributes, err := client.GetComputerExtensionAttributes() + if err != nil { + t.Fatalf("Error retrieving all Computer Extension Attributes: %v", err) + } + if len(allAttributes.Results) == 0 { + t.Fatal("No Computer Extension Attributes found for testing") + } + + // Use the ID of the first attribute for testing + testID := allAttributes.Results[0].ID + + attribute, err := client.GetComputerExtensionAttributeByID(testID) + if err != nil { + t.Errorf("Error retrieving Computer Extension Attribute by ID: %v", err) + } + + if attribute == nil || attribute.ID != testID { + t.Errorf("Attribute not found or ID mismatch. Expected ID: %d", testID) + } +} + +// TestGetComputerExtensionAttributeByName tests the retrieval of a computer extension attribute by its name. +func TestGetComputerExtensionAttributeByName(t *testing.T) { + client := getClient(t) + + // First, retrieve all attributes to get a valid name + allAttributes, err := client.GetComputerExtensionAttributes() + if err != nil { + t.Fatalf("Error retrieving all Computer Extension Attributes: %v", err) + } + if len(allAttributes.Results) == 0 { + t.Fatal("No Computer Extension Attributes found for testing") + } + + // Use the name of the first attribute for testing + testName := allAttributes.Results[0].Name + + attribute, err := client.GetComputerExtensionAttributeByName(testName) + if err != nil { + t.Errorf("Error retrieving Computer Extension Attribute by name: %v", err) + } + + if attribute == nil || attribute.Name != testName { + t.Errorf("Attribute not found or name mismatch. Expected Name: %s", testName) + } +} + +func getClient(t *testing.T) *jamfpro.Client { + // Read environment variables + clientID := os.Getenv("JAMFPRO_CLIENT_ID") + clientSecret := os.Getenv("JAMFPRO_CLIENT_SECRET") + instanceName := os.Getenv("JAMFPRO_INSTANCE_NAME") + debugMode := os.Getenv("JAMFPRO_DEBUG_MODE") == "true" + + // Check if environment variables are set + if clientID == "" { + t.Fatalf("Environment variable JAMFPRO_CLIENT_ID is not set") + } + if clientSecret == "" { + t.Fatalf("Environment variable JAMFPRO_CLIENT_SECRET is not set") + } + if instanceName == "" { + t.Fatalf("Environment variable JAMFPRO_INSTANCE_NAME is not set") + } + + // Create a config object + config := jamfpro.Config{ + InstanceName: instanceName, + DebugMode: debugMode, + ClientID: clientID, + ClientSecret: clientSecret, + MaxConcurrentRequests: 5, + TokenLifespan: 30 * time.Minute, + TokenRefreshBufferPeriod: 5 * time.Minute, + } + + // Initialize the client + client, err := jamfpro.NewClient(config) + if err != nil { + t.Fatalf("Failed to initialize client: %v", err) + } + + return client +} From 8c35515bdfbc489f35bdce276b82ce63f36ebac7 Mon Sep 17 00:00:00 2001 From: ShocOne Date: Sun, 29 Oct 2023 17:57:02 +0000 Subject: [PATCH 4/4] added more tests --- ...capi_computer_extension_attributes_test.go | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/sdk/jamfpro/classicapi_computer_extension_attributes_test.go b/sdk/jamfpro/classicapi_computer_extension_attributes_test.go index cc563064..2a4d69ff 100644 --- a/sdk/jamfpro/classicapi_computer_extension_attributes_test.go +++ b/sdk/jamfpro/classicapi_computer_extension_attributes_test.go @@ -204,6 +204,162 @@ func TestGetComputerExtensionAttributeByName(t *testing.T) { } } +// TestUpdateComputerExtensionAttributeByID_Basic tests the basic update of a computer extension attribute by its ID. +func TestUpdateComputerExtensionAttributeByID_Basic(t *testing.T) { + // getClient creates and returns a new Jamf Pro API client + client := getClient(t) + + // GetComputerExtensionAttributes retrieves all computer extension attributes + attributes, err := client.GetComputerExtensionAttributes() + if err != nil { + t.Fatalf("Error retrieving attributes: %v", err) + } + + var attributeToUpdate *jamfpro.ComputerExtensionAttributeResponse + for _, attr := range attributes.Results { + if attr.Name == "Basic Pop Up Menu Test" { + // Create a new variable of the correct type and assign relevant fields + attributeToUpdate = &jamfpro.ComputerExtensionAttributeResponse{ + ID: attr.ID, + Name: attr.Name, + // Assign other fields that are present in ComputerExtensionAttributeItem + } + break + } + } + + if attributeToUpdate == nil { + t.Fatalf("Could not find attribute to update") + } + + // Define updates for the attribute + updatedAttribute := &jamfpro.ComputerExtensionAttributeResponse{ + Name: "Renamed Basic Pop Up Menu Test", + // Assign the DataType or other fields if necessary and available + } + + // UpdateComputerExtensionAttributeByID updates the computer extension attribute with the specified ID + _, err = client.UpdateComputerExtensionAttributeByID(attributeToUpdate.ID, updatedAttribute) + if err != nil { + t.Errorf("Error updating Computer Extension Attribute by ID: %v", err) + } +} + +// TestUpdateComputerExtensionAttributeByID_Full tests a comprehensive update of a computer extension attribute by its ID. +func TestUpdateComputerExtensionAttributeByID_Full(t *testing.T) { + client := getClient(t) + + attributes, err := client.GetComputerExtensionAttributes() + if err != nil { + t.Fatalf("Error retrieving attributes: %v", err) + } + + var attributeToUpdate *jamfpro.ComputerExtensionAttributeResponse + for _, attr := range attributes.Results { + if attr.Name == "Renamed Basic Pop Up Menu Test" { + attributeToUpdate = &jamfpro.ComputerExtensionAttributeResponse{ + ID: attr.ID, + Name: attr.Name, + } + break + } + } + + if attributeToUpdate == nil { + t.Fatalf("Could not find attribute to update") + } + + updatedAttribute := &jamfpro.ComputerExtensionAttributeResponse{ + Name: "Updated Battery Cycle Count", + Description: "Updated number of charge cycles logged on the current battery", + DataType: "String", + InputType: jamfpro.ComputerExtensionAttributeInputType{Type: "Text Field"}, + InventoryDisplay: "General", + ReconDisplay: "Extension Attributes", + } + + _, err = client.UpdateComputerExtensionAttributeByID(attributeToUpdate.ID, updatedAttribute) + if err != nil { + t.Errorf("Error updating Computer Extension Attribute by ID: %v", err) + } +} + +// TestUpdateComputerExtensionAttributeByName_Basic tests the basic update of a computer extension attribute by its name. +func TestUpdateComputerExtensionAttributeByName_Basic(t *testing.T) { + client := getClient(t) + + // Retrieve the attribute to ensure it exists + attributeToUpdate, err := client.GetComputerExtensionAttributeByName("Basic Pop Up Menu Test") + if err != nil { + t.Fatalf("Error retrieving attribute by name: %v", err) + } + + if attributeToUpdate == nil { + t.Fatalf("Could not find attribute to update") + } + + updatedAttribute := &jamfpro.ComputerExtensionAttributeResponse{ + Name: "Renamed Basic Pop Up Menu Test", + } + + _, err = client.UpdateComputerExtensionAttributeByName(attributeToUpdate.Name, updatedAttribute) + if err != nil { + t.Errorf("Error updating Computer Extension Attribute by Name: %v", err) + } +} + +// TestUpdateComputerExtensionAttributeByName_Full tests a comprehensive update of a computer extension attribute by its name. +func TestUpdateComputerExtensionAttributeByName_Full(t *testing.T) { + client := getClient(t) + + attributeToUpdate, err := client.GetComputerExtensionAttributeByName("Renamed Basic Pop Up Menu Test") + if err != nil { + t.Fatalf("Error retrieving attribute by name: %v", err) + } + + if attributeToUpdate == nil { + t.Fatalf("Could not find attribute to update") + } + + updatedAttribute := &jamfpro.ComputerExtensionAttributeResponse{ + Name: "Updated Battery Cycle Count", + Description: "Updated number of charge cycles logged on the current battery", + DataType: "String", + InputType: jamfpro.ComputerExtensionAttributeInputType{Type: "Text Field"}, + InventoryDisplay: "General", + ReconDisplay: "Extension Attributes", + } + + _, err = client.UpdateComputerExtensionAttributeByName(attributeToUpdate.Name, updatedAttribute) + if err != nil { + t.Errorf("Error updating Computer Extension Attribute by Name: %v", err) + } +} + +// TestDeleteComputerExtensionAttributesByName removes the resources created as part of the this test strategy +func TestDeleteComputerExtensionAttributesByName(t *testing.T) { + client := getClient(t) + + // Names of resources created earlier and updated + namesToDelete := []string{"TestAttribute1", "TestAttribute2", "TestAttribute3", "UpdatedTestAttribute1", "UpdatedTestAttribute2", "UpdatedTestAttribute3"} + + // Test Deletion by Name + for _, name := range namesToDelete { + err := client.DeleteComputerExtensionAttributeByNameByID(name) + if err != nil { + t.Errorf("Failed to delete resource with name %s: %v", name, err) + } + + // Optional: Verify deletion + // attrs, _ := client.GetComputerExtensionAttributes() + // for _, attr := range attrs.Results { + // if attr.Name == name { + // t.Errorf("Resource with name %s still exists after deletion", name) + // } + // } + } +} + func getClient(t *testing.T) *jamfpro.Client { // Read environment variables clientID := os.Getenv("JAMFPRO_CLIENT_ID")