Change-Id: I3c6eeeb99f9d81cdbcb10880c9075ac94c4f5d19 Reviewed-on: https://cl.tvl.fyi/c/depot/+/341 Reviewed-by: tazjin <mail@tazj.in>
		
			
				
	
	
		
			101 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package main
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"flag"
 | |
| 	"io/ioutil"
 | |
| 	"os"
 | |
| 	"os/signal"
 | |
| 	"time"
 | |
| 
 | |
| 	"code.tvl.fyi/fun/clbot/gerrit"
 | |
| 	"github.com/davecgh/go-spew/spew"
 | |
| 	log "github.com/golang/glog"
 | |
| 	"golang.org/x/crypto/ssh"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	gerritAddr       = flag.String("gerrit_host", "cl.tvl.fyi:29418", "Gerrit SSH host:port")
 | |
| 	gerritSSHHostKey = flag.String("gerrit_ssh_pubkey", "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIUNYBYPCCBNDFSd0BuCR+8kgeuJ7IA5S2nTNQmkQUYNyXK+ot5os7rHtCk96+grd5+J8jFCuFBWisUe8h8NC0Q=", "Gerrit SSH public key")
 | |
| 	gerritSSHTimeout = flag.Duration("gerrit_tcp_timeout", 5*time.Second, "Gerrit SSH TCP connect timeout")
 | |
| 
 | |
| 	required           = flag.NewFlagSet("required flags", flag.ExitOnError)
 | |
| 	gerritAuthUsername = required.String("gerrit_ssh_auth_username", "", "Gerrit SSH username")
 | |
| 	gerritAuthKeyPath  = required.String("gerrit_ssh_auth_key", "", "Gerrit SSH private key path")
 | |
| )
 | |
| 
 | |
| func mustFixedHostKey(f string) ssh.HostKeyCallback {
 | |
| 	pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(f))
 | |
| 	if err != nil {
 | |
| 		log.Exitf("ParseAuthorizedKey(%q): %v", f, err)
 | |
| 	}
 | |
| 	return ssh.FixedHostKey(pk)
 | |
| }
 | |
| 
 | |
| func mustPrivateKey(p string) ssh.AuthMethod {
 | |
| 	pkBytes, err := ioutil.ReadFile(p)
 | |
| 	if err != nil {
 | |
| 		log.Exitf("reading SSH private key from %q: %v", p, err)
 | |
| 	}
 | |
| 	pk, err := ssh.ParsePrivateKey(pkBytes)
 | |
| 	if err != nil {
 | |
| 		log.Exitf("parsing private key from %q: %v", p, err)
 | |
| 	}
 | |
| 	return ssh.PublicKeys(pk)
 | |
| }
 | |
| 
 | |
| func checkRequired(fs *flag.FlagSet) {
 | |
| 	missing := map[string]bool{}
 | |
| 	fs.VisitAll(func(f *flag.Flag) { missing[f.Name] = true })
 | |
| 	fs.Visit(func(f *flag.Flag) { delete(missing, f.Name) })
 | |
| 	for f := range missing {
 | |
| 		log.Errorf("flag %q was unset but is required", f)
 | |
| 	}
 | |
| 	if len(missing) > 0 {
 | |
| 		os.Exit(1)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| var shutdownFuncs []func()
 | |
| 
 | |
| func callOnShutdown(f func()) {
 | |
| 	shutdownFuncs = append(shutdownFuncs, f)
 | |
| }
 | |
| 
 | |
| func main() {
 | |
| 	flag.Parse()
 | |
| 	checkRequired(required)
 | |
| 
 | |
| 	shutdownCh := make(chan os.Signal)
 | |
| 	signal.Notify(shutdownCh, os.Interrupt)
 | |
| 	go func() {
 | |
| 		<-shutdownCh
 | |
| 		for n := len(shutdownFuncs); n >= 0; n-- {
 | |
| 			shutdownFuncs[n]()
 | |
| 		}
 | |
| 	}()
 | |
| 
 | |
| 	ctx, cancel := context.WithCancel(context.Background())
 | |
| 	callOnShutdown(cancel)
 | |
| 	cfg := &ssh.ClientConfig{
 | |
| 		User:            *gerritAuthUsername,
 | |
| 		Auth:            []ssh.AuthMethod{mustPrivateKey(*gerritAuthKeyPath)},
 | |
| 		HostKeyCallback: mustFixedHostKey(*gerritSSHHostKey),
 | |
| 		Timeout:         *gerritSSHTimeout,
 | |
| 	}
 | |
| 	cfg.SetDefaults()
 | |
| 
 | |
| 	gw, err := gerrit.New(ctx, "tcp", *gerritAddr, cfg)
 | |
| 	if err != nil {
 | |
| 		log.Errorf("gerrit.New(%q): %v", *gerritAddr, err)
 | |
| 	}
 | |
| 	callOnShutdown(func() {
 | |
| 		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 | |
| 		defer cancel()
 | |
| 		gw.Close(ctx)
 | |
| 	})
 | |
| 
 | |
| 	for e := range gw.Events() {
 | |
| 		log.Infof("hello: %v", spew.Sdump(e))
 | |
| 	}
 | |
| }
 |