Skip to content

Commit

Permalink
Merge pull request #405 from mvshao/migration-fuse
Browse files Browse the repository at this point in the history
Prevent incompatible migration of Shoot to Runtime CR
  • Loading branch information
mvshao authored Oct 16, 2024
2 parents e67746e + c2ad40e commit d1bcfb5
Show file tree
Hide file tree
Showing 8 changed files with 580 additions and 7 deletions.
62 changes: 62 additions & 0 deletions hack/runtime-migrator/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
module github.com/kyma-project/infrastructure-manager/hack/runtime-migrator-app

go 1.23.1

require (
github.com/gardener/gardener v1.100.0
github.com/kyma-project/infrastructure-manager v0.0.0-20241010165136-c9d296aadebd
github.com/kyma-project/infrastructure-manager/hack/shoot-comparator v0.0.0-20241010165136-c9d296aadebd
github.com/pkg/errors v0.9.1
k8s.io/api v0.31.1
k8s.io/apimachinery v0.31.1
k8s.io/client-go v0.31.1
sigs.k8s.io/controller-runtime v0.19.0
sigs.k8s.io/yaml v1.4.0
)

require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/gardener/gardener-extension-provider-aws v1.56.1 // indirect
github.com/gardener/gardener-extension-provider-gcp v1.37.0 // indirect
github.com/gardener/gardener-extension-provider-openstack v1.41.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/onsi/gomega v1.34.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/oauth2 v0.22.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.6.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.31.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)
203 changes: 203 additions & 0 deletions hack/runtime-migrator/go.sum

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions hack/runtime-migrator/input/converter_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"kubernetes": {
"defaultVersion": "1.29",
"enableKubernetesVersionAutoUpdate": true,
"enableMachineImageVersionAutoUpdate": false
},
"dns": {
"secretName": "aws-route53-secret-dev",
"domainPrefix": "dev.kyma.ondemand.com",
"providerType": "aws-route53"
},
"aws": {
"enableIMDSv2": "true"
},
"machineImage": {
"defaultName" : "gardenlinux",
"defaultVersion": "1592.1.0"
},
"auditLogging": {
"policyConfigMapName": "auditPlaceholder",
"tenantConfigPath": "placeholder.json"
},
"gardener": {
"projectName": "kyma-dev"
}
}
7 changes: 4 additions & 3 deletions hack/runtime-migrator/input/runtimeids_sample.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
7c6b4bd3-09d3-462f-b27c-992727b62eec,
}
[
"7c6b4bd3-09d3-462f-b27c-992727b62eec",
"another-id"
]
58 changes: 58 additions & 0 deletions hack/runtime-migrator/internal/comparator/comparator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package comparator

import (
"github.com/gardener/gardener/pkg/apis/core/v1beta1"
"github.com/kyma-project/infrastructure-manager/hack/shoot-comparator/pkg/shoot"
"github.com/pkg/errors"
)

type Result struct {
Equal bool
Diff []Difference
}

type Difference struct {
ShootName string
LeftShoot v1beta1.Shoot
RightShoot v1beta1.Shoot
Message string
}

func CompareShoots(leftShoot, rightShoot v1beta1.Shoot) (Result, error) {

differences, err := compare(leftShoot, rightShoot)
if err != nil {
return Result{}, err
}

equal := len(differences) == 0

return Result{
Equal: equal,
Diff: differences,
}, nil
}

func compare(leftShoot, rightShoot v1beta1.Shoot) ([]Difference, error) {
var differences []Difference

matcher := shoot.NewMatcher(leftShoot)
equal, err := matcher.Match(rightShoot)
if err != nil {
return nil, err
}

if !equal {
if leftShoot.Name != rightShoot.Name {
return nil, errors.New("shoot names are different, stopping comparison")
}
diff := Difference{
ShootName: leftShoot.Name,
LeftShoot: leftShoot,
RightShoot: rightShoot,
Message: matcher.FailureMessage(nil),
}
differences = append(differences, diff)
}
return differences, nil
}
151 changes: 151 additions & 0 deletions hack/runtime-migrator/internal/comparator/report.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package comparator

import (
"fmt"
"log"
"os"
"path"
)

type Report struct {
reportFile *os.File
contents string
}

