Skip to content

Commit

Permalink
feat: add github action
Browse files Browse the repository at this point in the history
  • Loading branch information
Paulo-Lopes-Estevao committed Jul 13, 2023
1 parent 481f0d6 commit 8125136
Show file tree
Hide file tree
Showing 20 changed files with 1,085 additions and 0 deletions.
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM golang:1.19.2-alpine AS builder

RUN apk update && apk upgrade && \
apk add --no-cache make bash

WORKDIR /src

COPY . .

# Build
RUN make build

# Using a distroless image from https://github.com/GoogleContainerTools/distroless
FROM gcr.io/distroless/static-debian11

COPY --from=builder /src/bin/app /

EXPOSE 8000

CMD ["/app"]
72 changes: 72 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: 'API Integration - Github Actions Terraform'
description: 'Communicate with Github Actions and Terraform Cloud'
author: 'Monabele'
inputs:
tf_api_token:
description: 'Terraform Cloud API Token'
required: true
default: 'TF_API_TOKEN'
tf_workspace:
description: 'Terraform Cloud Workspace'
required: true
default: 'TF_WORKSPACE'
tf_organization:
description: 'Terraform Cloud Organization'
required: true
default: 'TF_ORGANIZATION'
tf_run_type:
description: 'Terraform Cloud Run Type'
required: true
default: 'TF_RUN_TYPE'

# Workspace Variables API
variable_type:
description: 'Workspace Variable Type'
required: false
default: 'var'
variable_key:
description: 'Workspace Variable Key'
required: false
variable_value:
description: 'Workspace Variable Value'
required: false
variable_category:
description: 'Workspace Variable Category'
required: false
default: 'terraform'
variable_sensitive:
description: 'Workspace Variable Sensitive'
required: false
default: 'false'
variable_hcl:
description: 'Workspace Variable HCL'
required: false
default: 'false'
variable_description:
description: 'Workspace Variable Description'
required: false
default: 'var_description'

# Workspace Variables API Interactions
delete_variable:
description: 'Delete Workspace Variable'
required: false

create_variable:
description: 'Create Workspace Variable'
required: false

runs:
using: docker
image: Dockerfile

args:
- ${{ inputs.variable_type }}
- ${{ inputs.variable_key }}
- ${{ inputs.variable_value }}
- ${{ inputs.variable_category }}
- ${{ inputs.variable_sensitive }}
- ${{ inputs.variable_hcl }}
- ${{ inputs.variable_description }}
- ${{ inputs.delete_variable }}
- ${{ inputs.create_variable }}
23 changes: 23 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module github.com/Mona-bele/action-integration-terraform

go 1.19

require github.com/spf13/viper v1.16.0

require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
55 changes: 55 additions & 0 deletions internal/utils/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package utils

import (
"github.com/joho/godotenv"
"github.com/spf13/viper"
"os"
"strconv"
)

type ConfigEnv struct {
TFAPITOKEN string `mapstructure:"tf_api_token"`
TFWORKSPACE string `mapstructure:"tf_workspace"`
TFORGANIZATION string `mapstructure:"tf_organization"`
TFRUNTYPE string `mapstructure:"tf_run_type"`

VariableType string `mapstructure:"variable_type"`
VariableKey string `mapstructure:"variable_key"`
VariableValue string `mapstructure:"variable_value"`
VariableCategory string `mapstructure:"variable_category"`
VariableSensitive bool `mapstructure:"variable_sensitive"`
VariableHcl bool `mapstructure:"variable_hcl"`
VariableDescription string `mapstructure:"variable_description"`

DeleteVariable string `mapstructure:"delete_variable"`
CreateVariable string `mapstructure:"create_variable"`
}

func LoadEnv(path string) (*ConfigEnv, error) {
var env ConfigEnv

_ = godotenv.Load()

env.TFAPITOKEN = os.Getenv("tf_api_token")
env.TFWORKSPACE = os.Getenv("tf_workspace")
env.TFORGANIZATION = os.Getenv("tf_organization")
env.TFRUNTYPE = os.Getenv("tf_run_type")

env.VariableType = os.Getenv("variable_type")
env.VariableKey = os.Getenv("variable_key")
env.VariableValue = os.Getenv("variable_value")
env.VariableDescription = os.Getenv("variable_description")
env.VariableCategory = os.Getenv("variable_category")
env.VariableSensitive, _ = strconv.ParseBool(os.Getenv("variable_sensitive"))
env.VariableHcl, _ = strconv.ParseBool(os.Getenv("variable_hcl"))

env.DeleteVariable = os.Getenv("delete_variable")
env.CreateVariable = os.Getenv("create_variable")

err := viper.Unmarshal(&env)
if err != nil {
return nil, err
}

return &env, nil
}
25 changes: 25 additions & 0 deletions internal/utils/github.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package utils

import (
"fmt"
"log"
"os"
)

func SetGithubEnvOutput(key string, value int) {
outputFilename := os.Getenv("GITHUB_OUTPUT")
f, err := os.OpenFile(outputFilename,
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Println(err)
}
defer func(f *os.File) {
err := f.Close()
if err != nil {
log.Println(err)
}
}(f)
if _, err := f.WriteString(fmt.Sprintf("%s=%d\n", key, value)); err != nil {
log.Println(err)
}
}
18 changes: 18 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

