Skip to content

Commit 52612da

Browse files
clamoriniere1Asdminonne
authored andcommitted
Create DaemonSetJob API definition (AmadeusITGroup#70)
issue: AmadeusITGroup#71
1 parent 5bafacc commit 52612da

File tree

9 files changed

+309
-21
lines changed

9 files changed

+309
-21
lines changed

pkg/api/common/default.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package common
2+
3+
import (
4+
batchv1 "k8s.io/api/batch/v1"
5+
)
6+
7+
// SetDefaults_Job copied here function from k8s.io/kubernetes/pkg/apis/batch/v1/defaults.go
8+
func SetDefaults_Job(obj *batchv1.Job) {
9+
// For a non-parallel job, you can leave both `.spec.completions` and
10+
// `.spec.parallelism` unset. When both are unset, both are defaulted to 1.
11+
if obj.Spec.Completions == nil && obj.Spec.Parallelism == nil {
12+
obj.Spec.Completions = new(int32)
13+
*obj.Spec.Completions = 1
14+
obj.Spec.Parallelism = new(int32)
15+
*obj.Spec.Parallelism = 1
16+
}
17+
if obj.Spec.Parallelism == nil {
18+
obj.Spec.Parallelism = new(int32)
19+
*obj.Spec.Parallelism = 1
20+
}
21+
labels := obj.Spec.Template.Labels
22+
if labels != nil && len(obj.Labels) == 0 {
23+
obj.Labels = labels
24+
}
25+
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package install
2+
3+
import (
4+
"k8s.io/api/rbac/v1alpha1"
5+
"k8s.io/apimachinery/pkg/apimachinery/announced"
6+
"k8s.io/apimachinery/pkg/apimachinery/registered"
7+
"k8s.io/apimachinery/pkg/runtime"
8+
9+
"github.com/amadeusitgroup/workflow-controller/pkg/api/daemonsetjob"
10+
)
11+
12+
// Install registers the API group and adds types to a scheme
13+
func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
14+
if err := announced.NewGroupMetaFactory(
15+
&announced.GroupMetaFactoryArgs{
16+
GroupName: daemonsetjob.GroupName,
17+
VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version},
18+
},
19+
announced.VersionToSchemeFunc{
20+
v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme,
21+
},
22+
).Announce(groupFactoryRegistry).RegisterAndEnable(registry, scheme); err != nil {
23+
panic(err)
24+
}
25+
}

pkg/api/daemonsetjob/register.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package daemonsetjob
15+
16+
const (
17+
// GroupName is the API group for the daemonsetjob
18+
GroupName = "daemonsetjob.k8s.io"
19+
)

pkg/api/daemonsetjob/v1/default.go

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package v1
2+
3+
import (
4+
reflect "reflect"
5+
6+
batchv1 "k8s.io/api/batch/v1"
7+
8+
"github.com/amadeusitgroup/workflow-controller/pkg/api/common"
9+
)
10+
11+
// IsDaemonSetJobDefaulted check wether
12+
func IsDaemonSetJobDefaulted(d *DaemonSetJob) bool {
13+
defaultedDaemonSetJob := DefaultDaemonSetJob(d)
14+
return reflect.DeepEqual(d.Spec, defaultedDaemonSetJob.Spec)
15+
}
16+
17+
// DefaultDaemonSetJob defaults workflow
18+
func DefaultDaemonSetJob(undefaultedDaemonSetJob *DaemonSetJob) *DaemonSetJob {
19+
d := undefaultedDaemonSetJob.DeepCopy()
20+
if d.Spec.JobTemplate == nil {
21+
return d
22+
}
23+
dummyJob := &batchv1.Job{
24+
Spec: d.Spec.JobTemplate.Spec,
25+
}
26+
common.SetDefaults_Job(dummyJob)
27+
d.Spec.JobTemplate.Spec = dummyJob.Spec
28+
29+
return d
30+
}

pkg/api/daemonsetjob/v1/doc.go

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Package v1 is the version 1 of the DaemonSetJobs Api
2+
// +k8s:deepcopy-gen=package
3+
package v1

