cmd/gitops-pusher: port to use ffcli

Signed-off-by: Xe <xe@tailscale.com>
This commit is contained in:
Xe 2022-07-21 12:23:53 -04:00
parent 43f3a969ca
commit 707df2efb2

View File

@ -20,20 +20,92 @@
"strings" "strings"
"time" "time"
"github.com/peterbourgon/ff/v3/ffcli"
"github.com/tailscale/hujson" "github.com/tailscale/hujson"
) )
var ( var (
policyFname = flag.String("policy-file", "./policy.hujson", "filename for policy file") rootFlagSet = flag.NewFlagSet("gitops-pusher", flag.ExitOnError)
timeout = flag.Duration("timeout", 5*time.Minute, "timeout for the entire CI run") policyFname = rootFlagSet.String("policy-file", "./policy.hujson", "filename for policy file")
githubSyntax = flag.Bool("github-syntax", true, "use GitHub Action error syntax (https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message)") timeout = rootFlagSet.Duration("timeout", 5*time.Minute, "timeout for the entire CI run")
githubSyntax = rootFlagSet.Bool("github-syntax", true, "use GitHub Action error syntax (https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message)")
) )
func main() { func apply(tailnet, apiKey string) func(context.Context, []string) error {
flag.Parse() return func(ctx context.Context, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), *timeout) controlEtag, err := getACLETag(ctx, tailnet, apiKey)
defer cancel() if err != nil {
return err
}
localEtag, err := sumFile(*policyFname)
if err != nil {
return err
}
log.Printf("control: %s", controlEtag)
log.Printf("local: %s", localEtag)
if controlEtag == localEtag {
log.Println("no update needed, doing nothing")
return nil
}
if err := applyNewACL(ctx, tailnet, apiKey, *policyFname, controlEtag); err != nil {
return err
}
return nil
}
}
func test(tailnet, apiKey string) func(context.Context, []string) error {
return func(ctx context.Context, args []string) error {
controlEtag, err := getACLETag(ctx, tailnet, apiKey)
if err != nil {
return err
}
localEtag, err := sumFile(*policyFname)
if err != nil {
return err
}
log.Printf("control: %s", controlEtag)
log.Printf("local: %s", localEtag)
if controlEtag == localEtag {
log.Println("no updates found, doing nothing")
return nil
}
if err := testNewACLs(ctx, tailnet, apiKey, *policyFname); err != nil {
return err
}
return nil
}
}
func getChecksums(tailnet, apiKey string) func(context.Context, []string) error {
return func(ctx context.Context, args []string) error {
controlEtag, err := getACLETag(ctx, tailnet, apiKey)
if err != nil {
return err
}
localEtag, err := sumFile(*policyFname)
if err != nil {
return err
}
log.Printf("control: %s", controlEtag)
log.Printf("local: %s", localEtag)
return nil
}
}
func main() {
tailnet, ok := os.LookupEnv("TS_TAILNET") tailnet, ok := os.LookupEnv("TS_TAILNET")
if !ok { if !ok {
log.Fatal("set envvar TS_TAILNET to your tailnet's name") log.Fatal("set envvar TS_TAILNET to your tailnet's name")
@ -43,54 +115,47 @@ func main() {
log.Fatal("set envvar TS_API_KEY to your Tailscale API key") log.Fatal("set envvar TS_API_KEY to your Tailscale API key")
} }
switch flag.Arg(0) { applyCmd := &ffcli.Command{
case "apply": Name: "apply",
controlEtag, err := getACLETag(ctx, tailnet, apiKey) ShortUsage: "gitops-pusher [options] apply",
if err != nil { ShortHelp: "Pushes changes to CONTROL",
LongHelp: `Pushes changes to CONTROL`,
Exec: apply(tailnet, apiKey),
}
testCmd := &ffcli.Command{
Name: "test",
ShortUsage: "gitops-pusher [options] test",
ShortHelp: "Tests ACL changes",
LongHelp: "Tests ACL changes",
Exec: test(tailnet, apiKey),
}
cksumCmd := &ffcli.Command{
Name: "checksum",
ShortUsage: "Shows checksums of ACL files",
ShortHelp: "Fetch checksum of CONTROL's ACL and the local ACL for comparison",
LongHelp: "Fetch checksum of CONTROL's ACL and the local ACL for comparison",
Exec: getChecksums(tailnet, apiKey),
}
root := &ffcli.Command{
ShortUsage: "gitops-pusher [options] <command>",
ShortHelp: "Push Tailscale ACLs to CONTROL using a GitOps workflow",
Subcommands: []*ffcli.Command{applyCmd, cksumCmd, testCmd},
FlagSet: rootFlagSet,
}
if err := root.Parse(os.Args[1:]); err != nil {
log.Fatal(err) log.Fatal(err)
} }
localEtag, err := sumFile(*policyFname) ctx, cancel := context.WithTimeout(context.Background(), *timeout)
if err != nil { defer cancel()
log.Fatal(err)
}
log.Printf("control: %s", controlEtag) if err := root.Run(ctx); err != nil {
log.Printf("local: %s", localEtag) fmt.Println(err)
os.Exit(1)
if controlEtag == localEtag {
log.Println("no update needed, doing nothing")
os.Exit(0)
}
if err := applyNewACL(ctx, tailnet, apiKey, *policyFname, controlEtag); err != nil {
log.Fatal(err)
}
case "test":
controlEtag, err := getACLETag(ctx, tailnet, apiKey)
if err != nil {
log.Fatal(err)
}
localEtag, err := sumFile(*policyFname)
if err != nil {
log.Fatal(err)
}
log.Printf("control: %s", controlEtag)
log.Printf("local: %s", localEtag)
if controlEtag == localEtag {
log.Println("no updates found, doing nothing")
os.Exit(0)
}
if err := testNewACLs(ctx, tailnet, apiKey, *policyFname); err != nil {
log.Fatal(err)
}
default:
log.Fatalf("usage: %s [options] <test|apply>", os.Args[0])
} }
} }