Skip to content

Commit

Permalink
Merge pull request #84 from humanitec/fix-creds
Browse files Browse the repository at this point in the history
fix: double encoding in registry creds
  • Loading branch information
johanneswuerbach authored May 7, 2024
2 parents 18b43d1 + 7b314bf commit 0a6ea3e
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 52 deletions.
37 changes: 16 additions & 21 deletions internal/provider/resource_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"

"github.com/humanitec/humanitec-go-autogen"
"github.com/humanitec/humanitec-go-autogen/client"
Expand Down Expand Up @@ -122,12 +121,17 @@ func (r *ResourceRegistry) Configure(ctx context.Context, req resource.Configure
r.orgID = resdata.OrgID
}

type RegistryCredsModel struct {
Username types.String `tfsdk:"username"`
Password types.String `tfsdk:"password"`
}

type RegistryModel struct {
ID types.String `tfsdk:"id"`
Registry types.String `tfsdk:"registry"`
Type types.String `tfsdk:"type"`
EnableCI types.Bool `tfsdk:"enable_ci"`
Creds types.Object `tfsdk:"creds"`
Creds *RegistryCredsModel `tfsdk:"creds"`
Secrets *map[string]SecretsModel `tfsdk:"secrets"`
}

Expand All @@ -146,7 +150,7 @@ func (r *ResourceRegistry) Create(ctx context.Context, req resource.CreateReques
return
}

request, diags := parseRegistryModel(ctx, data)
request, diags := parseRegistryModel(data)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
Expand All @@ -172,7 +176,7 @@ func (r *ResourceRegistry) Create(ctx context.Context, req resource.CreateReques
return
}

diags = parseRegistryResponse(ctx, registry, data)
diags = parseRegistryResponse(registry, data)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
Expand All @@ -185,13 +189,9 @@ func (r *ResourceRegistry) Create(ctx context.Context, req resource.CreateReques
func (r *ResourceRegistry) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var data *RegistryModel

tflog.Info(ctx, fmt.Sprintf("start"))

// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)

tflog.Info(ctx, fmt.Sprintf("data: %v", data))

if resp.Diagnostics.HasError() {
return
}
Expand All @@ -205,7 +205,6 @@ func (r *ResourceRegistry) Read(ctx context.Context, req resource.ReadRequest, r
return
}

tflog.Info(ctx, fmt.Sprintf("resp: %v", getRegistryResp.JSON200))
switch getRegistryResp.StatusCode() {
case http.StatusOK:
registry = getRegistryResp.JSON200
Expand All @@ -218,8 +217,7 @@ func (r *ResourceRegistry) Read(ctx context.Context, req resource.ReadRequest, r
return
}

diags := parseRegistryResponse(ctx, registry, data)
tflog.Info(ctx, fmt.Sprintf("parse: %v", data))
diags := parseRegistryResponse(registry, data)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
Expand All @@ -241,7 +239,7 @@ func (r *ResourceRegistry) Update(ctx context.Context, req resource.UpdateReques

id := state.ID.ValueString()

request, diags := parseRegistryModel(ctx, data)
request, diags := parseRegistryModel(data)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
Expand Down Expand Up @@ -273,7 +271,7 @@ func (r *ResourceRegistry) Update(ctx context.Context, req resource.UpdateReques
return
}

diags = parseRegistryResponse(ctx, registry, data)
diags = parseRegistryResponse(registry, data)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
Expand Down Expand Up @@ -329,17 +327,14 @@ func (r *ResourceRegistry) ImportState(ctx context.Context, req resource.ImportS
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), req.ID)...)
}

