github.com/someshkoli/terratest@v0.41.1/modules/opa/download_policy.go (about) 1 package opa 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "strings" 8 "sync" 9 10 getter "github.com/hashicorp/go-getter" 11 12 "github.com/gruntwork-io/terratest/modules/logger" 13 "github.com/gruntwork-io/terratest/modules/testing" 14 ) 15 16 var ( 17 // A map that maps the go-getter base URL to the temporary directory where it is downloaded. 18 policyDirCache sync.Map 19 ) 20 21 // DownloadPolicyE takes in a rule path written in go-getter syntax and downloads it to a temporary directory so that it 22 // can be passed to opa. The temporary directory that is used is cached based on the go-getter base path, and reused 23 // across calls. 24 // For example, if you call DownloadPolicyE with the go-getter URL multiple times: 25 // git::https://github.com/gruntwork-io/terratest.git//policies/foo.rego?ref=master 26 // The first time the gruntwork-io/terratest repo will be downloaded to a new temp directory. All subsequent calls will 27 // reuse that first temporary dir where the repo was cloned. This is preserved even if a different subdir is requested 28 // later, e.g.: git::https://github.com/gruntwork-io/terratest.git//examples/bar.rego?ref=master. 29 // Note that the query parameters are always included in the base URL. This means that if you use a different ref (e.g., 30 // git::https://github.com/gruntwork-io/terratest.git//examples/bar.rego?ref=v0.39.3), then that will be cloned to a new 31 // temporary directory rather than the cached dir. 32 func DownloadPolicyE(t testing.TestingT, rulePath string) (string, error) { 33 cwd, err := os.Getwd() 34 if err != nil { 35 return "", err 36 } 37 38 detected, err := getter.Detect(rulePath, cwd, getter.Detectors) 39 if err != nil { 40 return "", err 41 } 42 43 // File getters are assumed to be a local path reference, so pass through the original path. 44 if strings.HasPrefix(detected, "file") { 45 return rulePath, nil 46 } 47 48 // At this point we assume the getter URL is a remote URL, so we start the process of downloading it to a temp dir. 49 50 // First, check if we had already downloaded the source and it is in our cache. 51 baseDir, subDir := getter.SourceDirSubdir(rulePath) 52 downloadPath, hasDownloaded := policyDirCache.Load(baseDir) 53 if hasDownloaded { 54 logger.Logf(t, "Previously downloaded %s: returning cached path", baseDir) 55 return filepath.Join(downloadPath.(string), subDir), nil 56 } 57 58 // Not downloaded, so use go-getter to download the remote source to a temp dir. 59 tempDir, err := ioutil.TempDir("", "terratest-opa-policy-*") 60 if err != nil { 61 return "", err 62 } 63 // go-getter doesn't work if you give it a directory that already exists, so we add an additional path in the 64 // tempDir to make sure we feed a directory that doesn't exist yet. 65 tempDir = filepath.Join(tempDir, "getter") 66 67 logger.Logf(t, "Downloading %s to temp dir %s", rulePath, tempDir) 68 if err := getter.GetAny(tempDir, baseDir); err != nil { 69 return "", err 70 } 71 policyDirCache.Store(baseDir, tempDir) 72 return filepath.Join(tempDir, subDir), nil 73 }