Skip to content

Commit

Permalink
Merge pull request #312 from jumppad-labs/erik/add-exists-func
Browse files Browse the repository at this point in the history
add function to check if file/dir exists
  • Loading branch information
eveld authored Nov 21, 2024
2 parents 7cf9b74 + 8a77331 commit 134ed58
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 55 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ generate_mocks:

install_local:
go build -ldflags "-X main.version=${git_commit}" -gcflags=all="-N -l" -o bin/jumppad main.go
sudo mv /usr/bin/jumppad /usr/bin/jumppad-old || true
sudo cp bin/jumppad /usr/bin/jumppad
sudo mv /usr/bin/jumppad /usr/local/bin/jumppad-old || true
sudo cp bin/jumppad /usr/local/bin/jumppad

remove_local:
sudo mv /usr/bin/jumppad-old /usr/bin/jumppad || true
sudo mv /usr/local/bin/jumppad-old /usr/local/bin/jumppad || true
28 changes: 12 additions & 16 deletions examples/functions/container.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,17 @@ resource "container" "consul" {
}

environment = {
file_dir = dir()
env = env("HOME")
k8s_config = k8s_config("dc1")
k8s_config_docker = k8s_config_docker("dc1")
home = home()
shipyard = shipyard()
file = file("./default.vars")
data = data("mine")
docker_ip = docker_ip()
docker_host = docker_host()
shipyard_ip = shipyard_ip()
cluster_api = cluster_api("nomad_cluster.dc1")
cluster_port = cluster_port("nomad_cluster.dc1")
var_len = len(variable.test_var)
os = system("os")
arch = system("arch")
file_dir = dir()
env = env("HOME")
home = home()
file = file("./default.vars")
data = data("mine")
data_with_permissions = data_with_permissions("mine", 755)
docker_ip = docker_ip()
docker_host = docker_host()
var_len = len(variable.test_var)
os = system("os")
arch = system("arch")
exists = exists("file")
}
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ require (
github.com/infinytum/raymond/v2 v2.0.5
github.com/jumppad-labs/connector v0.4.0
github.com/jumppad-labs/gohup v0.4.0
github.com/jumppad-labs/hclconfig v0.25.0
github.com/jumppad-labs/hclconfig v0.26.0
github.com/jumppad-labs/plugin-sdk v0.1.1-0.20240306185853-c09f71f81b8a
github.com/kennygrant/sanitize v1.2.4
github.com/mattn/go-isatty v0.0.20
Expand Down Expand Up @@ -265,6 +265,6 @@ replace github.com/charmbracelet/log => github.com/jumppad-labs/log v0.0.0-20240

replace github.com/zclconf/go-cty => github.com/jumppad-labs/go-cty v0.0.0-20230804061424-9e985cb751f6

//replace github.com/jumppad-labs/hclconfig => ../hclconfig/
// replace github.com/jumppad-labs/hclconfig => ../hclconfig/

//replace github.com/jumppad-labs/gohup => ../gohup/
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -690,10 +690,8 @@ github.com/jumppad-labs/go-cty v0.0.0-20230804061424-9e985cb751f6 h1:1ADItCWr5pr
github.com/jumppad-labs/go-cty v0.0.0-20230804061424-9e985cb751f6/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0=
github.com/jumppad-labs/gohup v0.4.0 h1:0OplHvnKnOLkqWm417sRHLSiJ4xGeb8LiSSAJ51QrYg=
github.com/jumppad-labs/gohup v0.4.0/go.mod h1:JYvZnemxJlWDyx8RbDNcCBLZSvIrYlYLnkQqR1BKFW4=
github.com/jumppad-labs/hclconfig v0.24.0 h1:SyMCl2rwLC5o32CCp50fsVbJxyFFCiYoMejvfh9RJKM=
github.com/jumppad-labs/hclconfig v0.24.0/go.mod h1:AOzW0btnKiqUKYVi3ioGzSPNCWsTzsJxKcqzVORccvk=
github.com/jumppad-labs/hclconfig v0.25.0 h1:CRIprG+i+Ol9s2izb6PRrt23kyGYZ1OC/XGFqdI1o/M=
github.com/jumppad-labs/hclconfig v0.25.0/go.mod h1:AOzW0btnKiqUKYVi3ioGzSPNCWsTzsJxKcqzVORccvk=
github.com/jumppad-labs/hclconfig v0.26.0 h1:Qg/tC2WlhKwoTW0acAY/vyUXHwCuyr4NmshKLS81How=
github.com/jumppad-labs/hclconfig v0.26.0/go.mod h1:AOzW0btnKiqUKYVi3ioGzSPNCWsTzsJxKcqzVORccvk=
github.com/jumppad-labs/log v0.0.0-20240827082827-4404884e31a7 h1:tuoFYWXAqT5BheDlQNumY1DxvkW8bjG9JOzoxpFneZs=
github.com/jumppad-labs/log v0.0.0-20240827082827-4404884e31a7/go.mod h1:S9jhxE2C1+jv2PlLTAow3h+ZILzvXRhd6eBjFAUcfgI=
github.com/jumppad-labs/plugin-sdk v0.1.1-0.20240306185853-c09f71f81b8a h1:fqPvAO1o/6bUIm0fwEbXcUzUCng+GDlLmSMT/5oUJUE=
Expand Down
10 changes: 9 additions & 1 deletion pkg/config/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func customHCLFuncDockerHost() (string, error) {
}

func customHCLFuncDataFolderWithPermissions(name string, permissions int) (string, error) {
if permissions > 0 && permissions < 778 {
if permissions < 0 || permissions > 777 {
return "", fmt.Errorf("permissions must be a three digit number less than 777")
}

Expand All @@ -50,3 +50,11 @@ func customHCLFuncSystem(property string) (string, error) {
return "", fmt.Errorf("unknown system property %s", property)
}
}

func customHCLFuncExists(path string) (bool, error) {
if _, err := os.Stat(path); err != nil {
return false, nil
}

return true, nil
}
24 changes: 24 additions & 0 deletions pkg/config/functions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package config

import (
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
)

func TestExistsFalse(t *testing.T) {
exists, err := customHCLFuncExists("nonexistent")
require.NoError(t, err)
require.Equal(t, false, exists)
}

func TestExistsTrue(t *testing.T) {
file := filepath.Join(t.TempDir(), "testdata")
os.WriteFile(file, []byte("test"), 0644)

exists, err := customHCLFuncExists(file)
require.NoError(t, err)
require.Equal(t, true, exists)
}
83 changes: 58 additions & 25 deletions pkg/config/resources/exec/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ import (
"strings"
"time"

"github.com/jumppad-labs/hclconfig/convert"
htypes "github.com/jumppad-labs/hclconfig/types"
"github.com/jumppad-labs/jumppad/pkg/clients"
cmdClient "github.com/jumppad-labs/jumppad/pkg/clients/command"
cmdTypes "github.com/jumppad-labs/jumppad/pkg/clients/command/types"
contClient "github.com/jumppad-labs/jumppad/pkg/clients/container"
"github.com/jumppad-labs/jumppad/pkg/clients/container/types"
contTypes "github.com/jumppad-labs/jumppad/pkg/clients/container/types"
"github.com/jumppad-labs/jumppad/pkg/clients/logger"
"github.com/jumppad-labs/jumppad/pkg/utils"
sdk "github.com/jumppad-labs/plugin-sdk"
"github.com/zclconf/go-cty/cty"
)

// checks Provider implements the sdk.Provider interface
Expand Down Expand Up @@ -63,6 +64,13 @@ func (p *Provider) Create(ctx context.Context) error {

outPath := fmt.Sprintf("%s/%s.out", utils.JumppadTemp(), p.config.Meta.ID)

if _, err := os.Stat(outPath); err != nil {
err := os.WriteFile(outPath, []byte{}, 0755)
if err != nil {
return fmt.Errorf("unable to create output file: %w", err)
}
}

// cleanup the local output file
defer os.Remove(outPath)

Expand All @@ -83,31 +91,11 @@ func (p *Provider) Create(ctx context.Context) error {
p.config.PID = pid
}

// parse any output from the script
if _, err := os.Stat(outPath); err != nil {
p.log.Debug("Output file not found", "ref", p.config.Meta.ID, "path", outPath)
return nil
}

d, err := os.ReadFile(outPath)
err := p.generateOutput()
if err != nil {
return fmt.Errorf("unable to read output file: %w", err)
return fmt.Errorf("unable to generate output: %w", err)
}

output := map[string]string{}

outs := strings.Split(string(d), "\n")
for _, v := range outs {
parts := strings.Split(v, "=")
if len(parts) != 2 {
continue
}

output[parts[0]] = parts[1]
}

p.config.Output = output

return nil
}

Expand Down Expand Up @@ -146,6 +134,11 @@ func (p *Provider) Refresh(ctx context.Context) error {

p.log.Debug("Refresh Exec", "ref", p.config.Meta.Name)

err := p.generateOutput()
if err != nil {
return fmt.Errorf("unable to generate output: %w", err)
}

return nil
}

Expand Down Expand Up @@ -226,9 +219,9 @@ func (p *Provider) createRemoteExecContainer() (string, error) {
// generate the ID for the new container based on the clock time and a string
fqdn := utils.FQDN(p.config.Meta.Name, p.config.Meta.Module, p.config.Meta.Type)

new := contTypes.Container{
new := types.Container{
Name: fqdn,
Image: &contTypes.Image{Name: p.config.Image.Name, Username: p.config.Image.Username, Password: p.config.Image.Password},
Image: &types.Image{Name: p.config.Image.Name, Username: p.config.Image.Username, Password: p.config.Image.Password},
Environment: p.config.Environment,
}

Expand Down Expand Up @@ -331,3 +324,43 @@ func (p *Provider) createLocalExec(outputPath string) (int, error) {

return pid, nil
}

func (p *Provider) generateOutput() error {
outPath := fmt.Sprintf("%s/%s.out", utils.JumppadTemp(), p.config.Meta.ID)

// parse any output from the script
if _, err := os.Stat(outPath); err != nil {
p.log.Debug("Output file not found", "ref", p.config.Meta.ID, "path", outPath)
return nil
}

d, err := os.ReadFile(outPath)
if err != nil {
return fmt.Errorf("unable to read output file: %w", err)
}

output := map[string]string{}
outs := strings.Split(string(d), "\n")
for _, v := range outs {
parts := strings.Split(v, "=")
if len(parts) != 2 {
continue
}

output[parts[0]] = parts[1]
}

values := map[string]cty.Value{}
for k, v := range output {
value, err := convert.GoToCtyValue(v)
if err != nil {
return fmt.Errorf("unable to convert output value to cty: %w", err)
}

values[k] = value
}

p.config.Output = cty.ObjectVal(values)

return nil
}
2 changes: 1 addition & 1 deletion pkg/config/resources/exec/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func TestParsesOutput(t *testing.T) {
err := p.Create(context.Background())
require.NoError(t, err)

require.True(t, e.Output["FOO"] == "BAR")
require.True(t, e.Output.AsValueMap()["FOO"].AsString() == "BAR")
}

func TestDeletesOutput(t *testing.T) {
Expand Down
9 changes: 6 additions & 3 deletions pkg/config/resources/exec/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/jumppad-labs/jumppad/pkg/config"
ctypes "github.com/jumppad-labs/jumppad/pkg/config/resources/container"
"github.com/jumppad-labs/jumppad/pkg/utils"
"github.com/zclconf/go-cty/cty"
)

// TypeExec is the resource string for an Exec resource
Expand All @@ -33,9 +34,9 @@ type Exec struct {
RunAs *ctypes.User `hcl:"run_as,block" json:"run_as,omitempty"` // User block for mapping the user id and group id inside the container

// output
PID int `hcl:"pid,optional" json:"pid,omitempty"` // PID stores the ID of the created connector service if it is a local exec
ExitCode int `hcl:"exit_code,optional" json:"exit_code,omitempty"` // Exit code of the process
Output map[string]string `hcl:"output,optional" json:"output,omitempty"` // output values returned from exec
PID int `hcl:"pid,optional" json:"pid,omitempty"` // PID stores the ID of the created connector service if it is a local exec
ExitCode int `hcl:"exit_code,optional" json:"exit_code,omitempty"` // Exit code of the process
Output cty.Value `hcl:"output,optional"` // output values returned from exec
}

func (e *Exec) Process() error {
Expand All @@ -55,6 +56,8 @@ func (e *Exec) Process() error {
}
}

// e.Output = map[string]string{}

// do we have an existing resource in the state?
// if so we need to set any computed resources for dependents
cfg, err := config.LoadState()
Expand Down
1 change: 1 addition & 0 deletions pkg/config/zz_hclparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func NewParser(callback hclconfig.WalkCallback, variables map[string]string, var
p.RegisterFunction("data", customHCLFuncDataFolder)
p.RegisterFunction("data_with_permissions", customHCLFuncDataFolderWithPermissions)
p.RegisterFunction("system", customHCLFuncSystem)
p.RegisterFunction("exists", customHCLFuncExists)

return p
}

0 comments on commit 134ed58

Please sign in to comment.