feat: Add Terraform provider API client with HTTP methods and provider configuration

- Add APIClient struct with BaseURL, APIKey, and HTTPClient with 30s timeout
- Add providerConfigure to initialize client from schema with api_url and api_key
- Add doRequest helper with context support, JSON marshaling, Content-Type and Authorization headers
- Add get method accepting GET requests with 200 OK validation and JSON decoding
- Add post method accepting POST requests with 200/201 status validation and optional
This commit is contained in:
nutcas3
2026-04-17 17:37:18 +03:00
parent a1331bb55e
commit 8c8d71056f
+122
View File
@@ -0,0 +1,122 @@
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
// APIClient is the HTTP client for the Telecom API
type APIClient struct {
BaseURL string
APIKey string
HTTPClient *http.Client
}
func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
apiURL := d.Get("api_url").(string)
apiKey := d.Get("api_key").(string)
client := &APIClient{
BaseURL: apiURL,
APIKey: apiKey,
HTTPClient: &http.Client{
Timeout: 30 * time.Second,
},
}
return client, nil
}
func (c *APIClient) doRequest(ctx context.Context, method, path string, body interface{}) (*http.Response, error) {
var reqBody *bytes.Buffer
if body != nil {
jsonBody, err := json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("failed to marshal request body: %w", err)
}
reqBody = bytes.NewBuffer(jsonBody)
} else {
reqBody = bytes.NewBuffer(nil)
}
req, err := http.NewRequestWithContext(ctx, method, c.BaseURL+path, reqBody)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
if c.APIKey != "" {
req.Header.Set("Authorization", "Bearer "+c.APIKey)
}
return c.HTTPClient.Do(req)
}
func (c *APIClient) get(ctx context.Context, path string, result interface{}) error {
resp, err := c.doRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("API returned status %d for GET %s", resp.StatusCode, path)
}
return json.NewDecoder(resp.Body).Decode(result)
}
func (c *APIClient) post(ctx context.Context, path string, body, result interface{}) error {
resp, err := c.doRequest(ctx, http.MethodPost, path, body)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
return fmt.Errorf("API returned status %d for POST %s", resp.StatusCode, path)
}
if result != nil {
return json.NewDecoder(resp.Body).Decode(result)
}
return nil
}
func (c *APIClient) put(ctx context.Context, path string, body, result interface{}) error {
resp, err := c.doRequest(ctx, http.MethodPut, path, body)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("API returned status %d for PUT %s", resp.StatusCode, path)
}
if result != nil {
return json.NewDecoder(resp.Body).Decode(result)
}
return nil
}
func (c *APIClient) delete(ctx context.Context, path string) error {
resp, err := c.doRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent {
return fmt.Errorf("API returned status %d for DELETE %s", resp.StatusCode, path)
}
return nil
}