package main import ( "encoding/json" "flag" "net/http" "os" "strconv" "time" "github.com/sirupsen/logrus" "k8s.io/test-infra/pkg/flagutil" "k8s.io/test-infra/prow/config" "k8s.io/test-infra/prow/config/secret" prowflagutil "k8s.io/test-infra/prow/flagutil" configflagutil "k8s.io/test-infra/prow/flagutil/config" "k8s.io/test-infra/prow/github" "k8s.io/test-infra/prow/interrupts" "k8s.io/test-infra/prow/logrusutil" "k8s.io/test-infra/prow/pjutil" "k8s.io/test-infra/prow/pluginhelp" "k8s.io/test-infra/prow/pluginhelp/externalplugins" ) const pluginName = "comment-plugin" type options struct { port int config configflagutil.ConfigOptions dryRun bool github prowflagutil.GitHubOptions instrumentationOptions prowflagutil.InstrumentationOptions webhookSecretFile string } type server struct { tokenGenerator func() []byte botUser *github.UserData email string ghc github.Client log *logrus.Entry repos []github.Repo } func helpProvider(_ []config.OrgRepo) (*pluginhelp.PluginHelp, error) { pluginHelp := &pluginhelp.PluginHelp{ Description: `The sample plugin`, } return pluginHelp, nil } func (o *options) Validate() error { return nil } func gatherOptions() options { o := options{config: configflagutil.ConfigOptions{ConfigPath: "./config.yaml"}} fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError) fs.IntVar(&o.port, "port", 8888, "Port to listen on.") fs.BoolVar(&o.dryRun, "dry-run", false, "Dry run for testing. Uses API tokens but does not mutate.") fs.StringVar(&o.webhookSecretFile, "hmac-secret-file", "/etc/hmac", "Path to the file containing GitHub HMAC secret.") for _, group := range []flagutil.OptionGroup{&o.github} { group.AddFlags(fs) } fs.Parse(os.Args[1:]) return o } func main() { o := gatherOptions() if err := o.Validate(); err != nil { logrus.Fatalf("Invalid options: %v", err) } logrusutil.ComponentInit() log := logrus.StandardLogger().WithField("plugin", pluginName) if err := secret.Add(o.webhookSecretFile); err != nil { logrus.WithError(err).Fatal("Error starting secrets agent.") } gitHubClient, err := o.github.GitHubClient(o.dryRun) if err != nil { logrus.WithError(err).Fatal("Error getting GitHub client.") } email, err := gitHubClient.Email() if err != nil { log.WithError(err).Fatal("Error getting bot e-mail.") } botUser, err := gitHubClient.BotUser() if err != nil { logrus.WithError(err).Fatal("Error getting bot name.") } repos, err := gitHubClient.GetRepos(botUser.Login, true) if err != nil { log.WithError(err).Fatal("Error listing bot repositories.") } serv := &server{ tokenGenerator: secret.GetTokenGenerator(o.webhookSecretFile), botUser: botUser, email: email, ghc: gitHubClient, log: log, repos: repos, } health := pjutil.NewHealthOnPort(o.instrumentationOptions.HealthPort) health.ServeReady() mux := http.NewServeMux() mux.Handle("/", serv) externalplugins.ServeExternalPluginHelp(mux, log, helpProvider) logrus.Info("starting server " + strconv.Itoa(o.port)) httpServer := &http.Server{Addr: ":" + strconv.Itoa(o.port), Handler: mux} defer interrupts.WaitForGracefulShutdown() interrupts.ListenAndServe(httpServer, 5*time.Second) } func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) { logrus.Info("inside http server") _, _, payload, ok, _ := github.ValidateWebhook(w, r, s.tokenGenerator) logrus.Info(string(payload)) if !ok { return } logrus.Info(w, "Event received. Have a nice day.") if err := s.handleEvent(payload); err != nil { logrus.WithError(err).Error("Error parsing event.") } } func (s *server) handleEvent(payload []byte) error { logrus.Info("inside handler") var pr github.PullRequestEvent if err := json.Unmarshal(payload, &pr); err != nil { return err } logrus.Info(pr.Number) if err := s.ghc.CreateComment(pr.PullRequest.Base.Repo.Owner.Login, pr.PullRequest.Base.Repo.Name, pr.Number, "comment from smaple-plugin"); err != nil { return err } return nil }