Skip to content

Commit

Permalink
Read images from environment in the upstream operator (knative#51) (k…
Browse files Browse the repository at this point in the history
…native#52)

* Read images from environment in the upstream operator

* Review: Renames, adding tests, short-circuits
  • Loading branch information
markusthoemmes authored Sep 30, 2020
1 parent 88c0c03 commit fc66484
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
67 changes: 67 additions & 0 deletions pkg/reconciler/common/image_override.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package common

import (
"os"
"strings"

"knative.dev/operator/pkg/apis/operator/v1alpha1"
)

const imagePrefix = "IMAGE_"

// configureImagesFromEnvironment overrides registry images
func configureImagesFromEnvironment(obj v1alpha1.KComponent) {
reg := obj.GetSpec().GetRegistry()

reg.Override = imageMapFromEnvironment(os.Environ())

if defaultVal, ok := reg.Override["default"]; ok {
reg.Default = defaultVal
}

if ks, ok := obj.(*v1alpha1.KnativeServing); ok {
if qpVal, ok := reg.Override["queue-proxy"]; ok {
configure(ks, "deployment", "queueSidecarImage", qpVal)
}
}
}

func imageMapFromEnvironment(env []string) map[string]string {
overrideMap := map[string]string{}

for _, e := range env {
pair := strings.SplitN(e, "=", 2)
if strings.HasPrefix(pair[0], imagePrefix) {
if pair[1] == "" {
continue
}

// convert
// "IMAGE_container=docker.io/foo"
// "IMAGE_deployment__container=docker.io/foo2"
// "IMAGE_env_var=docker.io/foo3"
// "IMAGE_deployment__env_var=docker.io/foo4"
// to
// container: docker.io/foo
// deployment/container: docker.io/foo2
// env_var: docker.io/foo3
// deployment/env_var: docker.io/foo4
name := strings.TrimPrefix(pair[0], imagePrefix)
name = strings.Replace(name, "__", "/", 1)
overrideMap[name] = pair[1]
}
}
return overrideMap
}

func configure(ks *v1alpha1.KnativeServing, cm, key, value string) {
if ks.Spec.Config == nil {
ks.Spec.Config = map[string]map[string]string{}
}

if ks.Spec.Config[cm] == nil {
ks.Spec.Config[cm] = map[string]string{}
}

ks.Spec.Config[cm][key] = value
}
89 changes: 89 additions & 0 deletions pkg/reconciler/common/image_override_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package common

import (
"fmt"
"reflect"
"testing"
)

func TestImageMapFromEnvironment(t *testing.T) {
cases := []struct {
name string
envMap map[string]string
expected map[string]string
}{{
name: "Simple container name",
envMap: map[string]string{
"IMAGE_foo": "quay.io/myimage",
},
expected: map[string]string{
"foo": "quay.io/myimage",
},
}, {
name: "Simple env var",
envMap: map[string]string{
"IMAGE_CRONJOB_RA_IMAGE": "quay.io/myimage",
},
expected: map[string]string{
"CRONJOB_RA_IMAGE": "quay.io/myimage",
},
}, {
name: "Simple env var with deployment name",
envMap: map[string]string{
"IMAGE_eventing-controller__CRONJOB_RA_IMAGE": "quay.io/myimage",
},
expected: map[string]string{
"eventing-controller/CRONJOB_RA_IMAGE": "quay.io/myimage",
},
}, {
name: "Deployment+container name",
envMap: map[string]string{
"IMAGE_foo__bar": "quay.io/myimage",
},
expected: map[string]string{
"foo/bar": "quay.io/myimage",
},
}, {
name: "Deployment+container and container name",
envMap: map[string]string{
"IMAGE_foo__bar": "quay.io/myimage1",
"IMAGE_bar": "quay.io/myimage2",
},
expected: map[string]string{
"foo/bar": "quay.io/myimage1",
"bar": "quay.io/myimage2",
},
}, {
name: "Different prefix",
envMap: map[string]string{
"X_foo": "quay.io/myimage",
},
expected: map[string]string{},
}, {
name: "No env var value",
envMap: map[string]string{
"IMAGE_foo": "",
},
expected: map[string]string{},
}}

for i := range cases {
tc := cases[i]
environ := environFromMap(tc.envMap)
overrideMap := imageMapFromEnvironment(environ)

if !reflect.DeepEqual(overrideMap, tc.expected) {
t.Errorf("Image override map is not equal. Case name: %q. Expected: %v, actual: %v", tc.name, tc.expected, overrideMap)
}

}
}

func environFromMap(envMap map[string]string) []string {
e := make([]string, 0, len(envMap))
for k, v := range envMap {
e = append(e, fmt.Sprintf("%s=%s", k, v))
}

return e
}
5 changes: 5 additions & 0 deletions pkg/reconciler/common/transformers.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ import (
// transformers that are common to all components.
func transformers(ctx context.Context, obj v1alpha1.KComponent) []mf.Transformer {
logger := logging.FromContext(ctx)

// TODO: Openshift Hack: Take image registry from environment instead of CR
configureImagesFromEnvironment(obj)
logger.Infof("Openshift specific image override: %v", obj.GetSpec().GetRegistry())

return []mf.Transformer{
mf.InjectOwner(obj),
mf.InjectNamespace(obj.GetNamespace()),
Expand Down

0 comments on commit fc66484

Please sign in to comment.