Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Final fixes in the migrator #474

Merged
merged 4 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 58 additions & 19 deletions hack/runtime-migrator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ The `runtime-migrator` application
2. retrieves all existing shoot specifications
3. migrates the shoot specs to the new Runtime custom resource (Runtime CRs created with this migrator have the `operator.kyma-project.io/created-by-migrator=true` label)
4. saves the new Runtime custom resources to files
5. applies the new Runtime custom resources to the designated KCP cluster
5. checks if the new Runtime custom resource will not cause update on the Gardener
6. saves the results of the comparison between the original shoot and the shoot KIM produces based on the new Runtime CR
7. applies the new Runtime CRs to the designated KCP cluster
8. saves the migration results in the output json file

## Build

In order to build the app, run the `go build` in `/hack/runtime-migrator` directory.
In order to build the app, run the following command:

```bash
go build -o ./bin/runtime-migrator ./cmd
```

## Usage

Expand All @@ -19,34 +26,66 @@ cat input/runtimeIds.json | ./runtime-migrator \
-kcp-kubeconfig-path=/Users/myuser/kcp-kubeconfig.yml \
-output-path=/tmp/ \
-dry-run=true \
-input-type=json 1> /tmp/stdout.txt 2> /tmp/stderr.txt
-input-type=json
```

The above **execution example** will:
1. take the stdin input (json with runtimeIds array)
1. proceed only with Runtime CRs creation for clusters listed in the input
1. save generated Runtime CRs yamls in `/tmp/` directory. They will not be applied on the KCP cluster (`dry-run` mode)
1. send logs and errors to `/tmp/stderr.txt`
1. send json output to `/tmp/stdout.txt`
1. save output files in the `/tmp/` directory. The output directory contains the following:
- `migration.json` - the output file with the migration results
- `runtimes` - the directory with the Runtime CRs files
- `comparison-results` - the directory with the files generated during the comparison process
1. They will not be applied on the KCP cluster (`dry-run` mode)


### Json output example
### Output example

```
2024/10/28 13:38:49 INFO Starting runtime-migrator
2024/10/28 13:38:49 gardener-kubeconfig-path: /Users/i326211/Downloads/kubeconfig-garden-kyma-dev.yaml
2024/10/28 13:38:49 kcp-kubeconfig-path: /Users/i326211/dev/config/sap
2024/10/28 13:38:49 gardener-project-name: kyma-dev
2024/10/28 13:38:49 output-path: /tmp/
2024/10/28 13:38:49 dry-run: true
2024/10/28 13:38:49 input-type: json
2024/10/28 13:38:49
2024/10/28 13:38:49 INFO Migrating runtimes
2024/10/28 13:38:49 INFO Reading runtimeIds from stdin
2024/10/28 13:38:49 INFO Migrating runtime with ID: 80dfc8d7-6687-41b4-982c-2292afce5ac9
2024/10/28 13:39:01 WARN Runtime CR can cause unwanted update in Gardener. Please verify the runtime CR. runtimeID=80dfc8d7-6687-41b4-982c-2292afce5ac9
2024/10/28 13:39:01 INFO Migration completed. Successfully migrated runtimes: 0, Failed migrations: 0, Differences detected: 1
2024/10/28 13:39:01 INFO Migration results saved in: /tmp/migration-2024-10-28T13:38:49+01:00/migration-results.json
```

The above example shows that the migration process detected a potential problem with Runtime CR. In such a case, Runtime CR that may cause unwanted updates on Gardener will not be applied to the cluster and will require manual intervention.
The migration results are saved in the `/tmp/migration-2024-10-28T13:38:49+01:00/migration-results.json` file.

The `migration-results.json` file contains the following content:
```json
[
{
"runtimeId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"shootName": "shoot-name1",
"status": "Success",
"pathToCRYaml": "/tmp/shoot-shoot-name1.yaml"
},
{
"runtimeId": "",
"shootName": "shoot-name2",
"status": "Error",
"errorMessage": "Shoot networking pods is nil"
}
{
"runtimeId": "80dfc8d7-6687-41b4-982c-2292afce5ac9",
"shootName": "c6069ce",
"status": "ValidationError",
"errorMessage": "Runtime may cause unwanted update in Gardener. Please verify the runtime CR.",
"runtimeCRFilePath": "/tmp/migration-2024-10-28T13:38:49+01:00/runtimes/80dfc8d7-6687-41b4-982c-2292afce5ac9.yaml",
"comparisonResultDirPath": "/tmp/migration-2024-10-28T13:38:49+01:00/comparison-results/80dfc8d7-6687-41b4-982c-2292afce5ac9"
}
]
```
The runtime custom resource is saved in the `/tmp/migration-2024-10-28T13:38:49+01:00/runtimes/80dfc8d7-6687-41b4-982c-2292afce5ac9.yaml` file.

The `comparison-results` directory contains the following content:
```
drwxr-xr-x@ 5 i326211 wheel 160 28 paź 13:39 .
drwxr-xr-x@ 3 i326211 wheel 96 28 paź 13:39 ..
-rw-r--r--@ 1 i326211 wheel 1189 28 paź 13:39 c6069ce.diff
-rw-r--r--@ 1 i326211 wheel 3492 28 paź 13:39 converted-shoot.yaml
-rw-r--r--@ 1 i326211 wheel 24190 28 paź 13:39 original-shoot.yaml
```

The `c6069ce.diff` file contains the differences between the original shoot and the shoot that will be created based on the new Runtime CR. The `converted-shoot.yaml` file contains the shoot that will be created based on the new Runtime CR. The `original-shoot.yaml` file contains the shoot fetched from the Gardener.

## Configurable Parameters

Expand Down
16 changes: 10 additions & 6 deletions hack/runtime-migrator/cmd/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,23 @@ func (m Migration) Do(runtimeIDs []string) error {
slog.Error(errorMsg, "runtimeID", runtimeID)
}

reportValidationError := func(runtimeID, shootName string, msg string) {
results.ValidationFailed(runtimeID, shootName)
reportValidationError := func(runtimeID, shootName string, msg string, err error) {
errorMsg := fmt.Sprintf("%s: %v", msg, err)
results.ValidationErrorOccurred(runtimeID, shootName, errorMsg)
slog.Warn(msg, "runtimeID", runtimeID)
}

reportUnwantedUpdateDetected := func(runtimeID, shootName string, msg string) {
results.ValidationDetectedUnwantedUpdate(runtimeID, shootName)
slog.Info(msg, "runtimeID", runtimeID)
}

reportSuccess := func(runtimeID, shootName string, msg string) {
results.OperationSucceeded(runtimeID, shootName)
slog.Info(msg, "runtimeID", runtimeID)
}

for _, runtimeID := range runtimeIDs {
slog.Info(fmt.Sprintf("Migrating runtime with ID: %s", runtimeID))

shoot := findShoot(runtimeID, shootList)
if shoot == nil {
reportError(runtimeID, "", "Failed to find shoot", nil)
Expand All @@ -103,7 +107,7 @@ func (m Migration) Do(runtimeIDs []string) error {

shootComparisonResult, err := m.runtimeVerifier.Do(runtime, *shoot)
if err != nil {
reportError(runtimeID, shoot.Name, "Failed to verify runtime", err)
reportValidationError(runtimeID, shoot.Name, "Failed to verify runtime", err)

continue
}
Expand All @@ -113,7 +117,7 @@ func (m Migration) Do(runtimeIDs []string) error {
if err != nil {
reportError(runtimeID, shoot.Name, "Failed to save comparison result", err)
} else {
reportValidationError(runtimeID, shoot.Name, "Runtime CR can cause unwanted update in Gardener. Please verify the runtime CR.")
reportUnwantedUpdateDetected(runtimeID, shoot.Name, "Runtime CR can cause unwanted update in Gardener. Please verify the runtime CR.")
}

continue
Expand Down
27 changes: 20 additions & 7 deletions hack/runtime-migrator/internal/migration/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (
type StatusType string

const (
StatusSuccess StatusType = "Success"
StatusError StatusType = "Error"
StatusValidationError StatusType = "ValidationError"
StatusSuccess StatusType = "Success"
StatusError StatusType = "Error"
StatusValidationError StatusType = "ValidationError"
StatusValidationDetectedUnwantedUpdate StatusType = "ValidationDetectedUnwantedUpdate"
)

type RuntimeResult struct {
Expand Down Expand Up @@ -37,23 +38,35 @@ func NewMigratorResults(outputDirectory string) Results {
}

func (mr *Results) ErrorOccurred(runtimeID, shootName string, errorMsg string) {
result := RuntimeResult{
RuntimeID: runtimeID,
ShootName: shootName,
Status: StatusError,
ErrorMessage: errorMsg,
}

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

func (mr *Results) ValidationErrorOccurred(runtimeID, shootName string, errorMsg string) {
result := RuntimeResult{
RuntimeID: runtimeID,
ShootName: shootName,
Status: StatusError,
Status: StatusValidationError,
ErrorMessage: errorMsg,
RuntimeCRFilePath: mr.getRuntimeCRPath(shootName),
RuntimeCRFilePath: mr.getRuntimeCRPath(runtimeID),
}

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

func (mr *Results) ValidationFailed(runtimeID, shootName string) {
func (mr *Results) ValidationDetectedUnwantedUpdate(runtimeID, shootName string) {
result := RuntimeResult{
RuntimeID: runtimeID,
ShootName: shootName,
Status: StatusValidationError,
Status: StatusValidationDetectedUnwantedUpdate,
ErrorMessage: "Runtime may cause unwanted update in Gardener. Please verify the runtime CR.",
RuntimeCRFilePath: mr.getRuntimeCRPath(runtimeID),
ComparisonResultsDirPath: mr.getComparisonResultPath(runtimeID),
Expand Down
Loading