Skip to content

Commit

Permalink
Merge branch 'main' into retryable_improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Disper committed Nov 7, 2024
2 parents bad87c7 + 886aa52 commit 19eee00
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 90 deletions.
61 changes: 1 addition & 60 deletions .github/workflows/build_kim.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ on:
- .gitignore
- "**.md"

env:
trivy-table: trivy-table.txt

permissions:
id-token: write # This is required for requesting the JWT token
contents: read # This is required for actions/checkout
Expand All @@ -53,49 +50,6 @@ jobs:
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.event_name == 'push'
run: echo "latest=latest" >> $GITHUB_OUTPUT

trivy:
permissions:
contents: read
runs-on: "ubuntu-20.04"
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}

- name: Install trivy
run: |
mkdir ./trivy
curl -L https://github.com/aquasecurity/trivy/releases/download/v0.49.1/trivy_0.49.1_Linux-64bit.tar.gz | tar xvz --directory=./trivy
./trivy/trivy --version
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.24.0
with:
scan-type: "fs"
scan-ref: "."

exit-code: 1
severity: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL"
ignore-unfixed: false
timeout: "5m0s"
vuln-type: "os,library"

format: table
output: ${{ env.trivy-table }}

- name: Upload trivy table
if: success() || failure()
uses: actions/upload-artifact@v4
with:
name: ${{ env.trivy-table }}
path: ${{ env.trivy-table }}

- name: Print trivy table
if: success() || failure()
run: "test -f ${{ env.trivy-table }} && cat ${{ env.trivy-table }} || echo ':: no data ::'"

