alicloud/data_source_alicloud_ots_search_indexes.go (247 lines of code) (raw):
package alicloud
import (
"encoding/json"
"regexp"
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
"github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)
func dataSourceAlicloudOtsSearchIndexes() *schema.Resource {
return &schema.Resource{
Read: dataSourceAlicloudOtsSearchIndexesRead,
Schema: map[string]*schema.Schema{
"instance_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateOTSInstanceName,
},
"table_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateOTSTableName,
},
"ids": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
ForceNew: true,
},
"name_regex": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.ValidateRegexp,
},
"output_file": {
Type: schema.TypeString,
Optional: true,
},
"names": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"indexes": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"instance_name": {
Type: schema.TypeString,
Computed: true,
},
"table_name": {
Type: schema.TypeString,
Computed: true,
},
"index_name": {
Type: schema.TypeString,
Computed: true,
},
"create_time": {
Type: schema.TypeInt,
Computed: true,
},
"time_to_live": {
Type: schema.TypeInt,
Computed: true,
},
"sync_phase": {
Type: schema.TypeString,
Computed: true,
},
"current_sync_timestamp": {
Type: schema.TypeInt,
Computed: true,
},
"schema": {
Type: schema.TypeString,
Computed: true,
},
"storage_size": {
Type: schema.TypeInt,
Computed: true,
},
"row_count": {
Type: schema.TypeInt,
Computed: true,
},
"reserved_read_cu": {
Type: schema.TypeInt,
Computed: true,
},
"metering_last_update_time": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
},
}
}
func parseSearchIndexDataSourceArgs(d *schema.ResourceData) *SearchIndexDataSourceArgs {
args := &SearchIndexDataSourceArgs{
instanceName: d.Get("instance_name").(string),
tableName: d.Get("table_name").(string),
}
if ids, ok := d.GetOk("ids"); ok && len(ids.([]interface{})) > 0 {
args.ids = Interface2StrSlice(ids.([]interface{}))
}
if regx, ok := d.GetOk("name_regex"); ok && regx.(string) != "" {
args.nameRegex = regx.(string)
}
return args
}
type SearchIndexDataSourceArgs struct {
instanceName string
tableName string
ids []string
nameRegex string
}
type SearchIndexDataSource struct {
ids []string
names []string
indexes []map[string]interface{}
}
func (s *SearchIndexDataSource) export(d *schema.ResourceData) error {
d.SetId(dataResourceIdHash(s.ids))
if err := d.Set("indexes", s.indexes); err != nil {
return WrapError(err)
}
if err := d.Set("names", s.names); err != nil {
return WrapError(err)
}
if err := d.Set("ids", s.ids); err != nil {
return WrapError(err)
}
// create a json file in current directory and write data source to it.
if filepath, ok := d.GetOk("output_file"); ok && filepath.(string) != "" {
err := writeToFile(filepath.(string), s.indexes)
if err != nil {
return err
}
}
return nil
}
func dataSourceAlicloudOtsSearchIndexesRead(d *schema.ResourceData, meta interface{}) error {
args := parseSearchIndexDataSourceArgs(d)
client := meta.(*connectivity.AliyunClient)
otsService := OtsService{client}
totalIndexes, err := otsService.ListOtsSearchIndex(args.instanceName, args.tableName)
if err != nil {
return WrapError(err)
}
filteredIndexes := args.doFilters(totalIndexes)
source, err := genSearchIndexDataSource(&otsService, filteredIndexes, args)
if err != nil {
return WrapError(err)
}
if err := source.export(d); err != nil {
return WrapError(err)
}
return nil
}
func genSearchIndexDataSource(otsService *OtsService, filteredIndexes []interface{}, args *SearchIndexDataSourceArgs) (*SearchIndexDataSource, error) {
size := len(filteredIndexes)
ids := make([]string, 0, size)
names := make([]string, 0, size)
indexes := make([]map[string]interface{}, 0, size)
for _, idx := range filteredIndexes {
idxInfo := idx.(*tablestore.IndexInfo)
id := ID(args.instanceName, args.tableName, idxInfo.IndexName, SearchIndexTypeHolder)
indexResp, err := otsService.DescribeOtsSearchIndex(id)
if err != nil {
return nil, WrapError(err)
}
phase, err := ConvertSearchIndexSyncPhase(indexResp.SyncStat.SyncPhase)
if err != nil {
return nil, WrapError(err)
}
b, err := json.MarshalIndent(indexResp.Schema, "", " ")
if err != nil {
return nil, WrapError(err)
}
schemaJSON := string(b)
index := map[string]interface{}{
"id": id,
"instance_name": args.instanceName,
"table_name": args.tableName,
"index_name": idxInfo.IndexName,
"create_time": indexResp.CreateTime,
"time_to_live": indexResp.TimeToLive,
"sync_phase": phase,
"current_sync_timestamp": *indexResp.SyncStat.CurrentSyncTimestamp,
"storage_size": indexResp.MeteringInfo.StorageSize,
"row_count": indexResp.MeteringInfo.RowCount,
"reserved_read_cu": indexResp.MeteringInfo.ReservedReadCU,
"metering_last_update_time": indexResp.MeteringInfo.LastUpdateTime,
"schema": schemaJSON,
}
names = append(names, idxInfo.IndexName)
ids = append(ids, id)
indexes = append(indexes, index)
}
return &SearchIndexDataSource{
ids: ids,
names: names,
indexes: indexes,
}, nil
}
func (args *SearchIndexDataSourceArgs) doFilters(total []*tablestore.IndexInfo) []interface{} {
slice := make([]interface{}, len(total))
for i, t := range total {
slice[i] = t
}
ds := InputDataSource{
inputs: slice,
}
// add filter: index id
if args.ids != nil {
idFilter := &ValuesFilter{
allowedValues: Str2InterfaceSlice(args.ids),
getSourceValue: func(sourceObj interface{}) interface{} {
idx := sourceObj.(*tablestore.IndexInfo)
// search index and search index can have same IndexName, so joined IndexType for index id
return ID(args.instanceName, args.tableName, idx.IndexName, SearchIndexTypeHolder)
},
}
ds.filters = append(ds.filters, idFilter)
}
// add filter: index name regex
if args.nameRegex != "" {
regxFilter := &RegxFilter{
regx: regexp.MustCompile(args.nameRegex),
getSourceValue: func(sourceObj interface{}) interface{} {
return sourceObj.(*tablestore.IndexInfo).IndexName
},
}
ds.filters = append(ds.filters, regxFilter)
}
filtered := ds.doFilters()
return filtered
}