Example #1
0
func ValidateIdentity(identity *api.Identity) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}
	allErrs = append(allErrs, kvalidation.ValidateObjectMeta(&identity.ObjectMeta, false, ValidateIdentityName).Prefix("metadata")...)

	if len(identity.ProviderName) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("providerName"))
	} else if ok, msg := ValidateIdentityProviderName(identity.ProviderName); !ok {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("providerName", identity.ProviderName, msg))
	}

	if len(identity.ProviderUserName) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("providerUserName"))
	} else if ok, msg := ValidateIdentityProviderName(identity.ProviderUserName); !ok {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("providerUserName", identity.ProviderUserName, msg))
	}

	if len(identity.ProviderName) > 0 && len(identity.ProviderUserName) > 0 {
		expectedIdentityName := identity.ProviderName + ":" + identity.ProviderUserName
		if identity.Name != expectedIdentityName {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("user.name", identity.User.Name, fmt.Sprintf("must be %s", expectedIdentityName)))
		}
	}

	if ok, msg := ValidateUserName(identity.User.Name, false); !ok {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("user.name", identity.User.Name, msg))
	}
	if len(identity.User.Name) == 0 && len(identity.User.UID) != 0 {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("user.uid", identity.User.UID, "may not be set if user.name is empty"))
	}
	if len(identity.User.Name) != 0 && len(identity.User.UID) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("user.uid"))
	}
	return allErrs
}
Example #2
0
// ValidateDaemonSetSpec tests if required fields in the DaemonSetSpec are set.
func ValidateDaemonSetSpec(spec *experimental.DaemonSetSpec) errs.ValidationErrorList {
	allErrs := errs.ValidationErrorList{}

	selector := labels.Set(spec.Selector).AsSelector()
	if selector.Empty() {
		allErrs = append(allErrs, errs.NewFieldRequired("selector"))
	}

	if spec.Template == nil {
		allErrs = append(allErrs, errs.NewFieldRequired("template"))
	} else {
		labels := labels.Set(spec.Template.Labels)
		if !selector.Matches(labels) {
			allErrs = append(allErrs, errs.NewFieldInvalid("template.metadata.labels", spec.Template.Labels, "selector does not match template"))
		}
		allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(spec.Template).Prefix("template")...)
		// Daemons typically run on more than one node, so mark Read-Write persistent disks as invalid.
		allErrs = append(allErrs, apivalidation.ValidateReadOnlyPersistentDisks(spec.Template.Spec.Volumes).Prefix("template.spec.volumes")...)
		// RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec().
		if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways {
			allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy", spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)}))
		}
	}
	return allErrs
}
Example #3
0
func validateStrategy(strategy *buildapi.BuildStrategy) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}

	switch {
	case len(strategy.Type) == 0:
		allErrs = append(allErrs, fielderrors.NewFieldRequired("type"))

	case strategy.Type == buildapi.SourceBuildStrategyType:
		if strategy.SourceStrategy == nil {
			allErrs = append(allErrs, fielderrors.NewFieldRequired("stiStrategy"))
		} else {
			allErrs = append(allErrs, validateSourceStrategy(strategy.SourceStrategy).Prefix("stiStrategy")...)
		}

	case strategy.Type == buildapi.DockerBuildStrategyType:
		if strategy.DockerStrategy == nil {
			allErrs = append(allErrs, fielderrors.NewFieldRequired("dockerStrategy"))
		} else {
			allErrs = append(allErrs, validateDockerStrategy(strategy.DockerStrategy).Prefix("dockerStrategy")...)
		}

	case strategy.Type == buildapi.CustomBuildStrategyType:
		if strategy.CustomStrategy == nil {
			allErrs = append(allErrs, fielderrors.NewFieldRequired("customStrategy"))
		} else {
			allErrs = append(allErrs, validateCustomStrategy(strategy.CustomStrategy).Prefix("customStrategy")...)
		}
	default:
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("type", strategy.Type, "type is not in the enumerated list"))
	}

	return allErrs
}
Example #4
0
// ValidateImageStreamMapping tests required fields for an ImageStreamMapping.
func ValidateImageStreamMapping(mapping *api.ImageStreamMapping) fielderrors.ValidationErrorList {
	result := fielderrors.ValidationErrorList{}
	result = append(result, validation.ValidateObjectMeta(&mapping.ObjectMeta, true, oapi.MinimalNameRequirements).Prefix("metadata")...)

	hasRepository := len(mapping.DockerImageRepository) != 0
	hasName := len(mapping.Name) != 0
	switch {
	case hasRepository:
		if _, err := api.ParseDockerImageReference(mapping.DockerImageRepository); err != nil {
			result = append(result, fielderrors.NewFieldInvalid("dockerImageRepository", mapping.DockerImageRepository, err.Error()))
		}
	case hasName:
	default:
		result = append(result, fielderrors.NewFieldRequired("name"))
		result = append(result, fielderrors.NewFieldRequired("dockerImageRepository"))
	}

	if ok, msg := validation.ValidateNamespaceName(mapping.Namespace, false); !ok {
		result = append(result, fielderrors.NewFieldInvalid("namespace", mapping.Namespace, msg))
	}
	if len(mapping.Tag) == 0 {
		result = append(result, fielderrors.NewFieldRequired("tag"))
	}
	if errs := ValidateImage(&mapping.Image).Prefix("image"); len(errs) != 0 {
		result = append(result, errs...)
	}
	return result
}
Example #5
0
func ValidateNodeAuthConfig(config api.NodeAuthConfig) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}

	if len(config.AuthenticationCacheTTL) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("authenticationCacheTTL"))
	} else if ttl, err := time.ParseDuration(config.AuthenticationCacheTTL); err != nil {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("authenticationCacheTTL", config.AuthenticationCacheTTL, fmt.Sprintf("%v", err)))
	} else if ttl < 0 {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("authenticationCacheTTL", config.AuthenticationCacheTTL, fmt.Sprintf("cannot be less than zero")))
	}

	if config.AuthenticationCacheSize <= 0 {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("authenticationCacheSize", config.AuthenticationCacheSize, fmt.Sprintf("must be greater than zero")))
	}

	if len(config.AuthorizationCacheTTL) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("authorizationCacheTTL"))
	} else if ttl, err := time.ParseDuration(config.AuthorizationCacheTTL); err != nil {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("authorizationCacheTTL", config.AuthorizationCacheTTL, fmt.Sprintf("%v", err)))
	} else if ttl < 0 {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("authorizationCacheTTL", config.AuthorizationCacheTTL, fmt.Sprintf("cannot be less than zero")))
	}

	if config.AuthorizationCacheSize <= 0 {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("authorizationCacheSize", config.AuthorizationCacheSize, fmt.Sprintf("must be greater than zero")))
	}

	return allErrs
}
Example #6
0
func validateSource(input *buildapi.BuildSource) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}
	switch input.Type {
	case buildapi.BuildSourceGit:
		if input.Git == nil {
			allErrs = append(allErrs, fielderrors.NewFieldRequired("git"))
		} else {
			allErrs = append(allErrs, validateGitSource(input.Git).Prefix("git")...)
		}
		if input.Dockerfile != nil {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("dockerfile", "", "may not be set when type is Git"))
		}
	case buildapi.BuildSourceDockerfile:
		if input.Dockerfile == nil {
			allErrs = append(allErrs, fielderrors.NewFieldRequired("dockerfile"))
		} else {
			if len(*input.Dockerfile) > maxDockerfileLengthBytes {
				allErrs = append(allErrs, fielderrors.NewFieldInvalid("dockerfile", "", fmt.Sprintf("must be smaller than %d bytes", maxDockerfileLengthBytes)))
			}
		}
		if input.Git != nil {
			allErrs = append(allErrs, validateGitSource(input.Git).Prefix("git")...)
		}
	case "":
		allErrs = append(allErrs, fielderrors.NewFieldRequired("type"))
	}
	allErrs = append(allErrs, validateSecretRef(input.SourceSecret).Prefix("sourceSecret")...)
	return allErrs
}
Example #7
0
func ValidateJobSpec(spec *experimental.JobSpec) errs.ValidationErrorList {
	allErrs := errs.ValidationErrorList{}

	if spec.Parallelism != nil && *spec.Parallelism < 0 {
		allErrs = append(allErrs, errs.NewFieldInvalid("parallelism", spec.Parallelism, isNegativeErrorMsg))
	}
	if spec.Completions != nil && *spec.Completions < 0 {
		allErrs = append(allErrs, errs.NewFieldInvalid("completions", spec.Completions, isNegativeErrorMsg))
	}

	selector := labels.Set(spec.Selector).AsSelector()
	if selector.Empty() {
		allErrs = append(allErrs, errs.NewFieldRequired("selector"))
	}

	if spec.Template == nil {
		allErrs = append(allErrs, errs.NewFieldRequired("template"))
	} else {
		labels := labels.Set(spec.Template.Labels)
		if !selector.Matches(labels) {
			allErrs = append(allErrs, errs.NewFieldInvalid("template.labels", spec.Template.Labels, "selector does not match template"))
		}
		allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(spec.Template).Prefix("template")...)
		if spec.Template.Spec.RestartPolicy != api.RestartPolicyOnFailure &&
			spec.Template.Spec.RestartPolicy != api.RestartPolicyNever {
			allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy",
				spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyOnFailure), string(api.RestartPolicyNever)}))
		}
	}
	return allErrs
}
Example #8
0
func ValidateRFC2307Config(config *api.RFC2307Config) ValidationResults {
	validationResults := ValidationResults{}

	groupQueryResults := ValidateLDAPQuery("groupQuery", config.GroupQuery)
	validationResults.AddErrors(groupQueryResults.Errors...)
	validationResults.AddWarnings(groupQueryResults.Warnings...)

	if len(config.GroupNameAttributes) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("groupName"))
	}

	if len(config.GroupMembershipAttributes) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("groupMembership"))
	}

	userQueryResults := ValidateLDAPQuery("userQuery", config.UserQuery)
	validationResults.AddErrors(userQueryResults.Errors...)
	validationResults.AddWarnings(userQueryResults.Warnings...)

	if len(config.UserNameAttributes) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("userName"))
	}

	return validationResults
}
Example #9
0
// ValidateRoute tests if required fields in the route are set.
func ValidateRoute(route *routeapi.Route) fielderrors.ValidationErrorList {
	result := fielderrors.ValidationErrorList{}

	//ensure meta is set properly
	result = append(result, kval.ValidateObjectMeta(&route.ObjectMeta, true, oapi.GetNameValidationFunc(kval.ValidatePodName)).Prefix("metadata")...)

	//host is not required but if it is set ensure it meets DNS requirements
	if len(route.Spec.Host) > 0 {
		if !util.IsDNS1123Subdomain(route.Spec.Host) {
			result = append(result, fielderrors.NewFieldInvalid("host", route.Spec.Host, "host must conform to DNS 952 subdomain conventions"))
		}
	}

	if len(route.Spec.Path) > 0 && !strings.HasPrefix(route.Spec.Path, "/") {
		result = append(result, fielderrors.NewFieldInvalid("path", route.Spec.Path, "path must begin with /"))
	}

	if len(route.Spec.To.Name) == 0 {
		result = append(result, fielderrors.NewFieldRequired("serviceName"))
	}

	if route.Spec.Port != nil {
		switch target := route.Spec.Port.TargetPort; {
		case target.Kind == util.IntstrInt && target.IntVal == 0,
			target.Kind == util.IntstrString && len(target.StrVal) == 0:
			result = append(result, fielderrors.NewFieldRequired("targetPort"))
		}
	}

	if errs := validateTLS(route); len(errs) != 0 {
		result = append(result, errs.Prefix("tls")...)
	}

	return result
}
Example #10
0
func validateImageChangeParams(params *deployapi.DeploymentTriggerImageChangeParams) fielderrors.ValidationErrorList {
	errs := fielderrors.ValidationErrorList{}

	if len(params.From.Name) != 0 {
		if len(params.From.Kind) == 0 {
			params.From.Kind = "ImageStream"
		}
		kinds := util.NewStringSet("ImageRepository", "ImageStream", "ImageStreamTag")
		if !kinds.Has(params.From.Kind) {
			msg := fmt.Sprintf("kind must be one of: %s", strings.Join(kinds.List(), ", "))
			errs = append(errs, fielderrors.NewFieldInvalid("from.kind", params.From.Kind, msg))
		}

		if !util.IsDNS1123Subdomain(params.From.Name) {
			errs = append(errs, fielderrors.NewFieldInvalid("from.name", params.From.Name, "name must be a valid subdomain"))
		}
		if len(params.From.Namespace) != 0 && !util.IsDNS1123Subdomain(params.From.Namespace) {
			errs = append(errs, fielderrors.NewFieldInvalid("from.namespace", params.From.Namespace, "namespace must be a valid subdomain"))
		}

		if len(params.RepositoryName) != 0 {
			errs = append(errs, fielderrors.NewFieldInvalid("repositoryName", params.RepositoryName, "only one of 'from', 'repository' name may be specified"))
		}
	} else {
		if len(params.RepositoryName) == 0 {
			errs = append(errs, fielderrors.NewFieldRequired("from"))
		}
	}

	if len(params.ContainerNames) == 0 {
		errs = append(errs, fielderrors.NewFieldRequired("containerNames"))
	}

	return errs
}
Example #11
0
func validateToImageReference(reference *kapi.ObjectReference) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}
	kind, name, namespace := reference.Kind, reference.Name, reference.Namespace
	switch kind {
	case "ImageStreamTag":
		if len(name) == 0 {
			allErrs = append(allErrs, fielderrors.NewFieldRequired("name"))
		} else if _, _, ok := imageapi.SplitImageStreamTag(name); !ok {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("name", name, "ImageStreamTag object references must be in the form <name>:<tag>"))
		}
		if len(namespace) != 0 && !kvalidation.IsDNS1123Subdomain(namespace) {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("namespace", namespace, "namespace must be a valid subdomain"))
		}

	case "DockerImage":
		if len(namespace) != 0 {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("namespace", namespace, "namespace is not valid when used with a 'DockerImage'"))
		}
		if _, err := imageapi.ParseDockerImageReference(name); err != nil {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("name", name, fmt.Sprintf("name is not a valid Docker pull specification: %v", err)))
		}
	case "":
		allErrs = append(allErrs, fielderrors.NewFieldRequired("kind"))
	default:
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("kind", kind, "the target of build output must be an 'ImageStreamTag' or 'DockerImage'"))

	}
	return allErrs
}
Example #12
0
func validateDeploymentStrategy(strategy *deployapi.DeploymentStrategy) fielderrors.ValidationErrorList {
	errs := fielderrors.ValidationErrorList{}

	if len(strategy.Type) == 0 {
		errs = append(errs, fielderrors.NewFieldRequired("type"))
	}

	switch strategy.Type {
	case deployapi.DeploymentStrategyTypeRecreate:
		if strategy.RecreateParams != nil {
			errs = append(errs, validateRecreateParams(strategy.RecreateParams).Prefix("recreateParams")...)
		}
	case deployapi.DeploymentStrategyTypeRolling:
		if strategy.RollingParams == nil {
			errs = append(errs, fielderrors.NewFieldRequired("rollingParams"))
		} else {
			errs = append(errs, validateRollingParams(strategy.RollingParams).Prefix("rollingParams")...)
		}
	case deployapi.DeploymentStrategyTypeCustom:
		if strategy.CustomParams == nil {
			errs = append(errs, fielderrors.NewFieldRequired("customParams"))
		} else {
			errs = append(errs, validateCustomParams(strategy.CustomParams).Prefix("customParams")...)
		}
	}

	// TODO: validate resource requirements (prereq: https://github.com/GoogleCloudPlatform/kubernetes/pull/7059)

	return errs
}
Example #13
0
func ValidateRoleBindingSubject(subject kapi.ObjectReference, isNamespaced bool) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}

	if len(subject.Name) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("name"))
	}
	if len(subject.UID) != 0 {
		allErrs = append(allErrs, fielderrors.NewFieldForbidden("uid", subject.UID))
	}
	if len(subject.APIVersion) != 0 {
		allErrs = append(allErrs, fielderrors.NewFieldForbidden("apiVersion", subject.APIVersion))
	}
	if len(subject.ResourceVersion) != 0 {
		allErrs = append(allErrs, fielderrors.NewFieldForbidden("resourceVersion", subject.ResourceVersion))
	}
	if len(subject.FieldPath) != 0 {
		allErrs = append(allErrs, fielderrors.NewFieldForbidden("fieldPath", subject.FieldPath))
	}

	switch subject.Kind {
	case authorizationapi.ServiceAccountKind:
		if valid, reason := validation.ValidateServiceAccountName(subject.Name, false); len(subject.Name) > 0 && !valid {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("name", subject.Name, reason))
		}
		if !isNamespaced && len(subject.Namespace) == 0 {
			allErrs = append(allErrs, fielderrors.NewFieldRequired("namespace"))
		}

	case authorizationapi.UserKind:
		if valid, reason := uservalidation.ValidateUserName(subject.Name, false); len(subject.Name) > 0 && !valid {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("name", subject.Name, reason))
		}

	case authorizationapi.GroupKind:
		if valid, reason := uservalidation.ValidateGroupName(subject.Name, false); len(subject.Name) > 0 && !valid {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("name", subject.Name, reason))
		}

	case authorizationapi.SystemUserKind:
		isValidSAName, _ := validation.ValidateServiceAccountName(subject.Name, false)
		isValidUserName, _ := uservalidation.ValidateUserName(subject.Name, false)
		if isValidSAName || isValidUserName {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("name", subject.Name, "conforms to User.name or ServiceAccount.name restrictions"))
		}

	case authorizationapi.SystemGroupKind:
		if valid, _ := uservalidation.ValidateGroupName(subject.Name, false); len(subject.Name) > 0 && valid {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("name", subject.Name, "conforms to Group.name restrictions"))
		}

	default:
		allErrs = append(allErrs, fielderrors.NewFieldValueNotSupported("kind", subject.Kind, []string{authorizationapi.ServiceAccountKind, authorizationapi.UserKind, authorizationapi.GroupKind, authorizationapi.SystemGroupKind, authorizationapi.SystemUserKind}))
	}

	return allErrs
}
Example #14
0
func ValidateRequestHeaderIdentityProvider(provider *api.RequestHeaderIdentityProvider, identityProvider api.IdentityProvider) ValidationResults {
	validationResults := ValidationResults{}

	if len(provider.ClientCA) > 0 {
		validationResults.AddErrors(ValidateFile(provider.ClientCA, "provider.clientCA")...)
	}
	if len(provider.Headers) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("provider.headers"))
	}
	if identityProvider.UseAsChallenger && len(provider.ChallengeURL) == 0 {
		err := fielderrors.NewFieldRequired("provider.challengeURL")
		err.Detail = "challengeURL is required if challenge=true"
		validationResults.AddErrors(err)
	}
	if identityProvider.UseAsLogin && len(provider.LoginURL) == 0 {
		err := fielderrors.NewFieldRequired("provider.loginURL")
		err.Detail = "loginURL is required if login=true"
		validationResults.AddErrors(err)
	}

	if len(provider.ChallengeURL) > 0 {
		url, urlErrs := ValidateURL(provider.ChallengeURL, "provider.challengeURL")
		validationResults.AddErrors(urlErrs...)
		if len(urlErrs) == 0 && !strings.Contains(url.RawQuery, redirector.URLToken) && !strings.Contains(url.RawQuery, redirector.QueryToken) {
			validationResults.AddWarnings(
				fielderrors.NewFieldInvalid(
					"provider.challengeURL",
					provider.ChallengeURL,
					fmt.Sprintf("query does not include %q or %q, redirect will not preserve original authorize parameters", redirector.URLToken, redirector.QueryToken),
				),
			)
		}
	}
	if len(provider.LoginURL) > 0 {
		url, urlErrs := ValidateURL(provider.LoginURL, "provider.loginURL")
		validationResults.AddErrors(urlErrs...)
		if len(urlErrs) == 0 && !strings.Contains(url.RawQuery, redirector.URLToken) && !strings.Contains(url.RawQuery, redirector.QueryToken) {
			validationResults.AddWarnings(
				fielderrors.NewFieldInvalid(
					"provider.loginURL",
					provider.LoginURL,
					fmt.Sprintf("query does not include %q or %q, redirect will not preserve original authorize parameters", redirector.URLToken, redirector.QueryToken),
				),
			)
		}
	}

	// Warn if it looks like they expect direct requests to the OAuth endpoints, and have not secured the header checking with a client certificate check
	if len(provider.ClientCA) == 0 && (len(provider.ChallengeURL) > 0 || len(provider.LoginURL) > 0) {
		validationResults.AddWarnings(fielderrors.NewFieldInvalid("provider.clientCA", "", "if no clientCA is set, no request verification is done, and any request directly against the OAuth server can impersonate any identity from this provider"))
	}

	return validationResults
}
Example #15
0
func ValidateResourceAccessReview(review *authorizationapi.ResourceAccessReview) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}

	if len(review.Verb) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("verb"))
	}
	if len(review.Resource) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("resource"))
	}

	return allErrs
}
Example #16
0
func ValidateActiveDirectoryConfig(config *api.ActiveDirectoryConfig) ValidationResults {
	validationResults := ValidationResults{}

	validationResults.Append(ValidateLDAPQuery(config.AllUsersQuery).Prefix("usersQuery"))
	if len(config.UserNameAttributes) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("userNameAttributes"))
	}
	if len(config.GroupMembershipAttributes) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("groupMembershipAttributes"))
	}

	return validationResults
}
Example #17
0
func validateSource(input *buildapi.BuildSource) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}
	if input.Type != buildapi.BuildSourceGit {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("type"))
	}
	if input.Git == nil {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("git"))
	} else {
		allErrs = append(allErrs, validateGitSource(input.Git).Prefix("git")...)
	}
	allErrs = append(allErrs, validateSecretRef(input.SourceSecret).Prefix("sourceSecret")...)
	return allErrs
}
Example #18
0
func ValidateUserIdentityMapping(mapping *api.UserIdentityMapping) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}
	allErrs = append(allErrs, kvalidation.ValidateObjectMeta(&mapping.ObjectMeta, false, ValidateIdentityName).Prefix("metadata")...)
	if len(mapping.Identity.Name) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("identity.name"))
	}
	if mapping.Identity.Name != mapping.Name {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("identity.name", mapping.Identity.Name, "must match metadata.name"))
	}
	if len(mapping.User.Name) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("user.name"))
	}
	return allErrs
}
Example #19
0
func ValidateOAuthConfig(config *api.OAuthConfig) ValidationResults {
	validationResults := ValidationResults{}

	if len(config.MasterURL) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("masterURL"))
	}

	if _, urlErrs := ValidateURL(config.MasterPublicURL, "masterPublicURL"); len(urlErrs) > 0 {
		validationResults.AddErrors(urlErrs...)
	}

	if len(config.AssetPublicURL) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("assetPublicURL"))
	}

	if config.SessionConfig != nil {
		validationResults.AddErrors(ValidateSessionConfig(config.SessionConfig).Prefix("sessionConfig")...)
	}

	validationResults.AddErrors(ValidateGrantConfig(config.GrantConfig).Prefix("grantConfig")...)

	providerNames := util.NewStringSet()
	redirectingIdentityProviders := []string{}
	for i, identityProvider := range config.IdentityProviders {
		if identityProvider.UseAsLogin {
			redirectingIdentityProviders = append(redirectingIdentityProviders, identityProvider.Name)

			if api.IsPasswordAuthenticator(identityProvider) {
				if config.SessionConfig == nil {
					validationResults.AddErrors(fielderrors.NewFieldInvalid("sessionConfig", config, "sessionConfig is required if a password identity provider is used for browser based login"))
				}
			}
		}

		validationResults.Append(ValidateIdentityProvider(identityProvider).Prefix(fmt.Sprintf("identityProvider[%d]", i)))

		if len(identityProvider.Name) > 0 {
			if providerNames.Has(identityProvider.Name) {
				validationResults.AddErrors(fielderrors.NewFieldInvalid(fmt.Sprintf("identityProvider[%d].name", i), identityProvider.Name, "must have a unique name"))
			}
			providerNames.Insert(identityProvider.Name)
		}
	}

	if len(redirectingIdentityProviders) > 1 {
		validationResults.AddErrors(fielderrors.NewFieldInvalid("identityProviders", config.IdentityProviders, fmt.Sprintf("only one identity provider can support login for a browser, found: %v", redirectingIdentityProviders)))
	}

	return validationResults
}
Example #20
0
func ValidateIdentityProvider(identityProvider api.IdentityProvider) ValidationResults {
	validationResults := ValidationResults{}

	if len(identityProvider.Name) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("name"))
	}
	if ok, err := validation.ValidateIdentityProviderName(identityProvider.Name); !ok {
		validationResults.AddErrors(fielderrors.NewFieldInvalid("name", identityProvider.Name, err))
	}

	if len(identityProvider.MappingMethod) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("mappingMethod"))
	} else if !validMappingMethods.Has(identityProvider.MappingMethod) {
		validationResults.AddErrors(fielderrors.NewFieldValueNotSupported("mappingMethod", identityProvider.MappingMethod, validMappingMethods.List()))
	}

	if !api.IsIdentityProviderType(identityProvider.Provider) {
		validationResults.AddErrors(fielderrors.NewFieldInvalid("provider", identityProvider.Provider, fmt.Sprintf("%v is invalid in this context", identityProvider.Provider)))
	} else {
		switch provider := identityProvider.Provider.Object.(type) {
		case (*api.RequestHeaderIdentityProvider):
			validationResults.Append(ValidateRequestHeaderIdentityProvider(provider, identityProvider))

		case (*api.BasicAuthPasswordIdentityProvider):
			validationResults.AddErrors(ValidateRemoteConnectionInfo(provider.RemoteConnectionInfo).Prefix("provider")...)

		case (*api.HTPasswdPasswordIdentityProvider):
			validationResults.AddErrors(ValidateFile(provider.File, "provider.file")...)

		case (*api.LDAPPasswordIdentityProvider):
			validationResults.Append(ValidateLDAPIdentityProvider(provider))

		case (*api.KeystonePasswordIdentityProvider):
			validationResults.Append(ValidateKeystoneIdentityProvider(provider, identityProvider).Prefix("provider"))

		case (*api.GitHubIdentityProvider):
			validationResults.AddErrors(ValidateOAuthIdentityProvider(provider.ClientID, provider.ClientSecret, identityProvider.UseAsChallenger)...)

		case (*api.GoogleIdentityProvider):
			validationResults.AddErrors(ValidateOAuthIdentityProvider(provider.ClientID, provider.ClientSecret, identityProvider.UseAsChallenger)...)

		case (*api.OpenIDIdentityProvider):
			validationResults.AddErrors(ValidateOpenIDIdentityProvider(provider, identityProvider)...)

		}
	}

	return validationResults
}
Example #21
0
func validateLifecycleHook(hook *deployapi.LifecycleHook) fielderrors.ValidationErrorList {
	errs := fielderrors.ValidationErrorList{}

	if len(hook.FailurePolicy) == 0 {
		errs = append(errs, fielderrors.NewFieldRequired("failurePolicy"))
	}

	if hook.ExecNewPod == nil {
		errs = append(errs, fielderrors.NewFieldRequired("execNewPod"))
	} else {
		errs = append(errs, validateExecNewPod(hook.ExecNewPod).Prefix("execNewPod")...)
	}

	return errs
}
Example #22
0
func ValidateOAuthIdentityProvider(clientID, clientSecret string, challenge bool) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}

	if len(clientID) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("provider.clientID"))
	}
	if len(clientSecret) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("provider.clientSecret"))
	}
	if challenge {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("challenge", challenge, "oauth providers cannot be used for challenges"))
	}

	return allErrs
}
Example #23
0
func ValidateSessionConfig(config *api.SessionConfig) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}

	// Validate session secrets file, if specified
	if len(config.SessionSecretsFile) > 0 {
		fileErrs := ValidateFile(config.SessionSecretsFile, "sessionSecretsFile")
		if len(fileErrs) != 0 {
			// Missing file
			allErrs = append(allErrs, fileErrs...)
		} else {
			// Validate file contents
			secrets, err := latest.ReadSessionSecrets(config.SessionSecretsFile)
			if err != nil {
				allErrs = append(allErrs, fielderrors.NewFieldInvalid("sessionSecretsFile", config.SessionSecretsFile, fmt.Sprintf("error reading file: %v", err)))
			} else {
				for _, err := range ValidateSessionSecrets(secrets) {
					allErrs = append(allErrs, fielderrors.NewFieldInvalid("sessionSecretsFile", config.SessionSecretsFile, err.Error()))
				}
			}
		}
	}

	if len(config.SessionName) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("sessionName"))
	}

	return allErrs
}
Example #24
0
// GenerateParameterValues generates Value for each Parameter of the given
// Template that has Generate field specified where Value is not already
// supplied.
//
// Examples:
//
// from             | value
// -----------------------------
// "test[0-9]{1}x"  | "test7x"
// "[0-1]{8}"       | "01001100"
// "0x[A-F0-9]{4}"  | "0xB3AF"
// "[a-zA-Z0-9]{8}" | "hW4yQU5i"
func (p *Processor) GenerateParameterValues(t *api.Template) error {
	for i := range t.Parameters {
		param := &t.Parameters[i]
		if len(param.Value) > 0 {
			continue
		}
		if param.Generate != "" {
			generator, ok := p.Generators[param.Generate]
			if !ok {
				return fmt.Errorf("template.parameters[%v]: Unable to find the '%v' generator", i, param.Generate)
			}
			if generator == nil {
				return fmt.Errorf("template.parameters[%v]: Invalid '%v' generator", i, param.Generate)
			}
			value, err := generator.GenerateValue(param.From)
			if err != nil {
				return err
			}
			param.Value, ok = value.(string)
			if !ok {
				return fmt.Errorf("template.parameters[%v]: Unable to convert the generated value '%#v' to string", i, value)
			}
		}
		if len(param.Value) == 0 && param.Required {
			err := fielderrors.NewFieldRequired(fmt.Sprintf("parameters[%d].value", i))
			err.Detail = fmt.Sprintf("parameter %s is required and must be specified")
			return err
		}
	}
	return nil
}
Example #25
0
func ValidateNodeConfig(config *api.NodeConfig) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}

	if len(config.NodeName) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("nodeName"))
	}
	if len(config.NodeIP) > 0 {
		allErrs = append(allErrs, ValidateSpecifiedIP(config.NodeIP, "nodeIP")...)
	}

	allErrs = append(allErrs, ValidateServingInfo(config.ServingInfo).Prefix("servingInfo")...)
	if config.ServingInfo.BindNetwork == "tcp6" {
		allErrs = append(allErrs, fielderrors.NewFieldInvalid("servingInfo.bindNetwork", config.ServingInfo.BindNetwork, "tcp6 is not a valid bindNetwork for nodes, must be tcp or tcp4"))
	}
	allErrs = append(allErrs, ValidateKubeConfig(config.MasterKubeConfig, "masterKubeConfig")...)

	if len(config.DNSIP) > 0 {
		allErrs = append(allErrs, ValidateSpecifiedIP(config.DNSIP, "dnsIP")...)
	}

	allErrs = append(allErrs, ValidateImageConfig(config.ImageConfig).Prefix("imageConfig")...)

	if config.PodManifestConfig != nil {
		allErrs = append(allErrs, ValidatePodManifestConfig(config.PodManifestConfig).Prefix("podManifestConfig")...)
	}

	allErrs = append(allErrs, ValidateNetworkConfig(config.NetworkConfig).Prefix("networkConfig")...)

	allErrs = append(allErrs, ValidateDockerConfig(config.DockerConfig).Prefix("dockerConfig")...)

	allErrs = append(allErrs, ValidateKubeletExtendedArguments(config.KubeletArguments).Prefix("kubeletArguments")...)

	return allErrs
}
Example #26
0
func ValidatePolicyBinding(policyBinding *authorizationapi.PolicyBinding, isNamespaced bool) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}
	allErrs = append(allErrs, validation.ValidateObjectMeta(&policyBinding.ObjectMeta, isNamespaced, PolicyBindingNameValidator(policyBinding.PolicyRef.Namespace)).Prefix("metadata")...)

	if !isNamespaced {
		if len(policyBinding.PolicyRef.Namespace) > 0 {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("policyRef.namespace", policyBinding.PolicyRef.Namespace, "may not reference another namespace"))
		}
	}

	for roleBindingKey, roleBinding := range policyBinding.RoleBindings {
		if roleBinding == nil {
			allErrs = append(allErrs, fielderrors.NewFieldRequired("roleBindings."+roleBindingKey))
		}

		if roleBinding.RoleRef.Namespace != policyBinding.PolicyRef.Namespace {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("roleBindings."+roleBindingKey+".roleRef.namespace", policyBinding.PolicyRef.Namespace, "must be "+policyBinding.PolicyRef.Namespace))
		}

		if roleBindingKey != roleBinding.Name {
			allErrs = append(allErrs, fielderrors.NewFieldInvalid("roleBindings."+roleBindingKey+".metadata.name", roleBinding.Name, "must be "+roleBindingKey))
		}

		allErrs = append(allErrs, ValidateRoleBinding(roleBinding, isNamespaced).Prefix("roleBindings."+roleBindingKey)...)
	}

	return allErrs
}
Example #27
0
func ValidateJobSpec(spec *extensions.JobSpec) errs.ValidationErrorList {
	allErrs := errs.ValidationErrorList{}

	if spec.Parallelism != nil {
		allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(*spec.Parallelism), "parallelism")...)
	}
	if spec.Completions != nil {
		allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(*spec.Completions), "completions")...)
	}
	if spec.Selector == nil {
		allErrs = append(allErrs, errs.NewFieldRequired("selector"))
	} else {
		allErrs = append(allErrs, ValidatePodSelector(spec.Selector).Prefix("selector")...)
	}

	if selector, err := extensions.PodSelectorAsSelector(spec.Selector); err == nil {
		labels := labels.Set(spec.Template.Labels)
		if !selector.Matches(labels) {
			allErrs = append(allErrs, errs.NewFieldInvalid("template.metadata.labels", spec.Template.Labels, "selector does not match template"))
		}
	}

	allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(&spec.Template).Prefix("template")...)
	if spec.Template.Spec.RestartPolicy != api.RestartPolicyOnFailure &&
		spec.Template.Spec.RestartPolicy != api.RestartPolicyNever {
		allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy",
			spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyOnFailure), string(api.RestartPolicyNever)}))
	}
	return allErrs
}
Example #28
0
func ValidateEtcdConfig(config *api.EtcdConfig) ValidationResults {
	validationResults := ValidationResults{}

	validationResults.Append(ValidateServingInfo(config.ServingInfo).Prefix("servingInfo"))
	if config.ServingInfo.BindNetwork == "tcp6" {
		validationResults.AddErrors(fielderrors.NewFieldInvalid("servingInfo.bindNetwork", config.ServingInfo.BindNetwork, "tcp6 is not a valid bindNetwork for etcd, must be tcp or tcp4"))
	}
	if len(config.ServingInfo.NamedCertificates) > 0 {
		validationResults.AddErrors(fielderrors.NewFieldInvalid("servingInfo.namedCertificates", "<not shown>", "namedCertificates are not supported for etcd"))
	}

	validationResults.Append(ValidateServingInfo(config.PeerServingInfo).Prefix("peerServingInfo"))
	if config.ServingInfo.BindNetwork == "tcp6" {
		validationResults.AddErrors(fielderrors.NewFieldInvalid("peerServingInfo.bindNetwork", config.ServingInfo.BindNetwork, "tcp6 is not a valid bindNetwork for etcd peers, must be tcp or tcp4"))
	}
	if len(config.ServingInfo.NamedCertificates) > 0 {
		validationResults.AddErrors(fielderrors.NewFieldInvalid("peerServingInfo.namedCertificates", "<not shown>", "namedCertificates are not supported for etcd"))
	}

	validationResults.AddErrors(ValidateHostPort(config.Address, "address")...)
	validationResults.AddErrors(ValidateHostPort(config.PeerAddress, "peerAddress")...)

	if len(config.StorageDir) == 0 {
		validationResults.AddErrors(fielderrors.NewFieldRequired("storageDirectory"))
	}

	return validationResults
}
Example #29
0
func validateWebHook(webHook *buildapi.WebHookTrigger) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}
	if len(webHook.Secret) == 0 {
		allErrs = append(allErrs, fielderrors.NewFieldRequired("secret"))
	}
	return allErrs
}
Example #30
0
func validateHTTPIngressRuleValue(httpIngressRuleValue *extensions.HTTPIngressRuleValue) errs.ValidationErrorList {
	allErrs := errs.ValidationErrorList{}
	if len(httpIngressRuleValue.Paths) == 0 {
		allErrs = append(allErrs, errs.NewFieldRequired("paths"))
	}
	for _, rule := range httpIngressRuleValue.Paths {
		if len(rule.Path) > 0 {
			if !strings.HasPrefix(rule.Path, "/") {
				allErrs = append(allErrs, errs.NewFieldInvalid("path", rule.Path, "path must begin with /"))
			}
			// TODO: More draconian path regex validation.
			// Path must be a valid regex. This is the basic requirement.
			// In addition to this any characters not allowed in a path per
			// RFC 3986 section-3.3 cannot appear as a literal in the regex.
			// Consider the example: http://host/valid?#bar, everything after
			// the last '/' is a valid regex that matches valid#bar, which
			// isn't a valid path, because the path terminates at the first ?
			// or #. A more sophisticated form of validation would detect that
			// the user is confusing url regexes with path regexes.
			_, err := regexp.CompilePOSIX(rule.Path)
			if err != nil {
				allErrs = append(allErrs, errs.NewFieldInvalid("path", rule.Path, "httpIngressRuleValue.path must be a valid regex."))
			}
		}
		allErrs = append(allErrs, validateIngressBackend(&rule.Backend).Prefix("backend")...)
	}
	return allErrs
}