build-image:
needs: setup
uses: kyma-project/test-infra/.github/workflows/image-builder.yml@main # Usage: kyma-project/test-infra/.github/workflows/image-builder.yml@main
Expand All @@ -109,26 +63,13 @@ jobs:
summary:
runs-on: ubuntu-latest
needs: [build-image, trivy]
needs: [build-image]
if: success() || failure()
steps:
- name: "Download trivy log"
uses: actions/download-artifact@v4
continue-on-error: true
with:
name: ${{ env.trivy-table }}
- name: "Generate summary"
run: |
{
echo '# Kyma Infrastructure Manager'
# if trivy results table exists
if [ -f ${{ env.trivy-table }} ]; then
echo '## Trivy'
printf '\n```txt\n'
cat ${{ env.trivy-table }}
printf '\n```\n'
fi
# if build-image was successful
if [ "${{ needs.build-image.result }}" == "success" ]; then
printf '\n\n## Image\n'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ func convertCreate(instance *imv1.Runtime, cfg config.ConverterConfig) (gardener
converter := gardener_shoot.NewConverterCreate(cfg)
newShoot, err := converter.ToShoot(*instance)
if err != nil {
setObjectFields(&newShoot)
return newShoot, err
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ func sFnDeleteShoot(ctx context.Context, m *fsm, s *systemState) (stateFn, *ctrl
if !isGardenerCloudDelConfirmationSet(s.shoot.Annotations) {
m.log.Info("patching shoot with del-confirmation")
// workaround for Gardener client
setObjectFields(s.shoot)
s.shoot.Annotations = addGardenerCloudDelConfirmation(s.shoot.Annotations)

err := m.ShootClient.Patch(ctx, s.shoot, client.Apply, &client.PatchOptions{
Expand Down
30 changes: 19 additions & 11 deletions internal/controller/runtime/fsm/runtime_fsm_patch_shoot.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fsm

import (
"context"
"slices"

gardener "github.com/gardener/gardener/pkg/apis/core/v1beta1"
imv1 "github.com/kyma-project/infrastructure-manager/api/v1"
Expand All @@ -16,7 +17,8 @@ import (
func sFnPatchExistingShoot(ctx context.Context, m *fsm, s *systemState) (stateFn, *ctrl.Result, error) {
m.log.Info("Patch shoot state")

updatedShoot, err := convertPatch(&s.instance, m.Config.ConverterConfig)
zonesFromShoot := getZones(s.shoot.Spec.Provider.Workers)
updatedShoot, err := convertPatch(&s.instance, m.Config.ConverterConfig, zonesFromShoot)
if err != nil {
m.log.Error(err, "Failed to convert Runtime instance to shoot object, exiting with no retry")
m.Metrics.IncRuntimeFSMStopCounter()
Expand Down Expand Up @@ -58,28 +60,34 @@ func sFnPatchExistingShoot(ctx context.Context, m *fsm, s *systemState) (stateFn
return updateStatusAndRequeueAfter(m.RCCfg.GardenerRequeueDuration)
}

func convertPatch(instance *imv1.Runtime, cfg config.ConverterConfig) (gardener.Shoot, error) {
func getZones(workers []gardener.Worker) []string {
var zones []string

for _, worker := range workers {
for _, zone := range worker.Zones {
if !slices.Contains(zones, zone) {
zones = append(zones, zone)
}
}
}

return zones
}

func convertPatch(instance *imv1.Runtime, cfg config.ConverterConfig, zonesFromShoot []string) (gardener.Shoot, error) {
if err := instance.ValidateRequiredLabels(); err != nil {
return gardener.Shoot{}, err
}

converter := gardener_shoot.NewConverterPatch(cfg)
converter := gardener_shoot.NewConverterPatch(cfg, zonesFromShoot)
newShoot, err := converter.ToShoot(*instance)
if err != nil {
setObjectFields(&newShoot)
return newShoot, err
}

return newShoot, nil
}

// workaround
func setObjectFields(shoot *gardener.Shoot) {
shoot.Kind = "Shoot"
shoot.APIVersion = "core.gardener.cloud/v1beta1"
shoot.ManagedFields = nil
}

func updateStatePendingWithErrorAndStop(instance *imv1.Runtime,
//nolint:unparam
c imv1.RuntimeConditionType, r imv1.RuntimeConditionReason, msg string) (stateFn, *ctrl.Result, error) {
Expand Down
11 changes: 8 additions & 3 deletions pkg/gardener/shoot/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func newConverter(config config.ConverterConfig, extenders ...Extend) Converter
func NewConverterCreate(cfg config.ConverterConfig) Converter {
baseExtenders := baseExtenders(cfg)
// https://github.com/kyma-project/infrastructure-manager/pull/460
providerExtender := extender2.NewProviderExtender(
providerExtender := extender2.NewProviderExtenderForCreateOperation(
cfg.Provider.AWS.EnableIMDSv2,
cfg.MachineImage.DefaultName,
cfg.MachineImage.DefaultVersion,
Expand All @@ -54,13 +54,14 @@ func NewConverterCreate(cfg config.ConverterConfig) Converter {
return newConverter(cfg, baseExtenders...)
}

func NewConverterPatch(cfg config.ConverterConfig) Converter {
func NewConverterPatch(cfg config.ConverterConfig, zonesFromShoot []string) Converter {
baseExtenders := baseExtenders(cfg)
// https://github.com/kyma-project/infrastructure-manager/pull/460
providerExtender := extender2.NewProviderExtender(
providerExtender := extender2.NewProviderExtenderPatchOperation(
cfg.Provider.AWS.EnableIMDSv2,
cfg.MachineImage.DefaultName,
cfg.MachineImage.DefaultVersion,
zonesFromShoot,
)

baseExtenders = append(baseExtenders, providerExtender)
Expand All @@ -83,6 +84,10 @@ func (c Converter) ToShoot(runtime imv1.Runtime) (gardener.Shoot, error) {
// - if any logic is needed to be implemented, either enhance existing, or create a new extender

shoot := gardener.Shoot{
TypeMeta: v1.TypeMeta{
Kind: "Shoot",
APIVersion: "core.gardener.cloud/v1beta1",
},
ObjectMeta: v1.ObjectMeta{
Name: runtime.Spec.Shoot.Name,
Namespace: fmt.Sprintf("garden-%s", c.config.Gardener.ProjectName),
Expand Down
49 changes: 42 additions & 7 deletions pkg/gardener/shoot/converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,49 @@ func TestConverter(t *testing.T) {

// then
require.NoError(t, err)
assert.Equal(t, runtime.Spec.Shoot.Purpose, *shoot.Spec.Purpose)
assert.Equal(t, runtime.Spec.Shoot.Region, shoot.Spec.Region)
assert.Equal(t, runtime.Spec.Shoot.SecretBindingName, *shoot.Spec.SecretBindingName)
assert.Equal(t, runtime.Spec.Shoot.ControlPlane, shoot.Spec.ControlPlane)
assert.Equal(t, runtime.Spec.Shoot.Networking.Nodes, *shoot.Spec.Networking.Nodes)
assert.Equal(t, runtime.Spec.Shoot.Networking.Pods, *shoot.Spec.Networking.Pods)
assert.Equal(t, runtime.Spec.Shoot.Networking.Services, *shoot.Spec.Networking.Services)
assertShootFields(t, runtime, shoot)
})

t.Run("Create shoot from Runtime for existing shoot", func(t *testing.T) {
// given
runtime := fixRuntime()
converterConfig := fixConverterConfig()
converter := NewConverterPatch(converterConfig, fixReversedZones())

// when
shoot, err := converter.ToShoot(runtime)

// then
require.NoError(t, err)
assertShootFields(t, runtime, shoot)

expectedZonesAreInSameOrder := []string{
"eu-central-1c",
"eu-central-1b",
"eu-central-1a",
}
assert.Equal(t, expectedZonesAreInSameOrder, shoot.Spec.Provider.Workers[0].Zones)
})
}

func assertShootFields(t *testing.T, runtime imv1.Runtime, shoot gardener.Shoot) {
assert.Equal(t, runtime.Spec.Shoot.Purpose, *shoot.Spec.Purpose)
assert.Equal(t, runtime.Spec.Shoot.Region, shoot.Spec.Region)
assert.Equal(t, runtime.Spec.Shoot.SecretBindingName, *shoot.Spec.SecretBindingName)
assert.Equal(t, runtime.Spec.Shoot.ControlPlane, shoot.Spec.ControlPlane)
assert.Equal(t, runtime.Spec.Shoot.Networking.Nodes, *shoot.Spec.Networking.Nodes)
assert.Equal(t, runtime.Spec.Shoot.Networking.Pods, *shoot.Spec.Networking.Pods)
assert.Equal(t, runtime.Spec.Shoot.Networking.Services, *shoot.Spec.Networking.Services)
assert.Equal(t, "Shoot", shoot.TypeMeta.Kind)
assert.Equal(t, "core.gardener.cloud/v1beta1", shoot.TypeMeta.APIVersion)
}

func fixReversedZones() []string {
return []string{
"eu-central-1c",
"eu-central-1b",
"eu-central-1a",
}
}

func fixConverterConfig() config.ConverterConfig {
Expand Down
52 changes: 47 additions & 5 deletions pkg/gardener/shoot/extender/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ import (
"k8s.io/apimachinery/pkg/runtime"
)

func NewProviderExtender(enableIMDSv2 bool, defaultMachineImageName, defaultMachineImageVersion string) func(rt imv1.Runtime, shoot *gardener.Shoot) error {
func NewProviderExtenderForCreateOperation(enableIMDSv2 bool, defaultMachineImageName, defaultMachineImageVersion string) func(rt imv1.Runtime, shoot *gardener.Shoot) error {
return func(rt imv1.Runtime, shoot *gardener.Shoot) error {
provider := &shoot.Spec.Provider
provider.Type = rt.Spec.Shoot.Provider.Type
provider.Workers = rt.Spec.Shoot.Provider.Workers

var err error
var controlPlaneConf, infraConfig *runtime.RawExtension
infraConfig, controlPlaneConf, err = getConfig(rt.Spec.Shoot)
zones := getZones(rt.Spec.Shoot.Provider.Workers)
infraConfig, controlPlaneConf, err = getConfig(rt.Spec.Shoot, zones)
if err != nil {
return err
}
Expand All @@ -46,13 +47,46 @@ func NewProviderExtender(enableIMDSv2 bool, defaultMachineImageName, defaultMach
}
}

func NewProviderExtenderPatchOperation(enableIMDSv2 bool, defaultMachineImageName, defaultMachineImageVersion string, zones []string) func(rt imv1.Runtime, shoot *gardener.Shoot) error {
return func(rt imv1.Runtime, shoot *gardener.Shoot) error {
var err error
provider := &shoot.Spec.Provider
provider.Type = rt.Spec.Shoot.Provider.Type
provider.Workers = rt.Spec.Shoot.Provider.Workers

var controlPlaneConf, infraConfig *runtime.RawExtension

infraConfig, controlPlaneConf, err = getConfig(rt.Spec.Shoot, zones)
if err != nil {
return err
}

if rt.Spec.Shoot.Provider.ControlPlaneConfig != nil {
controlPlaneConf = rt.Spec.Shoot.Provider.ControlPlaneConfig
}

if rt.Spec.Shoot.Provider.InfrastructureConfig != nil {
infraConfig = rt.Spec.Shoot.Provider.InfrastructureConfig
}

provider.ControlPlaneConfig = controlPlaneConf
provider.InfrastructureConfig = infraConfig

setDefaultMachineImage(provider, defaultMachineImageName, defaultMachineImageVersion)
err = setWorkerConfig(provider, provider.Type, enableIMDSv2)
setWorkerSettings(provider)

alignWithExistingShoot(provider, zones)

return err
}
}

type InfrastructureProviderFunc func(workersCidr string, zones []string) ([]byte, error)
type ControlPlaneProviderFunc func(zones []string) ([]byte, error)

func getConfig(runtimeShoot imv1.RuntimeShoot) (infrastructureConfig *runtime.RawExtension, controlPlaneConfig *runtime.RawExtension, err error) {
func getConfig(runtimeShoot imv1.RuntimeShoot, zones []string) (infrastructureConfig *runtime.RawExtension, controlPlaneConfig *runtime.RawExtension, err error) {
getConfigForProvider := func(runtimeShoot imv1.RuntimeShoot, infrastructureConfigFunc InfrastructureProviderFunc, controlPlaneConfigFunc ControlPlaneProviderFunc) (*runtime.RawExtension, *runtime.RawExtension, error) {
zones := getZones(runtimeShoot.Provider.Workers)

infrastructureConfigBytes, err := infrastructureConfigFunc(runtimeShoot.Networking.Nodes, zones)
if err != nil {
return nil, nil, err
Expand Down Expand Up @@ -161,3 +195,11 @@ func setDefaultMachineImage(provider *gardener.Provider, defaultMachineImageName
worker.Machine.Image.Version = machineImageVersion
}
}

// We can't predict what will be the order of zones stored by Gardener.
// Without this patch, gardener's admission webhook might reject the request if the zones order does not match.
func alignWithExistingShoot(provider *gardener.Provider, zones []string) {
for i := range provider.Workers {
provider.Workers[i].Zones = zones
}
}
4 changes: 2 additions & 2 deletions pkg/gardener/shoot/extender/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestProviderExtender(t *testing.T) {
shoot := fixEmptyGardenerShoot("cluster", "kcp-system")

// when
extender := NewProviderExtender(testCase.EnableIMDSv2, testCase.DefaultMachineImageName, testCase.DefaultMachineImageVersion)
extender := NewProviderExtenderForCreateOperation(testCase.EnableIMDSv2, testCase.DefaultMachineImageName, testCase.DefaultMachineImageVersion)
err := extender(testCase.Runtime, &shoot)

// then
Expand All @@ -92,7 +92,7 @@ func TestProviderExtender(t *testing.T) {
}

// when
extender := NewProviderExtender(false, "", "")
extender := NewProviderExtenderForCreateOperation(false, "", "")
err := extender(runtime, &shoot)

// then
Expand Down

0 comments on commit 19eee00

Please sign in to comment.