pkg/api/daemonsetjob/v1/register.go

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package v1
2+
3+
import (
4+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5+
"k8s.io/apimachinery/pkg/runtime"
6+
"k8s.io/apimachinery/pkg/runtime/schema"
7+
8+
"github.com/amadeusitgroup/workflow-controller/pkg/api/daemonsetjob"
9+
)
10+
11+
var (
12+
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
13+
AddToScheme = SchemeBuilder.AddToScheme
14+
)
15+
16+
const (
17+
// ResourcePlural is the id to indentify pluarals
18+
ResourcePlural = "daemonsetjobs"
19+
// ResourceSingular represents the id for identify singular resource
20+
ResourceSingular = "daemonsetjob"
21+
// ResourceKind
22+
ResourceKind = "DaemonSetJob"
23+
// ResourceVersion
24+
ResourceVersion = "v1"
25+
)
26+
27+
// SchemeGroupVersion is the group version used to register these objects.
28+
var SchemeGroupVersion = schema.GroupVersion{Group: daemonsetjob.GroupName, Version: ResourceVersion}
29+
30+
// Resource takes an unqualified resource and returns a Group qualified GroupResource
31+
func Resource(resource string) schema.GroupResource {
32+
return SchemeGroupVersion.WithResource(resource).GroupResource()
33+
}
34+
35+
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
36+
func Kind(kind string) schema.GroupKind {
37+
return SchemeGroupVersion.WithKind(kind).GroupKind()
38+
}
39+
40+
// addKnownTypes adds the set of types defined in this package to the supplied scheme.
41+
func addKnownTypes(scheme *runtime.Scheme) error {
42+
scheme.AddKnownTypes(SchemeGroupVersion,
43+
&DaemonSetJob{},
44+
&DaemonSetJobList{},
45+
)
46+
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
47+
return nil
48+
}

pkg/api/daemonsetjob/v1/types.go

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
Copyright 2016 The Kubernetes Authors All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1
18+
19+
import (
20+
batch "k8s.io/api/batch/v2alpha1"
21+
api "k8s.io/api/core/v1"
22+
23+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
)
25+
26+
// +genclient
27+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
28+
29+
// DaemonSetJob represents a DaemonSet Job
30+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
31+
type DaemonSetJob struct {
32+
metav1.TypeMeta `json:",inline"`
33+
// Standard object's metadata.
34+
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
35+
metav1.ObjectMeta `json:"metadata,omitempty"`
36+
37+
// Spec represents the desired behaviour of the DaemonSetJob.
38+
Spec DaemonSetJobSpec `json:"spec,omitempty"`
39+
40+
// Status contains the current status off the DaemonSetJob
41+
Status DaemonSetJobStatus `json:"status,omitempty"`
42+
}
43+
44+
// DaemonSetJobList implements list of DaemonSetJob.
45+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
46+
type DaemonSetJobList struct {
47+
metav1.TypeMeta `json:",inline"`
48+
// Standard list metadata
49+
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
50+
metav1.ListMeta `json:"metadata,omitempty"`
51+
52+
// Items is the list of DaemonSetJob
53+
Items []DaemonSetJob `json:"items"`
54+
}
55+
56+
// DaemonSetJobSpec contains DaemonSetJob specification
57+
type DaemonSetJobSpec struct {
58+
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`
59+
60+
// JobTemplate contains the job specificaton that should be run in this Workflow.
61+
// Only one between externalRef and JobTemplate can be set.
62+
JobTemplate *batch.JobTemplateSpec `json:"jobTemplate,omitempty"`
63+
64+
// NodeSelector use to create DaemonSetJobs only on selected nodes
65+
NodeSelector *metav1.LabelSelector `json:"nodeSelector,omitempty"`
66+
67+
// Selector for created jobs (if any)
68+
Selector *metav1.LabelSelector `json:"selector,omitempty"`
69+
}
70+
71+
// DaemonSetJobStatus represents the status of DaemonSetJob
72+
type DaemonSetJobStatus struct {
73+
// Conditions represent the latest available observations of an object's current state.
74+
Conditions []DaemonSetJobCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
75+
76+
// StartTime represents time when the workflow was acknowledged by the DaemonSetJob controller
77+
// It is not guaranteed to be set in happens-before order across separate operations.
78+
// It is represented in RFC3339 form and is in UTC.
79+
// StartTime doesn't consider startime of `ExternalReference`
80+
StartTime *metav1.Time `json:"startTime,omitempty"`
81+
82+
// CompletionTime represents time when the workflow was completed. It is not guaranteed to
83+
// be set in happens-before order across separate operations.
84+
// It is represented in RFC3339 form and is in UTC.
85+
CompletionTime *metav1.Time `json:"completionTime,omitempty"`
86+
87+
// Statuses represent status of different steps
88+
Statuses []DaemonSetJobNodeJobStatus `json:"statuses"`
89+
}
90+
91+
// DaemonSetJobNodeJobStatus contains necessary information for the step status
92+
type DaemonSetJobNodeJobStatus struct {
93+
// Name represents the Name of the Step
94+
Name string `json:"name,omitempty"`
95+
// Complete reports the completion of status`
96+
Complete bool `json:"complete"`
97+
// Reference contains a reference to the DaemonSetJob JobNode
98+
Reference api.ObjectReference `json:"reference"`
99+
}
100+
101+
// DaemonSetJobCondition represent the condition of the DaemonSetJob
102+
type DaemonSetJobCondition struct {
103+
// Type of workflow condition
104+
Type DaemonSetJobConditionType `json:"type"`
105+
// Status of the condition, one of True, False, Unknown.
106+
Status api.ConditionStatus `json:"status"`
107+
// Last time the condition was checked.
108+
LastProbeTime metav1.Time `json:"lastProbeTime,omitempty"`
109+
// Last time the condition transited from one status to another.
110+
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
111+
// (brief) reason for the condition's last transition.
112+
Reason string `json:"reason,omitempty"`
113+
// Human readable message indicating details about last transition.
114+
Message string `json:"message,omitempty"`
115+
}
116+
117+
// DaemonSetJobConditionType is the type of DaemonSetJobCondition
118+
type DaemonSetJobConditionType string
119+
120+
// These are valid conditions of a workflow.
121+
const (
122+
// DaemonSetJobComplete means the workflow has completed its execution.
123+
DaemonSetJobComplete DaemonSetJobConditionType = "Complete"
124+
// DaemonSetJobFailed means the workflow has failed its execution.
125+
DaemonSetJobFailed DaemonSetJobConditionType = "Failed"
126+
)

