簡體   English   中英

如何使用 DiffSuppressFunc() 實現它?

[英]How can I implement it using DiffSuppressFunc()?

上下文:我正在開發一個 TF 提供程序。

我的一個資源中有一個string類型的屬性foo foo值的不同表示可以 map 到相同的規范化版本,但只有后端可以返回foo值的規范化版本。

在實現資源時,我想我可以為foo存儲任何用戶值(即,它不一定是規范化的)。 然后我可以利用DiffSuppressFunc來檢測任何潛在的差異。 例如,main.tf 存儲任何用戶輸入(根據定義),TF state 可以存儲從后端返回的規范化版本或用戶輸入版本(無關緊要)。 然后,最大的挑戰是區分結構更新(需要更新)和語法更新(不需要更新,因為它可以轉換為相同的規范化版本)。

為了實現這個我可以使用

"foo": {
...
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
    // Option #1
    normalizedOld := network.GetNormalized(old)
    normalizedNew := network.GetNormalized(new)
    return normalizedOld == normalizedNew

    // Option #2
    // Backend also supports a check whether such a value exists already 
    // and returns such a object
    if obj, ok := network.Exists(new); ok { return obj.Id == d.GetObjId(); }
}
}

但是,我似乎無法在 DiffSuppressFunc 中發送網絡請求,因為它不接受來自以下方的meta interface{}

func resourceCreate(ctx context.Context, d *schema.ResourceData, meta interface{})

所以我無法訪問我的特定 http 客戶端(即使我可以發送一些 generic.network 請求)。

有沒有一種聰明的方法可以避免將meta interface{}傳遞給 DiffSuppressFunc 的這種限制:

    // The interface{} parameter is the result of the Provider type
    // ConfigureFunc field execution. If the Provider does not define
    // a ConfigureFunc, this will be nil. This parameter is conventionally
    // used to store API clients and other provider instance specific data.
    //
    // The diagnostics return parameter, if not nil, can contain any
    // combination and multiple of warning and/or error diagnostics.
    ReadContext ReadContextFunc

DiffSuppressFunc的目的是它只是不依賴於提供程序外部信息的語法規范化。 DiffSuppressFunc通常不應與提供程序外部的任何內容交互,因為 SDK 可以在不同的步驟調用它並期望它每次都返回一致的結果,而不是根據遠程系統的 state 而變化。

如果您需要依賴來自遠程系統的信息,那么您需要實施您在CustomizeDiff function中討論的邏輯。 function 是 SDK 中差異定制的最低抽象級別,但作為低抽象級別的回報,它還允許比 SDK 中更高級別的內置行為更大的靈活性。

CustomizeDiff function 中,您將有權訪問meta數據,因此如果需要,您可以發出 API 請求。

在您的CustomizeDiff function 中,您可以使用d.GetChange從配置中獲取以前的值和新值,以與old的和new的 arguments 到DiffSuppressFunc相同的方式使用。

然后,您可以使用d.Set根據您學到的知識更改特定屬性的計划值。 要估計DiffSuppressFunc會做什么,您可以使用先前 state中的值調用d.Set “舊”值。

實施CustomizeDiff時,您必須遵守適用於所有 Terraform 提供程序的一致性規則,其中包括:

  • 在計划初始創建 object 時,如果模塊作者在配置中提供了特定值,那么您必須准確保留該值,而不進行規范化。
  • 當計划更新現有的 object 時,如果模塊作者在配置中提供了特定值,那么您必須返回他們在沒有規范化的情況下寫入的確切值,或者返回之前 state 中的值以指示新配置值是在功能上等同於先前的值。

在實現Read時也有類似的一致性規則:

  • 如果您從遠程系統讀取的值不等於之前的 state 中的值,但新值在功能上等同於之前的 state 那么您必須返回之前的 state 中的值以保留作者最初編寫它的方式,而不是遠程系統規范化它的方式。

所有這些規則的存在都是為了幫助確保特定的 Terraform 配置可以收斂,也就是說,在運行terraform apply之后,應該可以立即運行terraform plan並看到它報告“No changes”。 如果您不遵守這些規則,那么 Terraform 可能會返回一個明確的錯誤(對於它能夠檢測到的問題),或者由於提供者產生與協議假設不匹配的混淆信息,它可能會表現得很奇怪。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM