Skip to content

Commit

Permalink
feat(datasource): improved the data source filter system
Browse files Browse the repository at this point in the history
- Added a new way to filter and sort the datasource
- Update the documentation for the data source, instance_size, kubernetes_version, template

BREAKING CHANGE: No

Signed-off-by: Alejandro JNM <alejandrojnm@gmail.com>
  • Loading branch information
alejandrojnm committed Apr 24, 2020
1 parent c12905c commit 48470cc
Show file tree
Hide file tree
Showing 14 changed files with 1,012 additions and 338 deletions.
32 changes: 0 additions & 32 deletions civo/datasource_common_schema.go

This file was deleted.

8 changes: 0 additions & 8 deletions civo/datasource_common_struct.go

This file was deleted.

218 changes: 69 additions & 149 deletions civo/datasource_intances_size.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,175 +3,95 @@ package civo
import (
"fmt"
"github.com/civo/civogo"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/civo/terraform-provider-civo/internal/datalist"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"log"
"regexp"
"strconv"
)

// Data source to get and filter all instances size
// use to define the size in resourceInstance
func dataSourceInstancesSize() *schema.Resource {
return &schema.Resource{
Read: dataSourceInstancesSizeRead,
Schema: map[string]*schema.Schema{
"filter": dataSourceFiltersSchema(),
// computed attributes
"sizes": {
Type: schema.TypeSet,
Required: true,
Description: "a list of backend instances, each containing an instance_id, protocol (http or https) and port",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},
"nice_name": {
Type: schema.TypeString,
Computed: true,
},
"cpu_cores": {
Type: schema.TypeInt,
Computed: true,
},
"ram_mb": {
Type: schema.TypeInt,
Computed: true,
},
"disk_gb": {
Type: schema.TypeInt,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"selectable": {
Type: schema.TypeBool,
Computed: true,
},
},
},
dataListConfig := &datalist.ResourceConfig{
RecordSchema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},
"nice_name": {
Type: schema.TypeString,
Computed: true,
},
"cpu_cores": {
Type: schema.TypeInt,
Computed: true,
},
"ram_mb": {
Type: schema.TypeInt,
Computed: true,
},
"disk_gb": {
Type: schema.TypeInt,
Computed: true,
},
"description": {
Type: schema.TypeString,
Computed: true,
},
"selectable": {
Type: schema.TypeBool,
Computed: true,
},
},
FilterKeys: []string{
"name",
"nice_name",
"cpu_cores",
"ram_mb",
"disk_gb",
"selectable",
},
SortKeys: []string{
"cpu_cores",
"ram_mb",
"disk_gb",
"selectable",
},
ResultAttributeName: "sizes",
FlattenRecord: flattenInstancesSize,
GetRecords: getInstancesSizes,
}

return datalist.NewResource(dataListConfig)

}

func dataSourceInstancesSizeRead(d *schema.ResourceData, m interface{}) error {
func getInstancesSizes(m interface{}) ([]interface{}, error) {
apiClient := m.(*civogo.Client)

filters, filtersOk := d.GetOk("filter")

if !filtersOk {
return fmt.Errorf("one of filters must be assigned")
sizes := []interface{}{}
partialSizes, err := apiClient.ListInstanceSizes()
if err != nil {
return nil, fmt.Errorf("[ERR] error retrieving sizes: %s", err)
}

if filtersOk {
log.Printf("[INFO] Getting the instances size")
resp, err := apiClient.ListInstanceSizes()
if err != nil {
return fmt.Errorf("no instances size was found in the server")
}

log.Printf("[INFO] Finding the size of the instances")
size, err := findInstancesSizeByFilter(resp, filters.(*schema.Set))
if err != nil {
return fmt.Errorf("no instances size was found in the server, %s", err)
}

d.SetId(resource.UniqueId())

if err := d.Set("sizes", size); err != nil {
return fmt.Errorf("unable to set `%s` attribute: %s", "sizes", err)
}
for _, partialSize := range partialSizes {
sizes = append(sizes, partialSize)
}

return nil
return sizes, nil
}

func findInstancesSizeByFilter(sizes []civogo.InstanceSize, set *schema.Set) ([]civogo.InstanceSize, error) {
results := make([]civogo.InstanceSize, 0)

var filters []Filter

for _, v := range set.List() {
m := v.(map[string]interface{})
var filterValues []string
for _, e := range m["values"].([]interface{}) {
filterValues = append(filterValues, e.(string))
}
filters = append(filters, Filter{Name: m["name"].(string), Values: filterValues, Regex: m["regex"].(bool)})
}

for _, valueFilters := range filters {
for _, valueSize := range sizes {
func flattenInstancesSize(size, m interface{}) (map[string]interface{}, error) {

// filter for the name
if valueFilters.Name == "name" {
if valueFilters.Regex {
r, _ := regexp.Compile(valueFilters.Values[0])
if r.MatchString(valueSize.Name) {
results = append(results, valueSize)
}
} else {
if valueSize.Name == valueFilters.Values[0] {
results = append(results, valueSize)
}
}
}
s := size.(civogo.InstanceSize)

// filter for the CPU
if valueFilters.Name == "cpu" {
if valueFilters.Regex {
r, _ := regexp.Compile(valueFilters.Values[0])
if r.MatchString(strconv.Itoa(valueSize.CPUCores)) {
results = append(results, valueSize)
}
} else {
if strconv.Itoa(valueSize.CPUCores) == valueFilters.Values[0] {
results = append(results, valueSize)
}
}
}
flattenedSize := map[string]interface{}{}
flattenedSize["name"] = s.Name
flattenedSize["nice_name"] = s.NiceName
flattenedSize["cpu_cores"] = s.CPUCores
flattenedSize["ram_mb"] = s.RAMMegabytes
flattenedSize["disk_gb"] = s.DiskGigabytes
flattenedSize["description"] = s.Description
flattenedSize["selectable"] = s.Selectable

// filter for the RAM
if valueFilters.Name == "ram" {
if valueFilters.Regex {
r, _ := regexp.Compile(valueFilters.Values[0])
if r.MatchString(strconv.Itoa(valueSize.RAMMegabytes)) {
results = append(results, valueSize)
}
} else {
if strconv.Itoa(valueSize.RAMMegabytes) == valueFilters.Values[0] {
results = append(results, valueSize)
}
}
}

// filter for the Disk
if valueFilters.Name == "disk" {
if valueFilters.Regex {
r, _ := regexp.Compile(valueFilters.Values[0])
if r.MatchString(strconv.Itoa(valueSize.DiskGigabytes)) {
results = append(results, valueSize)
}
} else {
if strconv.Itoa(valueSize.DiskGigabytes) == valueFilters.Values[0] {
results = append(results, valueSize)
}
}
}

}
}

if len(results) > 1 {
return results, nil
}
if len(results) == 0 {
return nil, fmt.Errorf("no instances sizes found for your search")
}
return nil, fmt.Errorf("too many instances sizes found (found %d, expected 1)", len(results))
return flattenedSize, nil
}
Loading

0 comments on commit 48470cc

Please sign in to comment.