Skip to content

Commit

Permalink
Merge pull request #30 from rackn/datasource-import
Browse files Browse the repository at this point in the history
Add datasource and import capability
  • Loading branch information
galthaus authored Feb 13, 2018
2 parents 1124243 + b2baf99 commit c51417d
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 46 deletions.
4 changes: 4 additions & 0 deletions drp/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ func Provider() terraform.ResourceProvider {
ResourcesMap: map[string]*schema.Resource{
"drp_machine": resourceMachine(),
},
DataSourcesMap: map[string]*schema.Resource{
"drp_machine": dataSourceMachine(),
},

ConfigureFunc: providerConfigure,
}
Expand All @@ -66,6 +69,7 @@ func Provider() terraform.ResourceProvider {
spref = "raw_machine"
}
p.ResourcesMap[fmt.Sprintf("drp_%s", spref)] = resourceGeneric(pref)
p.DataSourcesMap[fmt.Sprintf("drp_%s", spref)] = dataSourceGeneric(pref)
}

return p
Expand Down
2 changes: 1 addition & 1 deletion drp/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestMain(m *testing.M) {
"--static-port", "10032",
"--tftp-port", "10033",
"--dhcp-port", "10034",
"--pxe-port", "10035",
"--binl-port", "10035",
"--fake-pinger",
"--drp-id", "Fred",
"--backend", "memory:///",
Expand Down
34 changes: 33 additions & 1 deletion drp/resource_drp_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,43 @@ import (
"github.com/hashicorp/terraform/helper/schema"
)

func dataSourceMachine() *schema.Resource {
log.Println("[DEBUG] [dataSourceMachine] Initializing data structure")

m, _ := models.New("machine")
r := buildSchema(m, false)
r.Create = nil
r.Update = nil
r.Delete = nil
r.Importer = nil
r.Exists = nil

// Machines also have filters
r.Schema["filters"] = &schema.Schema{
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
},
"jsonvalue": {
Type: schema.TypeString,
Optional: true,
},
},
},
}
return r
}

