cmd/gitops-pusher: add --fail-on-manual-edits flag (#13066)

For cases where users want to be extra careful about not overwriting
manual changes, add a flag to hard-fail. This is only useful if the etag
cache is persistent or otherwise reliable. This flag should not be used
in ephemeral CI workers that won't persist the cache.

Updates https://github.com/tailscale/corp/issues/22177

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit is contained in:
Andrew Lytvynov 2024-08-08 13:21:28 -05:00 committed by GitHub
parent 46db698333
commit ad038f4046
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -28,19 +28,20 @@
) )
var ( var (
rootFlagSet = flag.NewFlagSet("gitops-pusher", flag.ExitOnError) rootFlagSet = flag.NewFlagSet("gitops-pusher", flag.ExitOnError)
policyFname = rootFlagSet.String("policy-file", "./policy.hujson", "filename for policy file") policyFname = rootFlagSet.String("policy-file", "./policy.hujson", "filename for policy file")
cacheFname = rootFlagSet.String("cache-file", "./version-cache.json", "filename for the previous known version hash") cacheFname = rootFlagSet.String("cache-file", "./version-cache.json", "filename for the previous known version hash")
timeout = rootFlagSet.Duration("timeout", 5*time.Minute, "timeout for the entire CI run") 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)") 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)")
apiServer = rootFlagSet.String("api-server", "api.tailscale.com", "API server to contact") apiServer = rootFlagSet.String("api-server", "api.tailscale.com", "API server to contact")
failOnManualEdits = rootFlagSet.Bool("fail-on-manual-edits", false, "fail if manual edits to the ACLs in the admin panel are detected; when set to false (the default) only a warning is printed")
) )
func modifiedExternallyError() { func modifiedExternallyError() error {
if *githubSyntax { if *githubSyntax {
fmt.Printf("::warning file=%s,line=1,col=1,title=Policy File Modified Externally::The policy file was modified externally in the admin console.\n", *policyFname) return fmt.Errorf("::warning file=%s,line=1,col=1,title=Policy File Modified Externally::The policy file was modified externally in the admin console.", *policyFname)
} else { } else {
fmt.Printf("The policy file was modified externally in the admin console.\n") return fmt.Errorf("The policy file was modified externally in the admin console.")
} }
} }
@ -66,7 +67,13 @@ func apply(cache *Cache, client *http.Client, tailnet, apiKey string) func(conte
log.Printf("cache: %s", cache.PrevETag) log.Printf("cache: %s", cache.PrevETag)
if cache.PrevETag != controlEtag { if cache.PrevETag != controlEtag {
modifiedExternallyError() if err := modifiedExternallyError(); err != nil {
if *failOnManualEdits {
return err
} else {
fmt.Println(err)
}
}
} }
if controlEtag == localEtag { if controlEtag == localEtag {
@ -107,7 +114,13 @@ func test(cache *Cache, client *http.Client, tailnet, apiKey string) func(contex
log.Printf("cache: %s", cache.PrevETag) log.Printf("cache: %s", cache.PrevETag)
if cache.PrevETag != controlEtag { if cache.PrevETag != controlEtag {
modifiedExternallyError() if err := modifiedExternallyError(); err != nil {
if *failOnManualEdits {
return err
} else {
fmt.Println(err)
}
}
} }
if controlEtag == localEtag { if controlEtag == localEtag {