Skip to content

Commit

Permalink
Merge pull request #17 from jumppad-labs/restructure
Browse files Browse the repository at this point in the history
Restructure to remove sdk dependencies on cty
  • Loading branch information
nicholasjackson committed Mar 5, 2024
2 parents 849dbcf + cc6b8c9 commit 2b82646
Show file tree
Hide file tree
Showing 20 changed files with 202 additions and 144 deletions.
15 changes: 8 additions & 7 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/jumppad-labs/hclconfig/errors"
"github.com/jumppad-labs/hclconfig/resources"
"github.com/jumppad-labs/hclconfig/types"
"github.com/silas/dag"
)
Expand Down Expand Up @@ -82,7 +83,7 @@ func (c *Config) FindResource(path string) (types.Resource, error) {

// local version of FindResource that does not lock the config
func (c *Config) findResource(path string) (types.Resource, error) {
fqdn, err := types.ParseFQRN(path)
fqdn, err := resources.ParseFQRN(path)
if err != nil {
return nil, err
}
Expand All @@ -108,7 +109,7 @@ func (c *Config) FindRelativeResource(path string, parentModule string) (types.R
c.sync.Lock()
defer c.sync.Unlock()

fqdn, err := types.ParseFQRN(path)
fqdn, err := resources.ParseFQRN(path)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -157,12 +158,12 @@ func (c *Config) FindModuleResources(module string, includeSubModules bool) ([]t
c.sync.Lock()
defer c.sync.Unlock()

fqdn, err := types.ParseFQRN(module)
fqdn, err := resources.ParseFQRN(module)
if err != nil {
return nil, err
}

if fqdn.Type != types.TypeModule {
if fqdn.Type != resources.TypeModule {
return nil, fmt.Errorf("resource %s is not a module reference", module)
}

Expand Down Expand Up @@ -206,7 +207,7 @@ func (c *Config) AppendResourcesFromConfig(new *Config) error {
defer c.sync.Unlock()

for _, r := range new.Resources {
fqdn := types.FQDNFromResource(r).String()
fqdn := resources.FQRNFromResource(r).String()

// does the resource already exist?
if _, err := c.findResource(fqdn); err == nil {
Expand Down Expand Up @@ -420,7 +421,7 @@ func (c *Config) Walk(wf WalkCallback, reverse bool) error {
}

// if this is the root module or is disabled skip
if (r.Metadata().Type == types.TypeRoot || r.Metadata().Type == types.TypeModule) || r.GetDisabled() {
if (r.Metadata().Type == resources.TypeRoot || r.Metadata().Type == resources.TypeModule) || r.GetDisabled() {
return nil
}

Expand Down Expand Up @@ -493,7 +494,7 @@ func (c *Config) walk(wf dag.WalkFunc, reverse bool) []error {
}

func (c *Config) addResource(r types.Resource, ctx *hcl.EvalContext, b *hclsyntax.Body) error {
fqdn := types.FQDNFromResource(r)
fqdn := resources.FQRNFromResource(r)

// set the ID
r.Metadata().ID = fqdn.String()
Expand Down
31 changes: 16 additions & 15 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ import (
"sync"
"testing"

"github.com/jumppad-labs/hclconfig/resources"
"github.com/jumppad-labs/hclconfig/test_fixtures/structs"
"github.com/jumppad-labs/hclconfig/types"
"github.com/stretchr/testify/require"
)

func testSetupConfig(t *testing.T) (*Config, []types.Resource) {
typs := types.DefaultTypes()
typs := resources.DefaultResources()
typs[structs.TypeNetwork] = &structs.Network{}
typs[structs.TypeContainer] = &structs.Container{}
typs[structs.TypeTemplate] = &structs.Template{}

var1, _ := typs.CreateResource(types.TypeVariable, "var1")
var1, _ := typs.CreateResource(resources.TypeVariable, "var1")
var1.Metadata().Checksum = types.Checksum{
Parsed: "123",
Processed: "abc",
Expand All @@ -28,21 +29,21 @@ func testSetupConfig(t *testing.T) (*Config, []types.Resource) {
Processed: "bcd",
}

mod1, _ := typs.CreateResource(types.TypeModule, "module1")
mod1, _ := typs.CreateResource(resources.TypeModule, "module1")
mod1.SetDependsOn([]string{"resource.network.cloud"})
mod1.Metadata().Checksum = types.Checksum{
Parsed: "345",
Processed: "cde",
}

var2, _ := typs.CreateResource(types.TypeVariable, "var2")
var2, _ := typs.CreateResource(resources.TypeVariable, "var2")
var2.Metadata().Module = "module1"
var2.Metadata().Checksum = types.Checksum{
Parsed: "456",
Processed: "def",
}

mod2, _ := typs.CreateResource(types.TypeModule, "module2")
mod2, _ := typs.CreateResource(resources.TypeModule, "module2")
mod2.Metadata().Module = "module1"
mod2.Metadata().Checksum = types.Checksum{
Parsed: "567",
Expand Down Expand Up @@ -87,14 +88,14 @@ func testSetupConfig(t *testing.T) (*Config, []types.Resource) {
Processed: "ijk",
}

out1, _ := typs.CreateResource(types.TypeOutput, "fqdn")
out1, _ := typs.CreateResource(resources.TypeOutput, "fqdn")
out1.Metadata().Module = "module1.module2"
out1.Metadata().Checksum = types.Checksum{
Parsed: "0ab",
Processed: "jkl",
}

out2, _ := typs.CreateResource(types.TypeOutput, "out")
out2, _ := typs.CreateResource(resources.TypeOutput, "out")
out2.SetDependsOn([]string{"resource.network.cloud.id", "resource.container.test_dev"})
out2.Metadata().Checksum = types.Checksum{
Parsed: "abc",
Expand Down Expand Up @@ -293,7 +294,7 @@ func TestRemoveResourceRemoves(t *testing.T) {
}

func TestRemoveResourceNotFoundReturnsError(t *testing.T) {
typs := types.DefaultTypes()
typs := resources.DefaultResources()
typs[structs.TypeNetwork] = &structs.Network{}

c, _ := testSetupConfig(t)
Expand All @@ -315,7 +316,7 @@ func TestToJSONSerializesJSON(t *testing.T) {
}

func TestAppendResourcesMerges(t *testing.T) {
typs := types.DefaultTypes()
typs := resources.DefaultResources()
typs[structs.TypeNetwork] = &structs.Network{}

c, _ := testSetupConfig(t)
Expand All @@ -334,7 +335,7 @@ func TestAppendResourcesMerges(t *testing.T) {
}

func TestAppendResourcesWhenExistsReturnsError(t *testing.T) {
typs := types.DefaultTypes()
typs := resources.DefaultResources()
typs[structs.TypeNetwork] = &structs.Network{}

c, _ := testSetupConfig(t)
Expand All @@ -357,7 +358,7 @@ func TestProcessForwardExecutesCallbacksInCorrectOrder(t *testing.T) {
func(r types.Resource) error {
callSync.Lock()

calls = append(calls, types.ResourceFQRN{
calls = append(calls, resources.FQRN{
Module: r.Metadata().Module,
Resource: r.Metadata().Name,
Type: r.Metadata().Type,
Expand Down Expand Up @@ -389,7 +390,7 @@ func TestProcessReverseExecutesCallbacksInCorrectOrder(t *testing.T) {
func(r types.Resource) error {
callSync.Lock()

calls = append(calls, types.ResourceFQRN{
calls = append(calls, resources.FQRN{
Module: r.Metadata().Module,
Resource: r.Metadata().Name,
Type: r.Metadata().Type,
Expand Down Expand Up @@ -418,7 +419,7 @@ func TestProcessCallbackErrorHaltsExecution(t *testing.T) {
err := c.Walk(
func(r types.Resource) error {
callSync.Lock()
calls = append(calls, types.ResourceFQRN{
calls = append(calls, resources.FQRN{
Module: r.Metadata().Module,
Resource: r.Metadata().Name,
Type: r.Metadata().Type,
Expand Down Expand Up @@ -458,8 +459,8 @@ func TestDiffReturnsResourcesAdded(t *testing.T) {
c, _ := testSetupConfig(t)
new := copyConfig(t, c)

typs := types.DefaultTypes()
var1, _ := typs.CreateResource(types.TypeVariable, "var22")
typs := resources.DefaultResources()
var1, _ := typs.CreateResource(resources.TypeVariable, "var22")
var1.Metadata().Checksum = types.Checksum{
Parsed: "zzz",
Processed: "111",
Expand Down
41 changes: 21 additions & 20 deletions dag.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/jumppad-labs/hclconfig/convert"
"github.com/jumppad-labs/hclconfig/errors"
"github.com/jumppad-labs/hclconfig/resources"
"github.com/jumppad-labs/hclconfig/types"
"github.com/silas/dag"
"github.com/zclconf/go-cty/cty"
Expand All @@ -21,13 +22,13 @@ func doYaLikeDAGs(c *Config) (*dag.AcyclicGraph, error) {
graph := &dag.AcyclicGraph{}

// add a root node for the graph
root, _ := types.DefaultTypes().CreateResource(types.TypeRoot, "root")
root, _ := resources.DefaultResources().CreateResource(resources.TypeRoot, "root")
graph.Add(root)

// Loop over all resources and add to graph
for _, resource := range c.Resources {
// ignore variables
if resource.Metadata().Type != types.TypeVariable {
if resource.Metadata().Type != resources.TypeVariable {
graph.Add(resource)
}
}
Expand All @@ -37,7 +38,7 @@ func doYaLikeDAGs(c *Config) (*dag.AcyclicGraph, error) {
hasDeps := false

// do nothing with variables
if resource.Metadata().Type == types.TypeVariable {
if resource.Metadata().Type == resources.TypeVariable {
continue
}

Expand All @@ -62,7 +63,7 @@ func doYaLikeDAGs(c *Config) (*dag.AcyclicGraph, error) {

for _, d := range resource.GetDependsOn() {
var err error
fqdn, err := types.ParseFQRN(d)
fqdn, err := resources.ParseFQRN(d)
if err != nil {
pe := errors.ParserError{}
pe.Line = resource.Metadata().Line
Expand All @@ -75,7 +76,7 @@ func doYaLikeDAGs(c *Config) (*dag.AcyclicGraph, error) {
}

// when the dependency is a module, depend on all resources in the module
if fqdn.Type == types.TypeModule {
if fqdn.Type == resources.TypeModule {
// assume that all dependencies references have been written with no
// knowledge of their parent module. Therefore if the parent module is
// "module1" and the reference is "module.module2.resource.container.mine.id"
Expand All @@ -100,7 +101,7 @@ func doYaLikeDAGs(c *Config) (*dag.AcyclicGraph, error) {
}

// when the dependency is a resource, depend on the resource
if fqdn.Type != types.TypeModule {
if fqdn.Type != resources.TypeModule {
// assume that all dependencies references have been written with no
// knowledge of their parent module. Therefore if the parent module is
// "module1" and the reference is "module.module2.resource.container.mine.id"
Expand Down Expand Up @@ -173,7 +174,7 @@ func createCallback(c *Config, wf WalkCallback) func(v dag.Vertex) (diags dag.Di
}

// if this is the root module or is disabled skip or is a variable
if (r.Metadata().Type == types.TypeRoot) || r.GetDisabled() || r.Metadata().Type == types.TypeVariable {
if (r.Metadata().Type == resources.TypeRoot) || r.GetDisabled() || r.Metadata().Type == resources.TypeVariable {
return nil
}

Expand All @@ -191,7 +192,7 @@ func createCallback(c *Config, wf WalkCallback) func(v dag.Vertex) (diags dag.Di
// all linked values should now have been processed as the graph
// will have handled them first
for _, v := range r.Metadata().Links {
fqrn, err := types.ParseFQRN(v)
fqrn, err := resources.ParseFQRN(v)
if err != nil {
pe := errors.ParserError{}
pe.Filename = r.Metadata().File
Expand Down Expand Up @@ -221,11 +222,11 @@ func createCallback(c *Config, wf WalkCallback) func(v dag.Vertex) (diags dag.Di
// once we have found a resource convert it to a cty type and then
// set it on the context
switch l.Metadata().Type {
case types.TypeLocal:
loc := l.(*types.Local)
case resources.TypeLocal:
loc := l.(*resources.Local)
ctyRes = loc.CtyValue
case types.TypeOutput:
out := l.(*types.Output)
case resources.TypeOutput:
out := l.(*resources.Output)
ctyRes = out.CtyValue
default:
ctyRes, err = convert.GoToCtyValue(l)
Expand Down Expand Up @@ -278,7 +279,7 @@ func createCallback(c *Config, wf WalkCallback) func(v dag.Vertex) (diags dag.Di
// if the type is a module the potentially we only just found out that we should be
// disabled
// as an additional check, set all module resources to disabled if the module is disabled
if r.GetDisabled() && r.Metadata().Type == types.TypeModule {
if r.GetDisabled() && r.Metadata().Type == resources.TypeModule {
// find all dependent resources
dr, err := c.FindModuleResources(r.Metadata().ID, true)
if err != nil {
Expand All @@ -304,7 +305,7 @@ func createCallback(c *Config, wf WalkCallback) func(v dag.Vertex) (diags dag.Di
//
// if disabled was set through interpolation, the value has only been set here
// we need to handle an additional check
if !r.GetDisabled() && r.Metadata().Type != types.TypeModule {
if !r.GetDisabled() && r.Metadata().Type != resources.TypeModule {

// call the callbacks
if wf != nil {
Expand All @@ -324,8 +325,8 @@ func createCallback(c *Config, wf WalkCallback) func(v dag.Vertex) (diags dag.Di

// if the type is a module we need to add the variables to the
// context
if r.Metadata().Type == types.TypeModule {
mod := r.(*types.Module)
if r.Metadata().Type == resources.TypeModule {
mod := r.(*resources.Module)

var mapVars map[string]cty.Value
if att, ok := mod.Variables.(*hcl.Attribute); ok {
Expand All @@ -340,16 +341,16 @@ func createCallback(c *Config, wf WalkCallback) func(v dag.Vertex) (diags dag.Di

// if this is an output or local we need to convert the value into
// a go type
if r.Metadata().Type == types.TypeOutput {
o := r.(*types.Output)
if r.Metadata().Type == resources.TypeOutput {
o := r.(*resources.Output)

if !o.CtyValue.IsNull() {
o.Value = castVar(o.CtyValue)
}
}

if r.Metadata().Type == types.TypeLocal {
o := r.(*types.Local)
if r.Metadata().Type == resources.TypeLocal {
o := r.(*resources.Local)

if !o.CtyValue.IsNull() {
o.Value = castVar(o.CtyValue)
Expand Down
3 changes: 2 additions & 1 deletion example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"

"github.com/jumppad-labs/hclconfig"
"github.com/jumppad-labs/hclconfig/resources"
"github.com/jumppad-labs/hclconfig/types"
)

Expand Down Expand Up @@ -89,7 +90,7 @@ func printConfig(c *hclconfig.Config) {
fmt.Println(printPostgres(t, 2))

case "output":
t := r.(*types.Output)
t := r.(*resources.Output)
fmt.Printf(" Postgres %s\n", t.Meta.Name)
fmt.Printf(" Module %s\n", t.Meta.Module)
fmt.Printf(" --- Value: %s\n", t.Value)
Expand Down

0 comments on commit 2b82646

Please sign in to comment.