func resourceMachine() *schema.Resource {
log.Println("[DEBUG] [resourceMachine] Initializing data structure")

m, _ := models.New("machine")
r := buildSchema(m)
r := buildSchema(m, true)

r.Create = resourceMachineCreate
r.Update = resourceMachineUpdate
Expand Down
20 changes: 16 additions & 4 deletions drp/resource_drp_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ var testAccDrpPlugin_basic = `

func TestAccDrpPlugin_basic(t *testing.T) {
plugin := models.Plugin{Name: "foo",
Provider: "ipmi",
Meta: map[string]string{"field1": "value1", "field2": "value2"},
Provider: "ipmi",
Meta: map[string]string{"field1": "value1", "field2": "value2"},
PluginErrors: []string{"Missing Plugin Provider: ipmi"},
}
plugin.Fill()

Expand Down Expand Up @@ -56,9 +57,19 @@ var testAccDrpPlugin_change_2 = `
}`

func TestAccDrpPlugin_change(t *testing.T) {
plugin1 := models.Plugin{Name: "foo", Description: "I am a plugin", Provider: "ipmi"}
plugin1 := models.Plugin{
Name: "foo",
Description: "I am a plugin",
Provider: "ipmi",
PluginErrors: []string{"Missing Plugin Provider: ipmi"},
}
plugin1.Fill()
plugin2 := models.Plugin{Name: "foo", Description: "I am a plugin again", Provider: "ipmi"}
plugin2 := models.Plugin{
Name: "foo",
Description: "I am a plugin again",
Provider: "ipmi",
PluginErrors: []string{"Missing Plugin Provider: ipmi"},
}
plugin2.Fill()

resource.Test(t, resource.TestCase{
Expand Down Expand Up @@ -102,6 +113,7 @@ func TestAccDrpPlugin_withParams(t *testing.T) {
"test/bool": true,
"test/list": []string{"one", "two"},
},
PluginErrors: []string{"Missing Plugin Provider: ipmi"},
}
plugin.Fill()

Expand Down
26 changes: 13 additions & 13 deletions drp/resource_drp_subnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ func TestAccDrpSubnet_basic(t *testing.T) {
Strategy: "MAC",
Meta: map[string]string{"field1": "value1", "field2": "value2"},
Pickers: []string{"hint", "nextFree", "mostExpired"},
Options: []*models.DhcpOption{
&models.DhcpOption{Code: 1, Value: "255.255.255.0"},
&models.DhcpOption{Code: 28, Value: "1.1.1.255"},
Options: []models.DhcpOption{
models.DhcpOption{Code: 1, Value: "255.255.255.0"},
models.DhcpOption{Code: 28, Value: "1.1.1.255"},
},
}

Expand Down Expand Up @@ -112,11 +112,11 @@ func TestAccDrpSubnet_change(t *testing.T) {
ActiveEnd: net.ParseIP("1.1.1.9"),
Strategy: "MAC",
Pickers: []string{"none"},
Options: []*models.DhcpOption{
&models.DhcpOption{Code: 30, Value: "fred"},
&models.DhcpOption{Code: 3, Value: "1.1.1.1"},
&models.DhcpOption{Code: 1, Value: "255.255.255.0"},
&models.DhcpOption{Code: 28, Value: "1.1.1.255"},
Options: []models.DhcpOption{
models.DhcpOption{Code: 30, Value: "fred"},
models.DhcpOption{Code: 3, Value: "1.1.1.1"},
models.DhcpOption{Code: 1, Value: "255.255.255.0"},
models.DhcpOption{Code: 28, Value: "1.1.1.255"},
},
}
subnet1.Fill()
Expand All @@ -129,11 +129,11 @@ func TestAccDrpSubnet_change(t *testing.T) {
ActiveEnd: net.ParseIP("1.1.1.10"),
Strategy: "MAC",
Pickers: []string{"hint", "none"},
Options: []*models.DhcpOption{
&models.DhcpOption{Code: 33, Value: "fred"},
&models.DhcpOption{Code: 4, Value: "1.2.1.1"},
&models.DhcpOption{Code: 1, Value: "255.255.255.0"},
&models.DhcpOption{Code: 28, Value: "1.1.1.255"},
Options: []models.DhcpOption{
models.DhcpOption{Code: 33, Value: "fred"},
models.DhcpOption{Code: 4, Value: "1.2.1.1"},
models.DhcpOption{Code: 1, Value: "255.255.255.0"},
models.DhcpOption{Code: 28, Value: "1.1.1.255"},
},
}
subnet2.Fill()
Expand Down
8 changes: 4 additions & 4 deletions drp/resource_drp_task_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ var testAccDrpTask_basic = `
resource "drp_task" "foo" {
Name = "foo"
Meta = {
"feature-flags" = "original-exit-codes"
"feature-flags" = "sane-exit-codes"
"field1" = "value1"
"field2" = "value2"
}
}`

func TestAccDrpTask_basic(t *testing.T) {
task := models.Task{Name: "foo",
Meta: map[string]string{"field1": "value1", "field2": "value2", "feature-flags": "original-exit-codes"},
Meta: map[string]string{"field1": "value1", "field2": "value2", "feature-flags": "sane-exit-codes"},
}
task.Fill()

Expand Down Expand Up @@ -71,7 +71,7 @@ func TestAccDrpTask_change(t *testing.T) {
Name: "foo",
Description: "I am a task",
Documentation: "I am docs",
Meta: map[string]string{"feature-flags": "original-exit-codes"},
Meta: map[string]string{"feature-flags": "sane-exit-codes"},
RequiredParams: []string{"p1", "p2"},
OptionalParams: []string{"p3", "p4"},
Templates: []models.TemplateInfo{
Expand All @@ -84,7 +84,7 @@ func TestAccDrpTask_change(t *testing.T) {
Name: "foo",
Description: "I am a task again",
Documentation: "I am docs more so",
Meta: map[string]string{"feature-flags": "original-exit-codes"},
Meta: map[string]string{"feature-flags": "sane-exit-codes"},
RequiredParams: []string{"p3", "p4"},
OptionalParams: []string{"p1", "p2"},
Templates: []models.TemplateInfo{
Expand Down
69 changes: 51 additions & 18 deletions drp/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ import (
"github.com/pborman/uuid"
)

func buildSchemaListFromObject(m interface{}) *schema.Schema {
func buildSchemaListFromObject(m interface{}, computed bool) *schema.Schema {
r := &schema.Resource{
Schema: buildSchemaFromObject(m),
Schema: buildSchemaFromObject(m, computed),
}
return &schema.Schema{
Type: schema.TypeList,
Elem: r,
Optional: true,
Computed: true,
Computed: computed,
}
}

func buildSchemaFromObject(m interface{}) map[string]*schema.Schema {
func buildSchemaFromObject(m interface{}, computed bool) map[string]*schema.Schema {
sm := map[string]*schema.Schema{}

val := reflect.ValueOf(m).Elem()
Expand Down Expand Up @@ -66,7 +66,7 @@ func buildSchemaFromObject(m interface{}) map[string]*schema.Schema {
Type: schema.TypeString,
},
Optional: true,
Computed: true,
Computed: computed,
}

continue
Expand All @@ -85,15 +85,15 @@ func buildSchemaFromObject(m interface{}) map[string]*schema.Schema {
Type: schema.TypeString,
},
Optional: true,
Computed: true,
Computed: computed,
}
continue
}
if fieldName == "Schema" {
sm["Schema"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
Computed: computed,
}
continue
}
Expand All @@ -109,18 +109,18 @@ func buildSchemaFromObject(m interface{}) map[string]*schema.Schema {
Type: schema.TypeString,
},
Optional: true,
Computed: true,
Computed: computed,
}
case "models.DhcpOption", "*models.DhcpOption":
sm[fieldName] = buildSchemaListFromObject(&models.DhcpOption{})
sm[fieldName] = buildSchemaListFromObject(&models.DhcpOption{}, computed)

case "models.TemplateInfo":
sm[fieldName] = buildSchemaListFromObject(&models.TemplateInfo{})
sm[fieldName] = buildSchemaListFromObject(&models.TemplateInfo{}, computed)
case "uint8":
sm[fieldName] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
Computed: computed,
}
default:
fmt.Printf("[DEBUG] UNKNOWN List Field Name: %s (%s),\t Tag Value: %s\n",
Expand All @@ -133,24 +133,24 @@ func buildSchemaFromObject(m interface{}) map[string]*schema.Schema {
switch typeField.Type.String() {
case "models.OsInfo":
// Singleton struct - encode as a list for now.
sm[fieldName] = buildSchemaListFromObject(&models.OsInfo{})
sm[fieldName] = buildSchemaListFromObject(&models.OsInfo{}, computed)
case "string", "net.IP", "uuid.UUID", "time.Time":
sm[fieldName] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
Computed: computed,
}
case "bool":
sm[fieldName] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Computed: true,
Computed: computed,
}
case "int", "int32", "uint8":
sm[fieldName] = &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Computed: true,
Computed: computed,
}
default:
fmt.Printf("[DEBUG] UNKNOWN Base Field Name: %s (%s),\t Tag Value: %s\n",
Expand All @@ -162,20 +162,36 @@ func buildSchemaFromObject(m interface{}) map[string]*schema.Schema {
return sm
}

func dataSourceGeneric(pref string) *schema.Resource {
log.Printf("[DEBUG] [dataSourceGeneric] Initializing data structure: %s\n", pref)
m, _ := models.New(pref)
r := buildSchema(m, false)
r.Read = createDefaultDataSourceReadFunction(m)
r.Create = nil
r.Update = nil
r.Delete = nil
r.Importer = nil
r.Exists = nil
return r
}

func resourceGeneric(pref string) *schema.Resource {
log.Printf("[DEBUG] [resourceGeneric] Initializing data structure: %s\n", pref)
m, _ := models.New(pref)
return buildSchema(m)
return buildSchema(m, true)
}

func buildSchema(m models.Model) *schema.Resource {
func buildSchema(m models.Model, computed bool) *schema.Resource {
r := &schema.Resource{
Create: createDefaultCreateFunction(m),
Read: createDefaultReadFunction(m),
Update: createDefaultUpdateFunction(m),
Delete: createDefaultDeleteFunction(m),
Exists: createDefaultExistsFunction(m),
Schema: buildSchemaFromObject(m),
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: buildSchemaFromObject(m, computed),
}

return r
Expand Down Expand Up @@ -449,6 +465,23 @@ func createDefaultCreateFunction(m models.Model) func(*schema.ResourceData, inte
}
}

func createDefaultDataSourceReadFunction(m models.Model) func(*schema.ResourceData, interface{}) error {
return func(d *schema.ResourceData, meta interface{}) error {
cc := meta.(*Config)

id := d.Get(m.KeyName()).(string)
d.SetId(id)

log.Printf("[DEBUG] [dataSource%sRead] reading %s\n", m.Prefix(), id)

answer, err := cc.session.GetModel(m.Prefix(), id)
if err != nil {
return err
}

return updateResourceData(answer, d)
}
}
func createDefaultReadFunction(m models.Model) func(*schema.ResourceData, interface{}) error {
return func(d *schema.ResourceData, meta interface{}) error {
cc := meta.(*Config)
Expand Down
Loading

0 comments on commit c51417d

Please sign in to comment.