@@ -82,27 +82,6 @@ func formatProperties(json *gabs.Container, reqPropertiesForStoreType []string)
8282 return json
8383}
8484
85- func serializeStoreFromTypeDef (storeTypeName string , input string ) (string , error ) {
86- // check if storetypename is an integer
87- storeTypes , _ := readStoreTypesConfig ("" , DefaultGitRef , DefaultGitRepo , offline )
88- log .Debug ().
89- Str ("storeTypeName" , storeTypeName ).
90- Msg ("checking if storeTypeName is an integer" )
91- sTypeId , err := strconv .Atoi (storeTypeName )
92- if err == nil {
93- log .Debug ().
94- Int ("storeTypeId" , sTypeId ).
95- Msg ("storeTypeName is an integer" )
96- }
97- for _ , st := range storeTypes {
98- log .Debug ().
99- Interface ("st" , st ).
100- Msg ("iterating through store types" )
101- }
102- return "" , nil
103-
104- }
105-
10685var importStoresCmd = & cobra.Command {
10786 Use : "import" ,
10887 Short : "Import a file with certificate store definitions and create them in Keyfactor Command." ,
@@ -163,6 +142,7 @@ If you do not wish to include credentials in your CSV file they can be provided
163142 serverUsername , _ := cmd .Flags ().GetString ("server-username" )
164143 serverPassword , _ := cmd .Flags ().GetString ("server-password" )
165144 storePassword , _ := cmd .Flags ().GetString ("store-password" )
145+ allowUpdates , _ := cmd .Flags ().GetBool ("sync" )
166146
167147 if serverUsername == "" {
168148 serverUsername = os .Getenv (EnvStoresImportCSVServerUsername )
@@ -174,12 +154,6 @@ If you do not wish to include credentials in your CSV file they can be provided
174154 storePassword = os .Getenv (EnvStoresImportCSVStorePassword )
175155 }
176156
177- //// Flag Checks
178- //inputErr := storeTypeIdentifierFlagCheck(cmd)
179- //if inputErr != nil {
180- // return inputErr
181- //}
182-
183157 // expEnabled checks
184158 isExperimental := false
185159 debugErr := warnExperimentalFeature (expEnabled , isExperimental )
@@ -351,10 +325,14 @@ If you do not wish to include credentials in your CSV file they can be provided
351325 log .Debug ().Msgf ("ContainerId is 0, omitting from request" )
352326 reqJson .Set (nil , "ContainerId" )
353327 }
328+
329+ storeId := reqJson .S ("Id" ).String ()
330+ if storeId != "" && allowUpdates {
331+ log .Debug ().Str ("storeId" , storeId ).Msgf ("Store Id present in row, will attempt update operation" )
332+ }
354333 //log.Debug().Msgf("Request JSON: %s", reqJson.String())
355334
356335 // parse properties
357- var createStoreReqParameters api.CreateStoreFctArgs
358336 props := unmarshalPropertiesString (reqJson .S ("Properties" ).String ())
359337
360338 //check if ServerUsername is present in the properties
@@ -382,6 +360,37 @@ If you do not wish to include credentials in your CSV file they can be provided
382360 }
383361 }
384362 mJSON := stripAllBOMs (reqJson .String ())
363+
364+ var createStoreReqParameters api.CreateStoreFctArgs
365+ if storeId != "" && allowUpdates {
366+ updateReqParameters := api.UpdateStoreFctArgs {}
367+ conversionError := json .Unmarshal ([]byte (mJSON ), & updateReqParameters )
368+ if conversionError != nil {
369+ //outputError(conversionError, true, outputFormat)
370+ log .Error ().Err (conversionError ).Msgf (
371+ "Unable to convert the json into the request parameters object. %s" ,
372+ conversionError .Error (),
373+ )
374+ return conversionError
375+ }
376+
377+ updateReqParameters .Password = passwdParams
378+ updateReqParameters .Properties = props
379+ log .Info ().Msgf ("Calling Command to update store from row '%d'" , idx )
380+ res , err := kfClient .UpdateStore (& updateReqParameters )
381+ if err != nil {
382+ log .Error ().Err (err ).Msgf ("Error updating store from row '%d'" , idx )
383+ resultsMap = append (resultsMap , []string {err .Error ()})
384+ inputMap [idx - 1 ]["Errors" ] = err .Error ()
385+ inputMap [idx - 1 ]["Id" ] = "error"
386+ errorCount ++
387+ } else {
388+ log .Info ().Msgf ("Successfully updated store from row '%d' as '%s'" , idx , res .Id )
389+ resultsMap = append (resultsMap , []string {fmt .Sprintf ("%s" , res .Id )})
390+ inputMap [idx - 1 ]["Id" ] = res .Id
391+ }
392+ continue
393+ }
385394 conversionError := json .Unmarshal ([]byte (mJSON ), & createStoreReqParameters )
386395
387396 if conversionError != nil {
@@ -619,7 +628,15 @@ var storesExportCmd = &cobra.Command{
619628
620629 // Authenticate
621630
622- kfClient , _ := initClient (false )
631+ kfClient , cErr := initClient (false )
632+ if cErr != nil {
633+ log .Error ().Err (cErr ).Msg ("Error initializing client" )
634+ return cErr
635+ }
636+ if kfClient == nil {
637+ log .Error ().Msg ("Keyfactor client is nil after initialization" )
638+ return fmt .Errorf ("Keyfactor client is nil after initialization" )
639+ }
623640
624641 // CLI Logic
625642 log .Info ().
@@ -791,7 +808,13 @@ var storesExportCmd = &cobra.Command{
791808 if _ , isInt := prop .(int ); isInt {
792809 prop = strconv .Itoa (prop .(int ))
793810 }
794- if name != "ServerUsername" && name != "ServerPassword" { // Don't add ServerUsername and ServerPassword to properties as they can't be exported via API
811+ switch prop .(type ) {
812+ case map [string ]interface {}:
813+ for k , v := range prop .(map [string ]interface {}) {
814+ csvData [store .Id ][fmt .Sprintf ("Properties.%s.%s" , name , k )] = v
815+ }
816+
817+ default :
795818 csvData [store .Id ]["Properties." + name ] = prop
796819 }
797820 }
@@ -1026,44 +1049,6 @@ func unmarshalPropertiesString(properties string) map[string]interface{} {
10261049 return make (map [string ]interface {})
10271050}
10281051
1029- //func parseSecretField(secretField interface{}) interface{} {
1030- // var secret api.StorePasswordConfig
1031- // secretByte, errors := json.Marshal(secretField)
1032- // if errors != nil {
1033- // log.Printf("Error in Marshalling: %s", errors)
1034- // fmt.Printf("Error in Marshalling: %s\n", errors)
1035- // panic("error marshalling secret field as StorePasswordConfig")
1036- // }
1037- //
1038- // errors = json.Unmarshal(secretByte, &secret)
1039- // if errors != nil {
1040- // log.Printf("Error in Unmarshalling: %s", errors)
1041- // fmt.Printf("Error in Unmarshalling: %s\n", errors)
1042- // panic("error unmarshalling secret field as StorePasswordConfig")
1043- // }
1044- //
1045- // if secret.IsManaged {
1046- // params := make(map[string]string)
1047- // for _, p := range *secret.ProviderTypeParameterValues {
1048- // params[*p.ProviderTypeParam.Name] = *p.Value
1049- // }
1050- // return map[string]interface{}{
1051- // "Provider": secret.ProviderId,
1052- // "Parameters": params,
1053- // }
1054- // } else {
1055- // if secret.Value != "" {
1056- // return map[string]string{
1057- // "SecretValue": secret.Value,
1058- // }
1059- // } else {
1060- // return map[string]*string{
1061- // "SecretValue": nil,
1062- // }
1063- // }
1064- // }
1065- //}
1066-
10671052func getJsonForRequest (headerRow []string , row []string ) * gabs.Container {
10681053 log .Debug ().Msgf ("Getting JSON for request" )
10691054 reqJson := gabs .New ()
@@ -1160,6 +1145,8 @@ func init() {
11601145 file string
11611146 resultsPath string
11621147 exportAll bool
1148+ sync bool
1149+ dryRun bool
11631150 )
11641151
11651152 storesCmd .AddCommand (importStoresCmd )
@@ -1239,7 +1226,15 @@ func init() {
12391226
12401227 storesCreateFromCSVCmd .Flags ().StringVarP (& file , "file" , "f" , "" , "CSV file containing cert stores to create." )
12411228 storesCreateFromCSVCmd .MarkFlagRequired ("file" )
1242- storesCreateFromCSVCmd .Flags ().BoolP ("dry-run" , "d" , false , "Do not import, just check for necessary fields." )
1229+ storesCreateFromCSVCmd .Flags ().BoolVarP (
1230+ & dryRun , "dry-run" , "d" , false , "Do not import, " +
1231+ "just check for necessary fields." ,
1232+ )
1233+ storesCreateFromCSVCmd .Flags ().BoolVarP (
1234+ & sync ,
1235+ "sync" , "z" , false , "Create or update existing stores. " +
1236+ "NOTE: Use this w/ --dry-run to view changes." ,
1237+ )
12431238 storesCreateFromCSVCmd .Flags ().StringVarP (
12441239 & resultsPath ,
12451240 "results-path" ,
0 commit comments