diff --git a/.gitignore b/.gitignore index 7a3e2fd..af63df9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,29 +1,22 @@ -# Local .terraform directories -**/.terraform/* - -# .tfstate files -*.tfstate -*.tfstate.* - -# Crash log files -crash.log - -# Ignore any .tfvars files that are generated automatically for each Terraform run. Most -# .tfvars files are managed as part of configuration and so should be included in -# version control. +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore # -# example.tfvars +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib -# Ignore override files as they are usually used to override resources locally and so -# are not checked in -override.tf -override.tf.json -*_override.tf -*_override.tf.json +# Test binary, built with `go test -c` +*.test -# Include override files you do wish to add to version control using negated pattern -# -# !example_override.tf +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ -# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan -# example: *tfplan* +# Go workspace file +go.work +.env \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2c02d9a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,2 @@ +FROM curlimages/curl as curl + diff --git a/README.md b/README.md index e2b0754..dfef7a0 100644 --- a/README.md +++ b/README.md @@ -1 +1,24 @@ # terrafir-github-action + + + +### Flow + +```mermaid +--- +title: Terrafir Github Action +--- +flowchart TD + A["`__Github Action__ + Inputs: + - Terrafir API Key + - Plan to Assess + `"]--Spins up Docker Container - Dockerfile-->B[Container] + B --Make Post Request to Terrafir API-->C[Terrafir API] + C --Authorizes Request-->D[AuthService] + D -.Allow Plan Assessment.->E + C <--Assesses Plan -->E[PlanService] + E <--Sent Plan to Policy Engine -->F[Policy Engine] + C --Processes Assessment and Returns Result to Container-->B + B --Receives Assessment and Creates Github Comment Output-->A +``` diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..3642f51 --- /dev/null +++ b/action.yml @@ -0,0 +1,22 @@ +name: 'Terrafir Plan Assessment' +description: 'Assess the plan file for security vulnerabilities' +inputs: + api-key: + description: 'API key for Terrafir' + required: true + email: + description: 'Email for Terrafir' + required: true + plan-file: + description: 'Path to the terraform plan file' + +outputs: + time: + description: 'The time plan was assessed' #TODO +runs: + using: 'docker' + image: 'Dockerfile' + args: + - ${{ inputs.api-key }} + - ${{ inputs.email }} + - ${{ inputs.plan-file }} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c4b2b0b --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/sachasmart/terrafir-github-action + +go 1.20 + +require github.com/joho/godotenv v1.5.1 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d61b19e --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= diff --git a/main.go b/main.go new file mode 100644 index 0000000..a175866 --- /dev/null +++ b/main.go @@ -0,0 +1,57 @@ +package main + +import ( + "flag" + "fmt" + "log" + "net/http" + "net/url" + "os" + + "github.com/joho/godotenv" + "github.com/sachasmart/terrafir-github-action/types" +) + +var ( + apiKey = flag.String("api-key", os.Getenv("API_KEY"), "API key Terrafir API.") + email = flag.String("email", os.Getenv("EMAIL"), "Email address to send the request to.") + input = flag.String("input", os.Getenv("INPUT"), "Input to send to the API.") + verboseMode = flag.String("verbose", os.Getenv("VERBOSE"), "Verbose mode") +) + +func main() { + godotenv.Load(".env") + flag.Parse() + checkEnvironmentVariables(*apiKey, *email, *input) + sendRequest(*apiKey, *email, *input) +} + +func preRequestCheck() { + response, err := http.Get(types.URL) + if err != nil { + log.Fatal(err) + } + if response.StatusCode != 200 { + log.Fatal("API is not available") + } + fmt.Println("API is available") +} + +func sendRequest(apiKey string, email string, input string) { + preRequestCheck() + response, err := http.Post(types.URL, "application/json", nil) + if err != nil { + log.Fatal(err) + } + fmt.Println(response.Body) +} + +func checkEnvironmentVariables(apiKey string, email string, input string) { + if apiKey == "" { + log.Fatalf("Environment variable 'API_KEY' not found.") + } + _, err := url.Parse(apiKey) + if err != nil { + log.Fatalf("Environment variable 'API_KEY' is not a valid.") + } +} diff --git a/types/request.types.go b/types/request.types.go new file mode 100644 index 0000000..a4e01f4 --- /dev/null +++ b/types/request.types.go @@ -0,0 +1,9 @@ +package types + +type Post struct { + APIKey string `json:"api_key"` + Email string `json:"email"` + Input string `json:"input"` +} + +const URL string = "https://api.terrafir.com/"