Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Resolve lint errors w.r.t operator/pull/204 #2

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions controllers/shipwrightbuild_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ func (r *ShipwrightBuildReconciler) Reconcile(ctx context.Context, req ctrl.Requ
images := common.ToLowerCaseKeys(common.ImagesFromEnv(common.ShipwrightImagePrefix))

transformerfncs := []manifestival.Transformer{}
transformerfncs = append(transformerfncs, common.TruncateCRDFieldTransformer("description", 50))
if common.IsOpenShiftPlatform() {
transformerfncs = append(transformerfncs, manifestival.InjectNamespace(targetNamespace))
transformerfncs = append(transformerfncs, common.DeploymentImages(images))
Expand Down
40 changes: 40 additions & 0 deletions pkg/common/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,46 @@ func ToLowerCaseKeys(keyValues map[string]string) map[string]string {
return newMap
}

// truncateNestedFields truncates the named "field" from the given data object and all of its sub-objects to maxLength characters.
func truncateNestedFields(data map[string]interface{}, maxLength int, field string) {
queue := []map[string]interface{}{data}

for len(queue) > 0 {
curr := queue[0]
queue = queue[1:]

for key, value := range curr {
if key == field {
if str, ok := value.(string); ok && len(str) > maxLength {
curr[key] = str[:maxLength]
}
} else {
if subObj, ok := value.(map[string]interface{}); ok {
queue = append(queue, subObj)
} else if subObjs, ok := value.([]interface{}); ok {
for _, subObj := range subObjs {
if subObjMap, ok := subObj.(map[string]interface{}); ok {
queue = append(queue, subObjMap)
}
}
}
}
}
}
}

// TruncateCRDFieldTransformer returns a manifestival.Transformer that truncates the value of the given field within a CRD spec to the provided max length.
func TruncateCRDFieldTransformer(field string, maxLength int) manifestival.Transformer {
return func(u *unstructured.Unstructured) error {
if u.GetKind() != "CustomResourceDefinition" {
return nil
}
data := u.Object
truncateNestedFields(data, maxLength, field)
return nil
}
}

// deploymentImages replaces container and env vars images.
func DeploymentImages(images map[string]string) manifestival.Transformer {
return func(u *unstructured.Unstructured) error {
Expand Down
94 changes: 93 additions & 1 deletion pkg/common/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
mf "github.com/manifestival/manifestival"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"gopkg.in/yaml.v2"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -62,6 +62,98 @@ func TestDeploymentImages(t *testing.T) {
})
}

func TestTruncateNestedFields(t *testing.T) {
RegisterFailHandler(Fail)
t.Run("test truncation of manifests", func(t *testing.T) {
testData := map[string]interface{}{
"field1": "This is a long string that should be truncated",
"field2": map[string]interface{}{
"field1": "This is another long string that should be truncated",
},
}

expected := map[string]interface{}{
"field1": "This is a ",
"field2": map[string]interface{}{
"field1": "This is an",
},
}

truncateNestedFields(testData, 10, "field1")
Expect(testData).To(Equal(expected))
})
}

func CheckNestedFieldLengthWithinLimit(data map[string]interface{}, maxLength int, field string) bool {
isFieldSizeInLimit := true
queue := []map[string]interface{}{data}

for len(queue) > 0 {
curr := queue[0]
queue = queue[1:]

for key, value := range curr {
if key == field {
if str, ok := value.(string); ok {
isFieldSizeInLimit = isFieldSizeInLimit && (len(str) <= maxLength)
}
} else {
if subObj, ok := value.(map[string]interface{}); ok {
queue = append(queue, subObj)
} else if subObjs, ok := value.([]interface{}); ok {
for _, subObj := range subObjs {
if subObjMap, ok := subObj.(map[string]interface{}); ok {
queue = append(queue, subObjMap)
}
}
}
}
}
}

return isFieldSizeInLimit
}

func TestTruncateCRDFieldTransformer(t *testing.T) {
RegisterFailHandler(Fail)

t.Run("test truncate CRD field Transformer", func(t *testing.T) {
crdYaml := `
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: test.crd.com
spec:
group: crd.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
properties:
spec:
properties:
field1:
type: string
description: This is a long string that should be truncated
scope: Namespaced
names:
plural: tests
singular: test
kind: Test
shortNames:
- tst
`
u := &unstructured.Unstructured{}
_ = yaml.Unmarshal([]byte(crdYaml), &u.Object)
_ = TruncateCRDFieldTransformer("description", 10)(u)

isDscriptionTruncated := CheckNestedFieldLengthWithinLimit(u.Object, 10, "description")
Expect(isDscriptionTruncated).To(Equal(true))
})
}

func deploymentFor(t *testing.T, unstr unstructured.Unstructured) *appsv1.Deployment {
deployment := &appsv1.Deployment{}
err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstr.Object, deployment)
Expand Down
Loading