@@ -17,6 +17,7 @@ package cmd
1717import (
1818 "context"
1919 "encoding/json"
20+ "errors"
2021 "fmt"
2122
2223 // "github.com/Keyfactor/keyfactor-go-client-sdk/v24/api/keyfactor/v2"
@@ -72,25 +73,15 @@ var migratePamCmd = &cobra.Command{
7273 // TODO: assign error and check
7374 legacyClient , _ := initClient (false )
7475
75- log . Info (). Msg ( "looking up usage of <<from>> PAM Provider" )
76+ found , fromPamProvider , processedError := getExistingPamProvider ( sdkClient , migrateFrom )
7677
77- log .Debug ().Msg ("call: PAMProviderGetPamProviders()" )
78- listPamProvidersInUse , httpResponse , rErr := sdkClient .PAMProviderApi .PAMProviderGetPamProviders (context .Background ()).
79- XKeyfactorRequestedWith (XKeyfactorRequestedWith ).XKeyfactorApiVersion (XKeyfactorApiVersion ).
80- PqQueryString (fmt .Sprintf ("name -eq \" %s\" " , migrateFrom )).
81- Execute ()
82- log .Debug ().Msg ("returned: PAMProviderGetPamProviders()" )
83-
84- if rErr != nil {
85- log .Error ().Err (rErr ).Send ()
86- return returnHttpErr (httpResponse , rErr )
78+ if processedError != nil {
79+ return processedError
8780 }
8881
89- jobject , _ := json .MarshalIndent (listPamProvidersInUse , "" , " " )
90- fmt .Println (string (jobject ))
91-
92- // TODO: ensure only 1 returned PAM Provider definition
93- fromPamProvider := listPamProvidersInUse [0 ]
82+ if found == false {
83+ return errors .New ("Original PAM Provider to migrate from was not found by Name" )
84+ }
9485
9586 // get PAM Type definition for PAM Provider migrating <<FROM>>
9687 log .Debug ().Msg ("call: PAMProviderGetPamProviders()" )
@@ -151,14 +142,14 @@ var migratePamCmd = &cobra.Command{
151142 }
152143 }
153144
154- jobject , _ = json .MarshalIndent (inUsePamParamValues , "" , " " )
145+ jobject , _ : = json .MarshalIndent (inUsePamParamValues , "" , " " )
155146 fmt .Println (string (jobject ))
156147
157148 // step through list of every defined param value
158149 // record unique GUIDs of every param value on InstanceLevel : true
159150 // InstanceLevel : true is for per-secret fields
160151 // InstanceLevel : false is provider level secrets - these are also recorded for migration
161- for _ , pamParam := range listPamProvidersInUse [ 0 ] .ProviderTypeParamValues {
152+ for _ , pamParam := range fromPamProvider .ProviderTypeParamValues {
162153 // jobject, _ = json.MarshalIndent(pamParam, "", " ")
163154 // fmt.Println(string(jobject))
164155 fieldName := * pamParam .ProviderTypeParam .Name
@@ -182,87 +173,24 @@ var migratePamCmd = &cobra.Command{
182173 // mark GUID ID for pam type
183174 // mark integer IDs for each Parameter type
184175
185- // TODO: check that migration target PAM Provider was not already created
176+ var migrationTargetPamProvider keyfactor. CSSCMSDataModelModelsProvider
186177
187- fmt .Println ("creating new Provider of migration target PAM Type" )
188- var migrationPamProvider keyfactor.CSSCMSDataModelModelsProvider
189- migrationPamProvider .Name = fromPamProvider .Name + appendName
190- migrationPamProvider .ProviderType = keyfactor.CSSCMSDataModelModelsProviderType {
191- Id : toPamType .Id ,
192- }
193- var onevalue int32 = 1
194- migrationPamProvider .Area = & onevalue
195- migrationPamProvider .SecuredAreaId = nil
178+ // check if target PAM Provider already exists
179+ found , migrationTargetPamProvider , processedError = getExistingPamProvider (sdkClient , fromPamProvider .Name + appendName )
196180
197- // need to init AdditionalProperties map when setting value
198- migrationPamProvider .AdditionalProperties = map [string ]interface {}{
199- "Remote" : false , // this property is not on the model for some reason
181+ if processedError != nil {
182+ return processedError
200183 }
201184
202- fmt .Println ("getting migration target PAM Type parameter definitions, InstanceLevel : false" )
203- // TODO: check typing, have to access "Parameters" instead of ProviderTypeParams
204- for _ , pamParamType := range fromPamType .AdditionalProperties ["Parameters" ].([]interface {}) {
205- if ! pamParamType .(map [string ]interface {})["InstanceLevel" ].(bool ) {
206- // found a provider level parameter
207- // need to find the value to map over
208- // then create an object with that value and TypeParam settings
209- paramName := pamParamType .(map [string ]interface {})["Name" ].(string )
210- paramValue := selectProviderParamValue (paramName , fromPamProvider .ProviderTypeParamValues )
211- paramTypeId := selectProviderTypeParamId (paramName , toPamType .AdditionalProperties ["Parameters" ].([]interface {}))
212- falsevalue := false
213- providerLevelParameter := keyfactor.CSSCMSDataModelModelsPamProviderTypeParamValue {
214- Value : & paramValue ,
215- ProviderTypeParam : & keyfactor.CSSCMSDataModelModelsProviderTypeParam {
216- Id : & paramTypeId ,
217- Name : & paramName ,
218- InstanceLevel : & falsevalue ,
219- },
220- }
221-
222- // append filled out provider type parameter object, which contains the Provider-level parameter values
223- // migrationPamProvider.ProviderTypeParamValues = append(migrationPamProvider.ProviderTypeParamValues, providerLevelParameter)
185+ // create PAM Provider if it does not exist already
186+ if found == false {
187+ migrationTargetPamProvider , processedError = createMigrationTargetPamProvider (sdkClient , fromPamProvider , fromPamType , toPamType , appendName )
224188
225- // TODO: need to explicit filter for CyberArk expected params, i.e. not map over Safe
226- // this needs to be done programatically for other provider types
227- if paramName == "AppId" {
228- migrationPamProvider .ProviderTypeParamValues = append (migrationPamProvider .ProviderTypeParamValues , providerLevelParameter )
229- }
189+ if processedError != nil {
190+ return processedError
230191 }
231192 }
232193
233- msg := "Created new PAM Provider definition to be created."
234- fmt .Println (msg )
235- log .Info ().Msg (msg )
236- jobject , _ = json .MarshalIndent (migrationPamProvider , "" , " " )
237- fmt .Println (string (jobject ))
238- fmt .Println ("^^^ PAM Provider to be created ^^^" )
239-
240- // POST new PAM Provider
241- // create new PAM Instance of designated <<TO>> type
242- // set area = 1 or previous value
243- // name = old name plus append parameter
244- // providertype.id = Type GUID
245- // for all provider level values:
246- // set value to migrating value
247- // null for instanceid, instanceguid
248- // providertypeparam should be set to all matching values from GET TYPES
249- // ignoring datatype
250-
251- createdPamProvider , httpResponse , rErr := sdkClient .PAMProviderApi .PAMProviderCreatePamProvider (context .Background ()).
252- Provider (migrationPamProvider ).
253- XKeyfactorRequestedWith (XKeyfactorRequestedWith ).XKeyfactorApiVersion (XKeyfactorApiVersion ).
254- Execute ()
255-
256- if rErr != nil {
257- log .Error ().Err (rErr ).Send ()
258- return returnHttpErr (httpResponse , rErr )
259- }
260-
261- fmt .Println ("vvv CREATED MIGRATION PAM PROVIDER vvv" )
262- jobject , _ = json .MarshalIndent (createdPamProvider , "" , " " )
263- fmt .Println (string (jobject ))
264- fmt .Println ("^^^ CREATED MIGRATION PAM PROVIDER ^^^" )
265-
266194 // foreach store GUID pass in as a parameter-----
267195 // GET Store by GUID (instance GUID matches Store Id GUID)
268196 // output some store info to confirm
@@ -300,7 +228,7 @@ var migratePamCmd = &cobra.Command{
300228 // check if Pam Secret is using our migrating provider
301229 if * fromPamProvider .Id == int32 (propSecret ["ProviderId" ].(float64 )) {
302230 // Pam Secret that Needs to be migrated
303- formattedSecret ["Value" ] = buildMigratedPamSecret (propSecret , fromProviderLevelParamValues , * createdPamProvider .Id )
231+ formattedSecret ["Value" ] = buildMigratedPamSecret (propSecret , fromProviderLevelParamValues , * migrationTargetPamProvider .Id )
304232 } else {
305233 // reformat to required POST format for properties
306234 formattedSecret ["Value" ] = reformatPamSecretForPost (propSecret )
@@ -354,6 +282,119 @@ var migratePamCmd = &cobra.Command{
354282 },
355283}
356284
285+ func getExistingPamProvider (sdkClient * keyfactor.APIClient , name string ) (bool , keyfactor.CSSCMSDataModelModelsProvider , error ) {
286+ var pamProvider keyfactor.CSSCMSDataModelModelsProvider
287+
288+ logMsg := fmt .Sprintf ("Looking up usage of PAM Provider with name %s" , name )
289+ log .Debug ().Msg (logMsg )
290+ fmt .Println (logMsg )
291+
292+ foundProvider , httpResponse , err := sdkClient .PAMProviderApi .PAMProviderGetPamProviders (context .Background ()).
293+ XKeyfactorRequestedWith (XKeyfactorRequestedWith ).XKeyfactorApiVersion (XKeyfactorApiVersion ).
294+ PqQueryString (fmt .Sprintf ("name -eq \" %s\" " , name )).
295+ Execute ()
296+
297+ logMsg = fmt .Sprintf ("Reading response for PAM Provider with name %s" , name )
298+ log .Debug ().Msg (logMsg )
299+ fmt .Println (logMsg )
300+
301+ if err != nil {
302+ log .Error ().Err (err ).Send ()
303+ return false , pamProvider , returnHttpErr (httpResponse , err )
304+ }
305+
306+ if len (foundProvider ) != 1 {
307+ logMsg = "More than one PAM Provider returned for the same name. This is not supported behavior."
308+ log .Error ().Msg (logMsg )
309+ return false , pamProvider , errors .New (logMsg )
310+ }
311+
312+ return true , foundProvider [0 ], nil
313+ }
314+
315+ func createMigrationTargetPamProvider (sdkClient * keyfactor.APIClient , fromPamProvider keyfactor.CSSCMSDataModelModelsProvider , fromPamType keyfactor.CSSCMSDataModelModelsProviderType , toPamType keyfactor.CSSCMSDataModelModelsProviderType , appendName string ) (keyfactor.CSSCMSDataModelModelsProvider , error ) {
316+ fmt .Println ("creating new Provider of migration target PAM Type" )
317+ var migrationPamProvider keyfactor.CSSCMSDataModelModelsProvider
318+ migrationPamProvider .Name = fromPamProvider .Name + appendName
319+ migrationPamProvider .ProviderType = keyfactor.CSSCMSDataModelModelsProviderType {
320+ Id : toPamType .Id ,
321+ }
322+ var onevalue int32 = 1
323+ migrationPamProvider .Area = & onevalue
324+ migrationPamProvider .SecuredAreaId = nil
325+
326+ // need to init AdditionalProperties map when setting value
327+ migrationPamProvider .AdditionalProperties = map [string ]interface {}{
328+ "Remote" : false , // this property is not on the model for some reason
329+ }
330+
331+ fmt .Println ("getting migration target PAM Type parameter definitions, InstanceLevel : false" )
332+ // TODO: check typing, have to access "Parameters" instead of ProviderTypeParams
333+ for _ , pamParamType := range fromPamType .AdditionalProperties ["Parameters" ].([]interface {}) {
334+ if ! pamParamType .(map [string ]interface {})["InstanceLevel" ].(bool ) {
335+ // found a provider level parameter
336+ // need to find the value to map over
337+ // then create an object with that value and TypeParam settings
338+ paramName := pamParamType .(map [string ]interface {})["Name" ].(string )
339+ paramValue := selectProviderParamValue (paramName , fromPamProvider .ProviderTypeParamValues )
340+ paramTypeId := selectProviderTypeParamId (paramName , toPamType .AdditionalProperties ["Parameters" ].([]interface {}))
341+ falsevalue := false
342+ providerLevelParameter := keyfactor.CSSCMSDataModelModelsPamProviderTypeParamValue {
343+ Value : & paramValue ,
344+ ProviderTypeParam : & keyfactor.CSSCMSDataModelModelsProviderTypeParam {
345+ Id : & paramTypeId ,
346+ Name : & paramName ,
347+ InstanceLevel : & falsevalue ,
348+ },
349+ }
350+
351+ // append filled out provider type parameter object, which contains the Provider-level parameter values
352+ // migrationPamProvider.ProviderTypeParamValues = append(migrationPamProvider.ProviderTypeParamValues, providerLevelParameter)
353+
354+ // TODO: need to explicit filter for CyberArk expected params, i.e. not map over Safe
355+ // this needs to be done programatically for other provider types
356+ if paramName == "AppId" {
357+ migrationPamProvider .ProviderTypeParamValues = append (migrationPamProvider .ProviderTypeParamValues , providerLevelParameter )
358+ }
359+ }
360+ }
361+
362+ msg := "Created new PAM Provider definition to be created."
363+ fmt .Println (msg )
364+ log .Info ().Msg (msg )
365+ jobject , _ := json .MarshalIndent (migrationPamProvider , "" , " " )
366+ fmt .Println (string (jobject ))
367+ fmt .Println ("^^^ PAM Provider to be created ^^^" )
368+
369+ // POST new PAM Provider
370+ // create new PAM Instance of designated <<TO>> type
371+ // set area = 1 or previous value
372+ // name = old name plus append parameter
373+ // providertype.id = Type GUID
374+ // for all provider level values:
375+ // set value to migrating value
376+ // null for instanceid, instanceguid
377+ // providertypeparam should be set to all matching values from GET TYPES
378+ // ignoring datatype
379+
380+ createdPamProvider , httpResponse , rErr := sdkClient .PAMProviderApi .PAMProviderCreatePamProvider (context .Background ()).
381+ Provider (migrationPamProvider ).
382+ XKeyfactorRequestedWith (XKeyfactorRequestedWith ).XKeyfactorApiVersion (XKeyfactorApiVersion ).
383+ Execute ()
384+
385+ if rErr != nil {
386+ log .Error ().Err (rErr ).Send ()
387+ return * createdPamProvider , returnHttpErr (httpResponse , rErr )
388+ }
389+
390+ fmt .Println ("vvv CREATED MIGRATION PAM PROVIDER vvv" )
391+ jobject , _ = json .MarshalIndent (createdPamProvider , "" , " " )
392+ fmt .Println (string (jobject ))
393+ fmt .Println ("^^^ CREATED MIGRATION PAM PROVIDER ^^^" )
394+
395+ return * createdPamProvider , nil
396+ }
397+
357398func selectProviderParamValue (name string , providerParameters []keyfactor.CSSCMSDataModelModelsPamProviderTypeParamValue ) string {
358399 for _ , parameter := range providerParameters {
359400 if name == * parameter .ProviderTypeParam .Name {
0 commit comments