Skip to content

Commit

Permalink
Merge pull request #329 from akgalwas/migrator-fixes
Browse files Browse the repository at this point in the history
Fixes to make migrator up to date
  • Loading branch information
kyma-bot authored Aug 20, 2024
2 parents 74f7687 + f08eddb commit b1440d7
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 70 deletions.
22 changes: 11 additions & 11 deletions api/v1/runtime_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,17 @@ type RuntimeStatus struct {
}

type RuntimeShoot struct {
Name string `json:"name"`
Purpose gardener.ShootPurpose `json:"purpose"`
PlatformRegion string `json:"platformRegion"`
Region string `json:"region"`
LicenceType *string `json:"licenceType,omitempty"`
SecretBindingName string `json:"secretBindingName"`
EnforceSeedLocation *bool `json:"enforceSeedLocation,omitempty"`
Kubernetes Kubernetes `json:"kubernetes,omitempty"`
Provider Provider `json:"provider"`
Networking Networking `json:"networking"`
ControlPlane gardener.ControlPlane `json:"controlPlane"`
Name string `json:"name"`
Purpose gardener.ShootPurpose `json:"purpose"`
PlatformRegion string `json:"platformRegion"`
Region string `json:"region"`
LicenceType *string `json:"licenceType,omitempty"`
SecretBindingName string `json:"secretBindingName"`
EnforceSeedLocation *bool `json:"enforceSeedLocation,omitempty"`
Kubernetes Kubernetes `json:"kubernetes,omitempty"`
Provider Provider `json:"provider"`
Networking Networking `json:"networking"`
ControlPlane *gardener.ControlPlane `json:"controlPlane,omitempty"`
}

