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

Cannot unmarshal some ConfigMap values #3193

Closed
tgjonestx opened this issue May 18, 2022 · 4 comments · Fixed by #3229
Closed

Cannot unmarshal some ConfigMap values #3193

tgjonestx opened this issue May 18, 2022 · 4 comments · Fixed by #3229
Assignees
Labels
bug Something isn't working p0 triaged Issue has been triaged by adding an `area/` label

Comments

@tgjonestx
Copy link

Expected behavior

A FunctionConfig defined via an inline configMap should accept values like "true" and "123" as long as they are explicitly quoted to indicate they are of type string. This type of functionality was working with sigs.k8s.io/kustomize/kyaml v0.13.3, but something seems to have changed with the introduction of v0.13.6

Actual behavior

The ResourceList.FunctionConfig.As() method fails with an error like:

unable to convert object to *v1.ConfigMap with error: json: cannot unmarshal [number|bool] into Go struct field ConfigMap.data of type string

Information

Here's my example GO application compiled against github.com/GoogleContainerTools/kpt-functions-sdk/go/fn v0.0.0-20220517213353-b99a4025f2aa:

package main

import (
	"fmt"
	"os"

	k8score "k8s.io/api/core/v1"

	"github.com/GoogleContainerTools/kpt-functions-sdk/go/fn"
)

func Run(rl *fn.ResourceList) (bool, error) {
	configMap := &k8score.ConfigMap{}
	if err := rl.FunctionConfig.As(configMap); err != nil {
		rl.Results = append(rl.Results, &fn.Result{
			Severity: fn.Error,
			Message:  fmt.Sprintf("can not get ConfigMap: %s", err),
		})
		return false, err
	}
	rl.Results = append(rl.Results, &fn.Result{
		Severity: fn.Info,
		Message:  fmt.Sprintf("ConfigMap.data[verbose]=%s", configMap.Data["verbose"]),
	})
	rl.Results = append(rl.Results, &fn.Result{
		Severity: fn.Info,
		Message:  fmt.Sprintf("ConfigMap.data[port]=%s", configMap.Data["port"]),
	})

	return false, nil // return false to force output of the Results
}

func main() {
	if err := fn.AsMain(fn.ResourceListProcessorFunc(Run)); err != nil {
		os.Exit(1)
	}
}

Here's the Kptfile which produces the error:

apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
  name: example
pipeline:
  mutators:
    - image: gcr.io/wpe-cr-dev/kpt-fn-gjones:test
      configMap:
        verbose: "true"
        port: "65"
      # configPath: map.yaml

Note that error does not occur, if you replace configMap with configPath which references a ConfigMap like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: example
data:
  verbose: "true"
  port: "65"

Steps to reproduce the behavior

  1. Compile the sample app (I used go 1.17.1 on OSX)
  2. Run kpt as kpt fn render --truncate-output=false --output _output --image-pull-policy=ifnotpresent . using the example Kptfile above (replacing the image name as necesssary)
  3. Observe the error message reported above
  4. Edit the Kptfile removing the configMap entry and enabling configPath: which references a ConfigMap file with the same data values
  5. Repeat the kpt fn render command from (2)
  6. Observe that the json unmarshal error is not reported, and the Results include output like:
  Results:
    [info]: ConfigMap.data[verbose]=true
    [info]: ConfigMap.data[port]=65
@tgjonestx tgjonestx added the bug Something isn't working label May 18, 2022
@droot
Copy link
Contributor

droot commented May 19, 2022

Thank you so much for such a detailed report @tgjonestx

@yuwenma can you pl. take a look at it.

@droot droot added triaged Issue has been triaged by adding an `area/` label p0 labels May 19, 2022
@yuwenma
Copy link
Contributor

yuwenma commented May 19, 2022

Thanks for reporting @tgjonestx!

The problem is that kyaml cannot properly set the "data" field types when kpt fn render builds the inline ConfigMap functionConfig.

@droot We are pushing the strong typed KRM resource in the function SDK, so input values like ConfigMap should have data field as type map[string]string as the k8s/api defines, but kpt passed in the inline ConfigMap with data type "bool" and "int".

Agree with @tgjonestx that it might due to some behavior change between kyaml versions which kpt is also being affected See version diff between kpt beta-14 and beta-15 around kyaml

@yuwenma
Copy link
Contributor

yuwenma commented May 19, 2022

cc @natasha41575

@natasha41575
Copy link
Contributor

This is fixed and will be available in the next release. Thank you for filing the issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working p0 triaged Issue has been triaged by adding an `area/` label
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants