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

operator-sdk generate openapi fails when json name does not match attribute name #1222

Closed
miguelsorianod opened this issue Mar 18, 2019 · 4 comments
Labels
triage/support Indicates an issue that is a support question.

Comments

@miguelsorianod
Copy link
Contributor

miguelsorianod commented Mar 18, 2019

Hi,

We have installed operator-sdk v0.6.0 and we have observed the problem that when you define an attribute in the *Spec struct of a defined API type and the attribute name differs from its json struct tag name, the operator-sdk generate openapi command fails, whereas that did not happen in older versions that we were using.

An example of the error we observe in that case is:

$ GOFLAGS="-v" operator-sdk generate openapi
INFO[0000] Running OpenAPI code-generation for Custom Resource group versions: [app:[v1alpha1], ] 
API rule violation: names_match,github.com/anotherproject/pkg/apis/app/v1alpha1,ExampleAppSpec,ExampleField
2019/03/18 18:35:19 OpenAPI code generation error: Failed executing generator: some packages had errors:
API rule violations exist
Error: failed to perform openapi code-generation: failed to exec []string{"/home/msoriano/anotherowrkspace/src/github.com/anotherproject/build/_output/bin/openapi-gen", "--input-dirs", "github.com/anotherproject/pkg/apis/app/v1alpha1", "--output-package", "github.com/anotherproject/pkg/apis/app/v1alpha1", "--output-file-base", "zz_generated.openapi", "--go-header-file", "build/_output/bin/869558625"}: exit status 1
Usage:
  operator-sdk generate openapi [flags]

Flags:
      --header-file string   Path to file containing headers for generated files.
  -h, --help                 help for openapi

Investigating, we have seen that one of the changes between v0.4.0 and v0.5.0 is that in v0.5.0 and newer versions the sentence // +k8s:openapi-gen=true is used in the *Spec and *Status struct types additionally to the struct type of the defined API type. In v0.4.0 it was only used in the struct type of the defined API type.

Upgrading from an older version would break the existing functionality due to this changes, which is the action we were trying to perform.

For example, in v0.4.0, for a 'ExampleApp' API type you would have the following code:

// ExampleAppSpec defines the desired state of ExampleApp
type ExampleAppSpec struct {
  // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
  // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
  // Add custom validation using kubebuilder tags: https://book.kubebuilder.io/beyond_basics/generating_crd.html
}

// ExampleAppStatus defines the observed state of ExampleApp
type ExampleAppStatus struct {
  // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
  // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
  // Add custom validation using kubebuilder tags: https://book.kubebuilder.io/beyond_basics/generating_crd.html
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ExampleApp is the Schema for the exampleapps API
// +k8s:openapi-gen=true
type ExampleApp struct {
  metav1.TypeMeta   `json:",inline"`
  metav1.ObjectMeta `json:"metadata,omitempty"`

  Spec   ExampleAppSpec   `json:"spec,omitempty"`
  Status ExampleAppStatus `json:"status,omitempty"`
}

Whereas in v0.6.0 you have (notice the additional // +k8s:openapi-gen=true):

// ExampleAppSpec defines the desired state of ExampleApp
// +k8s:openapi-gen=true
type ExampleAppSpec struct {
  // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
  // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
  // Add custom validation using kubebuilder tags: https://book.kubebuilder.io/beyond_basics/generating_crd.html
}

// ExampleAppStatus defines the observed state of ExampleApp
// +k8s:openapi-gen=true
type ExampleAppStatus struct {
  // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
  // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
  // Add custom validation using kubebuilder tags: https://book.kubebuilder.io/beyond_basics/generating_crd.html
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ExampleApp is the Schema for the exampleapps API
// +k8s:openapi-gen=true
type ExampleApp struct {
  metav1.TypeMeta   `json:",inline"`
  metav1.ObjectMeta `json:"metadata,omitempty"`

  Spec   ExampleAppSpec   `json:"spec,omitempty"`
  Status ExampleAppStatus `json:"status,omitempty"`
}

To reproduce the problem, in v0.6.0 you can:

operator-sdk new exampleproject
operator-sdk add api --api-version=app.example.com/v1alpha1 --kind=ExampleApp
operator-sdk add controller --api-version=app.example.com/v1alpha1 --kind=ExampleApp
operator-sdk generate k8s
operator-sdk generate openapi
// From here you can see that everything is OK because no fields
// have been added to the Spec/Status of the type

// Now edit the file pkg/apis/app/v1alpha1/exampleapp_types.go
// and add a new attribute in the ExampleAppSpec struct type:
//   ExampleField int32 `json:"anothername"`
// and try to generate k8s and openapi again with:
operator-sdk generate k8s
operator-sdk generate openapi
// Notice that now the openapi generation fails with an error.
// The same steps in v0.4.0 do not generate any error and the openapi generation is performed
// correctly.

// You can also test that if you set the same name (excluding the first letter) in the json tag it generates it correctly:
// ExampleField int32 `json:"exampleField"`
operator-sdk generate k8s
operator-sdk generate openapi
// Now openapi generation works correctly

Environment

  • operator-sdk version: v0.6.0
  • Kubernetes version information: 1.11
@lilic
Copy link
Member

lilic commented Mar 22, 2019

Not sure this is an issue with operator-sdk, think this might be an issue with openapi-gen itself, but cc @estroz as he worked on openapi in operator-sdk IIRC, and might have more insight into the above issue.

@lilic lilic added kind/bug Categorizes issue or PR as related to a bug. triage/support Indicates an issue that is a support question. labels Mar 22, 2019
@hasbro17
Copy link
Contributor

@miguelsorianod Having the json name differ from the field name causes a problem with the kube-openapi name_match rule.
Similar issue #1181 (comment)

Since this is an API rule violation for the generator I'm not sure that there's another way around it, except your json field name has to match the struct attribute name.
We might have to follow this upstream in kube-openapi since I don't know if we can work around this in the SDK.

riccardomc added a commit to ContainerSolutions/externalsecret-operator that referenced this issue May 9, 2019
riccardomc added a commit to ContainerSolutions/externalsecret-operator that referenced this issue May 29, 2019
riccardomc added a commit to ContainerSolutions/externalsecret-operator that referenced this issue May 29, 2019
@joelanford
Copy link
Member

@miguelsorianod @hasbro17 @lilic @estroz Just wanted to follow up on this issue, which hasn't had any movement for awhile.

Since it looks like this is working as intended based on kube-openapi's rules, I think it makes sense to close this issue. If anyone disagrees, feel free to re-open.

@joelanford joelanford removed the kind/bug Categorizes issue or PR as related to a bug. label Jun 18, 2019
@hasbro17
Copy link
Contributor

Yes I was incorrect when I mentioned a work around or fixing this upstream.
This rule is per the Kubernetes naming conventions:

Go field names must be CamelCase. JSON field names must be camelCase. Other than capitalization of the initial letter, the two should almost always match. No underscores nor dashes in either

I think that's something @miguelsorianod seems to have already fixed judging from the recent commits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage/support Indicates an issue that is a support question.
Projects
None yet
Development

No branches or pull requests

4 participants