diff --git a/hack/runtime-migrator/README.md b/hack/runtime-migrator/README.md index 4c71ca1f..f0874ba4 100644 --- a/hack/runtime-migrator/README.md +++ b/hack/runtime-migrator/README.md @@ -20,83 +20,133 @@ go build -o ./bin/runtime-migrator ./cmd ## Usage ```bash -cat input/runtimeIds.json | ./runtime-migrator \ +cat ./runtime-migrator \ -gardener-kubeconfig-path=/Users/myuser/gardener-kubeconfig.yml \ -gardener-project-name=kyma-dev \ -kcp-kubeconfig-path=/Users/myuser/kcp-kubeconfig.yml \ -output-path=/tmp/ \ -dry-run=true \ + -input-file-path=input/runtimeIds.json \ -input-type=json ``` The above **execution example** will: -1. take the stdin input (json with runtimeIds array) +1. take the input from the `input/runtimeIds.json` file (json with runtime identifiers array) 1. proceed only with Runtime CRs creation for clusters listed in the input -1. save output files in the `/tmp/` directory. The output directory contains the following: - - `migration.json` - the output file with the migration results +1. save output files in the `/tmp/` directory. The output directory contains the following: + - `migration-results.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) +The input can be also provided in the form of a text file: +```bash +cat ./runtime-migrator \ + -gardener-kubeconfig-path=/Users/myuser/gardener-kubeconfig.yml \ + -gardener-project-name=kyma-stage \ + -kcp-kubeconfig-path=/Users/myuser/kcp-kubeconfig.yml \ + -output-path=/tmp/ \ + -dry-run=true \ + -input-file-path=/Users/myuser/migrator-input/runtimeIds.txt \ + -input-type=txt +``` ### 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 +2024/11/21 14:53:24 INFO Starting runtime-migrator +2024/11/21 14:53:24 gardener-kubeconfig-path: /Users/myuser/gardener-kubeconfig.yml +2024/11/21 14:53:24 kcp-kubeconfig-path: /Users/myuser/kcp-kubeconfig.yml +2024/11/21 14:53:24 gardener-project-name: kyma-stage +2024/11/21 14:53:24 output-path: /tmp/ +2024/11/21 14:53:24 dry-run: true +2024/11/21 14:53:24 input-type: txt +2024/11/21 14:53:24 input-file-path: /Users/myuser/migrator-input/runtimeIds.txt +2024/11/21 14:53:24 +2024/11/21 14:53:24 INFO Migrating runtimes +2024/11/21 14:53:24 INFO Reading runtimeIds from input file +2024/11/21 14:53:29 INFO Runtime processed successfully runtimeID=1df09b5b-0347-459d-aa0a-715db8fcaad7 +2024/11/21 14:53:32 INFO Runtime processed successfully runtimeID=ea439a5e-aa59-4e3e-8bfb-9bab1b31371e +2024/11/21 14:53:33 INFO Runtime processed successfully runtimeID=d6eeafee-ffd5-4f23-97dc-a1df197b3b30 +2024/11/21 14:53:37 WARN Runtime CR can cause unwanted update in Gardener runtimeID=99a38a99-e8d7-4b98-a6f2-5a54ed389c4d +2024/11/21 14:53:37 ERROR Failed to find shoot: no shoot with given runtimeID found runtimeID=0a61a3c4-0ea8-4e39-860a-7853f0b6d180 +2024/11/21 14:53:40 ERROR Failed to verify runtime runtimeID=6daf5f59-b0ab-44af-bb8e-7735fd609449 +2024/11/21 14:53:40 INFO Migration completed. Successfully migrated runtimes: 3, Failed migrations: 2, Differences detected: 1 +2024/11/21 14:53:40 INFO Migration results saved in: /tmp/migration-2024-11-21T14:53:24+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 are saved in the `/tmp/migration-2024-11-21T14:53:24+01:00/migration-results.json` file. +The runtime custom resources are saved in the `/tmp/migration-2024-11-21T14:53:24+01:00/runtimes` directory. The `migration-results.json` file contains the following content: ```json [ - { - "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" - } + { + "runtimeId": "1df09b5b-0347-459d-aa0a-715db8fcaad7", + "shootName": "c-1228ddd", + "status": "Success", + "runtimeCRFilePath": "/tmp/migration-2024-11-21T14:53:24+01:00/runtimes/1df09b5b-0347-459d-aa0a-715db8fcaad7.yaml" + }, + { + "runtimeId": "ea439a5e-aa59-4e3e-8bfb-9bab1b31371e", + "shootName": "c3a59d5", + "status": "Success", + "runtimeCRFilePath": "/tmp/migration-2024-11-21T14:53:24+01:00/runtimes/ea439a5e-aa59-4e3e-8bfb-9bab1b31371e.yaml" + }, + { + "runtimeId": "d6eeafee-ffd5-4f23-97dc-a1df197b3b30", + "shootName": "c141da7", + "status": "Success", + "runtimeCRFilePath": "/tmp/migration-2024-11-21T14:53:24+01:00/runtimes/d6eeafee-ffd5-4f23-97dc-a1df197b3b30.yaml" + }, + { + "runtimeId": "99a38a99-e8d7-4b98-a6f2-5a54ed389c4d", + "shootName": "c-71da0f2", + "status": "ValidationDetectedUnwantedUpdate", + "errorMessage": "Runtime may cause unwanted update in Gardener", + "runtimeCRFilePath": "/tmp/migration-2024-11-21T14:53:24+01:00/runtimes/99a38a99-e8d7-4b98-a6f2-5a54ed389c4d.yaml", + "comparisonResultDirPath": "/tmp/migration-2024-11-21T14:53:24+01:00/comparison-results/99a38a99-e8d7-4b98-a6f2-5a54ed389c4d" + }, + { + "runtimeId": "0a61a3c4-0ea8-4e39-860a-7853f0b6d180", + "shootName": "", + "status": "Error", + "errorMessage": "Failed to find shoot: no shoot with given runtimeID found" + }, + { + "runtimeId": "6daf5f59-b0ab-44af-bb8e-7735fd609449", + "shootName": "c-1f810d0", + "status": "ValidationError", + "errorMessage": "Failed to verify runtime: audit logs configuration not found: missing region: 'australiaeast' for providerType: 'azure'", + "runtimeCRFilePath": "/tmp/migration-2024-11-21T14:53:24+01:00/runtimes/6daf5f59-b0ab-44af-bb8e-7735fd609449.yaml" + } ] -``` -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 following problems were detected in the above example: +- The runtime with the `0a61a3c4-0ea8-4e39-860a-7853f0b6d180` identifier was not found ; the identifier may be incorrect, or the corresponding shoot was deleted for some reason. +- The validation process for the runtime with the `6daf5f59-b0ab-44af-bb8e-7735fd609449` identifier failed. +- The runtime with the `99a38a99-e8d7-4b98-a6f2-5a54ed389c4d` identifier may cause an unwanted update in the Gardener. The comparison results are saved in the `/tmp/migration-2024-11-21T14:53:24+01:00/comparison-results/99a38a99-e8d7-4b98-a6f2-5a54ed389c4d` directory. + + +The `/tmp/migration-2024-11-21T14:53:24+01:00/comparison-results/99a38a99-e8d7-4b98-a6f2-5a54ed389c4d"` directory contains the following files: +- `c-71da0f2.diff` +- `converted-shoot.yaml` +- `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. +The `c-71da0f2.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 This table lists the configurable parameters, their descriptions, and default values: -| Parameter | Description | Default value | -|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------| -| **kcp-kubeconfig-path** | Path to the Kubeconfig file of KCP cluster. | `/path/to/kcp/kubeconfig` | -| **gardener-kubeconfig-path** | Path to the Kubeconfig file of Gardener cluster. | `/path/to/gardener/kubeconfig` | -| **gardener-project-name** | Name of the Gardener project. | `gardener-project-name` | -| **output-path** | Path where generated yamls will be saved. Directory has to exist. | `/tmp/` | -| **dry-run** | Dry-run flag. Has to be set to **false**, otherwise migrator will not apply the CRs on the KCP cluster. | `true` | -| **input-type** | Type of input to be used. Possible values: **all** (will migrate all Gardener shoots), and **json** (will migrate only clusters whose runtimeIds were passed as an input, [see the example](input/runtimeids_sample.json)). | `json` | +| Parameter | Description | Default value | +|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------| +| **kcp-kubeconfig-path** | Path to the Kubeconfig file of KCP cluster. | `/path/to/kcp/kubeconfig` | +| **gardener-kubeconfig-path** | Path to the Kubeconfig file of Gardener cluster. | `/path/to/gardener/kubeconfig` | +| **gardener-project-name** | Name of the Gardener project. | `gardener-project-name` | +| **output-path** | Path where generated report, and yamls will be saved. Directory has to exist. | `/tmp/` | +| **dry-run** | Dry-run flag. Has to be set to **false**, otherwise migrator will not apply the CRs on the KCP cluster. | `true` | +| **input-type** | Type of input to be used. Possible values: **txt** (will expect text file with one runtime identifier per line, [see the example](input/runtimeids_sample.txt)), and **json** (will expect `json` array with runtime identifiers, [see the example](input/runtimeids_sample.json)). | `json` | +| **input-file-path** | Path to the file containing Runtimes to be migrated. | `/path/to/input/file` | diff --git a/hack/runtime-migrator/cmd/main.go b/hack/runtime-migrator/cmd/main.go index 34e15cd8..eb00d060 100644 --- a/hack/runtime-migrator/cmd/main.go +++ b/hack/runtime-migrator/cmd/main.go @@ -29,7 +29,7 @@ import ( ) const ( - timeoutK8sOperation = 5 * time.Second + timeoutK8sOperation = 10 * time.Second expirationTime = 60 * time.Minute runtimeIDAnnotation = "kcp.provisioner.kyma-project.io/runtime-id" ) diff --git a/hack/runtime-migrator/cmd/migration.go b/hack/runtime-migrator/cmd/migration.go index 2c5b4ef2..263d38ef 100644 --- a/hack/runtime-migrator/cmd/migration.go +++ b/hack/runtime-migrator/cmd/migration.go @@ -70,12 +70,12 @@ func (m Migration) Do(ctx context.Context, runtimeIDs []string) error { 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) + slog.Error(msg, "runtimeID", runtimeID) } reportUnwantedUpdateDetected := func(runtimeID, shootName string, msg string) { results.ValidationDetectedUnwantedUpdate(runtimeID, shootName) - slog.Info(msg, "runtimeID", runtimeID) + slog.Warn(msg, "runtimeID", runtimeID) } reportSuccess := func(runtimeID, shootName string, msg string) { @@ -119,7 +119,7 @@ func (m Migration) Do(ctx context.Context, runtimeIDs []string) error { return } - reportUnwantedUpdateDetected(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") return } diff --git a/hack/runtime-migrator/input/runtimeids_sample.txt b/hack/runtime-migrator/input/runtimeids_sample.txt new file mode 100644 index 00000000..fa80cc87 --- /dev/null +++ b/hack/runtime-migrator/input/runtimeids_sample.txt @@ -0,0 +1,2 @@ +7c6b4bd3-09d3-462f-b27c-992727b62eec +another-id" \ No newline at end of file diff --git a/hack/runtime-migrator/internal/config/config.go b/hack/runtime-migrator/internal/config/config.go index e2a8da06..451968a9 100644 --- a/hack/runtime-migrator/internal/config/config.go +++ b/hack/runtime-migrator/internal/config/config.go @@ -33,6 +33,7 @@ func printConfig(cfg Config) { log.Println("output-path:", cfg.OutputPath) log.Println("dry-run:", cfg.IsDryRun) log.Println("input-type:", cfg.InputType) + log.Println("input-file-path:", cfg.InputFilePath) log.Println("") } @@ -44,7 +45,7 @@ func NewConfig() Config { flag.StringVar(&result.GardenerProjectName, "gardener-project-name", "gardener-project-name", "Name of the Gardener project.") flag.StringVar(&result.OutputPath, "output-path", "/tmp/", "Path where generated yamls will be saved. Directory has to exist.") flag.BoolVar(&result.IsDryRun, "dry-run", true, "Dry-run flag. Has to be set to 'false' otherwise it will not apply the Custom Resources on the KCP cluster.") - flag.StringVar(&result.InputType, "input-type", InputTypeJSON, "Type of input to be used. Possible values: **all** (will migrate all gardener shoots), and **json** (will migrate only cluster whose runtimeIds were passed as an input, see the example hack/runtime-migrator/input/runtimeids_sample.json).") + flag.StringVar(&result.InputType, "input-type", InputTypeJSON, "Type of input to be used. Possible values: **txt** (see the example hack/runtime-migrator/input/runtimeids_sample.txt), and **json** (see the example hack/runtime-migrator/input/runtimeids_sample.json).") flag.StringVar(&result.InputFilePath, "input-file-path", "/path/to/input/file", "Path to the input file containing RuntimeCRs to be migrated.") flag.Parse()