11package cmd
22
33import (
4+ "fmt"
5+ "net/http"
46 "os"
7+ "path/filepath"
58 "sync"
69
10+ "github.com/go-resty/resty/v2"
711 "gopkg.in/yaml.v3"
812)
913
@@ -108,6 +112,13 @@ type PolicyFile struct {
108112 Policies []Policy `yaml:"Policies"`
109113}
110114
115+ type PolicySourceType int
116+
117+ const (
118+ LocalFile PolicySourceType = iota
119+ RemoteURL
120+ )
121+
111122func LoadPolicyFile (filename string ) (* PolicyFile , error ) {
112123 data , err := os .ReadFile (filename )
113124 if err != nil {
@@ -130,6 +141,79 @@ func LoadPolicyFile(filename string) (*PolicyFile, error) {
130141 return & policyFile , nil
131142}
132143
144+ // Load Remote
145+
146+ // LoadRemotePolicy loads a policy file from a remote HTTPS endpoint
147+ func LoadRemotePolicy (url string , expectedChecksum string ) (* PolicyFile , error ) {
148+ // Create a temporary directory to store the downloaded file
149+ tempDir , err := os .MkdirTemp (outputDir , "_remote" )
150+ if err != nil {
151+ return nil , fmt .Errorf ("failed to create temporary directory: %w" , err )
152+ }
153+ defer os .RemoveAll (tempDir ) // Clean up the temporary directory when done
154+
155+ // Generate a temporary file name
156+ tempFile := filepath .Join (tempDir , "remote_policy.yaml" )
157+
158+ // Create a resty client
159+ client := resty .New ()
160+
161+ // Download the file
162+ resp , err := client .R ().SetOutput (tempFile ).Get (url )
163+ if err != nil {
164+ return nil , fmt .Errorf ("failed to download policy file: %w" , err )
165+ }
166+
167+ if resp .StatusCode () != http .StatusOK {
168+ return nil , fmt .Errorf ("failed to download policy file: HTTP status %d" , resp .StatusCode ())
169+ }
170+
171+ // If a checksum is provided, validate it
172+ if expectedChecksum != "" {
173+ actualChecksum , err := calculateSHA256 (tempFile )
174+ if err != nil {
175+ log .Fatal ().Err (err ).Msg ("failed to calculate policy checksum" )
176+ }
177+
178+ if actualChecksum != expectedChecksum {
179+ log .Fatal ().Msgf ("Policy checksum mismatch: expected %s, got %s" , expectedChecksum , actualChecksum )
180+
181+ }
182+ }
183+
184+ // Load the policy file
185+ policyFile , err := LoadPolicyFile (tempFile )
186+ if err != nil {
187+ log .Fatal ().Err (err ).Msg ("failed to load policy file" )
188+ }
189+
190+ return policyFile , nil
191+ }
192+
193+ func DeterminePolicySource (input string ) (PolicySourceType , string , error ) {
194+ // First, check if it's a valid URL
195+ if isURL (input ) {
196+ return RemoteURL , input , nil
197+ }
198+
199+ // If not a URL, treat it as a file path
200+ absPath , err := filepath .Abs (input )
201+ if err != nil {
202+ return LocalFile , "" , err
203+ }
204+
205+ // Check if the file exists
206+ _ , err = os .Stat (absPath )
207+ if err != nil {
208+ if os .IsNotExist (err ) {
209+ return LocalFile , "" , fmt .Errorf ("file does not exist: %s" , absPath )
210+ }
211+ return LocalFile , "" , err
212+ }
213+
214+ return LocalFile , absPath , nil
215+ }
216+
133217// Policy store
134218
135219var (
0 commit comments