feat(clbot): Create Gerrit watcher and basic clbot binary.
gerrit.Watcher is a class which watches the Gerrit stream-events SSH connection and produces events. There's a basic CLBot binary as well, to demonstrate driving it to produce messages on the logging output. It doesn't really do anything else. Change-Id: I274fe0a77c8329f79456425405e2fbdc3ca2edf0 Reviewed-on: https://cl.tvl.fyi/c/depot/+/245 Reviewed-by: tazjin <mail@tazj.in>
This commit is contained in:
parent
f6c7c85d94
commit
c05803ff14
14 changed files with 1235 additions and 0 deletions
78
fun/clbot/clbot.go
Normal file
78
fun/clbot/clbot.go
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"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)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
checkRequired(required)
|
||||
|
||||
ctx := context.Background()
|
||||
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)
|
||||
}
|
||||
|
||||
for e := range gw.Events() {
|
||||
log.Infof("hello: %v", spew.Sdump(e))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue