1 回答

TA貢獻1877條經驗 獲得超1個贊
Terraform 的舊版 SDK (SDKv2) 并不是圍繞解碼成標記結構的范例而設計的,而是希望您使用d.Get并手動鍵入斷言單個值,在您的情況下,這些值可能看起來像這樣:
raw := d.Get("template").([]interface{})[0].(map[string]interface{})
t := &TestStruct{
NameTest: raw["name_test"].(string),
ListsTests: make([]string, len(raw["lists_test"].([]interface{})),
}
for i, itemRaw := range raw["lists_test"].([]interface{}) {
t.ListsTests[i] = itemRaw.(string)
}
大多數 Terraform 提供程序的慣用風格是為每個復雜類型的屬性在單獨的函數中編寫這樣的邏輯,其中每個屬性返回目標平臺 SDK 中適當類型的對象。通常還會有一個相反方向的匹配函數:從目標平臺的 SDK 中給定一個對象,返回一個map[string]interface{}可以分配給該屬性的d.Set.
然而,僅僅因為 SDK 中沒有內置的東西來處理這個,并不意味著你不能使用其他庫,這些庫是更通用的實用程序,可用于任何 Go 程序。
一個示例庫是github.com/mitchellh/mapstructure,它正是為您的目標而設計的:獲取某種接口類型的值并嘗試使用反射將其適合標記的結構類型。
如果你想使用那個庫,那么你需要用mapstructure:,而不是json:那些來注釋你的結構,然后將你的raw值傳遞給mapstructure.Decode函數:
raw := d.Get("template").([]interface{})[0].(map[string]interface{})
var t TestStruct
err := mapstructure.Decode(raw, &t)
由于schema.ResourceDataSDKv2 中的抽象保證根據您定義的模式返回特定數據類型,因此mapstructure.Decode只要您的模式和目標類型匹配,您通常不會收到錯誤,但無論如何檢查錯誤仍然是一個好主意,否則您的t價值可能沒有完全填充,導致下游混亂的破壞行為。
這不是官方提供程序中使用的典型實現樣式,但如果您發現這種樣式更方便或更易于維護,那么以這種方式編寫您的提供程序并沒有什么真正的壞處。
或者,如果您還沒有深入研究 SDKv2,那么您可能希望考慮改用Terraform 插件框架。除了圍繞現代 Terraform 的類型系統設計(而 SDKv2 是為 Terraform v0.11 及更早版本設計的),它還支持一種更像您所追求的編程風格,使用諸如tfsdk.Plan.Get和之類的方法tfsdk.Plan.GetAttribute可以直接解碼為適當形狀和適當標記的“正?!盙o 值。
我無法簡單地展示一個例子,因為它會假定提供程序以完全不同的方式編寫,但希望您可以從這兩個函數的簽名中看出它們的使用方式。在訪問狀態、配置和計劃中有更多的評論和示例。
- 1 回答
- 0 關注
- 127 瀏覽
添加回答
舉報