type Kubernetes struct {
Expand Down
6 changes: 5 additions & 1 deletion api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,6 @@ spec:
secretBindingName:
type: string
required:
- controlPlane
- name
- networking
- platformRegion
Expand Down
3 changes: 1 addition & 2 deletions hack/runtime-migrator/input/runtimeids_sample.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{
c65d5c9b-b321-4481-b567-d331d769ff1c,
61e18f65-6c82-4fdd-97dc-cf51bfbbbeb2
7c6b4bd3-09d3-462f-b27c-992727b62eec,
}
44 changes: 26 additions & 18 deletions hack/runtime-migrator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ func saveRuntime(ctx context.Context, cfg migrator.Config, runtime v1.Runtime, g
func createRuntime(ctx context.Context, shoot v1beta1.Shoot, cfg migrator.Config, provider kubeconfig.Provider) (v1.Runtime, error) {
var subjects = getAdministratorsList(ctx, provider, shoot.Name)
var oidcConfig = getOidcConfig(shoot)
var hAFailureToleranceType = getFailureToleranceType(shoot)
var licenceType = shoot.Annotations["kcp.provisioner.kyma-project.io/licence-type"]
labels, err := getAllRuntimeLabels(ctx, shoot, cfg.Client)
if err != nil {
Expand Down Expand Up @@ -210,17 +209,12 @@ func createRuntime(ctx context.Context, shoot v1beta1.Shoot, cfg migrator.Config
Workers: shoot.Spec.Provider.Workers,
},
Networking: v1.Networking{
Type: shoot.Spec.Networking.Type,
Pods: *shoot.Spec.Networking.Pods,
Nodes: *shoot.Spec.Networking.Nodes,
Services: *shoot.Spec.Networking.Services,
},
ControlPlane: v1beta1.ControlPlane{
HighAvailability: &v1beta1.HighAvailability{
FailureTolerance: v1beta1.FailureTolerance{
Type: hAFailureToleranceType,
},
},
},
ControlPlane: getControlPlane(shoot),
},
Security: v1.Security{
Administrators: subjects,
Expand Down Expand Up @@ -280,23 +274,29 @@ func getShootList(ctx context.Context, cfg migrator.Config, gardenerNamespace st
return list
}

func getFailureToleranceType(shoot v1beta1.Shoot) v1beta1.FailureToleranceType {
func getControlPlane(shoot v1beta1.Shoot) *v1beta1.ControlPlane {
if shoot.Spec.ControlPlane != nil {
if shoot.Spec.ControlPlane.HighAvailability != nil {
return shoot.Spec.ControlPlane.HighAvailability.FailureTolerance.Type
return &v1beta1.ControlPlane{HighAvailability: &v1beta1.HighAvailability{
FailureTolerance: v1beta1.FailureTolerance{
Type: shoot.Spec.ControlPlane.HighAvailability.FailureTolerance.Type,
},
},
}
}
}
return ""

return nil
}

func getAdministratorsList(ctx context.Context, provider kubeconfig.Provider, shootName string) []string {
var kubeconfig, err = provider.Fetch(ctx, shootName)
if kubeconfig == "" {
var clusterKubeconfig, err = provider.Fetch(ctx, shootName)
if clusterKubeconfig == "" {
log.Printf("Failed to get dynamic kubeconfig for shoot %s, %s\n", shootName, err.Error())
return []string{}
}

restClientConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(kubeconfig))
restClientConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(clusterKubeconfig))
if err != nil {
log.Printf("Failed to create REST client from kubeconfig - %s\n", err)
return []string{}
Expand All @@ -311,7 +311,8 @@ func getAdministratorsList(ctx context.Context, provider kubeconfig.Provider, sh
LabelSelector: "reconciler.kyma-project.io/managed-by=reconciler,app=kyma",
})

var subjects = []string{}
subjects := make([]string, 0)

for _, clusterRoleBinding := range clusterRoleBindings.Items {
for _, subject := range clusterRoleBinding.Subjects {
subjects = append(subjects, subject.Name)
Expand Down Expand Up @@ -395,8 +396,14 @@ func getAllRuntimeLabels(ctx context.Context, shoot v1beta1.Shoot, getClient mig
return map[string]string{}, errors.Wrap(clientErr, fmt.Sprintf("Failed to get GardenerClient for shoot %s - %s\n", shoot.Name, clientErr))
}
gardenerCluster := v1.GardenerCluster{}
shootKey := types.NamespacedName{Name: shoot.Name, Namespace: "kcp-system"}
getGardenerCRerr := k8sClient.Get(ctx, shootKey, &gardenerCluster)

kymaID, found := shoot.Annotations["kcp.provisioner.kyma-project.io/runtime-id"]
if !found {
return nil, errors.New("Runtime ID not found in shoot annotations")
}

gardenerCRKey := types.NamespacedName{Name: kymaID, Namespace: "kcp-system"}
getGardenerCRerr := k8sClient.Get(ctx, gardenerCRKey, &gardenerCluster)
if getGardenerCRerr != nil {
var errMsg = fmt.Sprintf("Failed to retrieve GardenerCluster CR for shoot %s\n", shoot.Name)
return map[string]string{}, errors.Wrap(getGardenerCRerr, errMsg)
Expand All @@ -410,7 +417,8 @@ func getAllRuntimeLabels(ctx context.Context, shoot v1beta1.Shoot, getClient mig
enrichedRuntimeLabels["kyma-project.io/region"] = gardenerCluster.Labels["kyma-project.io/region"]
enrichedRuntimeLabels["kyma-project.io/shoot-name"] = gardenerCluster.Labels["kyma-project.io/shoot-name"]
enrichedRuntimeLabels["operator.kyma-project.io/kyma-name"] = gardenerCluster.Labels["operator.kyma-project.io/kyma-name"]

// The runtime CR should be controlled by the KIM
enrichedRuntimeLabels["kyma-project.io/controlled-by-provisioner"] = "false"
// add custom label for the migrator
enrichedRuntimeLabels[migratorLabel] = "true"

Expand Down
5 changes: 3 additions & 2 deletions hack/shoot-comparator/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ require (
github.com/gardener/gardener v1.98.0
github.com/onsi/ginkgo/v2 v2.19.0
github.com/onsi/gomega v1.33.1
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/apimachinery v0.29.6
sigs.k8s.io/yaml v1.4.0
)

Expand All @@ -31,10 +34,8 @@ require (
golang.org/x/tools v0.22.0 // 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/api v0.29.6 // indirect
k8s.io/apiextensions-apiserver v0.29.6 // indirect
k8s.io/apimachinery v0.29.6 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
Expand Down
71 changes: 71 additions & 0 deletions hack/shoot-comparator/pkg/shoot/extensionmatcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package shoot

import (
"fmt"
"github.com/gardener/gardener/pkg/apis/core/v1beta1"
"github.com/onsi/gomega"
"github.com/onsi/gomega/types"
"reflect"
"sort"
"strings"
)

type ExtensionMatcher struct {
toMatch interface{}
fails []string
}

func NewExtensionMatcher(i interface{}) types.GomegaMatcher {
return &ExtensionMatcher{
toMatch: i,
}
}

func (m *ExtensionMatcher) Match(actual interface{}) (success bool, err error) {
aExtensions, err := getExtension(actual)
if err != nil {
return false, err
}

eExtensions, err := getExtension(m.toMatch)
if err != nil {
return false, err
}

sort.Sort(Extensions(aExtensions))
sort.Sort(Extensions(eExtensions))

return gomega.BeComparableTo(eExtensions).Match(aExtensions)
}

func getExtension(i interface{}) ([]v1beta1.Extension, error) {
switch v := i.(type) {
case []v1beta1.Extension:
return v, nil

default:
return []v1beta1.Extension{}, fmt.Errorf(`%w: %s`, errInvalidType, reflect.TypeOf(v))
}
}

type Extensions []v1beta1.Extension

func (e Extensions) Len() int {
return len(e)
}

func (e Extensions) Less(i, j int) bool {
return e[i].Type < e[j].Type
}

func (e Extensions) Swap(i, j int) {
e[i], e[j] = e[j], e[i]
}

func (m *ExtensionMatcher) NegatedFailureMessage(_ interface{}) string {
return "expected should not equal actual"
}

func (m *ExtensionMatcher) FailureMessage(_ interface{}) string {
return strings.Join(m.fails, "\n")
}
106 changes: 106 additions & 0 deletions hack/shoot-comparator/pkg/shoot/extensionmatcher_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package shoot

import (
"fmt"
"github.com/gardener/gardener/pkg/apis/core/v1beta1"
. "github.com/onsi/ginkgo/v2" //nolint:revive
. "github.com/onsi/gomega" //nolint:revive
"k8s.io/apimachinery/pkg/runtime"
)

var _ = Describe(":: extension matcher :: ", func() {
emptyExt := make([]v1beta1.Extension, 0)

DescribeTable(
"checking invalid args :: ",
testExtensionInvalidArgs,
Entry("when actual is not of Extension type", v1beta1.Shoot{}, emptyExt),
Entry("when expected is not of Extension type", emptyExt, v1beta1.Shoot{}),
Entry("when actual is nil", nil, emptyExt),
Entry("when expected is nil", emptyExt, nil),
)

dnsExtEnabled := getDNSExtension(false, true)
dnsExtDisabled := getDNSExtension(true, false)
networkingExtDisabled := getNetworkingExtension(true)
certificateExtEnabled := getCertificateExtension(false, true)

DescribeTable(
"checking results :: ",
testExtensionResults,
Entry(
"should match empty values",
emptyExt,
emptyExt,
true,
),
Entry(
"should match identical tables",
[]v1beta1.Extension{dnsExtEnabled, networkingExtDisabled, certificateExtEnabled},
[]v1beta1.Extension{networkingExtDisabled, certificateExtEnabled, dnsExtEnabled},
true,
),
Entry(
"should detect extension differs",
[]v1beta1.Extension{dnsExtEnabled, networkingExtDisabled, certificateExtEnabled},
[]v1beta1.Extension{dnsExtDisabled, networkingExtDisabled, certificateExtEnabled},
false,
),
Entry(
"should detect redundant extension",
[]v1beta1.Extension{dnsExtEnabled, networkingExtDisabled, certificateExtEnabled},
[]v1beta1.Extension{networkingExtDisabled, certificateExtEnabled},
false,
),
Entry(
"should detect missing extension",
[]v1beta1.Extension{networkingExtDisabled, certificateExtEnabled},
[]v1beta1.Extension{dnsExtEnabled, networkingExtDisabled, certificateExtEnabled},
false,
),
)
})

func testExtensionInvalidArgs(actual, expected interface{}) {
matcher := NewExtensionMatcher(expected)
_, err := matcher.Match(actual)
Expect(err).To(HaveOccurred())
}

func testExtensionResults(actual, expected interface{}, expectedMatch bool) {
matcher := NewExtensionMatcher(expected)
actualMatch, err := matcher.Match(actual)
Expect(err).ShouldNot(HaveOccurred())
Expect(actualMatch).Should(Equal(expectedMatch), matcher.FailureMessage(actual))
}

func getDNSExtension(disabled bool, replicationEnabled bool) v1beta1.Extension {
json := fmt.Sprintf(`{apiVersion: "service.dns.extensions.gardener.cloud/v1alpha1", kind: "DNSConfig", dnsProviderReplication: {enabled: %v}}`, replicationEnabled)

return v1beta1.Extension{
Type: "shoot-dns-service",
Disabled: &disabled,
ProviderConfig: &runtime.RawExtension{
Raw: []byte(json),
},
}
}

func getNetworkingExtension(disabled bool) v1beta1.Extension {
return v1beta1.Extension{
Type: "shoot-networking-service",
Disabled: &disabled,
}
}

func getCertificateExtension(disabled bool, shootIssuersEnabled bool) v1beta1.Extension {
json := fmt.Sprintf(`{apiVersion: "service.cert.extensions.gardener.cloud/v1alpha1", kind: "CertConfig", shootIssuers: {enabled: %v}}`, shootIssuersEnabled)

return v1beta1.Extension{
Type: "shoot-cert-service",
Disabled: &disabled,
ProviderConfig: &runtime.RawExtension{
Raw: []byte(json),
},
}
}
Loading

0 comments on commit b1440d7

Please sign in to comment.