-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #36 from nullplatform/features/account
feature: accounts on terraform
- Loading branch information
Showing
6 changed files
with
403 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package nullplatform | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
) | ||
|
||
const ACCOUNT_PATH = "/account" | ||
|
||
type Account struct { | ||
Id int `json:"id,omitempty"` | ||
Name string `json:"name,omitempty"` | ||
OrganizationId string `json:"organization_id,omitempty"` | ||
RepositoryPrefix string `json:"repository_prefix,omitempty"` | ||
RepositoryProvider string `json:"repository_provider,omitempty"` | ||
Slug string `json:"slug,omitempty"` | ||
Status string `json:"status,omitempty"` | ||
} | ||
|
||
func (c *NullClient) CreateAccount(account *Account) (*Account, error) { | ||
var buf bytes.Buffer | ||
err := json.NewEncoder(&buf).Encode(*account) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res, err := c.MakeRequest("POST", ACCOUNT_PATH, &buf) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer res.Body.Close() | ||
|
||
if res.StatusCode != http.StatusOK { | ||
var nErr NullErrors | ||
if err := json.NewDecoder(res.Body).Decode(&nErr); err != nil { | ||
return nil, fmt.Errorf("failed to decode null error response: %w", err) | ||
} | ||
return nil, fmt.Errorf("error creating account resource, got status code: %d, message: %s", res.StatusCode, nErr.Message) | ||
} | ||
|
||
accountRes := &Account{} | ||
derr := json.NewDecoder(res.Body).Decode(accountRes) | ||
|
||
if derr != nil { | ||
return nil, derr | ||
} | ||
|
||
return accountRes, nil | ||
} | ||
|
||
func (c *NullClient) PatchAccount(accountId string, account *Account) error { | ||
path := fmt.Sprintf("%s/%s", ACCOUNT_PATH, accountId) | ||
|
||
var buf bytes.Buffer | ||
err := json.NewEncoder(&buf).Encode(*account) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
res, err := c.MakeRequest("PATCH", path, &buf) | ||
if err != nil { | ||
return err | ||
} | ||
defer res.Body.Close() | ||
|
||
if (res.StatusCode != http.StatusOK) && (res.StatusCode != http.StatusNoContent) { | ||
var nErr NullErrors | ||
if err := json.NewDecoder(res.Body).Decode(&nErr); err != nil { | ||
return fmt.Errorf("failed to decode null error response: %w", err) | ||
} | ||
return fmt.Errorf("error updating account resource, got status code: %d, message: %s", res.StatusCode, nErr.Message) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (c *NullClient) GetAccount(accountId string) (*Account, error) { | ||
path := fmt.Sprintf("%s/%s", ACCOUNT_PATH, accountId) | ||
|
||
res, err := c.MakeRequest("GET", path, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer res.Body.Close() | ||
|
||
account := &Account{} | ||
derr := json.NewDecoder(res.Body).Decode(account) | ||
|
||
if derr != nil { | ||
return nil, derr | ||
} | ||
|
||
if account.Status == "deleted" { | ||
return account, fmt.Errorf("error getting account resource, the status is %s", account.Status) | ||
} | ||
|
||
if res.StatusCode != http.StatusOK { | ||
return nil, fmt.Errorf("error getting account resource, got %d for %s", res.StatusCode, accountId) | ||
} | ||
|
||
return account, nil | ||
} | ||
|
||
func (c *NullClient) DeleteAccount(accountId string) error { | ||
account := &Account{ | ||
Status: "inactive", | ||
} | ||
|
||
return c.PatchAccount(accountId, account) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package nullplatform | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strconv" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
func resourceAccount() *schema.Resource { | ||
return &schema.Resource{ | ||
Description: "The account resource allows you to configure a nullplatform account", | ||
|
||
Create: AccountCreate, | ||
Read: AccountRead, | ||
Update: AccountUpdate, | ||
Delete: AccountDelete, | ||
|
||
Importer: &schema.ResourceImporter{ | ||
StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
d.Set("id", d.Id()) | ||
return []*schema.ResourceData{d}, nil | ||
}, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "The name of the account", | ||
}, | ||
"organization_id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
ForceNew: true, | ||
Description: "The ID of the organization this account belongs to (computed from authentication token)", | ||
}, | ||
"repository_prefix": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "The prefix used for repositories in this account", | ||
}, | ||
"repository_provider": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "The repository provider for this account", | ||
}, | ||
"slug": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "The unique slug identifier for the account", | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func AccountCreate(d *schema.ResourceData, m any) error { | ||
nullOps := m.(NullOps) | ||
client := nullOps.(*NullClient) | ||
|
||
organizationID, err := client.GetOrganizationIDFromToken() | ||
if err != nil { | ||
return fmt.Errorf("error getting organization ID from token: %w", err) | ||
} | ||
|
||
newAccount := &Account{ | ||
Name: d.Get("name").(string), | ||
OrganizationId: organizationID, | ||
RepositoryPrefix: d.Get("repository_prefix").(string), | ||
RepositoryProvider: d.Get("repository_provider").(string), | ||
Slug: d.Get("slug").(string), | ||
} | ||
|
||
account, err := nullOps.CreateAccount(newAccount) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
d.SetId(strconv.Itoa(account.Id)) | ||
|
||
// Set the computed organization_id in the state | ||
if err := d.Set("organization_id", account.OrganizationId); err != nil { | ||
return fmt.Errorf("error setting organization_id: %w", err) | ||
} | ||
|
||
return AccountRead(d, m) | ||
} | ||
|
||
func AccountRead(d *schema.ResourceData, m any) error { | ||
nullOps := m.(NullOps) | ||
accountId := d.Id() | ||
|
||
account, err := nullOps.GetAccount(accountId) | ||
if err != nil { | ||
if account.Status == "inactive" { | ||
d.SetId("") | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
if err := d.Set("name", account.Name); err != nil { | ||
return err | ||
} | ||
if err := d.Set("organization_id", account.OrganizationId); err != nil { | ||
return err | ||
} | ||
if err := d.Set("repository_prefix", account.RepositoryPrefix); err != nil { | ||
return err | ||
} | ||
if err := d.Set("repository_provider", account.RepositoryProvider); err != nil { | ||
return err | ||
} | ||
if err := d.Set("slug", account.Slug); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func AccountUpdate(d *schema.ResourceData, m any) error { | ||
nullOps := m.(NullOps) | ||
accountId := d.Id() | ||
|
||
account := &Account{} | ||
|
||
if d.HasChange("name") { | ||
account.Name = d.Get("name").(string) | ||
} | ||
if d.HasChange("repository_prefix") { | ||
account.RepositoryPrefix = d.Get("repository_prefix").(string) | ||
} | ||
if d.HasChange("repository_provider") { | ||
account.RepositoryProvider = d.Get("repository_provider").(string) | ||
} | ||
if d.HasChange("slug") { | ||
account.Slug = d.Get("slug").(string) | ||
} | ||
|
||
err := nullOps.PatchAccount(accountId, account) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return AccountRead(d, m) | ||
} | ||
|
||
func AccountDelete(d *schema.ResourceData, m any) error { | ||
nullOps := m.(NullOps) | ||
accountId := d.Id() | ||
|
||
err := nullOps.DeleteAccount(accountId) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
d.SetId("") | ||
return nil | ||
} |
Oops, something went wrong.