import (
"context"
"github.com/Mona-bele/action-integration-terraform/pkg/run"
"log"
"os"
)

func main() {
tfRunType := os.Getenv("tf_run_type")
builder, err := run.GetBuilder(tfRunType)
if err != nil {
log.Println(err)
}
ctx := context.Background()
builder.GetRunBuilder(ctx)
}
50 changes: 50 additions & 0 deletions pkg/model/setting_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package model

import "fmt"

type SettingAPI struct {
TfApiToken string
TfOrgID string
TfWorkspaceName string
TfRunType string
}

func NewSettingAPI(apiToken, tfOrgID, tfWorkspaceName, tfRunType string) (*SettingAPI, error) {
setting := &SettingAPI{
TfApiToken: apiToken,
TfOrgID: tfOrgID,
TfWorkspaceName: tfWorkspaceName,
TfRunType: tfRunType,
}

if err := setting.invalid(); err != nil {
return nil, err
}

return setting, nil
}

func (s *SettingAPI) invalid() error {
if s.TfApiToken == "" {
return fmt.Errorf("TF_API_TOKEN is not set")
}
if s.TfOrgID == "" {
return fmt.Errorf("ID of organization is not set")
}
if s.TfWorkspaceName == "" {
return fmt.Errorf("name of workspace is not set")
}
if s.TfRunType == "" {
return fmt.Errorf("TF_RUN_TYPE is not set")
}
return nil
}

func TypeRun(runType string) string {
switch runType {
case "type_action":
return "actions"
default:
return "runs"
}
}
34 changes: 34 additions & 0 deletions pkg/model/setting_api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package model

import (
"testing"
)

func TestNewSettingAPI(t *testing.T) {
sttApi, err := NewSettingAPI("token", "org", "workspace", "type_run")
if err != nil {
t.Errorf("NewSettingAPI() error = %v", err)
}
t.Log(sttApi)
}

func TestEmptySettingAPI(t *testing.T) {
_, err := NewSettingAPI("", "", "", "")
if err == nil {
t.Errorf("NewSettingAPI() error = %v", err)
}
}

func TestEmptyApiToken(t *testing.T) {
_, err := NewSettingAPI("", "org", "workspace", "type_run")
if err == nil {
t.Errorf("NewSettingAPI() error = %v", err)
}
}

func TestOrgEqualIsNotSet(t *testing.T) {
_, err := NewSettingAPI("token", "", "workspace", "type_run")
if err.Error() == "TF_API_ORG is not set" {
t.Log("TF_API_ORG is not set")
}
}
15 changes: 15 additions & 0 deletions pkg/model/workspace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package model

type Workspaces struct {
Data DataWorkspaces `json:"data"`
}

type DataWorkspaces struct {
ID string `json:"id"`
Type string `json:"type"`
Attributes AttributesWorkspaces `json:"attributes"`
}

type AttributesWorkspaces struct {
Name string `json:"name"`
}
73 changes: 73 additions & 0 deletions pkg/model/workspace_variables.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package model

import "fmt"

type WorkspaceVariables struct {
Data *Data `json:"data"`
}

type WorkspaceVariablesList struct {
Data []*Data `json:"data"`
}

type Data struct {
ID string `json:"id"`
Type string `json:"type"`
Attributes Attributes `json:"attributes"`
}

type Attributes struct {
Key string `json:"key"`
Value string `json:"value"`
Description string `json:"description"`
Category string `json:"category"`
Hcl bool `json:"hcl"`
Sensitive bool `json:"sensitive"`
}

func NewWorkspaceVariables(typeVar string, attributes Attributes) (*WorkspaceVariables, error) {
wv := &WorkspaceVariables{
Data: &Data{
Type: typeVar,
Attributes: attributes,
},
}

if err := wv.invalid(); err != nil {
return nil, err
}

return wv, nil
}

func (wv *WorkspaceVariables) invalid() error {
if wv.Data.Type == "" {
return fmt.Errorf("type is not set")
}
if wv.Data.Attributes.Key == "" {
return fmt.Errorf("key is not set")
}
if wv.Data.Attributes.Value == "" {
return fmt.Errorf("value is not set")
}
if wv.Data.Attributes.Category == "" {
return fmt.Errorf("category is not set")
}

return nil
}

func (wv *WorkspaceVariables) Update(wV *WorkspaceVariables) error {
wv.Data.Attributes.Key = wV.Data.Attributes.Key
wv.Data.Attributes.Value = wV.Data.Attributes.Value
wv.Data.Attributes.Description = wV.Data.Attributes.Description
wv.Data.Attributes.Category = wV.Data.Attributes.Category
wv.Data.Attributes.Hcl = wV.Data.Attributes.Hcl
wv.Data.Attributes.Sensitive = wV.Data.Attributes.Sensitive

if err := wv.invalid(); err != nil {
return err
}

return nil
}
Loading

0 comments on commit 8125136

Please sign in to comment.