init project
This commit is contained in:
105
provider.go
Normal file
105
provider.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
// apiClient holds configuration and auth token for talking to the backend API.
|
||||
type apiClient struct {
|
||||
BaseURL string
|
||||
Token string
|
||||
}
|
||||
|
||||
// loginRequest represents the request body for /login.
|
||||
type loginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// loginResponse represents the response body from /login.
|
||||
type loginResponse struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// Provider defines the vcluster Terraform provider.
|
||||
func Provider() *schema.Provider {
|
||||
return &schema.Provider{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"base_url": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Base URL of vcluster API, e.g. http://localhost:8082",
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Username for login to vcluster API",
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Sensitive: true,
|
||||
Description: "Password for login to vcluster API",
|
||||
},
|
||||
},
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"vcluster_cluster": resourceCluster(),
|
||||
},
|
||||
ConfigureContextFunc: func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
|
||||
baseURL := d.Get("base_url").(string)
|
||||
username := d.Get("username").(string)
|
||||
password := d.Get("password").(string)
|
||||
|
||||
client := &apiClient{
|
||||
BaseURL: baseURL,
|
||||
}
|
||||
|
||||
// Perform login to obtain token.
|
||||
reqBody, err := json.Marshal(loginRequest{
|
||||
Username: username,
|
||||
Password: password,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, diag.FromErr(err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/login", baseURL), bytes.NewReader(reqBody))
|
||||
if err != nil {
|
||||
return nil, diag.FromErr(err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, diag.FromErr(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
b, _ := io.ReadAll(resp.Body)
|
||||
return nil, diag.Errorf("login failed: %s: %s", resp.Status, string(b))
|
||||
}
|
||||
|
||||
var lr loginResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&lr); err != nil {
|
||||
return nil, diag.FromErr(err)
|
||||
}
|
||||
if lr.Token == "" {
|
||||
return nil, diag.Errorf("login succeeded but no token returned")
|
||||
}
|
||||
|
||||
client.Token = lr.Token
|
||||
return client, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user