github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/external-plugins/cherrypicker/main.go (about) 1 /* 2 Copyright 2017 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 "flag" 21 "net/http" 22 "os" 23 "os/signal" 24 "strconv" 25 "syscall" 26 27 "github.com/sirupsen/logrus" 28 29 "k8s.io/test-infra/pkg/flagutil" 30 "k8s.io/test-infra/prow/config/secret" 31 prowflagutil "k8s.io/test-infra/prow/flagutil" 32 "k8s.io/test-infra/prow/pluginhelp/externalplugins" 33 ) 34 35 type options struct { 36 port int 37 38 dryRun bool 39 github prowflagutil.GitHubOptions 40 41 webhookSecretFile string 42 prowAssignments bool 43 allowAll bool 44 } 45 46 func (o *options) Validate() error { 47 for _, group := range []flagutil.OptionGroup{&o.github} { 48 if err := group.Validate(o.dryRun); err != nil { 49 return err 50 } 51 } 52 53 return nil 54 } 55 56 func gatherOptions() options { 57 o := options{} 58 fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError) 59 fs.IntVar(&o.port, "port", 8888, "Port to listen on.") 60 fs.BoolVar(&o.dryRun, "dry-run", true, "Dry run for testing. Uses API tokens but does not mutate.") 61 fs.StringVar(&o.webhookSecretFile, "hmac-secret-file", "/etc/webhook/hmac", "Path to the file containing the GitHub HMAC secret.") 62 fs.BoolVar(&o.prowAssignments, "use-prow-assignments", true, "Use prow commands to assign cherrypicked PRs.") 63 fs.BoolVar(&o.allowAll, "allow-all", false, "Allow anybody to use automated cherrypicks by skipping Github organization membership checks.") 64 for _, group := range []flagutil.OptionGroup{&o.github} { 65 group.AddFlags(fs) 66 } 67 fs.Parse(os.Args[1:]) 68 return o 69 } 70 71 func main() { 72 o := gatherOptions() 73 if err := o.Validate(); err != nil { 74 logrus.Fatalf("Invalid options: %v", err) 75 } 76 77 logrus.SetFormatter(&logrus.JSONFormatter{}) 78 // TODO: Use global option from the prow config. 79 logrus.SetLevel(logrus.DebugLevel) 80 log := logrus.StandardLogger().WithField("plugin", "cherrypick") 81 82 // Ignore SIGTERM so that we don't drop hooks when the pod is removed. 83 // We'll get SIGTERM first and then SIGKILL after our graceful termination 84 // deadline. 85 signal.Ignore(syscall.SIGTERM) 86 87 secretAgent := &secret.Agent{} 88 if err := secretAgent.Start([]string{o.github.TokenPath, o.webhookSecretFile}); err != nil { 89 logrus.WithError(err).Fatal("Error starting secrets agent.") 90 } 91 92 githubClient, err := o.github.GitHubClient(secretAgent, o.dryRun) 93 if err != nil { 94 logrus.WithError(err).Fatal("Error getting GitHub client.") 95 } 96 gitClient, err := o.github.GitClient(secretAgent, o.dryRun) 97 if err != nil { 98 logrus.WithError(err).Fatal("Error getting Git client.") 99 } 100 defer gitClient.Clean() 101 102 email, err := githubClient.Email() 103 if err != nil { 104 log.WithError(err).Fatal("Error getting bot e-mail.") 105 } 106 107 botName, err := githubClient.BotName() 108 if err != nil { 109 logrus.WithError(err).Fatal("Error getting bot name.") 110 } 111 repos, err := githubClient.GetRepos(botName, true) 112 if err != nil { 113 log.WithError(err).Fatal("Error listing bot repositories.") 114 } 115 116 server := &Server{ 117 tokenGenerator: secretAgent.GetTokenGenerator(o.webhookSecretFile), 118 botName: botName, 119 email: email, 120 121 gc: gitClient, 122 ghc: githubClient, 123 log: log, 124 125 prowAssignments: o.prowAssignments, 126 allowAll: o.allowAll, 127 128 bare: &http.Client{}, 129 patchURL: "https://patch-diff.githubusercontent.com", 130 131 repos: repos, 132 } 133 134 http.Handle("/", server) 135 externalplugins.ServeExternalPluginHelp(http.DefaultServeMux, log, HelpProvider) 136 logrus.Fatal(http.ListenAndServe(":"+strconv.Itoa(o.port), nil)) 137 }