Skip to content

Commit

Permalink
Merge pull request #13 from datadrivers/fix/name-generation
Browse files Browse the repository at this point in the history
fix(name): Fix validation and handling of name variable
  • Loading branch information
anmoel authored Jun 27, 2022
2 parents 8a4a27c + 64f94a8 commit f507ce8
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 159 deletions.
40 changes: 0 additions & 40 deletions .github/workflows/add-content-to-project.yml

This file was deleted.

68 changes: 68 additions & 0 deletions internal/provider/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package provider

import (
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"k8s.io/apimachinery/pkg/util/rand"
)

// validateInputs checks if all needed inputs are set
func validateInputs(inputs map[string]string, variables []Variable) diag.Diagnostics {
var diags diag.Diagnostics

missingInputs := []string{}
for _, variable := range variables {
if variable.Default.IsNull() && (variable.Generated.IsNull() || !variable.Generated.Value) {
if _, ok := inputs[variable.Name.Value]; !ok && variable.Name.Value != "name" {
missingInputs = append(missingInputs, variable.Name.Value)
}
}

}
if len(missingInputs) > 0 {
diags.AddError(
"Convention Usage Error",
fmt.Sprintf("All convention variables that are not generated or have a default must be present. Missing inputs: %s", strings.Join(missingInputs, ", ")),
)
}

return diags
}

// generateName generates the name with the inputs, variables and definition
func generateName(name string, inputs map[string]string, convention Convention) (types.String, diag.Diagnostics) {
var diags diag.Diagnostics

result := convention.Definition

for _, variable := range convention.Variables {
block := fmt.Sprintf("(%s)", variable.Name.Value)
replacement := inputs[variable.Name.Value]
if variable.Name.Value == "name" {
replacement = name
}
length := 0

if !variable.MaxLength.IsNull() && variable.MaxLength.Value > int64(0) {
length = int(variable.MaxLength.Value)
}

if !variable.Generated.IsNull() && variable.Generated.Value {
replacement = rand.String(length)
}

if replacement == "" {
replacement = variable.Default.Value
}

if length > 0 && len(replacement) > length {
replacement = replacement[0:length]
}
result = strings.Replace(result, block, replacement, -1)
}

return types.String{Value: result}, diags
}
145 changes: 145 additions & 0 deletions internal/provider/helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package provider

import (
"testing"

// "github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/stretchr/testify/assert"
)

func TestValidateInputs(t *testing.T) {
variables := []Variable{
{
Name: types.String{Value: "name"},
Generated: types.Bool{
Null: true,
},
Default: types.String{
Null: true,
},
MaxLength: types.Int64{
Null: false,
Value: int64(8),
},
},
{
Name: types.String{Value: "not-generated"},
Generated: types.Bool{
Null: true,
Value: false,
},
Default: types.String{
Null: true,
},
MaxLength: types.Int64{
Null: true,
},
},
{
Name: types.String{Value: "generated"},
Generated: types.Bool{Value: true},
Default: types.String{
Null: true,
},
MaxLength: types.Int64{
Null: true,
},
},
{
Name: types.String{Value: "default"},
Generated: types.Bool{
Null: true,
},
Default: types.String{
Null: false,
Value: "default",
},
MaxLength: types.Int64{
Null: true,
},
},
}

inputs := map[string]string{
"not-generated": "test",
}

diags := validateInputs(inputs, variables)
assert.False(t, diags.HasError())

inputs2 := map[string]string{
"generated": "test",
}
diags2 := validateInputs(inputs2, variables)

assert.True(t, diags2.HasError())
}

func TestGenerateName(t *testing.T) {
name := "foobar"
convention := Convention{
Definition: "(name)-(not-generated)-(default)-(generated)",
Variables: []Variable{
{
Name: types.String{Value: "name"},
Generated: types.Bool{
Null: true,
},
Default: types.String{
Null: true,
},
MaxLength: types.Int64{
Null: false,
Value: int64(3),
},
},
{
Name: types.String{Value: "not-generated"},
Generated: types.Bool{
Null: true,
Value: false,
},
Default: types.String{
Null: true,
},
MaxLength: types.Int64{
Null: true,
},
},
{
Name: types.String{Value: "generated"},
Generated: types.Bool{
Value: true,
Null: false,
},
MaxLength: types.Int64{
Null: false,
Value: int64(4),
},
},
{
Name: types.String{Value: "default"},
Generated: types.Bool{
Null: true,
},
Default: types.String{
Null: false,
Value: "default",
},
MaxLength: types.Int64{
Null: true,
},
},
},
}

inputs := map[string]string{
"not-generated": "bar",
}

result, diags := generateName(name, inputs, convention)
assert.False(t, diags.HasError())
assert.Contains(t, result.Value, "foo-bar-default-")
assert.Len(t, result.Value, 20)
}
58 changes: 2 additions & 56 deletions internal/provider/resource_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import (
"context"
"encoding/json"
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"k8s.io/apimachinery/pkg/util/rand"
)

// Ensure provider defined types fully satisfy framework interfaces
Expand Down Expand Up @@ -107,7 +105,7 @@ func (r nameResource) Create(ctx context.Context, req tfsdk.CreateResourceReques
return
}

result, diags := generateName(resourceData.Name.Value, inputs, &convention)
result, diags := generateName(resourceData.Name.Value, inputs, convention)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
Expand Down Expand Up @@ -173,7 +171,7 @@ func (r nameResource) Update(ctx context.Context, req tfsdk.UpdateResourceReques
return
}

result, diags := generateName(resourceData.Name.Value, inputs, &convention)
result, diags := generateName(resourceData.Name.Value, inputs, convention)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
Expand All @@ -192,55 +190,3 @@ func (r nameResource) Update(ctx context.Context, req tfsdk.UpdateResourceReques
func (r nameResource) Delete(ctx context.Context, req tfsdk.DeleteResourceRequest, resp *tfsdk.DeleteResourceResponse) {
resp.State.RemoveResource(ctx)
}

// validateInputs checks if all needed inputs are set
func validateInputs(inputs map[string]string, variables []Variable) diag.Diagnostics {
var diags diag.Diagnostics

missingInputs := []string{}
for _, variable := range variables {
if variable.Default.IsNull() && (variable.Generated.IsNull() || !variable.Generated.Value) {
if _, ok := inputs[variable.Name.Value]; !ok {
missingInputs = append(missingInputs, variable.Name.Value)
}
}

}
if len(missingInputs) > 0 {
diags.AddError(
"Convention Usage Error",
fmt.Sprintf("All convention variables that are not generated or have a default must be present. Missing inputs: %s", strings.Join(missingInputs, ", ")),
)
}

return diags
}

// generateName generates the name with the inputs, variables and definition
func generateName(name string, inputs map[string]string, convention *Convention) (types.String, diag.Diagnostics) {
var diags diag.Diagnostics
result := strings.Replace(convention.Definition, "(name)", name, -1)

for _, variable := range convention.Variables {
block := fmt.Sprintf("(%s)", variable.Name.Value)
replacement := inputs[variable.Name.Value]
length := 0

if !variable.MaxLength.Null && variable.MaxLength.Value > int64(0) {
length = int(variable.MaxLength.Value)
}
if variable.Generated.Value {
replacement = rand.String(length)
}

if replacement == "" {
replacement = variable.Default.Value
}
if length > 0 && len(replacement) > length {
replacement = replacement[0:length]
}
result = strings.Replace(result, block, replacement, -1)
}

return types.String{Value: result}, diags
}
Loading

0 comments on commit f507ce8

Please sign in to comment.