Skip to content

Commit 0f8db18

Browse files
committed
initial sketch of migrate function
1 parent 8627008 commit 0f8db18

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

cmd/migrate.go

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Copyright 2025 Keyfactor
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cmd
16+
17+
import (
18+
"context"
19+
"fmt"
20+
21+
"github.com/rs/zerolog/log"
22+
"github.com/spf13/cobra"
23+
)
24+
25+
// type JSONImportableObject interface {
26+
// keyfactor.KeyfactorApiPAMProviderTypeCreateRequest |
27+
// keyfactor.CSSCMSDataModelModelsProvider
28+
// }
29+
30+
// const (
31+
// convertResponseMsg = "Converting PAM Provider response to JSON"
32+
// )
33+
34+
type PAMParameterValue struct {
35+
GUID string
36+
Value string
37+
}
38+
39+
var migrateCmd = &cobra.Command{
40+
Use: "migrate",
41+
Short: "Keyfactor Migration Tools.",
42+
Long: `Migrating to new Types and Extension implementations in Keyfactor is possible but not currently automated
43+
in the platform. This tool aims to assist in performing the necessary steps to migrate, in limited scenarios,
44+
to new Extension implementations that have definitions that differ from prior releases.`,
45+
}
46+
47+
var migratePamCmd = &cobra.Command{
48+
Use: "pam",
49+
Short: "Migrate existing PAM Provider usage to a new PAM Provider",
50+
Long: "Migrate existing PAM Provider usage to a new PAM Provider",
51+
RunE: func(cmd *cobra.Command, args []string) error {
52+
cmd.SilenceUsage = true
53+
isExperimental := true
54+
55+
// load specified flags
56+
migrateFrom, _ := cmd.Flags().GetString("from")
57+
migrateTo, _ := cmd.Flags().GetString("to")
58+
appendName, _ := cmd.Flags().GetString("append-name")
59+
60+
// Debug + expEnabled checks
61+
informDebug(debugFlag)
62+
debugErr := warnExperimentalFeature(expEnabled, isExperimental)
63+
if debugErr != nil {
64+
return debugErr
65+
}
66+
67+
// Log flags
68+
log.Info().Str("from", migrateFrom).
69+
Str("to", migrateTo).
70+
Str("append-name", appendName).
71+
Msg("migrate PAM Provider")
72+
73+
// Authenticate
74+
sdkClient, cErr := initGenClient(false)
75+
if cErr != nil {
76+
return cErr
77+
}
78+
79+
log.Info().Msg("looking up usage of <<from>> PAM Provider")
80+
81+
log.Debug().Msg("call: PAMProviderGetPamProviders()")
82+
listPamProvidersInUse, httpResponse, rErr := sdkClient.PAMProviderApi.PAMProviderGetPamProviders(context.Background()).
83+
XKeyfactorRequestedWith(XKeyfactorRequestedWith).XKeyfactorApiVersion(XKeyfactorApiVersion).
84+
PqQueryString(fmt.Sprintf("name -eq \"%s\"", migrateFrom)).
85+
Execute()
86+
log.Debug().Msg("returned: PAMProviderGetPamProviders()")
87+
88+
if rErr != nil {
89+
log.Error().Err(rErr).Send()
90+
return returnHttpErr(httpResponse, rErr)
91+
}
92+
93+
// TODO: ensure only 1 returned PAM Provider definition
94+
95+
// get PAM Type definition for PAM Provider migrating <<FROM>>
96+
log.Debug().Msg("call: PAMProviderGetPamProviders()")
97+
pamTypes, httpResponse, rErr := sdkClient.PAMProviderApi.PAMProviderGetPamProviderTypes(context.Background()).
98+
XKeyfactorRequestedWith(XKeyfactorRequestedWith).XKeyfactorApiVersion(XKeyfactorApiVersion).
99+
Execute()
100+
log.Debug().Msg("returned: PAMProviderGetPamProviders()")
101+
102+
if rErr != nil {
103+
log.Error().Err(rErr).Send()
104+
return returnHttpErr(httpResponse, rErr)
105+
}
106+
107+
// assess <<FROM>> source PAM Type to create map for storing existing data
108+
// this map has the first string key record the parameter field name
109+
// the inner map tracks PAM instance GUIDs to that instances value for the field
110+
inUsePamParamValues := map[string]map[string]string{}
111+
for _, pamType := range pamTypes {
112+
if pamType.Id == listPamProvidersInUse[0].ProviderType.Id {
113+
for _, pamParamType := range pamType.ProviderTypeParams {
114+
if *pamParamType.InstanceLevel {
115+
// found definition of an instance level param for the type in question
116+
// create key in map for the field name
117+
inUsePamParamValues[*pamParamType.Name] = map[string]string{}
118+
}
119+
}
120+
}
121+
}
122+
123+
// step through list of every defined param value
124+
// record unique GUIDs of every param value on InstanceLevel : true
125+
// don't count InstanceLevel : false because those are Secret (DataType:2) instances for the Provider itself, not actual usages
126+
for _, pamParam := range listPamProvidersInUse[0].ProviderTypeParamValues {
127+
if *pamParam.ProviderTypeParam.InstanceLevel {
128+
fieldName := *pamParam.ProviderTypeParam.Name
129+
usageGuid := *pamParam.InstanceGuid
130+
inUsePamParamValues[fieldName][usageGuid] = *pamParam.Value
131+
}
132+
}
133+
134+
// TODO: make sure every field has the same number of GUIDs tracked
135+
// tally GUID count for logging
136+
137+
// log.Info().Msgf("Found %d PAM Provider usages of Provider %s",)
138+
139+
// implement migration logic
140+
// create new PAM Instance of designated <<TO>> type
141+
},
142+
}

0 commit comments

Comments
 (0)