Skip to content

Commit

Permalink
Started working on writing comparison results - WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
akgalwas committed Oct 27, 2024
1 parent 1783cbf commit 04ee1a6
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 56 deletions.
4 changes: 1 addition & 3 deletions hack/runtime-migrator/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,11 @@ func main() {
slog.Info("Migrating runtimes")
migrator := NewMigration(cfg, converterConfig, kubeconfigProvider, kcpClient, gardenerShootClient)

results, err := migrator.Do(getRuntimeIDsFromStdin(cfg))
err = migrator.Do(getRuntimeIDsFromStdin(cfg))
if err != nil {
slog.Error(fmt.Sprintf("Failed to migrate runtimes - %v", err))
os.Exit(1)
}

slog.Info(fmt.Sprintf("Migration completed. Successfully migrated runtimes: %d, Failed migrations: %d, Differences detected: %d", results.Succeeded, results.Failed, results.DifferenceDetected))
}

func setupKubernetesKubeconfigProvider(kubeconfigPath string, namespace string, expirationTime time.Duration) (kubeconfig.Provider, error) {
Expand Down
40 changes: 22 additions & 18 deletions hack/runtime-migrator/cmd/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,19 @@ type Migration struct {
shootClient gardener_types.ShootInterface
}

func (m Migration) Do(runtimeIDs []string) (migration.MigrationResults, error) {
func (m Migration) Do(runtimeIDs []string) error {

outputWriter, err := migration.NewOutputWriter(m.migrationConfig.OutputPath)
if err != nil {
return migration.MigrationResults{}, err
return err
}

shootList, err := m.shootClient.List(context.Background(), v1.ListOptions{})
if err != nil {
return migration.MigrationResults{}, err
return err
}

results := migration.NewMigratorResults(outputWriter.RuntimeDir)
results := migration.NewMigratorResults(outputWriter.NewResultsDir)

for _, runtimeID := range runtimeIDs {
slog.Info(fmt.Sprintf("Migrating runtime with ID: %s", runtimeID))
Expand Down Expand Up @@ -80,22 +80,13 @@ func (m Migration) Do(runtimeIDs []string) (migration.MigrationResults, error) {
shootComparisonResult, err := m.runtimeVerifier.Do(runtime, *shoot)
if err != nil {
msg := "Failed to verify runtime"
results.ValidationFailed(runtimeID, shoot.Name)
slog.Error(msg, "runtimeID", runtimeID)

continue
}

err = outputWriter.SaveComparisonResult(shootComparisonResult)
if err != nil {
msg := "Failed to store comparison results"
results.ErrorOccurred(runtimeID, shoot.Name, msg)
slog.Error(fmt.Sprintf("Failed to save comparison result: %v", err), "runtimeID", runtimeID)
slog.Error(msg, "runtimeID", runtimeID)

continue
}

if shootComparisonResult.Diff != nil && !m.migrationConfig.IsDryRun {
if shootComparisonResult.IsEqual() && !m.migrationConfig.IsDryRun {
err = m.applyRuntimeCR(runtime)
if err != nil {
msg := "Failed to apply Runtime CR"
Expand All @@ -106,18 +97,31 @@ func (m Migration) Do(runtimeIDs []string) (migration.MigrationResults, error) {
continue
}

results.OperationSucceeded(runtimeID, shoot.Name)
if shootComparisonResult.IsEqual() {
results.OperationSucceeded(runtimeID, shoot.Name)
} else {
err = outputWriter.SaveComparisonResult(shootComparisonResult)
if err != nil {
msg := "Failed to store comparison results"
results.ErrorOccurred(runtimeID, shoot.Name, msg)
slog.Error(fmt.Sprintf("Failed to save comparison result: %v", err), "runtimeID", runtimeID)

continue
}

results.ValidationFailed(runtimeID, shoot.Name)
}
}

resultsFile, err := outputWriter.SaveMigrationResults(results)
if err != nil {
return results, err
return err
}

slog.Info(fmt.Sprintf("Migration completed. Successfully migrated runtimes: %d, Failed migrations: %d, Differences detected: %d", results.Succeeded, results.Failed, results.DifferenceDetected))
slog.Info(fmt.Sprintf("Migration results saved in: %s", resultsFile))

return results, nil
return nil
}

func findShoot(runtimeID string, shootList *v1beta1.ShootList) *v1beta1.Shoot {
Expand Down
58 changes: 57 additions & 1 deletion hack/runtime-migrator/internal/migration/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func NewOutputWriter(outputDir string) (OutputWriter, error) {
}, nil
}

func (ow OutputWriter) SaveMigrationResults(results MigrationResults) (string, error) {
func (ow OutputWriter) SaveMigrationResults(results Results) (string, error) {
resultFile, err := json.Marshal(results.Results)
if err != nil {
return "", err
Expand Down Expand Up @@ -81,6 +81,62 @@ func writeSpecToFile(outputPath, runtimeID string, shootAsYaml []byte) error {
}

func (ow OutputWriter) SaveComparisonResult(comparisonResult runtime.ShootComparisonResult) error {
comparisonResultsForRuntimeDir := path.Join(ow.ComparisonResultsDir, comparisonResult.RuntimeID)
err := os.MkdirAll(comparisonResultsForRuntimeDir, 0644)
if err != nil {
return err
}

if comparisonResult.Diff != nil {
err = writeResultsToDiffFiles(comparisonResult.OriginalShoot.Name, comparisonResult.Diff, comparisonResultsForRuntimeDir)
if err != nil {
return err
}
}

err = saveShootToFile(path.Join(comparisonResultsForRuntimeDir, "original-shoot.yaml"), comparisonResult.OriginalShoot)
if err != nil {
return err
}

return saveShootToFile(path.Join(comparisonResultsForRuntimeDir, "converted-shoot.yaml"), comparisonResult.ConvertedShoot)
}

func saveShootToFile(filePath string, shoot interface{}) error {
shootAsYaml, err := yaml.Marshal(shoot)
if err != nil {
return err
}

err = os.WriteFile(filePath, shootAsYaml, 0644)
if err != nil {
return err
}

return nil
}

func writeResultsToDiffFiles(shootName string, difference *runtime.Difference, resultsDir string) error {
writeAndCloseFunc := func(filePath string, text string) error {
file, err := os.Create(filePath)
if err != nil {
return err
}
defer func() {
if file != nil {
err := file.Close()
if err != nil {
fmt.Printf("failed to close file: %v", err)
}
}
}()

_, err = file.Write([]byte(text))

return err
}

diffFile := path.Join(resultsDir, fmt.Sprintf("%s.diff", shootName))

return writeAndCloseFunc(diffFile, string(*difference))
}
51 changes: 27 additions & 24 deletions hack/runtime-migrator/internal/migration/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,64 @@ import (
migrator "github.com/kyma-project/infrastructure-manager/hack/runtime-migrator-app/internal"
)

const runtimeCrFullPath = "%sshoot-dd%s.yaml"

type MigrationResults struct {
type Results struct {
Results []migrator.MigrationResult
Succeeded int
Failed int
DifferenceDetected int
OutputDirectory string
}

func NewMigratorResults(outputDirectory string) MigrationResults {
return MigrationResults{
func NewMigratorResults(outputDirectory string) Results {
return Results{
Results: make([]migrator.MigrationResult, 0),
OutputDirectory: outputDirectory,
}
}

func (mr MigrationResults) ErrorOccurred(runtimeID, shootName string, errorMsg string) {
func (mr *Results) ErrorOccurred(runtimeID, shootName string, errorMsg string) {
result := migrator.MigrationResult{
RuntimeID: runtimeID,
ShootName: shootName,
Status: migrator.StatusError,
ErrorMessage: errorMsg,
PathToCRYaml: mr.getYamlPath(shootName),
RuntimeID: runtimeID,
ShootName: shootName,
Status: migrator.StatusError,
ErrorMessage: errorMsg,
RuntimeCRFilePath: mr.getRuntimeCRPath(shootName),
}

mr.Failed++
mr.Results = append(mr.Results, result)
}

func (mr MigrationResults) ValidationFailed(runtimeID, shootName string) {
func (mr *Results) ValidationFailed(runtimeID, shootName string) {
result := migrator.MigrationResult{
RuntimeID: runtimeID,
ShootName: shootName,
Status: migrator.StatusRuntimeCRCanCauseUnwantedUpdate,
ErrorMessage: "Runtime may cause unwanted update in Gardener. Please verify the runtime CR.",
PathToCRYaml: mr.getYamlPath(runtimeID),
RuntimeID: runtimeID,
ShootName: shootName,
Status: migrator.StatusRuntimeCRCanCauseUnwantedUpdate,
ErrorMessage: "Runtime may cause unwanted update in Gardener. Please verify the runtime CR.",
RuntimeCRFilePath: mr.getRuntimeCRPath(runtimeID),
ComparisonResultsDirPath: mr.getComparisonResultPath(runtimeID),
}

mr.DifferenceDetected++
mr.Results = append(mr.Results, result)
}

func (mr MigrationResults) OperationSucceeded(runtimeID string, shootName string) {
func (mr *Results) OperationSucceeded(runtimeID string, shootName string) {
result := migrator.MigrationResult{
RuntimeID: runtimeID,
ShootName: shootName,
Status: migrator.StatusSuccess,
PathToCRYaml: mr.getYamlPath(runtimeID),
RuntimeID: runtimeID,
ShootName: shootName,
Status: migrator.StatusSuccess,
RuntimeCRFilePath: mr.getRuntimeCRPath(runtimeID),
}

mr.Succeeded++
mr.Results = append(mr.Results, result)
}

func (mr MigrationResults) getYamlPath(runtimeID string) string {
return fmt.Sprintf(runtimeCrFullPath, mr.OutputDirectory, runtimeID)
func (mr *Results) getRuntimeCRPath(runtimeID string) string {
return fmt.Sprintf("%s/runtimes/%s", mr.OutputDirectory, runtimeID)
}

func (mr *Results) getComparisonResultPath(runtimeID string) string {
return fmt.Sprintf("%s/comparison-results/%s", mr.OutputDirectory, runtimeID)
}
14 changes: 8 additions & 6 deletions hack/runtime-migrator/internal/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ type StatusType string

const (
StatusSuccess StatusType = "Success"
StatusError StatusType = "Error"
StatusError StatusType = "GenerationError"
StatusCRApplyError StatusType = "CRApplyError"
StatusAlreadyExists StatusType = "AlreadyExists"
StatusRuntimeIDNotFound StatusType = "RuntimeIDNotFound"
StatusFailedToCreateRuntimeCR StatusType = "FailedToCreateRuntimeCR"
StatusRuntimeCRCanCauseUnwantedUpdate StatusType = "RuntimeCRCanCauseUnwantedUpdate"
)

type MigrationResult struct {
RuntimeID string `json:"runtimeId"`
ShootName string `json:"shootName"`
Status StatusType `json:"status"`
ErrorMessage string `json:"errorMessage,omitempty"`
PathToCRYaml string `json:"pathToCRYaml,omitempty"`
RuntimeID string `json:"runtimeId"`
ShootName string `json:"shootName"`
Status StatusType `json:"status"`
ErrorMessage string `json:"errorMessage,omitempty"`
RuntimeCRFilePath string `json:"runtimeCRFilePath,omitempty"`
ComparisonResultsDirPath string `json:"comparisonResultDirPath,omitempty"`
}
6 changes: 6 additions & 0 deletions hack/runtime-migrator/internal/runtime/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func NewVerifier(converterConfig config.ConverterConfig, outputPath string) Veri
}

type ShootComparisonResult struct {
RuntimeID string
OriginalShoot v1beta1.Shoot
ConvertedShoot v1beta1.Shoot
Diff *Difference
Expand All @@ -41,6 +42,7 @@ func (v Verifier) Do(runtimeToVerify v1.Runtime, shootToMatch v1beta1.Shoot) (Sh
}

return ShootComparisonResult{
RuntimeID: runtimeToVerify.Name,
OriginalShoot: shootToMatch,
ConvertedShoot: shootFromConverter,
Diff: diff,
Expand All @@ -61,3 +63,7 @@ func compare(originalShoot, convertedShoot v1beta1.Shoot) (*Difference, error) {

return nil, nil
}

func (cr ShootComparisonResult) IsEqual() bool {
return cr.Diff == nil
}
8 changes: 4 additions & 4 deletions hack/runtime-migrator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ func main() {
}

results = append(results, migrator.MigrationResult{
RuntimeID: shoot.Annotations[runtimeIDAnnotation],
ShootName: shoot.Name,
Status: migrator.StatusSuccess,
PathToCRYaml: fmt.Sprintf(runtimeCrFullPath, cfg.OutputPath, shoot.Name),
RuntimeID: shoot.Annotations[runtimeIDAnnotation],
ShootName: shoot.Name,
Status: migrator.StatusSuccess,
RuntimeCRFilePath: fmt.Sprintf(runtimeCrFullPath, cfg.OutputPath, shoot.Name),
})
}
encoder := json.NewEncoder(os.Stdout)
Expand Down

0 comments on commit 04ee1a6

Please sign in to comment.