mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-10 22:41:41 +00:00
fix(terraform): keep prior state when a virtual key update is rejected (#40512)
resourceKeyUpdate now calls d.Partial(true) on a failed /key/update so the SDK does not persist the rejected planned values into state, which made the next plan report no changes and silently dropped the update. Co-authored-by: yassin <yassin@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
083ddefa92
commit
fb603fdb6b
2 changed files with 42 additions and 0 deletions
|
|
@ -315,6 +315,7 @@ func resourceKeyUpdate(ctx context.Context, d *schema.ResourceData, m interface{
|
|||
|
||||
metadata, err := plannedKeyMetadata(c, d)
|
||||
if err != nil {
|
||||
d.Partial(true)
|
||||
return diag.FromErr(fmt.Errorf("error updating key: %s", err))
|
||||
}
|
||||
key.Metadata = metadata
|
||||
|
|
|
|||
|
|
@ -319,6 +319,47 @@ func TestUpdateKeyOmitsEmptyBudgetDuration(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestResourceKeyUpdateFailureKeepsPriorState(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if r.URL.Path == "/key/update" {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{"error":{"message":"Invalid budget_duration 'bad'"}}`))
|
||||
return
|
||||
}
|
||||
w.Write([]byte(`{"key":"hash-1","info":{"key_alias":"demo","models":["fake-model"]}}`))
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
res := resourceKey()
|
||||
priorData := newKeyResourceData(t, map[string]interface{}{
|
||||
"key_alias": "demo",
|
||||
"models": []interface{}{"fake-model"},
|
||||
})
|
||||
priorData.SetId("hash-1")
|
||||
prior := priorData.State()
|
||||
config := terraform.NewResourceConfigRaw(map[string]interface{}{
|
||||
"key_alias": "demo",
|
||||
"models": []interface{}{"fake-model"},
|
||||
"budget_duration": "bad",
|
||||
})
|
||||
diff, err := res.Diff(context.Background(), prior, config, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("diff failed: %v", err)
|
||||
}
|
||||
|
||||
newState, diags := res.Apply(context.Background(), prior, diff, NewClient(srv.URL, "test-key", true))
|
||||
if !diags.HasError() {
|
||||
t.Fatal("apply succeeded, want the proxy's 400 surfaced as an error")
|
||||
}
|
||||
if got, ok := newState.Attributes["budget_duration"]; ok {
|
||||
t.Errorf("failed update persisted budget_duration=%q into state, want it absent", got)
|
||||
}
|
||||
if newState.Attributes["key_alias"] != "demo" {
|
||||
t.Errorf("prior key_alias lost from state: %v", newState.Attributes)
|
||||
}
|
||||
}
|
||||
|
||||
// /key/info nests the key's fields under "info"; GetKey must unwrap that
|
||||
// envelope or reads map nothing back into state.
|
||||
func TestGetKeyUnwrapsInfoEnvelope(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue