Merge pull request #4653 from thockin/secret_fixups

Secrets fixups
This commit is contained in:
Tim Hockin
2015-02-23 13:49:19 -08:00
21 changed files with 162 additions and 160 deletions

View File

@@ -116,6 +116,28 @@ func ValidateNamespaceName(name string, prefix bool) (bool, string) {
return nameIsDNSSubdomain(name, prefix)
}
// ValidateLimitRangeName can be used to check whether the given limit range name is valid.
// Prefix indicates this name will be used as part of generation, in which case
// trailing dashes are allowed.
func ValidateLimitRangeName(name string, prefix bool) (bool, string) {
return nameIsDNSSubdomain(name, prefix)
}
// ValidateResourceQuotaName can be used to check whether the given
// resource quota name is valid.
// Prefix indicates this name will be used as part of generation, in which case
// trailing dashes are allowed.
func ValidateResourceQuotaName(name string, prefix bool) (bool, string) {
return nameIsDNSSubdomain(name, prefix)
}
// ValidateSecretName can be used to check whether the given secret name is valid.
// Prefix indicates this name will be used as part of generation, in which case
// trailing dashes are allowed.
func ValidateSecretName(name string, prefix bool) (bool, string) {
return nameIsDNSSubdomain(name, prefix)
}
// nameIsDNSSubdomain is a ValidateNameFunc for names that must be a DNS subdomain.
func nameIsDNSSubdomain(name string, prefix bool) (bool, string) {
if prefix {
@@ -233,7 +255,7 @@ func validateSource(source *api.VolumeSource) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if source.HostPath != nil {
numVolumes++
allErrs = append(allErrs, validateHostPath(source.HostPath).Prefix("hostPath")...)
allErrs = append(allErrs, validateHostPathVolumeSource(source.HostPath).Prefix("hostPath")...)
}
if source.EmptyDir != nil {
numVolumes++
@@ -241,15 +263,15 @@ func validateSource(source *api.VolumeSource) errs.ValidationErrorList {
}
if source.GitRepo != nil {
numVolumes++
allErrs = append(allErrs, validateGitRepo(source.GitRepo).Prefix("gitRepo")...)
allErrs = append(allErrs, validateGitRepoVolumeSource(source.GitRepo).Prefix("gitRepo")...)
}
if source.GCEPersistentDisk != nil {
numVolumes++
allErrs = append(allErrs, validateGCEPersistentDisk(source.GCEPersistentDisk).Prefix("persistentDisk")...)
allErrs = append(allErrs, validateGCEPersistentDiskVolumeSource(source.GCEPersistentDisk).Prefix("persistentDisk")...)
}
if source.Secret != nil {
numVolumes++
allErrs = append(allErrs, validateSecretSource(source.Secret).Prefix("secret")...)
allErrs = append(allErrs, validateSecretVolumeSource(source.Secret).Prefix("secret")...)
}
if numVolumes != 1 {
allErrs = append(allErrs, errs.NewFieldInvalid("", source, "exactly 1 volume type is required"))
@@ -257,7 +279,7 @@ func validateSource(source *api.VolumeSource) errs.ValidationErrorList {
return allErrs
}
func validateHostPath(hostDir *api.HostPath) errs.ValidationErrorList {
func validateHostPathVolumeSource(hostDir *api.HostPathVolumeSource) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if hostDir.Path == "" {
allErrs = append(allErrs, errs.NewFieldRequired("path", hostDir.Path))
@@ -265,7 +287,7 @@ func validateHostPath(hostDir *api.HostPath) errs.ValidationErrorList {
return allErrs
}
func validateGitRepo(gitRepo *api.GitRepo) errs.ValidationErrorList {
func validateGitRepoVolumeSource(gitRepo *api.GitRepoVolumeSource) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if gitRepo.Repository == "" {
allErrs = append(allErrs, errs.NewFieldRequired("repository", gitRepo.Repository))
@@ -273,7 +295,7 @@ func validateGitRepo(gitRepo *api.GitRepo) errs.ValidationErrorList {
return allErrs
}
func validateGCEPersistentDisk(PD *api.GCEPersistentDisk) errs.ValidationErrorList {
func validateGCEPersistentDiskVolumeSource(PD *api.GCEPersistentDiskVolumeSource) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if PD.PDName == "" {
allErrs = append(allErrs, errs.NewFieldRequired("pdName", PD.PDName))
@@ -287,7 +309,7 @@ func validateGCEPersistentDisk(PD *api.GCEPersistentDisk) errs.ValidationErrorLi
return allErrs
}
func validateSecretSource(secretSource *api.SecretSource) errs.ValidationErrorList {
func validateSecretVolumeSource(secretSource *api.SecretVolumeSource) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if secretSource.Target.Name == "" {
allErrs = append(allErrs, errs.NewFieldRequired("target.name", ""))
@@ -815,16 +837,8 @@ func validateResourceName(value string, field string) errs.ValidationErrorList {
// ValidateLimitRange tests if required fields in the LimitRange are set.
func ValidateLimitRange(limitRange *api.LimitRange) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if len(limitRange.Name) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("name", limitRange.Name))
} else if !util.IsDNSSubdomain(limitRange.Name) {
allErrs = append(allErrs, errs.NewFieldInvalid("name", limitRange.Name, dnsSubdomainErrorMsg))
}
if len(limitRange.Namespace) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("namespace", limitRange.Namespace))
} else if !util.IsDNSSubdomain(limitRange.Namespace) {
allErrs = append(allErrs, errs.NewFieldInvalid("namespace", limitRange.Namespace, dnsSubdomainErrorMsg))
}
allErrs = append(allErrs, ValidateObjectMeta(&limitRange.ObjectMeta, true, ValidateLimitRangeName).Prefix("metadata")...)
// ensure resource names are properly qualified per docs/resources.md
for i := range limitRange.Spec.Limits {
limit := limitRange.Spec.Limits[i]
@@ -841,21 +855,12 @@ func ValidateLimitRange(limitRange *api.LimitRange) errs.ValidationErrorList {
// ValidateSecret tests if required fields in the Secret are set.
func ValidateSecret(secret *api.Secret) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if len(secret.Name) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("name", secret.Name))
} else if !util.IsDNSSubdomain(secret.Name) {
allErrs = append(allErrs, errs.NewFieldInvalid("name", secret.Name, ""))
}
if len(secret.Namespace) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("namespace", secret.Namespace))
} else if !util.IsDNSSubdomain(secret.Namespace) {
allErrs = append(allErrs, errs.NewFieldInvalid("namespace", secret.Namespace, ""))
}
allErrs = append(allErrs, ValidateObjectMeta(&secret.ObjectMeta, true, ValidateSecretName).Prefix("metadata")...)
totalSize := 0
for key, value := range secret.Data {
if !util.IsDNSSubdomain(key) {
allErrs = append(allErrs, errs.NewFieldInvalid(fmt.Sprintf("data[%v]", key), key, cIdentifierErrorMsg))
allErrs = append(allErrs, errs.NewFieldInvalid(fmt.Sprintf("data[%s]", key), key, cIdentifierErrorMsg))
}
totalSize += len(value)
@@ -893,16 +898,8 @@ func validateResourceRequirements(container *api.Container) errs.ValidationError
// ValidateResourceQuota tests if required fields in the ResourceQuota are set.
func ValidateResourceQuota(resourceQuota *api.ResourceQuota) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if len(resourceQuota.Name) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("name", resourceQuota.Name))
} else if !util.IsDNSSubdomain(resourceQuota.Name) {
allErrs = append(allErrs, errs.NewFieldInvalid("name", resourceQuota.Name, dnsSubdomainErrorMsg))
}
if len(resourceQuota.Namespace) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("namespace", resourceQuota.Namespace))
} else if !util.IsDNSSubdomain(resourceQuota.Namespace) {
allErrs = append(allErrs, errs.NewFieldInvalid("namespace", resourceQuota.Namespace, dnsSubdomainErrorMsg))
}
allErrs = append(allErrs, ValidateObjectMeta(&resourceQuota.ObjectMeta, true, ValidateResourceQuotaName).Prefix("metadata")...)
for k := range resourceQuota.Spec.Hard {
allErrs = append(allErrs, validateResourceName(string(k), string(resourceQuota.TypeMeta.Kind))...)
}

View File

@@ -147,13 +147,13 @@ func TestValidateAnnotations(t *testing.T) {
func TestValidateVolumes(t *testing.T) {
successCase := []api.Volume{
{Name: "abc", Source: api.VolumeSource{HostPath: &api.HostPath{"/mnt/path1"}}},
{Name: "123", Source: api.VolumeSource{HostPath: &api.HostPath{"/mnt/path2"}}},
{Name: "abc-123", Source: api.VolumeSource{HostPath: &api.HostPath{"/mnt/path3"}}},
{Name: "empty", Source: api.VolumeSource{EmptyDir: &api.EmptyDir{}}},
{Name: "gcepd", Source: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDisk{"my-PD", "ext4", 1, false}}},
{Name: "gitrepo", Source: api.VolumeSource{GitRepo: &api.GitRepo{"my-repo", "hashstring"}}},
{Name: "secret", Source: api.VolumeSource{Secret: &api.SecretSource{api.ObjectReference{Namespace: api.NamespaceDefault, Name: "my-secret", Kind: "Secret"}}}},
{Name: "abc", Source: api.VolumeSource{HostPath: &api.HostPathVolumeSource{"/mnt/path1"}}},
{Name: "123", Source: api.VolumeSource{HostPath: &api.HostPathVolumeSource{"/mnt/path2"}}},
{Name: "abc-123", Source: api.VolumeSource{HostPath: &api.HostPathVolumeSource{"/mnt/path3"}}},
{Name: "empty", Source: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
{Name: "gcepd", Source: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{"my-PD", "ext4", 1, false}}},
{Name: "gitrepo", Source: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{"my-repo", "hashstring"}}},
{Name: "secret", Source: api.VolumeSource{Secret: &api.SecretVolumeSource{api.ObjectReference{Namespace: api.NamespaceDefault, Name: "my-secret", Kind: "Secret"}}}},
}
names, errs := validateVolumes(successCase)
if len(errs) != 0 {
@@ -162,7 +162,7 @@ func TestValidateVolumes(t *testing.T) {
if len(names) != len(successCase) || !names.HasAll("abc", "123", "abc-123", "empty", "gcepd", "gitrepo", "secret") {
t.Errorf("wrong names result: %v", names)
}
emptyVS := api.VolumeSource{EmptyDir: &api.EmptyDir{}}
emptyVS := api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}
errorCases := map[string]struct {
V []api.Volume
T errors.ValidationErrorType
@@ -573,8 +573,8 @@ func TestValidateManifest(t *testing.T) {
{
Version: "v1beta1",
ID: "abc",
Volumes: []api.Volume{{Name: "vol1", Source: api.VolumeSource{HostPath: &api.HostPath{"/mnt/vol1"}}},
{Name: "vol2", Source: api.VolumeSource{HostPath: &api.HostPath{"/mnt/vol2"}}}},
Volumes: []api.Volume{{Name: "vol1", Source: api.VolumeSource{HostPath: &api.HostPathVolumeSource{"/mnt/vol1"}}},
{Name: "vol2", Source: api.VolumeSource{HostPath: &api.HostPathVolumeSource{"/mnt/vol2"}}}},
Containers: []api.Container{
{
Name: "abc",
@@ -624,7 +624,7 @@ func TestValidateManifest(t *testing.T) {
"invalid volume name": {
Version: "v1beta1",
ID: "abc",
Volumes: []api.Volume{{Name: "vol.1", Source: api.VolumeSource{EmptyDir: &api.EmptyDir{}}}},
Volumes: []api.Volume{{Name: "vol.1", Source: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}},
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
DNSPolicy: api.DNSClusterFirst,
},
@@ -647,14 +647,14 @@ func TestValidateManifest(t *testing.T) {
func TestValidatePodSpec(t *testing.T) {
successCases := []api.PodSpec{
{ // Populate basic fields, leave defaults for most.
Volumes: []api.Volume{{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDir{}}}},
Volumes: []api.Volume{{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}},
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
DNSPolicy: api.DNSClusterFirst,
},
{ // Populate all fields.
Volumes: []api.Volume{
{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDir{}}},
{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
},
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
@@ -703,7 +703,7 @@ func TestValidatePod(t *testing.T) {
{ // Basic fields.
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: "ns"},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDir{}}}},
Volumes: []api.Volume{{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}},
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
DNSPolicy: api.DNSClusterFirst,
@@ -713,7 +713,7 @@ func TestValidatePod(t *testing.T) {
ObjectMeta: api.ObjectMeta{Name: "abc.123.do-re-mi", Namespace: "ns"},
Spec: api.PodSpec{
Volumes: []api.Volume{
{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDir{}}},
{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
},
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
@@ -1005,7 +1005,7 @@ func TestValidateBoundPods(t *testing.T) {
{ // Basic fields.
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: "ns"},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDir{}}}},
Volumes: []api.Volume{{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}},
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
DNSPolicy: api.DNSClusterFirst,
@@ -1015,7 +1015,7 @@ func TestValidateBoundPods(t *testing.T) {
ObjectMeta: api.ObjectMeta{Name: "abc.123.do-re-mi", Namespace: "ns"},
Spec: api.PodSpec{
Volumes: []api.Volume{
{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDir{}}},
{Name: "vol", Source: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
},
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
@@ -1477,7 +1477,7 @@ func TestValidateReplicationControllerUpdate(t *testing.T) {
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
DNSPolicy: api.DNSClusterFirst,
Volumes: []api.Volume{{Name: "gcepd", Source: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDisk{"my-PD", "ext4", 1, false}}}},
Volumes: []api.Volume{{Name: "gcepd", Source: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{"my-PD", "ext4", 1, false}}}},
},
},
}
@@ -1635,7 +1635,7 @@ func TestValidateReplicationController(t *testing.T) {
Labels: validSelector,
},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "gcepd", Source: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDisk{"my-PD", "ext4", 1, false}}}},
Volumes: []api.Volume{{Name: "gcepd", Source: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{"my-PD", "ext4", 1, false}}}},
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
DNSPolicy: api.DNSClusterFirst,
},
@@ -2302,8 +2302,7 @@ func TestValidateLimitRange(t *testing.T) {
for i := range errs {
field := errs[i].(*errors.ValidationError).Field
detail := errs[i].(*errors.ValidationError).Detail
if field != "name" &&
field != "namespace" {
if field != "metadata.name" && field != "metadata.namespace" {
t.Errorf("%s: missing prefix for: %v", k, errs[i])
}
if detail != v.D {
@@ -2370,8 +2369,7 @@ func TestValidateResourceQuota(t *testing.T) {
for i := range errs {
field := errs[i].(*errors.ValidationError).Field
detail := errs[i].(*errors.ValidationError).Detail
if field != "name" &&
field != "namespace" {
if field != "metadata.name" && field != "metadata.namespace" {
t.Errorf("%s: missing prefix for: %v", k, errs[i])
}
if detail != v.D {