From a71bbdd279bd593d1d0f7c15f3132edfb3ec3b8c Mon Sep 17 00:00:00 2001 From: Macey <11599974+doebrowsk@users.noreply.github.com> Date: Thu, 24 Jul 2025 01:38:46 +0000 Subject: [PATCH 1/4] fix(migrate): preserve cert store inventory schedule --- CHANGELOG.md | 8 ++++++++ cmd/migrate.go | 14 ++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee9b56e..befeb2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# v1.8.1 + +## Fixes + +### CLI + +- `migrate pam` will correctly preserve Inventory Schedules on targeted certificate stores + # v1.8.0 ## Features diff --git a/cmd/migrate.go b/cmd/migrate.go index 14fb33e..c2054da 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -359,12 +359,14 @@ var migratePamCmd = &cobra.Command{ // update property object // set required fields, and new Properties updateStoreArgs := api.UpdateStoreFctArgs{ - Id: certStore.Id, - ClientMachine: certStore.ClientMachine, - StorePath: certStore.StorePath, - AgentId: certStore.AgentId, - Properties: certStore.Properties, - Password: &certStore.Password, + Id: certStore.Id, + ClientMachine: certStore.ClientMachine, + StorePath: certStore.StorePath, + AgentId: certStore.AgentId, + Properties: certStore.Properties, + Password: &certStore.Password, // TODO: secret field, needs to be processed the same as other secret fields + InventorySchedule: &certStore.InventorySchedule, + CertStoreInventoryJobId: &certStore.CertStoreInventoryJobId, } // TODO: use updated client when API endpoint available From dda6e34c47d347d08cc8f39f701148d5c45b5bff Mon Sep 17 00:00:00 2001 From: Macey <11599974+doebrowsk@users.noreply.github.com> Date: Thu, 24 Jul 2025 22:54:03 +0000 Subject: [PATCH 2/4] fix(migrate): migrate store password if using matching pam provider --- cmd/migrate.go | 65 ++++++++++++++++++++++++++++++++++++++++++++------ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/cmd/migrate.go b/cmd/migrate.go index c2054da..e1a9cb2 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -117,6 +117,8 @@ var migrateCheckCmd = &cobra.Command{ certStoreGuids[store.Id] = true } } + + // TODO: check Password field for PAM usage } // print out list of Cert Store GUIDs @@ -356,19 +358,68 @@ var migratePamCmd = &cobra.Command{ fmt.Println("^^^ SECRETS REFORMATTED ^^^") } + // check Store Password for PAM field, and process migration if applicable + var storePassword *api.UpdateStorePasswordConfig + if certStore.Password.IsManaged { // managed secret, i.e. PAM Provider in use + + // check if Pam Secret is using our migrating provider + fmt.Println(*fromPamProvider.Id, " <= from id equals store password id => ", int32(certStore.Password.ProviderId)) + fmt.Println(*fromPamProvider.Id == int32(certStore.Password.ProviderId)) + if *fromPamProvider.Id == int32(certStore.Password.ProviderId) { + // Pam Secret that Needs to be migrated + var storePasswordInterface map[string]interface{} + // marshal and unmarshal strongly typed store password to match + // expected map[string]interface{} typing for helper function + storePasswordJson, _ := json.Marshal(certStore.Password) + json.Unmarshal(storePasswordJson, &storePasswordInterface) + + // migrate secret using helper function + var updateStorePasswordInterface map[string]interface{} + updateStorePasswordInterface = buildMigratedPamSecret(storePasswordInterface, fromProviderLevelParamValues, *migrationTargetPamProvider.Id) + + // finally, transform the migrated secret back to the strongly typed input for API client + updateStorePasswordJson, _ := json.Marshal(updateStorePasswordInterface) + json.Unmarshal(updateStorePasswordJson, &storePassword) + } else { + // leave Store Password untouched: set to null + storePassword = nil + } + } else { + // non-managed secret i.e. a KF-encrypted secret, or no value + // instead of reformatting, send null to effect no change + storePassword = nil + } + // update property object // set required fields, and new Properties updateStoreArgs := api.UpdateStoreFctArgs{ - Id: certStore.Id, - ClientMachine: certStore.ClientMachine, - StorePath: certStore.StorePath, - AgentId: certStore.AgentId, - Properties: certStore.Properties, - Password: &certStore.Password, // TODO: secret field, needs to be processed the same as other secret fields + Id: certStore.Id, + ClientMachine: certStore.ClientMachine, + StorePath: certStore.StorePath, + AgentId: certStore.AgentId, + Properties: certStore.Properties, + Password: storePassword, + // the password should be set to null (omitted) when it is not meant to be updated + // however it will need to be migrated if it is a matching PAM secret + // check formatting to see if it's a PAM secret + // then update to new provider format if it matches + // otherwise omit / set to null + + // password PAM format: + // { Provider: integer id, + // Parameters: { paramname:value + // Safe: safe, + // Folder: folder, + // Object: object }} InventorySchedule: &certStore.InventorySchedule, CertStoreInventoryJobId: &certStore.CertStoreInventoryJobId, } + fmt.Println("vvv REQUESTED UPDATE TO STORE vvv") + jobject, _ := json.MarshalIndent(updateStoreArgs, "", " ") + fmt.Println(string(jobject)) + fmt.Println("^^^ REQUESTED UPDATE TO STORE ^^^") + // TODO: use updated client when API endpoint available updatedStore, rErr := legacyClient.UpdateStore(&updateStoreArgs) @@ -378,7 +429,7 @@ var migratePamCmd = &cobra.Command{ } fmt.Println("vvv UPDATED STORE vvv") - jobject, _ := json.MarshalIndent(updatedStore, "", " ") + jobject, _ = json.MarshalIndent(updatedStore, "", " ") fmt.Println(string(jobject)) fmt.Println("^^^ UPDATED STORE ^^^") diff --git a/go.mod b/go.mod index a424d59..a0a1e70 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/Jeffail/gabs v1.4.0 github.com/Keyfactor/keyfactor-auth-client-go v1.3.0 github.com/Keyfactor/keyfactor-go-client-sdk/v2 v2.0.0 - github.com/Keyfactor/keyfactor-go-client/v3 v3.1.0 + github.com/Keyfactor/keyfactor-go-client/v3 v3.2.0-rc.5 github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 github.com/creack/pty v1.1.24 github.com/google/go-cmp v0.7.0 diff --git a/go.sum b/go.sum index ea69bb4..cc2bb6d 100644 --- a/go.sum +++ b/go.sum @@ -22,8 +22,8 @@ github.com/Keyfactor/keyfactor-auth-client-go v1.3.0 h1:otC213b6CYzqeN9b3CRlH1Qj github.com/Keyfactor/keyfactor-auth-client-go v1.3.0/go.mod h1:97vCisBNkdCK0l2TuvOSdjlpvQa4+GHsMut1UTyv1jo= github.com/Keyfactor/keyfactor-go-client-sdk/v2 v2.0.0 h1:ehk5crxEGVBwkC8yXsoQXcyITTDlgbxMEkANrl1dA2Q= github.com/Keyfactor/keyfactor-go-client-sdk/v2 v2.0.0/go.mod h1:11WXGG9VVKSV0EPku1IswjHbGGpzHDKqD4pe2vD7vas= -github.com/Keyfactor/keyfactor-go-client/v3 v3.1.0 h1:DQgb93m3xHZZ0FxWGFS90XI8prwS5fmIGrXNxP2IfHM= -github.com/Keyfactor/keyfactor-go-client/v3 v3.1.0/go.mod h1:LhIBGzTZeZ6o4i0gNg4qmwpwBnkoI6AfcEz8PLKruvc= +github.com/Keyfactor/keyfactor-go-client/v3 v3.2.0-rc.5 h1:sDdRCGa94GLSBL6mNFiSOuQZ9e9qZmUL1LYpCzESbXo= +github.com/Keyfactor/keyfactor-go-client/v3 v3.2.0-rc.5/go.mod h1:a7voCNCgvf+TbQxEno/xQ3wRJ+wlJRJKruhNco50GV8= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= From 3a8fd2ee3a32c4659ab7b00871fe616b2dab418c Mon Sep 17 00:00:00 2001 From: Macey <11599974+doebrowsk@users.noreply.github.com> Date: Fri, 25 Jul 2025 04:19:34 +0000 Subject: [PATCH 3/4] fix(migrate): migrate check find store password instances --- cmd/migrate.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/cmd/migrate.go b/cmd/migrate.go index e1a9cb2..e6b6293 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -110,15 +110,35 @@ var migrateCheckCmd = &cobra.Command{ // get properties field, as this will contain the Secret GUID for one of our active Instances if the PAM provider is in use storeProperties := store.PropertiesString + // need to specifically query each store to get set Password details + queryStore, err := legacyClient.GetCertificateStoreByID(store.Id) + + if err != nil { + log.Error().Err(err).Send() + return err + } + + storePasswordSettings := queryStore.Password + // loop through all found Instance GUIDs of the PAM Provider // if the GUID is present in the Properties field, add this Store ID to the list to return for instanceGuid, _ := range activePamSecretGuids { if strings.Contains(storeProperties, instanceGuid) { + if debugFlag { + fmt.Println("Found PAM usage in Properties for Store Id: ", store.Id) + } certStoreGuids[store.Id] = true } - } - // TODO: check Password field for PAM usage + if storePasswordSettings.IsManaged { + if *storePasswordSettings.InstanceGuid == instanceGuid { + if debugFlag { + fmt.Println("Found PAM usage in Store Password for Store Id: ", store.Id) + } + certStoreGuids[store.Id] = true + } + } + } } // print out list of Cert Store GUIDs From 3ee7730457c57603206cffc00738cb46377406da Mon Sep 17 00:00:00 2001 From: Macey <11599974+doebrowsk@users.noreply.github.com> Date: Fri, 25 Jul 2025 04:54:02 +0000 Subject: [PATCH 4/4] chore(docs): update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index befeb2a..caccc66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ ### CLI - `migrate pam` will correctly preserve Inventory Schedules on targeted certificate stores +- `migrate pam` will migrate matching PAM usages in the Store Password field, or leave value unchanged +- `migrate check` will reveal matching PAM usages in the Store Password field # v1.8.0