Skip to content

Commit

Permalink
Chore: Move all generated strategy to unversioned package (#327)
Browse files Browse the repository at this point in the history
* move all strategy to unversioned pkg

* better naming

* generate strategy to unversioned pkg when creatign resource

* remove used import in the code template

* nit: import order
  • Loading branch information
yue9944882 authored and k8s-ci-robot committed Mar 23, 2019
1 parent 6080217 commit 20b540d
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 125 deletions.
14 changes: 2 additions & 12 deletions cmd/apiregister-gen/generators/versioned_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ var (
{{.Kind}}SchemeFns{},
func() runtime.Object { return &{{ $api.Kind }}{} }, // Register versioned resource
func() runtime.Object { return &{{ $api.Kind }}List{} }, // Register versioned resource list
&{{ $api.Strategy }}{builders.StorageStrategySingleton},
&{{ $api.Group }}.{{ $api.Strategy }}{builders.StorageStrategySingleton},
)
{{ end -}}
{{ end -}}
Expand All @@ -101,7 +101,7 @@ var (
{{.Kind}}SchemeFns{},
func() runtime.Object { return &{{ $api.Kind }}{} }, // Register versioned resource
func() runtime.Object { return &{{ $api.Kind }}List{} }, // Register versioned resource list
&{{ $api.StatusStrategy }}{builders.StatusStorageStrategySingleton},
&{{ $api.Group }}.{{ $api.StatusStrategy }}{builders.StatusStorageStrategySingleton},
),{{ end -}}
{{ range $subresource := $api.Subresources -}}
Expand Down Expand Up @@ -146,16 +146,6 @@ type {{.Kind}}SchemeFns struct {
builders.DefaultSchemeFns
}
// +k8s:deepcopy-gen=false
type {{.Strategy}} struct {
builders.DefaultStorageStrategy
}
// +k8s:deepcopy-gen=false
type {{.StatusStrategy}} struct {
builders.DefaultStatusStorageStrategy
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type {{$api.Kind}}List struct {
Expand Down
71 changes: 46 additions & 25 deletions cmd/apiserver-boot/boot/create/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ func createResource(boilerplate string) {
if err != nil {
log.Fatal(err)
}
typesFileName := fmt.Sprintf("%s_types.go", strings.ToLower(kindName))
path := filepath.Join(dir, "pkg", "apis", groupName, versionName, typesFileName)

//
a := resourceTemplateArgs{
boilerplate,
util.Domain,
Expand All @@ -89,7 +89,20 @@ func createResource(boilerplate string) {

found := false

created := util.WriteIfNotFound(path, "resource-template", resourceTemplate, a)
strategyFileName := fmt.Sprintf("%s_strategy.go", strings.ToLower(kindName))
unversionedPath := filepath.Join(dir, "pkg", "apis", groupName, strategyFileName)
created := util.WriteIfNotFound(unversionedPath, "unversioned-strategy-template", unversionedStrategyTemplate, a)
if !created {
if !found {
log.Printf("API group version kind %s/%s/%s already exists.",
groupName, versionName, kindName)
found = true
}
}

typesFileName := fmt.Sprintf("%s_types.go", strings.ToLower(kindName))
path := filepath.Join(dir, "pkg", "apis", groupName, versionName, typesFileName)
created = util.WriteIfNotFound(path, "versioned-resource-template", versionedResourceTemplate, a)
if !created {
if !found {
log.Printf("API group version kind %s/%s/%s already exists.",
Expand Down Expand Up @@ -177,21 +190,45 @@ type resourceTemplateArgs struct {
NonNamespacedKind bool
}

var resourceTemplate = `
var unversionedStrategyTemplate = `
{{.BoilerPlate}}
package {{.Version}}
package {{.Group}}
import (
"log"
"context"
"log"
"k8s.io/apimachinery/pkg/runtime"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
)
// Validate checks that an instance of {{.Kind}} is well formed
func ({{.Kind}}Strategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
o := obj.(*{{.Kind}})
log.Printf("Validating fields for {{.Kind}} %s\n", o.Name)
errors := field.ErrorList{}
// perform validation here and add to errors using field.Invalid
return errors
}
{{- if .NonNamespacedKind }}
"{{ .Repo }}/pkg/apis/{{.Group}}"
func ({{.Kind}}Strategy) NamespaceScoped() bool { return false }
func ({{.Kind}}StatusStrategy) NamespaceScoped() bool { return false }
{{- end }}
`

var versionedResourceTemplate = `
{{.BoilerPlate}}
package {{.Version}}
import (
"log"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
Expand Down Expand Up @@ -219,22 +256,6 @@ type {{.Kind}}Spec struct {
type {{.Kind}}Status struct {
}
// Validate checks that an instance of {{.Kind}} is well formed
func ({{.Kind}}Strategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
o := obj.(*{{.Group}}.{{.Kind}})
log.Printf("Validating fields for {{.Kind}} %s\n", o.Name)
errors := field.ErrorList{}
// perform validation here and add to errors using field.Invalid
return errors
}
{{- if .NonNamespacedKind }}
func ({{.Kind}}Strategy) NamespaceScoped() bool { return false }
func ({{.Kind}}StatusStrategy) NamespaceScoped() bool { return false }
{{- end }}
// DefaultingFunction sets default {{.Kind}} field values
func ({{.Kind}}SchemeFns) DefaultingFunction(o interface{}) {
obj := o.(*{{.Kind}})
Expand Down
44 changes: 44 additions & 0 deletions example/pkg/apis/kingsport/festival_strategy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package kingsport

import (
"context"
"log"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
)

func (FestivalStrategy) NamespaceScoped() bool { return false }

func (FestivalStatusStrategy) NamespaceScoped() bool { return false }

// Validate checks that an instance of Festival is well formed
func (FestivalStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
o := obj.(*Festival)
log.Printf("Validating fields for Festival %s\n", o.Name)
errors := field.ErrorList{}

if o.Spec.Year < 0 {
errors = append(errors,
field.Invalid(field.NewPath("spec", "year"), o.Spec.Year, "year must be > 0"))
}

// perform validation here and add to errors using field.Invalid
return errors
}
25 changes: 0 additions & 25 deletions example/pkg/apis/kingsport/v1/festival_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,7 @@ package v1

import (
"log"
"context"

"k8s.io/apimachinery/pkg/runtime"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"

"github.com/kubernetes-incubator/apiserver-builder-alpha/example/pkg/apis/kingsport"
)

// +genclient
Expand Down Expand Up @@ -56,25 +50,6 @@ type FestivalStatus struct {
Attended uint `json:"attended,omitempty"`
}

// Validate checks that an instance of Festival is well formed
func (FestivalStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
o := obj.(*kingsport.Festival)
log.Printf("Validating fields for Festival %s\n", o.Name)
errors := field.ErrorList{}

if o.Spec.Year < 0 {
errors = append(errors,
field.Invalid(field.NewPath("spec", "year"), o.Spec.Year, "year must be > 0"))
}

// perform validation here and add to errors using field.Invalid
return errors
}

func (FestivalStrategy) NamespaceScoped() bool { return false }

func (FestivalStatusStrategy) NamespaceScoped() bool { return false }

// DefaultingFunction sets default Festival field values
func (FestivalSchemeFns) DefaultingFunction(o interface{}) {
obj := o.(*Festival)
Expand Down
File renamed without changes.
39 changes: 39 additions & 0 deletions example/pkg/apis/miskatonic/university_strategy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package miskatonic

import (
"context"
"log"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
)

// Resource Validation
func (UniversityStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
university := obj.(*University)
log.Printf("Validating University %s\n", university.Name)
errors := field.ErrorList{}
if university.Spec.MaxStudents == nil || *university.Spec.MaxStudents < 1 || *university.Spec.MaxStudents > 150 {
errors = append(errors, field.Invalid(
field.NewPath("spec", "MaxStudents"),
*university.Spec.MaxStudents,
"Must be between 1 and 150"))
}
return errors
}
18 changes: 0 additions & 18 deletions example/pkg/apis/miskatonic/v1beta1/university_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@ limitations under the License.
package v1beta1

import (
"context"
"log"

"github.com/kubernetes-incubator/apiserver-builder-alpha/example/pkg/apis/miskatonic"
corev1 "k8s.io/api/core/v1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
)

// Generating code from university_types.go file will generate storage and status REST endpoints for
Expand Down Expand Up @@ -93,20 +89,6 @@ type UniversityStatus struct {
FacultyEmployed []string `json:"faculty_employed,omitempty"`
}

// Resource Validation
func (UniversityStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
university := obj.(*miskatonic.University)
log.Printf("Validating University %s\n", university.Name)
errors := field.ErrorList{}
if university.Spec.MaxStudents == nil || *university.Spec.MaxStudents < 1 || *university.Spec.MaxStudents > 150 {
errors = append(errors, field.Invalid(
field.NewPath("spec", "MaxStudents"),
*university.Spec.MaxStudents,
"Must be between 1 and 150"))
}
return errors
}

// GetDefaultingFunctions returns functions for defaulting v1beta1.University values
func (UniversitySchemeFns) DefaultingFunction(o interface{}) {
obj := o.(*University)
Expand Down
65 changes: 65 additions & 0 deletions example/pkg/apis/olympus/poseidon_strategy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package olympus

import (
"context"
"log"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/storage"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apiserver/pkg/registry/generic"
)

// Validate checks that an instance of Poseidon is well formed
func (PoseidonStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
o := obj.(*Poseidon)
log.Printf("Validating fields for Poseidon %s\n", o.Name)
errors := field.ErrorList{}
// perform validation here and add to errors using field.Invalid
return errors
}

func (b PoseidonStrategy) TriggerFunc(obj runtime.Object) []storage.MatchValue {
// Change this function to override the trigger fn that is used
value := b.DefaultStorageStrategy.TriggerFunc(obj)
return value
}

func (b PoseidonStrategy) BasicMatch(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
return storage.SelectionPredicate{
Label: label,
Field: field,
GetAttrs: b.GetAttrs,
IndexFields: []string{"spec.deployment.name"},
}
}

// The following functions allow spec.deployment.name to be selected when listing
// or watching resources
func (b PoseidonStrategy) GetAttrs(o runtime.Object) (labels.Set, fields.Set, bool, error) {
// Change this function to override the attributes that are matched
l, _, uninit, e := b.DefaultStorageStrategy.GetAttrs(o)
obj := o.(*Poseidon)

fs := fields.Set{"spec.deployment.name": obj.Spec.Deployment.Name}
fs = generic.AddObjectMetaFieldsSet(fs, &obj.ObjectMeta, true)
return l, fs, uninit, e
}
Loading

0 comments on commit 20b540d

Please sign in to comment.