Files
kustomize/api/krusty/sortordertransformer_test.go
Yannis Zarkadas a502717460 Make ordering configurable (#4019)
* api: Add new types for customizeable resource ordering

Signed-off-by: Yannis Zarkadas <yanniszark@arrikto.com>

* plugins: Implement SortOrderTransformer plugin

Implement the SortOrderTransformer plugin. This plugin allows the user
to customize the order that kustomize will output resources in.

The API for the plugin is the following:

sortOptions:
  order: legacy | fifo
  legacySortOptions:
    orderFirst:
    - {GVK}
    orderLast:
    - {GVK}

Signed-off-by: Yannis Zarkadas <yanniszark@arrikto.com>

* plugins: Add boilerplate and generate code for new SortOrderTransformer

Signed-off-by: Yannis Zarkadas <yanniszark@arrikto.com>

* build: Add option to denote if the reorder flag was set by the user

We want to take different actions if the reorder flag was set by the
user or filled by the default value. Thus, we propagate this information
from build to the krusty options.

Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>

* api/krusty: Ensure sort ordering works with CLI flag and kustomization

Sort order can be defined in two places:
- (new) kustomization file
- (old) CLI flag
We want the kustomization file to take precedence over the CLI flag.

Eventually, we may want to move away from having a CLI flag altogether:
https://github.com/kubernetes-sigs/kustomize/issues/3947

Case 1: Sort order set in kustomization file AND in CLI flag.
Print a warning and let the kustomization file take precedence.

Case 2: Sort order set in CLI flag only or not at all.
Follow the CLI flag (defaults to legacy) and reorder at the end.

Case 3: Sort order set in kustomization file only.
Simply build the kustomization.

Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>

* krusty: Add e2e test for SortOrderTransformer

Signed-off-by: Yannis Zarkadas <yanniszark@arrikto.com>

* plugins: Purge LegacyOrderTransformer

Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>

* Update go.work.sum

Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>

* review: Make review changes

Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>

Signed-off-by: Yannis Zarkadas <yanniszark@arrikto.com>
Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>
2022-12-02 13:59:53 -08:00

332 lines
6.3 KiB
Go

// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"testing"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/krusty"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
//nolint:gochecknoglobals
var sortOrderResources = `
apiVersion: v1
kind: Service
metadata:
name: papaya
---
apiVersion: v1
kind: Role
metadata:
name: banana
---
apiVersion: v1
kind: ValidatingWebhookConfiguration
metadata:
name: pomegranate
---
apiVersion: v1
kind: LimitRange
metadata:
name: peach
---
apiVersion: v1
kind: Deployment
metadata:
name: pear
---
apiVersion: v1
kind: Namespace
metadata:
name: apple
---
apiVersion: v1
kind: Secret
metadata:
name: quince
---
apiVersion: v1
kind: Ingress
metadata:
name: durian
---
apiVersion: v1
kind: ConfigMap
metadata:
name: apricot
`
//nolint:gochecknoglobals
var legacyOrderResources = `
apiVersion: v1
kind: Namespace
metadata:
name: apple
---
apiVersion: v1
kind: Role
metadata:
name: banana
---
apiVersion: v1
kind: ConfigMap
metadata:
name: apricot
---
apiVersion: v1
kind: Secret
metadata:
name: quince
---
apiVersion: v1
kind: Service
metadata:
name: papaya
---
apiVersion: v1
kind: LimitRange
metadata:
name: peach
---
apiVersion: v1
kind: Deployment
metadata:
name: pear
---
apiVersion: v1
kind: Ingress
metadata:
name: durian
---
apiVersion: v1
kind: ValidatingWebhookConfiguration
metadata:
name: pomegranate
`
func TestCustomOrdering(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
resources:
- resources.yaml
sortOptions:
order: legacy
legacySortOptions:
orderFirst:
- MutatingWebhookConfiguration
- ValidatingWebhookConfiguration
- ResourceQuota
- StorageClass
- CustomResourceDefinition
- ServiceAccount
- PodSecurityPolicy
- Role
- ClusterRole
- RoleBinding
- ClusterRoleBinding
- ConfigMap
- Secret
- Endpoints
- Service
- LimitRange
- PriorityClass
- PersistentVolume
- PersistentVolumeClaim
- StatefulSet
- CronJob
- PodDisruptionBudget
orderLast:
- Namespace
- Deployment
`)
th.WriteF("base/resources.yaml", sortOrderResources)
th.AssertActualEqualsExpected(
th.Run("base", th.MakeDefaultOptions()),
`
apiVersion: v1
kind: ValidatingWebhookConfiguration
metadata:
name: pomegranate
---
apiVersion: v1
kind: Role
metadata:
name: banana
---
apiVersion: v1
kind: ConfigMap
metadata:
name: apricot
---
apiVersion: v1
kind: Secret
metadata:
name: quince
---
apiVersion: v1
kind: Service
metadata:
name: papaya
---
apiVersion: v1
kind: LimitRange
metadata:
name: peach
---
apiVersion: v1
kind: Ingress
metadata:
name: durian
---
apiVersion: v1
kind: Namespace
metadata:
name: apple
---
apiVersion: v1
kind: Deployment
metadata:
name: pear
`)
}
func TestDefaultLegacyOrdering(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
resources:
- resources.yaml
sortOptions:
order: legacy
`)
th.WriteF("base/resources.yaml", sortOrderResources)
th.AssertActualEqualsExpected(
th.Run("base", th.MakeDefaultOptions()), legacyOrderResources)
}
func TestFIFOOrdering(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
resources:
- resources.yaml
sortOptions:
order: fifo
`)
th.WriteF("base/resources.yaml", sortOrderResources)
th.AssertActualEqualsExpected(
th.Run("base", th.MakeDefaultOptions()), sortOrderResources)
}
func TestInvalidLegacySortOptionsWithoutOrderKey(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
resources:
- resources.yaml
sortOptions:
legacySortOptions: {}
`)
th.WriteF("base/resources.yaml", sortOrderResources)
err := th.RunWithErr("base", th.MakeDefaultOptions())
require.ErrorContains(t, err, "the field 'sortOptions.order' must be one of [fifo, legacy]")
}
func TestInvalidLegacySortOptionsWithFIFOOrder(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
resources:
- resources.yaml
sortOptions:
order: fifo
legacySortOptions: {}
`)
th.WriteF("base/resources.yaml", sortOrderResources)
err := th.RunWithErr("base", th.MakeDefaultOptions())
require.ErrorContains(t, err, "the field 'sortOptions.legacySortOptions' is set but the selected sort order is 'fifo', not 'legacy'")
}
// If the sort order is defined both in a CLI flag and the kustomization file,
// the kustomization file takes precedence.
func TestCLIAndKustomizationSet(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
resources:
- resources.yaml
sortOptions:
order: fifo
`)
th.WriteF("base/resources.yaml", sortOrderResources)
kustOptions := th.MakeDefaultOptions()
kustOptions.Reorder = krusty.ReorderOptionLegacy
th.AssertActualEqualsExpected(th.Run("base", kustOptions), sortOrderResources)
}
// If no sort order is set in the kustomization file, validate that we fallback
// to the default legacy sort ordering.
func TestKustomizationSortOrderNotSet(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
resources:
- resources.yaml
`)
th.WriteF("base/resources.yaml", sortOrderResources)
kustOptions := th.MakeDefaultOptions()
kustOptions.Reorder = krusty.ReorderOptionUnspecified
th.AssertActualEqualsExpected(th.Run("base", kustOptions), legacyOrderResources)
}
func TestChildKustomizationSortOrder(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
resources:
- resources.yaml
sortOptions:
order: legacy
`)
th.WriteF("base/resources.yaml", sortOrderResources)
th.WriteK("overlay", `
resources:
- ../base
sortOptions:
order: fifo
`)
kustOptions := th.MakeDefaultOptions()
// If child kustomization ordering takes effect, the order will be legacy,
// otherwise fifo.
th.AssertActualEqualsExpected(th.Run("overlay", kustOptions), sortOrderResources)
}
func TestSortOrderGivenAsTransformer(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
resources:
- resources.yaml
transformers:
- sort_order.yaml
`)
th.WriteF("base/resources.yaml", sortOrderResources)
th.WriteF("base/sort_order.yaml", `
apiVersion: builtin
kind: SortOrderTransformer
metadata:
name: notImportantHere
sortOptions:
order: fifo`)
kustOptions := th.MakeDefaultOptions()
err := th.RunWithErr("base", kustOptions)
require.ErrorContains(t, err, "unable to load builtin SortOrderTransformer.builtin.[noGrp]")
}