Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Jefftree committed Jan 19, 2021
1 parent bb53d0b commit 0605102
Show file tree
Hide file tree
Showing 8 changed files with 2,542 additions and 17 deletions.
39 changes: 27 additions & 12 deletions pkg/applyconfigurations/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,11 @@ import (
// types in the given package, writing the formatted result to given writer.
// May return nil if source could not be generated.
func (ctx *ObjectGenCtx) generateForPackage(root *loader.Package) []byte {
allTypes, err := enabledOnPackage(ctx.Collector, root)
if err != nil {
root.AddError(err)
return nil
}
// allTypes, err := enabledOnPackage(ctx.Collector, root)
// if err != nil {
// root.AddError(err)
// return nil
// }

ctx.Checker.Check(root)

Expand All @@ -184,12 +184,6 @@ func (ctx *ObjectGenCtx) generateForPackage(root *loader.Package) []byte {

if err := markers.EachType(ctx.Collector, root, func(info *markers.TypeInfo) {
outContent := new(bytes.Buffer)

if !enabledOnType(allTypes, info) {
//root.AddError(fmt.Errorf("skipping type: %v", info.Name)) // TODO(jpbetz): Remove
return
}

// not all types required a generate apply configuration. For example, no apply configuration
// type is needed for Quantity, IntOrString, RawExtension or Unknown.
if !shouldBeApplyConfiguration(root, info) {
Expand All @@ -203,7 +197,28 @@ func (ctx *ObjectGenCtx) generateForPackage(root *loader.Package) []byte {
codeWriter: &codeWriter{out: outContent},
}

copyCtx.GenerateTypesFor(root, info)
// TODO|jefftree: Make this a CLI toggle between builder and go structs
if false {
copyCtx.GenerateStruct(root, info)
copyCtx.GenerateFieldsStruct(root, info)
for _, field := range info.Fields {
if field.Name != "" {
copyCtx.GenerateMemberSet(field, root, info)
copyCtx.GenerateMemberRemove(field, root, info)
copyCtx.GenerateMemberGet(field, root, info)
}
}
copyCtx.GenerateToUnstructured(root, info)
copyCtx.GenerateFromUnstructured(root, info)
copyCtx.GenerateMarshal(root, info)
copyCtx.GenerateUnmarshal(root, info)
copyCtx.GeneratePrePostFunctions(root, info)

} else {
copyCtx.GenerateTypesFor(root, info)
copyCtx.GenerateStructConstructor(root, info)
}
copyCtx.GenerateListMapAlias(root, info)

outBytes := outContent.Bytes()
if len(outBytes) > 0 {
Expand Down
309 changes: 309 additions & 0 deletions pkg/applyconfigurations/testdata/cronjob_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
/*
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.
*/

// TODO(directxman12): test this across both versions (right now we're just
// trusting k/k conversion, which is probably fine though)

//go:generate ../../../.run-controller-gen.sh paths=. output:dir=.

// +groupName=testdata.kubebuilder.io
// +versionName=v1
package cronjob

import (
"encoding/json"
"fmt"

batchv1beta1 "k8s.io/api/batch/v1beta1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

// CronJobSpec defines the desired state of CronJob
type CronJobSpec struct {
// The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
Schedule string `json:"schedule"`

// Optional deadline in seconds for starting the job if it misses scheduled
// time for any reason. Missed jobs executions will be counted as failed ones.
// +optional
StartingDeadlineSeconds *int64 `json:"startingDeadlineSeconds,omitempty"`

// Specifies how to treat concurrent executions of a Job.
// Valid values are:
// - "Allow" (default): allows CronJobs to run concurrently;
// - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet;
// - "Replace": cancels currently running job and replaces it with a new one
// +optional
ConcurrencyPolicy ConcurrencyPolicy `json:"concurrencyPolicy,omitempty"`

// This flag tells the controller to suspend subsequent executions, it does
// not apply to already started executions. Defaults to false.
// +optional
Suspend *bool `json:"suspend,omitempty"`

// This tests that non-serialized fields aren't included in the schema.
InternalData string `json:"-"`

// This flag is like suspend, but for when you really mean it.
// It helps test the +kubebuilder:validation:Type marker.
// +optional
NoReallySuspend *TotallyABool `json:"noReallySuspend,omitempty"`

// This tests byte slice schema generation.
BinaryName []byte `json:"binaryName"`

// This tests that nullable works correctly
// +nullable
CanBeNull string `json:"canBeNull"`

// Specifies the job that will be created when executing a CronJob.
JobTemplate batchv1beta1.JobTemplateSpec `json:"jobTemplate"`

// The number of successful finished jobs to retain.
// This is a pointer to distinguish between explicit zero and not specified.
// +optional
SuccessfulJobsHistoryLimit *int32 `json:"successfulJobsHistoryLimit,omitempty"`

// The number of failed finished jobs to retain.
// This is a pointer to distinguish between explicit zero and not specified.
// +optional
FailedJobsHistoryLimit *int32 `json:"failedJobsHistoryLimit,omitempty"`

// This tests byte slices are allowed as map values.
ByteSliceData map[string][]byte `json:"byteSliceData,omitempty"`

// This tests string slices are allowed as map values.
StringSliceData map[string][]string `json:"stringSliceData,omitempty"`

// This tests pointers are allowed as map values.
PtrData map[string]*string `json:"ptrData,omitempty"`

// This tests that markers that are allowed on both fields and types are applied to fields
// +kubebuilder:validation:MinLength=4
TwoOfAKindPart0 string `json:"twoOfAKindPart0"`

// This tests that markers that are allowed on both fields and types are applied to types
TwoOfAKindPart1 LongerString `json:"twoOfAKindPart1"`

// This tests that primitive defaulting can be performed.
// +kubebuilder:default=forty-two
DefaultedString string `json:"defaultedString"`

// This tests that slice defaulting can be performed.
// +kubebuilder:default={a,b}
DefaultedSlice []string `json:"defaultedSlice"`

// This tests that object defaulting can be performed.
// +kubebuilder:default={{nested: {foo: "baz", bar: true}},{nested: {bar: false}}}
DefaultedObject []RootObject `json:"defaultedObject"`

// This tests that pattern validator is properly applied.
// +kubebuilder:validation:Pattern=`^$|^((https):\/\/?)[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/?))$`
PatternObject string `json:"patternObject"`

// +kubebuilder:validation:EmbeddedResource
// +kubebuilder:validation:nullable
EmbeddedResource runtime.RawExtension `json:"embeddedResource"`

// +kubebuilder:validation:nullable
// +kubebuilder:pruning:PreserveUnknownFields
UnprunedJSON NestedObject `json:"unprunedJSON"`

// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:EmbeddedResource
// +kubebuilder:validation:nullable
UnprunedEmbeddedResource runtime.RawExtension `json:"unprunedEmbeddedResource"`

// This tests that a type-level pruning maker works.
UnprunedFromType Preserved `json:"unprunedFomType"`

// This tests that associative lists work.
// +listType=map
// +listMapKey=name
// +listMapKey=secondary
AssociativeList []AssociativeType `json:"associativeList"`

// A map that allows different actors to manage different fields
// +mapType=granular
MapOfInfo map[string][]byte `json:"mapOfInfo"`

// A struct that can only be entirely replaced
// +structType=atomic
StructWithSeveralFields NestedObject `json:"structWithSeveralFields"`

// This tests that type references are properly flattened
// +kubebuilder:validation:optional
JustNestedObject *JustNestedObject `json:"justNestedObject,omitempty"`

// This tests that min/max properties work
MinMaxProperties MinMaxObject `json:"minMaxProperties,omitempty"`
}

// +kubebuilder:validation:Type=object
// +kubebuilder:pruning:PreserveUnknownFields
type Preserved struct {
ConcreteField string `json:"concreteField"`
Rest map[string]interface{} `json:"-"`
}
func (p *Preserved) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &p.Rest); err != nil {
return err
}
conc, found := p.Rest["concreteField"]
if !found {
return nil
}
concStr, isStr := conc.(string)
if !isStr {
return fmt.Errorf("concreteField was not string")
}
delete(p.Rest, "concreteField")
p.ConcreteField = concStr
return nil
}
func (p *Preserved) MarshalJSON() ([]byte, error) {
full := make(map[string]interface{}, len(p.Rest)+1)
for k, v := range p.Rest {
full[k] = v
}
full["concreteField"] = p.ConcreteField
return json.Marshal(full)
}

type NestedObject struct {
Foo string `json:"foo"`
Bar bool `json:"bar"`
}

type JustNestedObject NestedObject

// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=2
type MinMaxObject struct {
Foo string `json:"foo,omitempty"`
Bar string `json:"bar,omitempty"`
Baz string `json:"baz,omitempty"`
}

type RootObject struct {
Nested NestedObject `json:"nested"`
}

type AssociativeType struct {
Name string `json:"name"`
Secondary int `json:"secondary"`
Foo string `json:"foo"`
}

// +kubebuilder:validation:MinLength=4
// This tests that markers that are allowed on both fields and types are applied to types
type LongerString string

// use an explicit type marker to verify that apply-first markers generate properly

// +kubebuilder:validation:Type=string
// TotallyABool is a bool that serializes as a string.
type TotallyABool bool

func (t TotallyABool) MarshalJSON() ([]byte, error) {
if t {
return []byte(`"true"`), nil
} else {
return []byte(`"false"`), nil
}
}
func (t *TotallyABool) UnmarshalJSON(in []byte) error {
switch string(in) {
case `"true"`:
*t = true
return nil
case `"false"`:
*t = false
default:
return fmt.Errorf("bad TotallyABool value %q", string(in))
}
return nil
}

// ConcurrencyPolicy describes how the job will be handled.
// Only one of the following concurrent policies may be specified.
// If none of the following policies is specified, the default one
// is AllowConcurrent.
// +kubebuilder:validation:Enum=Allow;Forbid;Replace
type ConcurrencyPolicy string

const (
// AllowConcurrent allows CronJobs to run concurrently.
AllowConcurrent ConcurrencyPolicy = "Allow"

// ForbidConcurrent forbids concurrent runs, skipping next run if previous
// hasn't finished yet.
ForbidConcurrent ConcurrencyPolicy = "Forbid"

// ReplaceConcurrent cancels currently running job and replaces it with a new one.
ReplaceConcurrent ConcurrencyPolicy = "Replace"
)

// CronJobStatus defines the observed state of CronJob
type CronJobStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file

// A list of pointers to currently running jobs.
// +optional
Active []corev1.ObjectReference `json:"active,omitempty"`

// Information when was the last time the job was successfully scheduled.
// +optional
LastScheduleTime *metav1.Time `json:"lastScheduleTime,omitempty"`

// Information about the last time the job was successfully scheduled,
// with microsecond precision.
// +optional
LastScheduleMicroTime *metav1.MicroTime `json:"lastScheduleMicroTime,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:singular=mycronjob

// CronJob is the Schema for the cronjobs API
type CronJob struct {
/*
*/
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec CronJobSpec `json:"spec,omitempty"`
Status CronJobStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// CronJobList contains a list of CronJob
type CronJobList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []CronJob `json:"items"`
}

func init() {
SchemeBuilder.Register(&CronJob{}, &CronJobList{})
}
Loading

0 comments on commit 0605102

Please sign in to comment.