in prow/cmd/checkconfig/main.go [250:435]
func validate(o options) error {
// use all warnings by default
if len(o.warnings.Strings()) == 0 || o.includeDefaultWarnings {
if o.expensive {
o.warnings = flagutil.NewStrings(append(o.warnings.Strings(), getAllWarnings()...)...)
} else {
o.warnings = flagutil.NewStrings(append(o.warnings.Strings(), defaultWarnings...)...)
}
}
if o.github.AppID != "" && o.github.AppPrivateKeyPath != "" {
o.warnings.Add(validateGitHubAppInstallationWarning)
}
configAgent, err := o.config.ConfigAgent()
if err != nil {
return fmt.Errorf("error loading prow config: %w", err)
}
cfg := configAgent.Config()
if o.prowYAMLRepoName != "" {
if err := validateInRepoConfig(cfg, o.prowYAMLPath, o.prowYAMLRepoName, o.warningEnabled(unknownFieldsAllWarning)); err != nil {
return fmt.Errorf("error validating .prow.yaml: %w", err)
}
}
var pcfg *plugins.Configuration
if o.pluginsConfig.PluginConfigPath != "" {
pluginAgent, err := o.pluginsConfig.PluginAgent()
if err != nil {
return fmt.Errorf("error loading Prow plugin config: %w", err)
}
pcfg = pluginAgent.Config()
}
// the following checks are useful in finding user errors but their
// presence won't lead to strictly incorrect behavior, so we can
// detect them here but don't necessarily want to stop config re-load
// in all components on their failure.
var errs []error
if pcfg != nil && o.warningEnabled(verifyOwnersFilePresence) {
if o.github.TokenPath == "" {
return errors.New("cannot verify OWNERS file presence without a GitHub token")
}
githubClient, err := o.github.GitHubClient(false)
if err != nil {
return fmt.Errorf("error loading GitHub client: %w", err)
}
// 404s are expected to happen, no point in retrying
githubClient.SetMax404Retries(0)
if err := verifyOwnersPresence(pcfg, githubClient); err != nil {
errs = append(errs, err)
}
}
if pcfg != nil && o.warningEnabled(mismatchedTideWarning) {
if err := validateTideRequirements(cfg, pcfg, true); err != nil {
errs = append(errs, err)
}
} else if pcfg != nil && o.warningEnabled(mismatchedTideLenientWarning) {
if err := validateTideRequirements(cfg, pcfg, false); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(nonDecoratedJobsWarning) {
if err := validateDecoratedJobs(cfg); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(validDecorationConfigWarning) {
if err := validateDecorationConfig(cfg); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(jobNameLengthWarning) {
if err := validateJobRequirements(cfg.JobConfig); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(jobRefsDuplicationWarning) {
if err := validateJobExtraRefs(cfg.JobConfig); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(needsOkToTestWarning) {
if err := validateNeedsOkToTestLabel(cfg); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(managedWebhooksWarning) {
if err := validateManagedWebhooks(cfg); err != nil {
errs = append(errs, err)
}
}
if pcfg != nil && o.warningEnabled(validateOwnersWarning) {
if err := verifyOwnersPlugin(pcfg); err != nil {
errs = append(errs, err)
}
}
if pcfg != nil && o.warningEnabled(missingTriggerWarning) {
if err := validateTriggers(cfg, pcfg); err != nil {
errs = append(errs, err)
}
}
if pcfg != nil && o.warningEnabled(validateURLsWarning) {
if err := validateURLs(cfg.ProwConfig); err != nil {
errs = append(errs, err)
}
}
// If both "unknown-fields" and "unknown-fields-all" are enabled, just run "unknown-fields-all" validation
// since it is a superset. This will avoid duplicate warnings.
unknownAllEnabled := o.warningEnabled(unknownFieldsAllWarning)
unknownEnabled := o.warningEnabled(unknownFieldsWarning)
if unknownAllEnabled {
if _, err := config.LoadStrict(o.config.ConfigPath, o.config.JobConfigPath, nil, ""); err != nil {
errs = append(errs, err)
}
} else if unknownEnabled {
cfgBytes, err := ioutil.ReadFile(o.config.ConfigPath)
if err != nil {
return fmt.Errorf("error reading Prow config for validation: %w", err)
}
if err := validateUnknownFields(&config.Config{}, cfgBytes, o.config.ConfigPath); err != nil {
errs = append(errs, err)
}
}
if pcfg != nil && (unknownEnabled || unknownAllEnabled) {
pcfgBytes, err := ioutil.ReadFile(o.pluginsConfig.PluginConfigPath)
if err != nil {
return fmt.Errorf("error reading Prow plugin config for validation: %w", err)
}
if err := validateUnknownFields(&plugins.Configuration{}, pcfgBytes, o.pluginsConfig.PluginConfigPath); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(tideStrictBranchWarning) {
if err := validateStrictBranches(cfg.ProwConfig); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(tideContextPolicy) {
if err := validateTideContextPolicy(cfg); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(validateClusterFieldWarning) {
opener, err := io.NewOpener(context.Background(), o.storage.GCSCredentialsFile, o.storage.S3CredentialsFile)
if err != nil {
logrus.WithError(err).Fatal("Error creating opener")
}
if err := validateCluster(cfg, opener); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(validateSupplementalProwConfigOrgRepoHirarchy) {
if err := validateAdditionalProwConfigIsInOrgRepoDirectoryStructure(os.DirFS("./"), o.config.SupplementalProwConfigDirs.Strings(), o.pluginsConfig.SupplementalPluginsConfigDirs.Strings(), o.config.SupplementalProwConfigsFileNameSuffix, o.pluginsConfig.SupplementalPluginsConfigsFileNameSuffix); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(validateUnmanagedBranchConfigHasNoSubconfig) {
if err := validateUnmanagedBranchprotectionConfigDoesntHaveSubconfig(cfg.BranchProtection); err != nil {
errs = append(errs, err)
}
}
if o.warningEnabled(validateGitHubAppInstallationWarning) {
githubClient, err := o.github.GitHubClient(false)
if err != nil {
return fmt.Errorf("error loading GitHub client: %w", err)
}
if err := validateGitHubAppIsInstalled(githubClient, cfg.AllRepos); err != nil {
errs = append(errs, err)
}
}
if pcfg != nil && o.warningEnabled(validateLabelWarning) {
if err := verifyLabelPlugin(pcfg.Label); err != nil {
errs = append(errs, err)
}
}
return utilerrors.NewAggregate(errs)
}