func SaveComparisonReport(comparisonResult Result, outputDir string, shootName string) (string, error) {
resultsDir, err := createOutputDir(outputDir, shootName)
if err != nil {
return "", err
}

report, err := newReport(resultsDir)
if err != nil {
return "", err
}
defer func() {
if err := report.Close(); err != nil {
log.Printf("Failed to close report file: %q", err)
}
}()

writeSummary(&report, comparisonResult, shootName)

if !comparisonResult.Equal {
err = writeDifferencesToReport(&report, comparisonResult.Diff)
if err != nil {
return "", fmt.Errorf("failed to write results to file: %v", err)
}

err = writeResultsToDiffFiles(comparisonResult.Diff, resultsDir)
if err != nil {
return "", fmt.Errorf("failed to write files with detected differences: %v", err)
}
}

return resultsDir, report.Save()
}

func newReport(resultsDir string) (Report, error) {
resultsFile := path.Join(resultsDir, "results.txt")

file, err := os.Create(resultsFile)
if err != nil {
return Report{}, fmt.Errorf("failed to create results file: %v", err)
}

return Report{
reportFile: file,
}, nil
}

func createOutputDir(outputDir, shootName string) (string, error) {
resultsDir := path.Join(outputDir, shootName)

err := os.MkdirAll(resultsDir, os.ModePerm)
if err != nil {
return "", fmt.Errorf("failed to create results directory: %v", err)
}

return resultsDir, nil
}

func (rw *Report) Save() error {
_, err := rw.reportFile.Write([]byte(rw.contents))

return err
}

func (rw *Report) Close() error {
if rw.reportFile != nil {
return rw.reportFile.Close()
}

return nil
}

func (rw *Report) AddLine(line string) {
rw.contents += line + "\n"
}

func writeSummary(report *Report, comparisonResult Result, shootName string) {
report.AddLine(fmt.Sprintf("Comparing generated Shoot with Shoot from Gardener, name: %s", shootName))
report.AddLine("")

if comparisonResult.Equal {
report.AddLine("No differences found.")
} else {
report.AddLine("Differences found.")
}
}

func writeDifferencesToReport(report *Report, differences []Difference) error {
if len(differences) == 0 {
return nil
}

report.AddLine("")
report.AddLine("------------------------------------------------------------------------------------------")
report.AddLine("Shoot that differ: ")

for _, difference := range differences {
msg := fmt.Sprintf("-%s", difference.ShootName)

report.AddLine(msg)
}

report.AddLine("------------------------------------------------------------------------------------------")

return nil
}

func writeResultsToDiffFiles(differences []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
}

for _, difference := range differences {
diffFile := path.Join(resultsDir, fmt.Sprintf("%s.diff", difference.ShootName))

err := writeAndCloseFunc(diffFile, difference.Message)
if err != nil {
return err
}
}

return nil
}
17 changes: 17 additions & 0 deletions hack/runtime-migrator/internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package internal
import (
"flag"
"fmt"
gardener_shoot "github.com/kyma-project/infrastructure-manager/internal/gardener/shoot"
"io"
"log"
"os"

v1 "github.com/kyma-project/infrastructure-manager/api/v1"
corev1 "k8s.io/api/core/v1"
Expand All @@ -19,6 +22,7 @@ type Config struct {
OutputPath string
IsDryRun bool
InputType string
ConverterConfigPath string
}

const (
Expand All @@ -44,6 +48,7 @@ func NewConfig() Config {
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.ConverterConfigPath, "converter-config-filepath", "/path/to/converter_config.json", "A file path to the Gardener Shoot converter configuration.")

flag.Parse()

Expand Down Expand Up @@ -99,3 +104,15 @@ func CreateKcpClient(cfg *Config) (client.Client, error) {

return k8sClient, nil
}

func LoadConverterConfig(cfg Config) (gardener_shoot.ConverterConfig, error) {
getReader := func() (io.Reader, error) {
return os.Open(cfg.ConverterConfigPath)
}
var converterConfig gardener_shoot.ConverterConfig
if err := converterConfig.Load(getReader); err != nil {
log.Print(err, "unable to load converter configuration")
return gardener_shoot.ConverterConfig{}, err
}
return converterConfig, nil
}
Loading

0 comments on commit d1bcfb5

Please sign in to comment.