func parseRegistryModel(ctx context.Context, data *RegistryModel) (*client.RegistryRequest, diag.Diagnostics) {
func parseRegistryModel(data *RegistryModel) (*client.RegistryRequest, diag.Diagnostics) {
totalDiags := diag.Diagnostics{}

var creds *client.AccountCredsRequest
if !data.Creds.IsNull() {
dataCreds := data.Creds.Attributes()
password := dataCreds["password"].String()
username := dataCreds["username"].String()
if data.Creds != nil {
creds = &client.AccountCredsRequest{
Password: password,
Username: username,
Password: data.Creds.Password.ValueString(),
Username: data.Creds.Username.ValueString(),
}
}

Expand All @@ -365,7 +360,7 @@ func parseRegistryModel(ctx context.Context, data *RegistryModel) (*client.Regis
}, totalDiags
}

func parseRegistryResponse(ctx context.Context, res *client.RegistryResponse, data *RegistryModel) diag.Diagnostics {
func parseRegistryResponse(res *client.RegistryResponse, data *RegistryModel) diag.Diagnostics {
totalDiags := diag.Diagnostics{}

data.ID = types.StringValue(res.Id)
Expand Down
126 changes: 95 additions & 31 deletions internal/provider/resource_registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,77 @@ import (
"testing"
"time"

"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/stretchr/testify/assert"
)

func TestAccResourceRegistry(t *testing.T) {
id := fmt.Sprintf("test-%d", time.Now().UnixNano())
registry := fmt.Sprintf("test-%d.com.pl", time.Now().UnixNano())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and Read testing
{
Config: testAccResourceRegistry(id, registry, false),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "id", id),
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "registry", registry),
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "enable_ci", "false"),
),
testCases := []struct {
name string
configCreate func(id, registry string) string
configUpdate func(id, registry string) string
}{
{
name: "WithSecrets",
configCreate: func(id, registry string) string {
return testAccResourceRegistry(id, registry, false)
},
configUpdate: func(id, registry string) string {
return testAccResourceRegistry(id, registry, true)
},
// ImportState testing
{
ResourceName: "humanitec_registry.registry_test",
ImportStateId: id,
ImportState: true,
ImportStateVerify: true,
},
{
name: "WithCreds",
configCreate: func(id, registry string) string {
return testAccResourceRegistryCreds(id, registry, false)
},
// Update testing
{
Config: testAccResourceRegistry(id, registry, true),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "id", id),
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "registry", registry),
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "enable_ci", "true"),
),
configUpdate: func(id, registry string) string {
return testAccResourceRegistryCreds(id, registry, true)
},
// Delete testing automatically occurs in TestCase
},
})
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
id := fmt.Sprintf("test-%d", time.Now().UnixNano())
registry := fmt.Sprintf("test-%d.com.pl", time.Now().UnixNano())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and Read testing
{
Config: tc.configCreate(id, registry),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "id", id),
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "registry", registry),
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "enable_ci", "false"),
),
},
// ImportState testing
{
ResourceName: "humanitec_registry.registry_test",
ImportStateId: id,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"creds"},
},
// Update testing
{
Config: tc.configUpdate(id, registry),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "id", id),
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "registry", registry),
resource.TestCheckResourceAttr("humanitec_registry.registry_test", "enable_ci", "true"),
),
},
// Delete testing automatically occurs in TestCase
},
})
})
}
}

func testAccResourceRegistry(id, registry string, enable_ci bool) string {
Expand All @@ -65,3 +97,35 @@ resource "humanitec_registry" "registry_test" {
}
}`, id, registry, enable_ci)
}

func testAccResourceRegistryCreds(id, registry string, enable_ci bool) string {
return fmt.Sprintf(`
resource "humanitec_registry" "registry_test" {
id = "%s"
registry = "%s"
type = "amazon_ecr"
enable_ci = %t
creds = {
username = "test-username"
password = "test-password"
}
}`, id, registry, enable_ci)
}

func TestParseRegistryModel(t *testing.T) {
assert := assert.New(t)

registry := &RegistryModel{
ID: types.StringValue("test-id"),
Creds: &RegistryCredsModel{
Username: types.StringValue("test-username"),
Password: types.StringValue("test-password"),
},
}

model, diags := parseRegistryModel(registry)
assert.Empty(diags)
assert.Equal("test-id", model.Id)
assert.Equal("test-username", model.Creds.Username)
assert.Equal("test-password", model.Creds.Password)
}

0 comments on commit 0a6ea3e

Please sign in to comment.