refactor(terraform): drop comments and simplify guardrail not-found handling

This commit is contained in:
Devin AI 2026-07-15 15:36:00 +00:00
parent b81affffef
commit cae9d5f947
4 changed files with 8 additions and 37 deletions

View file

@ -2,6 +2,7 @@ package litellm
import (
"encoding/json"
"errors"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@ -74,7 +75,7 @@ func dataSourceLiteLLMGuardrailRead(d *schema.ResourceData, m interface{}) error
var guardrailResp GuardrailResponse
if err := handleGuardrailAPIResponse(resp, &guardrailResp, client); err != nil {
if err.Error() == "guardrail_not_found" {
if errors.Is(err, errGuardrailNotFound) {
return fmt.Errorf("guardrail '%s' not found", guardrailID)
}
return fmt.Errorf("failed to read guardrail: %w", err)

View file

@ -2,12 +2,15 @@ package litellm
import (
"encoding/json"
"errors"
"fmt"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
var errGuardrailNotFound = errors.New("guardrail not found")
func buildGuardrailSpec(d *schema.ResourceData) (GuardrailSpec, error) {
litellmParams := map[string]interface{}{
"guardrail": d.Get("guardrail").(string),
@ -41,7 +44,6 @@ func buildGuardrailSpec(d *schema.ResourceData) (GuardrailSpec, error) {
return spec, nil
}
// parseGuardrailMode returns a []string when the value is a JSON array, otherwise the raw string.
func parseGuardrailMode(mode string) interface{} {
trimmed := strings.TrimSpace(mode)
if strings.HasPrefix(trimmed, "[") {
@ -103,7 +105,7 @@ func resourceLiteLLMGuardrailRead(d *schema.ResourceData, m interface{}) error {
var guardrailResp GuardrailResponse
if err := handleGuardrailAPIResponse(resp, &guardrailResp, client); err != nil {
if err.Error() == "guardrail_not_found" {
if errors.Is(err, errGuardrailNotFound) {
d.SetId("")
return nil
}
@ -115,9 +117,6 @@ func resourceLiteLLMGuardrailRead(d *schema.ResourceData, m interface{}) error {
d.Set("created_at", guardrailResp.CreatedAt)
d.Set("updated_at", guardrailResp.UpdatedAt)
// Reconcile the non-sensitive params that live inside litellm_params. The
// rest of litellm_params is masked by the proxy on read, so persisting it
// would produce perpetual diffs; the configured value is left untouched.
if guardrail, ok := guardrailResp.LiteLLMParams["guardrail"].(string); ok {
d.Set("guardrail", guardrail)
}
@ -185,7 +184,7 @@ func resourceLiteLLMGuardrailDelete(d *schema.ResourceData, m interface{}) error
defer resp.Body.Close()
if err := handleGuardrailAPIResponse(resp, nil, client); err != nil {
if err.Error() == "guardrail_not_found" {
if errors.Is(err, errGuardrailNotFound) {
d.SetId("")
return nil
}
@ -196,8 +195,6 @@ func resourceLiteLLMGuardrailDelete(d *schema.ResourceData, m interface{}) error
return nil
}
// suppressEquivalentJSON suppresses diffs between two JSON strings that are
// semantically equal but differ in key ordering or whitespace.
func suppressEquivalentJSON(_, oldValue, newValue string, _ *schema.ResourceData) bool {
if oldValue == newValue {
return true

View file

@ -247,7 +247,6 @@ type VectorStoreInfoRequest struct {
VectorStoreID string `json:"vector_store_id"`
}
// GuardrailSpec is the guardrail object sent to and returned by the proxy.
type GuardrailSpec struct {
GuardrailID string `json:"guardrail_id,omitempty"`
GuardrailName string `json:"guardrail_name"`
@ -255,12 +254,10 @@ type GuardrailSpec struct {
GuardrailInfo map[string]interface{} `json:"guardrail_info,omitempty"`
}
// GuardrailRequest wraps a guardrail spec for create and update calls.
type GuardrailRequest struct {
Guardrail GuardrailSpec `json:"guardrail"`
}
// GuardrailResponse represents guardrail information returned by the proxy.
type GuardrailResponse struct {
GuardrailID string `json:"guardrail_id"`
GuardrailName string `json:"guardrail_name"`

View file

@ -247,24 +247,6 @@ func isVectorStoreNotFoundError(errResp ErrorResponse) bool {
return false
}
// isGuardrailNotFoundError checks if the error response indicates a guardrail not found
func isGuardrailNotFoundError(errResp ErrorResponse) bool {
if msg, ok := errResp.Error.Message.(string); ok {
if strings.Contains(msg, "not found") && strings.Contains(msg, "uardrail") {
return true
}
}
if errResp.Detail.Error != "" {
if strings.Contains(errResp.Detail.Error, "not found") && strings.Contains(errResp.Detail.Error, "uardrail") {
return true
}
}
return false
}
// handleGuardrailAPIResponse handles API responses specifically for guardrail operations
func handleGuardrailAPIResponse(resp *http.Response, result interface{}, client *Client) error {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
@ -272,16 +254,10 @@ func handleGuardrailAPIResponse(resp *http.Response, result interface{}, client
}
if resp.StatusCode == http.StatusNotFound {
return fmt.Errorf("guardrail_not_found")
return errGuardrailNotFound
}
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
var errResp ErrorResponse
if err := json.Unmarshal(bodyBytes, &errResp); err == nil {
if isGuardrailNotFoundError(errResp) {
return fmt.Errorf("guardrail_not_found")
}
}
return fmt.Errorf("API request failed: Status: %s, Response: %s",
resp.Status, client.redactSensitiveData(string(bodyBytes)))
}