fix(terraform): omit unset member budgets

This commit is contained in:
Erik Bogado 2026-09-07 03:33:08 -03:00
parent 168a0055a2
commit 952cf8660a
3 changed files with 103 additions and 22 deletions

View file

@ -58,9 +58,9 @@ func resourceLiteLLMTeamMemberCreate(d *schema.ResourceData, m interface{}) erro
"user_email": d.Get("user_email").(string),
},
},
"team_id": d.Get("team_id").(string),
"max_budget_in_team": d.Get("max_budget_in_team").(float64),
"team_id": d.Get("team_id").(string),
}
addOptionalTeamMemberBudget(d, memberData)
log.Printf("[DEBUG] Create team member request payload: %+v", memberData)
@ -94,12 +94,12 @@ func resourceLiteLLMTeamMemberUpdate(d *schema.ResourceData, m interface{}) erro
client := m.(*Client)
updateData := map[string]interface{}{
"user_id": d.Get("user_id").(string),
"user_email": d.Get("user_email").(string),
"team_id": d.Get("team_id").(string),
"role": d.Get("role").(string),
"max_budget_in_team": d.Get("max_budget_in_team").(float64),
"user_id": d.Get("user_id").(string),
"user_email": d.Get("user_email").(string),
"team_id": d.Get("team_id").(string),
"role": d.Get("role").(string),
}
addOptionalTeamMemberBudget(d, updateData)
log.Printf("[DEBUG] Update team member request payload: %+v", updateData)
@ -118,6 +118,12 @@ func resourceLiteLLMTeamMemberUpdate(d *schema.ResourceData, m interface{}) erro
return resourceLiteLLMTeamMemberRead(d, m)
}
func addOptionalTeamMemberBudget(d *schema.ResourceData, payload map[string]interface{}) {
if budget, configured := d.GetOkExists("max_budget_in_team"); configured {
payload["max_budget_in_team"] = budget.(float64)
}
}
func resourceLiteLLMTeamMemberDelete(d *schema.ResourceData, m interface{}) error {
client := m.(*Client)

View file

@ -58,7 +58,6 @@ func resourceLiteLLMTeamMemberAddCreate(d *schema.ResourceData, m interface{}) e
teamID := d.Get("team_id").(string)
members := d.Get("member").(*schema.Set)
maxBudget := d.Get("max_budget_in_team").(float64)
// Convert members to the expected format
membersList := make([]map[string]interface{}, 0, members.Len())
@ -77,10 +76,10 @@ func resourceLiteLLMTeamMemberAddCreate(d *schema.ResourceData, m interface{}) e
}
memberData := map[string]interface{}{
"member": membersList,
"team_id": teamID,
"max_budget_in_team": maxBudget,
"member": membersList,
"team_id": teamID,
}
addOptionalTeamMemberBudget(d, memberData)
log.Printf("[DEBUG] Create team members request payload: %+v", memberData)
@ -109,7 +108,6 @@ func resourceLiteLLMTeamMemberAddRead(d *schema.ResourceData, m interface{}) err
func resourceLiteLLMTeamMemberAddUpdate(d *schema.ResourceData, m interface{}) error {
client := m.(*Client)
teamID := d.Get("team_id").(string)
maxBudget := d.Get("max_budget_in_team").(float64)
o, n := d.GetChange("member")
oldMembers := o.(*schema.Set)
@ -142,16 +140,16 @@ func resourceLiteLLMTeamMemberAddUpdate(d *schema.ResourceData, m interface{}) e
// Check if max_budget_in_team has changed
if d.HasChange("max_budget_in_team") {
log.Printf("[DEBUG] max_budget_in_team changed, updating all existing members with new budget: %f", maxBudget)
log.Printf("[DEBUG] max_budget_in_team changed, updating all existing members")
// Update ALL existing members with the new budget
for key, newMember := range newMemberMap {
if _, exists := oldMemberMap[key]; exists {
updateData := map[string]interface{}{
"team_id": teamID,
"role": newMember["role"].(string),
"max_budget_in_team": maxBudget,
"team_id": teamID,
"role": newMember["role"].(string),
}
addOptionalTeamMemberBudget(d, updateData)
if userID, ok := newMember["user_id"].(string); ok && userID != "" {
updateData["user_id"] = userID
}
@ -216,10 +214,10 @@ func resourceLiteLLMTeamMemberAddUpdate(d *schema.ResourceData, m interface{}) e
// Check if member attributes have changed
if memberAttributesChanged(oldMember, newMember) {
updateData := map[string]interface{}{
"team_id": teamID,
"role": newMember["role"].(string),
"max_budget_in_team": maxBudget,
"team_id": teamID,
"role": newMember["role"].(string),
}
addOptionalTeamMemberBudget(d, updateData)
if userID, ok := newMember["user_id"].(string); ok && userID != "" {
updateData["user_id"] = userID
}
@ -261,10 +259,10 @@ func resourceLiteLLMTeamMemberAddUpdate(d *schema.ResourceData, m interface{}) e
if len(membersToAdd) > 0 {
memberData := map[string]interface{}{
"member": membersToAdd,
"team_id": teamID,
"max_budget_in_team": maxBudget,
"member": membersToAdd,
"team_id": teamID,
}
addOptionalTeamMemberBudget(d, memberData)
log.Printf("[DEBUG] Adding new team members request payload: %+v", memberData)

View file

@ -10,6 +10,46 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func TestTeamMemberCreateOmitsUnsetBudget(t *testing.T) {
var captured map[string]interface{}
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
json.Unmarshal(body, &captured)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{}`))
}))
defer srv.Close()
client := NewClient(srv.URL, "test-key", true)
d := schema.TestResourceDataRaw(t, resourceLiteLLMTeamMember().Schema, map[string]interface{}{
"team_id": "team-1",
"user_id": "user-1",
"user_email": "user@example.com",
"role": "user",
})
if err := resourceLiteLLMTeamMemberCreate(d, client); err != nil {
t.Fatalf("create failed: %v", err)
}
if _, ok := captured["max_budget_in_team"]; ok {
t.Fatalf("create payload included unset max_budget_in_team: %v", captured)
}
}
func TestOptionalTeamMemberBudgetPreservesExplicitZero(t *testing.T) {
d := schema.TestResourceDataRaw(t, resourceLiteLLMTeamMember().Schema, map[string]interface{}{
"max_budget_in_team": 0.0,
})
payload := map[string]interface{}{}
addOptionalTeamMemberBudget(d, payload)
if budget, ok := payload["max_budget_in_team"]; !ok || budget != 0.0 {
t.Fatalf("explicit zero budget was not preserved: %v", payload)
}
}
func TestTeamMemberUpdateSendsRole(t *testing.T) {
var captured map[string]interface{}
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@ -41,4 +81,41 @@ func TestTeamMemberUpdateSendsRole(t *testing.T) {
if role != "user" {
t.Fatalf("update payload sent role %v, want user", role)
}
if _, ok := captured["max_budget_in_team"]; ok {
t.Fatalf("update payload included unset max_budget_in_team: %v", captured)
}
}
func TestTeamMemberAddBudgetPresence(t *testing.T) {
for _, tc := range []struct {
name string
configured bool
budget float64
}{
{"omitted", false, 0}, {"zero", true, 0}, {"positive", true, 25},
} {
t.Run(tc.name, func(t *testing.T) {
var captured map[string]interface{}
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if err := json.NewDecoder(r.Body).Decode(&captured); err != nil {
t.Error(err)
}
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{}`))
}))
defer srv.Close()
raw := map[string]interface{}{"team_id": "team-1", "member": []interface{}{map[string]interface{}{"user_id": "user-1", "role": "user"}}}
if tc.configured {
raw["max_budget_in_team"] = tc.budget
}
d := schema.TestResourceDataRaw(t, resourceLiteLLMTeamMemberAdd().Schema, raw)
if err := resourceLiteLLMTeamMemberAddCreate(d, NewClient(srv.URL, "test-key", true)); err != nil {
t.Fatal(err)
}
got, present := captured["max_budget_in_team"]
if present != tc.configured || (present && got != tc.budget) {
t.Fatalf("budget = %v, present = %t", got, present)
}
})
}
}