This repository has been archived by the owner on Sep 5, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 159
Use pkg/webhook along with build webhook implementation #379
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
97bea78
Add validation & defaut for btmpl
2280b2f
add validation for cluster build template
7b7ecf3
Add validation and defaults for build
4a462d7
Use pkg webhook
432b2a4
compiles
a89dc49
Add webhook package
817a39c
Move tests
cba4a11
Add tests
496374f
webhook test
2c47a6c
cleanup unused code
58c05fe
Revert previous change
dddca9c
Add e2e tests for build with template and cluster template
0c21d5d
Fix typo
e328233
Fix test typo
64f2949
Increase coverage
80c7adc
Address comments
d2381d0
Add tests
864523c
Rename file to generic name
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package v1alpha1 | ||
|
||
import ( | ||
"time" | ||
|
||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
// DefaultTime is 10min | ||
const DefaultTimeout = 10 * time.Minute | ||
|
||
// SetDefaults for build | ||
func (b *Build) SetDefaults() { | ||
shashwathi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if b.Spec.ServiceAccountName == "" { | ||
b.Spec.ServiceAccountName = "default" | ||
} | ||
if b.Spec.Timeout.Duration == 0 { | ||
b.Spec.Timeout = metav1.Duration{Duration: DefaultTimeout} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package v1alpha1 | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
func TestSetDefault(t *testing.T) { | ||
shashwathi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
emptyBuild := &Build{} | ||
emptyBuild.SetDefaults() | ||
if emptyBuild.Spec.ServiceAccountName != "default" { | ||
t.Errorf("Expect default to be the serviceaccount name but got %s", emptyBuild.Spec.ServiceAccountName) | ||
} | ||
if emptyBuild.Spec.Timeout.Duration != DefaultTimeout { | ||
t.Errorf("Expect build timeout to be set") | ||
} | ||
} | ||
|
||
func TestAlreadySetDefault(t *testing.T) { | ||
setAccountName := "test-account-name" | ||
setTimeout := metav1.Duration{Duration: 20 * time.Minute} | ||
setDefaultBuild := &Build{ | ||
Spec: BuildSpec{ | ||
ServiceAccountName: setAccountName, | ||
Timeout: setTimeout, | ||
}, | ||
} | ||
setDefaultBuild.SetDefaults() | ||
if setDefaultBuild.Spec.ServiceAccountName != setAccountName { | ||
t.Errorf("Expect build.spec.serviceaccount name not to be overridden; but got %s", setDefaultBuild.Spec.ServiceAccountName) | ||
} | ||
if setDefaultBuild.Spec.Timeout != setTimeout { | ||
t.Errorf("Expect build.spec.timeout not to be overridden; but got %s", setDefaultBuild.Spec.Timeout) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package v1alpha1 | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/knative/pkg/apis" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
const ( | ||
maxLength = 63 | ||
) | ||
|
||
// Validate build template | ||
func (b *BuildTemplate) Validate() *apis.FieldError { | ||
return validateObjectMetadata(b.GetObjectMeta()).ViaField("metadata").Also(b.Spec.Validate().ViaField("spec")) | ||
} | ||
|
||
// Validate Build Template | ||
func (b *BuildTemplateSpec) Validate() *apis.FieldError { | ||
if err := validateSteps(b.Steps); err != nil { | ||
return err | ||
} | ||
if err := validateVolumes(b.Volumes); err != nil { | ||
return err | ||
} | ||
if err := validateParameters(b.Parameters); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func validateObjectMetadata(meta metav1.Object) *apis.FieldError { | ||
name := meta.GetName() | ||
|
||
if strings.Contains(name, ".") { | ||
return &apis.FieldError{ | ||
Message: "Invalid resource name: special character . must not be present", | ||
Paths: []string{"name"}, | ||
} | ||
} | ||
|
||
if len(name) > maxLength { | ||
return &apis.FieldError{ | ||
Message: "Invalid resource name: length must be no more than 63 characters", | ||
Paths: []string{"name"}, | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func validateParameters(params []ParameterSpec) *apis.FieldError { | ||
// Template must not duplicate parameter names. | ||
seen := map[string]struct{}{} | ||
for _, p := range params { | ||
if _, ok := seen[p.Name]; ok { | ||
return apis.ErrInvalidKeyName("ParamName", "b.spec.params") | ||
} | ||
seen[p.Name] = struct{}{} | ||
} | ||
return nil | ||
} | ||
|
||
func validateVolumes(volumes []corev1.Volume) *apis.FieldError { | ||
// Build must not duplicate volume names. | ||
vols := map[string]struct{}{} | ||
for _, v := range volumes { | ||
if _, ok := vols[v.Name]; ok { | ||
return apis.ErrMultipleOneOf("volumeName") | ||
} | ||
vols[v.Name] = struct{}{} | ||
} | ||
return nil | ||
} | ||
|
||
func validateSteps(steps []corev1.Container) *apis.FieldError { | ||
// Build must not duplicate step names. | ||
names := map[string]struct{}{} | ||
for _, s := range steps { | ||
if s.Image == "" { | ||
return apis.ErrMissingField("Image") | ||
} | ||
|
||
if s.Name == "" { | ||
continue | ||
} | ||
if _, ok := names[s.Name]; ok { | ||
return apis.ErrMultipleOneOf("stepName") | ||
} | ||
names[s.Name] = struct{}{} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package v1alpha1 | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/knative/pkg/apis" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
// Validate Build | ||
func (b *Build) Validate() *apis.FieldError { | ||
return validateObjectMetadata(b.GetObjectMeta()).ViaField("metadata").Also(b.Spec.Validate().ViaField("spec")) | ||
} | ||
|
||
// Validate for build spec | ||
func (bs *BuildSpec) Validate() *apis.FieldError { | ||
if bs.Template == nil && len(bs.Steps) == 0 { | ||
return apis.ErrMissingField("b.spec.template").Also(apis.ErrMissingField("b.spec.steps")) | ||
} | ||
if bs.Template != nil && len(bs.Steps) > 0 { | ||
return apis.ErrMissingField("b.spec.template").Also(apis.ErrMissingField("b.spec.steps")) | ||
} | ||
|
||
if bs.Template != nil && bs.Template.Name == "" { | ||
apis.ErrMissingField("build.spec.template.name") | ||
} | ||
|
||
// If a build specifies a template, all the template's parameters without | ||
// defaults must be satisfied by the build's parameters. | ||
//var volumes []corev1.Volume | ||
//var tmpl BuildTemplateInterface | ||
if bs.Template != nil { | ||
return bs.Template.Validate() | ||
} | ||
if err := validateVolumes(bs.Volumes); err != nil { | ||
return err | ||
} | ||
if err := validateTimeout(bs.Timeout); err != nil { | ||
return err | ||
} | ||
if err := validateSteps(bs.Steps); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// Validate templateKind | ||
func (b *TemplateInstantiationSpec) Validate() *apis.FieldError { | ||
if b.Name == "" { | ||
return apis.ErrMissingField("build.spec.template.name") | ||
} | ||
if b.Kind != "" { | ||
switch b.Kind { | ||
case ClusterBuildTemplateKind, | ||
BuildTemplateKind: | ||
return nil | ||
default: | ||
return apis.ErrInvalidValue(string(b.Kind), apis.CurrentField) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func validateTimeout(timeout metav1.Duration) *apis.FieldError { | ||
maxTimeout := time.Duration(24 * time.Hour) | ||
|
||
if timeout.Duration > maxTimeout { | ||
return apis.ErrInvalidValue(fmt.Sprintf("%s should be < 24h", timeout), "b.spec.timeout") | ||
} else if timeout.Duration < 0 { | ||
return apis.ErrInvalidValue(fmt.Sprintf("%s should be > 0", timeout), "b.spec.timeout") | ||
} | ||
return nil | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you confirm that the common infrastructure works properly with cluster-scoped resources, since AFAIK this is the first one we're trying :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool 👍
I have added e2e test for build with template and build with cluster template as well. Going forward we will have better coverage for these features