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

Add support for interface member #528

Closed
fiftoine opened this issue Dec 13, 2018 · 20 comments
Closed

Add support for interface member #528

fiftoine opened this issue Dec 13, 2018 · 20 comments
Labels
kind/bug Categorizes issue or PR as related to a bug. lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale.

Comments

@fiftoine
Copy link

Hi,

I have a resource type that has a interface{} type.

When running go run vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go crdI get an error :

2018/12/13 08:35:47 Unknown supported Kind Interface

Actually, This field could contain string or int or bool but I don't want to create a IntOrStringOrBool type. Is there a workaround or is it a bug?

Thanks

@droot droot added the kind/bug Categorizes issue or PR as related to a bug. label Dec 17, 2018
@droot droot assigned fanzhangio and unassigned fanzhangio Dec 17, 2018
@droot
Copy link
Contributor

droot commented Dec 17, 2018

It should not error-out for interface{} type.
@sohankunkerkar can you pl. take a look at this ?

@sohankunkerkar
Copy link
Member

@fiftoine Could you please help me out with your test case (like an example )here? Just wanted to make sure that I'm not missing out on any information.

@tantona
Copy link

tantona commented Jan 11, 2019

So happy this issue is already open - I just ran into this myself!

Are there any workarounds? @fiftoine did you get this figured out?

@sohankunkerkar
Copy link
Member

@tantona Could you please provide the test case that you're using here. It would help me in debugging this issue.

@andersjanmyr
Copy link

@sohankunkerkar Just declare a new type, like this:

type InterfaceExample struct {
	Inter interface{} `json:"inter"`
}

This will lead to an error like this:

$ make
go generate ./pkg/... ./cmd/...
F0114 14:33:10.565683   65790 main.go:82] Error: Failed executing generator: some packages had errors:
errors in package "gecgithub01.walmart.com/wce/marquis-mca/pkg/apis/marquis/v1beta1":
unable to format file "/Users/vn0wxf9/gocode/src/gecgithub01.walmart.com/wce/marquis-mca/pkg/apis/marquis/v1beta1/zz_generated.deepcopy.go" (62:39: expected ';', found '{' (and 5 more errors)).

@andersjanmyr
Copy link

Adding a type alias for interface{} changes the error

type Inter interface{}
type InterfaceExample struct {
	Inter Inter `json:"inter"`
}

to this

$ make
go generate ./pkg/... ./cmd/...
go fmt ./pkg/... ./cmd/...
go vet ./pkg/... ./cmd/...
# gecgithub01.walmart.com/wce/marquis-mca/pkg/apis/marquis/v1beta1
pkg/apis/marquis/v1beta1/zz_generated.deepcopy.go:69:23: in.Inter.DeepCopyInter undefined (type Inter is interface with no methods)
# gecgithub01.walmart.com/wce/marquis-mca/pkg/apis/marquis/v1beta1 [gecgithub01.walmart.com/wce/marquis-mca/pkg/apis/marquis/v1beta1.test]
pkg/apis/marquis/v1beta1/zz_generated.deepcopy.go:69:23: in.Inter.DeepCopyInter undefined (type Inter is interface with no methods)
make: *** [vet] Error 2

@andersjanmyr
Copy link

I think something like Mitchell Hashimoto's copystructure could be used to solve this.
https://godoc.org/github.com/mitchellh/copystructure

@sohankunkerkar
Copy link
Member

@andersjanmyr Thanks for the detailed analysis. I understood what's the problem here. Let me go through it and will get back to you soon.

@andersjanmyr
Copy link

@sohankunkerkar I looked at it some more and to be able to add this functionality the generator has to be altered. Here's an example that works (but is far from perfect). I need to add support to all interfaces and make sure that the copystructure package is included with dep.
kubernetes/gengo@master...andersjanmyr:add_support_for_interface

@andersjanmyr
Copy link

After the above change is applied, the following patch needs to be applied to sigs.k8s.io/controller-tools to generate a property with type: object in the CRD.

