github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/cmd/status-reconciler/main.go (about)

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"os"
    23  	"time"
    24  
    25  	"github.com/sirupsen/logrus"
    26  	"k8s.io/apimachinery/pkg/util/sets"
    27  	"sigs.k8s.io/prow/pkg/pjutil/pprof"
    28  
    29  	"sigs.k8s.io/prow/pkg/flagutil"
    30  	prowflagutil "sigs.k8s.io/prow/pkg/flagutil"
    31  	configflagutil "sigs.k8s.io/prow/pkg/flagutil/config"
    32  	pluginsflagutil "sigs.k8s.io/prow/pkg/flagutil/plugins"
    33  	"sigs.k8s.io/prow/pkg/interrupts"
    34  	"sigs.k8s.io/prow/pkg/logrusutil"
    35  	"sigs.k8s.io/prow/pkg/statusreconciler"
    36  )
    37  
    38  const (
    39  	defaultTokens = 300
    40  	defaultBurst  = 100
    41  )
    42  
    43  type options struct {
    44  	config        configflagutil.ConfigOptions
    45  	pluginsConfig pluginsflagutil.PluginOptions
    46  
    47  	continueOnError           bool
    48  	addedPresubmitDenylist    prowflagutil.Strings
    49  	addedPresubmitDenylistAll prowflagutil.Strings
    50  	dryRun                    bool
    51  	kubernetes                prowflagutil.KubernetesOptions
    52  	github                    prowflagutil.GitHubOptions
    53  	storage                   prowflagutil.StorageClientOptions
    54  	instrumentationOptions    prowflagutil.InstrumentationOptions
    55  
    56  	// statusURI where Status-reconciler stores last known state, i.e. configuration.
    57  	// Can be /local/path, gs://path/to/object or s3://path/to/object.
    58  	// GCS writes will use the bucket's default acl for new objects. Ensure both that
    59  	// a) the gcs credentials can write to this bucket
    60  	// b) the default acls do not expose any private info
    61  	statusURI string
    62  }
    63  
    64  func gatherOptions(fs *flag.FlagSet, args ...string) options {
    65  	o := options{config: configflagutil.ConfigOptions{ConfigPath: "/etc/config/config.yaml"}}
    66  
    67  	fs.StringVar(&o.statusURI, "status-path", "", "The /local/path, gs://path/to/object or s3://path/to/object to store status controller state. GCS writes will use the default object ACL for the bucket.")
    68  
    69  	fs.BoolVar(&o.continueOnError, "continue-on-error", false, "Indicates that the migration should continue if context migration fails for an individual PR.")
    70  	fs.Var(&o.addedPresubmitDenylist, "denylist", "Org or org/repo to ignore new added presubmits for, set more than once to add more.")
    71  	fs.Var(&o.addedPresubmitDenylistAll, "denylist-all", "Org or org/repo to ignore reconciling, set more than once to add more.")
    72  	fs.BoolVar(&o.dryRun, "dry-run", true, "Whether or not to make mutating API calls to GitHub.")
    73  	o.github.AddCustomizedFlags(fs, prowflagutil.ThrottlerDefaults(defaultTokens, defaultBurst))
    74  	o.pluginsConfig.PluginConfigPathDefault = "/etc/plugins/plugins.yaml"
    75  	for _, group := range []flagutil.OptionGroup{&o.kubernetes, &o.storage, &o.instrumentationOptions, &o.config, &o.pluginsConfig} {
    76  		group.AddFlags(fs)
    77  	}
    78  	fs.Parse(args)
    79  	return o
    80  }
    81  
    82  func (o *options) Validate() error {
    83  	for _, group := range []flagutil.OptionGroup{&o.kubernetes, &o.github, &o.storage, &o.config, &o.pluginsConfig} {
    84  		if err := group.Validate(o.dryRun); err != nil {
    85  			return err
    86  		}
    87  	}
    88  
    89  	return nil
    90  }
    91  
    92  func (o *options) getDenyList() sets.Set[string] {
    93  	denyList := o.addedPresubmitDenylist.Strings()
    94  
    95  	return sets.New[string](denyList...)
    96  }
    97  
    98  func (o *options) getDenyListAll() sets.Set[string] {
    99  	denyListAll := o.addedPresubmitDenylistAll.Strings()
   100  	return sets.New[string](denyListAll...)
   101  }
   102  
   103  func main() {
   104  	logrusutil.ComponentInit()
   105  
   106  	o := gatherOptions(flag.NewFlagSet(os.Args[0], flag.ExitOnError), os.Args[1:]...)
   107  	if err := o.Validate(); err != nil {
   108  		logrus.WithError(err).Fatal("Invalid options")
   109  	}
   110  
   111  	defer interrupts.WaitForGracefulShutdown()
   112  
   113  	pprof.Instrument(o.instrumentationOptions)
   114  
   115  	configAgent, err := o.config.ConfigAgent()
   116  	if err != nil {
   117  		logrus.WithError(err).Fatal("Error starting config agent.")
   118  	}
   119  
   120  	pluginAgent, err := o.pluginsConfig.PluginAgent()
   121  	if err != nil {
   122  		logrus.WithError(err).Fatal("Error starting plugin configuration agent.")
   123  	}
   124  
   125  	githubClient, err := o.github.GitHubClient(o.dryRun)
   126  	if err != nil {
   127  		logrus.WithError(err).Fatal("Error getting GitHub client.")
   128  	}
   129  
   130  	prowJobClient, err := o.kubernetes.ProwJobClient(configAgent.Config().ProwJobNamespace, o.dryRun)
   131  	if err != nil {
   132  		logrus.WithError(err).Fatal("Error getting kube client.")
   133  	}
   134  
   135  	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
   136  	defer cancel()
   137  	opener, err := o.storage.StorageClient(ctx)
   138  	if err != nil {
   139  		logrus.WithError(err).Fatal("Cannot create opener")
   140  	}
   141  
   142  	c := statusreconciler.NewController(o.continueOnError, o.getDenyList(), o.getDenyListAll(), opener, o.config, o.statusURI, prowJobClient, githubClient, pluginAgent)
   143  	interrupts.Run(func(ctx context.Context) {
   144  		c.Run(ctx)
   145  	})
   146  }