pkg/api/daemonsetjob/v1/validation.go

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package v1
2+
3+
import (
4+
"k8s.io/apimachinery/pkg/api/validation"
5+
v1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
6+
"k8s.io/apimachinery/pkg/util/validation/field"
7+
)
8+
9+
// ValidateDaemonSetJob validates DaemonSetJob
10+
func ValidateDaemonSetJob(daemonsetjob *DaemonSetJob) field.ErrorList {
11+
allErrs := validation.ValidateObjectMeta(&daemonsetjob.ObjectMeta, true, validation.NameIsDNSSubdomain, field.NewPath("metadata"))
12+
allErrs = append(allErrs, ValidateDaemonSetJobSpec(&(daemonsetjob.Spec), field.NewPath("spec"))...)
13+
return allErrs
14+
}
15+
16+
// ValidateDaemonSetJobSpec validates DaemonSetJobSpec
17+
func ValidateDaemonSetJobSpec(spec *DaemonSetJobSpec, fieldPath *field.Path) field.ErrorList {
18+
allErrs := field.ErrorList{}
19+
if spec.ActiveDeadlineSeconds != nil {
20+
allErrs = append(allErrs, validation.ValidateNonnegativeField(int64(*spec.ActiveDeadlineSeconds), fieldPath.Child("activeDeadlineSeconds"))...)
21+
}
22+
if spec.Selector == nil {
23+
allErrs = append(allErrs, field.Required(fieldPath.Child("selector"), ""))
24+
} else {
25+
allErrs = append(allErrs, v1validation.ValidateLabelSelector(spec.Selector, fieldPath.Child("selector"))...)
26+
}
27+
// TODO: daemonsetjob.spec.selector must be convertible to labels.Set
28+
// TODO: JobsTemplate must not have any label confliciting with daemonsetjob.spec.selector
29+
return allErrs
30+
}

pkg/api/workflow/v1/default.go

+3-21
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
reflect "reflect"
55

66
batchv1 "k8s.io/api/batch/v1"
7+
8+
"github.com/amadeusitgroup/workflow-controller/pkg/api/common"
79
)
810

911
// IsWorkflowDefaulted check wether
@@ -23,29 +25,9 @@ func DefaultWorkflow(undefaultedWorkflow *Workflow) *Workflow {
2325
dummyJob := &batchv1.Job{
2426
Spec: step.JobTemplate.Spec,
2527
}
26-
SetDefaults_Job(dummyJob)
28+
common.SetDefaults_Job(dummyJob)
2729
step.JobTemplate.Spec = dummyJob.Spec
2830
w.Spec.Steps[i] = step
2931
}
3032
return w
3133
}
32-
33-
// SetDefaults_Job copied here function from k8s.io/kubernetes/pkg/apis/batch/v1/defaults.go
34-
func SetDefaults_Job(obj *batchv1.Job) {
35-
// For a non-parallel job, you can leave both `.spec.completions` and
36-
// `.spec.parallelism` unset. When both are unset, both are defaulted to 1.
37-
if obj.Spec.Completions == nil && obj.Spec.Parallelism == nil {
38-
obj.Spec.Completions = new(int32)
39-
*obj.Spec.Completions = 1
40-
obj.Spec.Parallelism = new(int32)
41-
*obj.Spec.Parallelism = 1
42-
}
43-
if obj.Spec.Parallelism == nil {
44-
obj.Spec.Parallelism = new(int32)
45-
*obj.Spec.Parallelism = 1
46-
}
47-
labels := obj.Spec.Template.Labels
48-
if labels != nil && len(obj.Labels) == 0 {
49-
obj.Labels = labels
50-
}
51-
}

0 commit comments

Comments
 (0)