Skip to content

Commit

Permalink
Read profile and group from matchbox to detect drift
Browse files Browse the repository at this point in the history
* Update the profile resource ReadContextFunc function to
query matchbox for the profile and detect changes from state
* Update the group resource ReadContextFunc function to
query matchbox for the group and detect changes from state
  • Loading branch information
Nick-Triller authored and dghubble committed Jul 20, 2022
1 parent ec34e61 commit 010a7d2
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 15 deletions.
22 changes: 20 additions & 2 deletions matchbox/resource_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package matchbox

import (
"context"
"encoding/json"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

matchbox "github.com/poseidon/matchbox/matchbox/client"

"github.com/poseidon/matchbox/matchbox/server/serverpb"
"github.com/poseidon/matchbox/matchbox/storage/storagepb"
)
Expand Down Expand Up @@ -82,14 +83,31 @@ func resourceGroupRead(ctx context.Context, d *schema.ResourceData, meta interfa
client := meta.(*matchbox.Client)

name := d.Get("name").(string)
_, err := client.Groups.GroupGet(ctx, &serverpb.GroupGetRequest{
groupGetResponse, err := client.Groups.GroupGet(ctx, &serverpb.GroupGetRequest{
Id: name,
})

if err != nil {
// resource doesn't exist anymore
d.SetId("")
return nil
}

group := groupGetResponse.Group

var metadata map[string]string
if err := json.Unmarshal(group.Metadata, &metadata); err != nil {
return diag.FromErr(err)
}
if err := d.Set("selector", group.Selector); err != nil {
return diag.FromErr(err)
}
if err := d.Set("profile", group.Profile); err != nil {
return diag.FromErr(err)
}
if err := d.Set("metadata", metadata); err != nil {
return diag.FromErr(err)
}
return diags
}

Expand Down
48 changes: 44 additions & 4 deletions matchbox/resource_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ func TestResourceGroup(t *testing.T) {

hcl := `
resource "matchbox_group" "default" {
name = "default"
profile = "foo"
selector = {
name = "default"
profile = "foo"
selector = {
qux = "baz"
}
metadata = {
foo = "bar"
}
}
}
`

Expand Down Expand Up @@ -62,3 +62,43 @@ func TestResourceGroup(t *testing.T) {
}},
})
}

// TestResourceGroup_Read checks the provider compares the desired state with the actual matchbox state and not only
// the Terraform state.
func TestResourceGroup_Read(t *testing.T) {
srv := NewFixtureServer(clientTLSInfo, serverTLSInfo, testfakes.NewFixedStore())
go srv.Start()
defer srv.Stop()

hcl := `
resource "matchbox_group" "default" {
name = "default"
profile = "foo"
selector = {
qux = "baz"
}
metadata = {
foo = "bar"
}
}
`

resource.UnitTest(t, resource.TestCase{
Providers: testProviders,
Steps: []resource.TestStep{
{
Config: srv.AddProviderConfig(hcl),
},
{
PreConfig: func() {
group, _ := srv.Store.GroupGet("default")
group.Selector["bux"] = "qux"
},
Config: srv.AddProviderConfig(hcl),
PlanOnly: true,
ExpectNonEmptyPlan: true,
},
},
})
}
41 changes: 32 additions & 9 deletions matchbox/resource_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand Down Expand Up @@ -151,7 +152,7 @@ func resourceProfileRead(ctx context.Context, d *schema.ResourceData, meta inter

// Profile
name := d.Get("name").(string)
_, err := client.Profiles.ProfileGet(ctx, &serverpb.ProfileGetRequest{
profileGetResponse, err := client.Profiles.ProfileGet(ctx, &serverpb.ProfileGetRequest{
Id: name,
})
if err != nil {
Expand All @@ -160,28 +161,50 @@ func resourceProfileRead(ctx context.Context, d *schema.ResourceData, meta inter
return diags
}

// Container Linux Config
if name, content := containerLinuxConfig(d); content != "" {
_, err = client.Ignition.IgnitionGet(ctx, &serverpb.IgnitionGetRequest{
Name: name,
profile := profileGetResponse.Profile
if err := d.Set("kernel", profile.Boot.Kernel); err != nil {
return diag.FromErr(err)
}
if err := d.Set("initrd", profile.Boot.Initrd); err != nil {
return diag.FromErr(err)
}
if err := d.Set("args", profile.Boot.Args); err != nil {
return diag.FromErr(err)
}

if profile.IgnitionId != "" {
ignition, err := client.Ignition.IgnitionGet(ctx, &serverpb.IgnitionGetRequest{
Name: profile.IgnitionId,
})
if err != nil {
// resource doesn't exist or is corrupted and needs creating
d.SetId("")
return diags
}
// .ign and .ignition files indicate raw ignition,
// see https://github.com/poseidon/matchbox/blob/d6bb21d5853e7af7c3c54b74537176caf5460482/matchbox/http/ignition.go#L18
if strings.HasSuffix(profile.IgnitionId, ".ign") || strings.HasSuffix(profile.IgnitionId, ".ignition") {
err = d.Set("raw_ignition", string(ignition.Config))
} else {
err = d.Set("container_linux_config", string(ignition.Config))
}
if err != nil {
return diag.FromErr(err)
}
}

// Generic Config
if name, content := genericConfig(d); content != "" {
_, err = client.Generic.GenericGet(ctx, &serverpb.GenericGetRequest{
Name: name,
if profile.GenericId != "" {
ignition, err := client.Generic.GenericGet(ctx, &serverpb.GenericGetRequest{
Name: profile.GenericId,
})
if err != nil {
// resource doesn't exist or is corrupted and needs creating
d.SetId("")
return diags
}
if err := d.Set("generic_config", string(ignition.Config)); err != nil {
return diag.FromErr(err)
}
}

return diags
Expand Down
43 changes: 43 additions & 0 deletions matchbox/resource_profile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,5 +164,48 @@ func TestResourceProfile_withIgnitionAndContainerLinuxConfig(t *testing.T) {
ExpectError: regexp.MustCompile("are mutually exclusive"),
}},
})
}

// TestResourceProfile_Read checks the provider compares the desired state with the actual matchbox state and not only
// the Terraform state.
func TestResourceProfile_Read(t *testing.T) {
srv := NewFixtureServer(clientTLSInfo, serverTLSInfo, testfakes.NewFixedStore())
go srv.Start()
defer srv.Stop()

hcl := `
resource "matchbox_profile" "default" {
name = "default"
kernel = "foo"
initrd = [
"bar",
]
args = [
"qux",
]
raw_ignition = "baz"
}
`

resource.UnitTest(t, resource.TestCase{
Providers: testProviders,
Steps: []resource.TestStep{
{
Config: srv.AddProviderConfig(hcl),
},
{
PreConfig: func() {
profile, _ := srv.Store.ProfileGet("default")
profile.Boot.Args = append(profile.Boot.Args, "bux")

},
Config: srv.AddProviderConfig(hcl),
PlanOnly: true,
ExpectNonEmptyPlan: true,
},
},
})
}

0 comments on commit 010a7d2

Please sign in to comment.