func ValidateServiceAccountConfig(config api.ServiceAccountConfig, builtInKubernetes bool) ValidationResults { validationResults := ValidationResults{} managedNames := util.NewStringSet(config.ManagedNames...) if !managedNames.Has(bootstrappolicy.BuilderServiceAccountName) { validationResults.AddWarnings(fielderrors.NewFieldInvalid("managedNames", "", fmt.Sprintf("missing %q, which will require manual creation in each namespace before builds can run", bootstrappolicy.BuilderServiceAccountName))) } if !managedNames.Has(bootstrappolicy.DeployerServiceAccountName) { validationResults.AddWarnings(fielderrors.NewFieldInvalid("managedNames", "", fmt.Sprintf("missing %q, which will require manual creation in each namespace before deployments can run", bootstrappolicy.DeployerServiceAccountName))) } if builtInKubernetes && !managedNames.Has(bootstrappolicy.DefaultServiceAccountName) { validationResults.AddWarnings(fielderrors.NewFieldInvalid("managedNames", "", fmt.Sprintf("missing %q, which will prevent creation of pods that do not specify a valid service account", bootstrappolicy.DefaultServiceAccountName))) } for i, name := range config.ManagedNames { if ok, msg := kvalidation.ValidateServiceAccountName(name, false); !ok { validationResults.AddErrors(fielderrors.NewFieldInvalid(fmt.Sprintf("managedNames[%d]", i), name, msg)) } } if len(config.PrivateKeyFile) > 0 { if fileErrs := ValidateFile(config.PrivateKeyFile, "privateKeyFile"); len(fileErrs) > 0 { validationResults.AddErrors(fileErrs...) } else if privateKey, err := serviceaccount.ReadPrivateKey(config.PrivateKeyFile); err != nil { validationResults.AddErrors(fielderrors.NewFieldInvalid("privateKeyFile", config.PrivateKeyFile, err.Error())) } else if err := privateKey.Validate(); err != nil { validationResults.AddErrors(fielderrors.NewFieldInvalid("privateKeyFile", config.PrivateKeyFile, err.Error())) } } else if builtInKubernetes { validationResults.AddWarnings(fielderrors.NewFieldInvalid("privateKeyFile", "", "no service account tokens will be generated, which could prevent builds and deployments from working")) } if len(config.PublicKeyFiles) == 0 { validationResults.AddWarnings(fielderrors.NewFieldInvalid("publicKeyFiles", "", "no service account tokens will be accepted by the API, which will prevent builds and deployments from working")) } for i, publicKeyFile := range config.PublicKeyFiles { if fileErrs := ValidateFile(publicKeyFile, fmt.Sprintf("publicKeyFiles[%d]", i)); len(fileErrs) > 0 { validationResults.AddErrors(fileErrs...) } else if _, err := serviceaccount.ReadPublicKey(publicKeyFile); err != nil { validationResults.AddErrors(fielderrors.NewFieldInvalid(fmt.Sprintf("publicKeyFiles[%d]", i), publicKeyFile, err.Error())) } } if len(config.MasterCA) > 0 { validationResults.AddErrors(ValidateFile(config.MasterCA, "masterCA")...) } else if builtInKubernetes { validationResults.AddWarnings(fielderrors.NewFieldInvalid("masterCA", "", "master CA information will not be automatically injected into pods, which will prevent verification of the API server from inside a pod")) } return validationResults }
// SplitUsername returns the namespace and ServiceAccount name embedded in the given username, // or an error if the username is not a valid name produced by MakeUsername func SplitUsername(username string) (string, string, error) { if !strings.HasPrefix(username, ServiceAccountUsernamePrefix) { return "", "", invalidUsernameErr } trimmed := strings.TrimPrefix(username, ServiceAccountUsernamePrefix) parts := strings.Split(trimmed, ServiceAccountUsernameSeparator) if len(parts) != 2 { return "", "", invalidUsernameErr } namespace, name := parts[0], parts[1] if ok, _ := validation.ValidateNamespaceName(namespace, false); !ok { return "", "", invalidUsernameErr } if ok, _ := validation.ValidateServiceAccountName(name, false); !ok { return "", "", invalidUsernameErr } return namespace, name, nil }