--- a/vendor/sigs.k8s.io/controller-tools/pkg/internal/codegen/parse/crd.go
+++ b/vendor/sigs.k8s.io/controller-tools/pkg/internal/codegen/parse/crd.go
@@ -198,6 +198,8 @@ func (b *APIs) typeToJSONSchemaProps(t *types.Type, found sets.String, comments
                v, s = b.typeToJSONSchemaProps(t.Elem, found, comments, false)
        case types.Alias:
                v, s = b.typeToJSONSchemaProps(t.Underlying, found, comments, false)
+       case types.Interface:
+               v, s = b.parseObjectValidation(t, found, comments, isRoot)

@sohankunkerkar
Copy link
Member

@andersjanmyr That's awesome. I was planning to handle this condition in the controller-tools itself.
https://github.com/kubernetes-sigs/controller-tools/compare/master...sohankunkerkar:interface?expand=1
I did not change anything in gengo package

@andersjanmyr
Copy link

@sohankunkerkar How does the generated copy code look? The zz_generated.deepcopy.go must make a deep copy using reflection for interfaces. I don't think you can get that to work without using reflection.

@j-vizcaino
Copy link

j-vizcaino commented Feb 22, 2019

Stumbled upon this today as well. Reading the thread of comments it seems two issues are actually entangled here:

  • one is about generation of the CRD
  • one is about generation of the deepcopy code

My use-case is a bit similar to the one described above, although in my case, the structure member is a map[string]interface{}. I was able to circumvent the deepcopy issue by creating the DeepCopy and DeepCopyInto functions manually but I can't get past the CRD.

Here is the code that handles the copy (maybe helpful to other people):

// +k8s:deepcopy-gen=false
type ExtraFields map[string]interface{}

func (in *ExtraFields) DeepCopyInto(out *ExtraFields) {
	if in == nil {
		*out = nil
	} else {
		*out = runtime.DeepCopyJSON(*in)
	}
}

func (in *ExtraFields) DeepCopy() *ExtraFields {
	if in == nil {
		return nil
	}
	out := new(ExtraFields)
	in.DeepCopyInto(out)
	return out
}

@sohankunkerkar
Copy link
Member

@j-vizcaino Could you provide your feedback over here?
kubernetes-sigs/controller-tools#126

@fejta-bot
Copy link

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label May 23, 2019
@DirectXMan12
Copy link
Contributor

this should have been fixed in the latest release of CT, IIRC

@austince
Copy link

austince commented Jul 22, 2019

I'm using version 2.0.0-beta.0 of Kubebuilder and still seeing this problem. I've verified that I'm using the latest version of CT, 0.2.0-beta.4. My interface looks like this:

type DeploymentTargetSpec struct {
	DeploymentPatchSet []interface{} `json:"deploymentPatchSet"`
}

Seeing the error message:

github.com/.../api/v1beta1:-: name requested for invalid type interface{}
github.com/.../api/v1beta1:-: invalid slice element type interface{}

Is there something I'm still doing wrong? It's also worth noting that this happens without the slice as well.

@szediktam
Copy link

szediktam commented Aug 5, 2019

no fixed in master. @DirectXMan12
go run vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go crd paths=./pkg/apis/aiops/... output:crd:dir=/tmp/crds
error:
map values must be a named type, not *ast.InterfaceType

same problem:
https://github.com/kubernetes-sigs/controller-tools/issues/294

@DirectXMan12
Copy link
Contributor

I've replied on the equivalent controller-tools issue. Please direct all comments there.

@kubernetes-sigs kubernetes-sigs locked as resolved and limited conversation to collaborators Aug 5, 2019
@DirectXMan12
Copy link
Contributor

I've locked this in the hopes that we can keep discussion in one place, not to discourage filing of issues. In general, generation issues should be discussed in the controller-tools repo.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
kind/bug Categorizes issue or PR as related to a bug. lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale.
Projects
None yet
Development

No branches or pull requests