Skip to content

Commit

Permalink
handle external challenge deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
ginkoid committed Feb 20, 2022
1 parent 970fbf3 commit 4a43137
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 106 deletions.
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ builds:
flags:
- -trimpath
ldflags:
- -s -w -X github.com/redpwn/terraform-provider-rctf/internal/version.Version={{.Version}}
- -s -w -X {{ .ModulePath }}/internal/version.Version={{ .Version }}
goos:
- windows
- linux
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ require (
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg v1.0.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 // indirect
github.com/aws/aws-sdk-go v1.25.3 // indirect
Expand Down
28 changes: 3 additions & 25 deletions go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions internal/provider/rctf.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package provider

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/redpwn/terraform-provider-rctf/internal/rctf"
Expand Down
94 changes: 35 additions & 59 deletions internal/provider/resource_challenge.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package provider

import (
"context"
"errors"
"fmt"
"regexp"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/redpwn/terraform-provider-rctf/internal/rctf"
Expand All @@ -20,9 +23,7 @@ func resourceChallenge() *schema.Resource {
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"name": {
Type: schema.TypeString,
Expand Down Expand Up @@ -82,9 +83,10 @@ func resourceChallenge() *schema.Resource {
}
}

func resourceChallengePut(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var idReg = regexp.MustCompile(`[^\w-]+`)

func resourceChallengePut(ctx context.Context, d *schema.ResourceData, m interface{}) (diags diag.Diagnostics) {
r := m.(*rctf.Client)
var diags diag.Diagnostics
c := rctf.Challenge{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
Expand All @@ -108,80 +110,54 @@ func resourceChallengePut(ctx context.Context, d *schema.ResourceData, m interfa
}
c.Id = d.Id()
if c.Id == "" {
c.Id = d.Get("id").(string)
}
if c.Id == "" {
c.Id = fmt.Sprintf("%s-%s", c.Category, c.Name)
c.Id = idReg.ReplaceAllString(fmt.Sprintf("%s-%s", c.Category, c.Name), "-")
d.SetId(c.Id)
d.Set("id", c.Id)
}
d.SetId(c.Id)
if err := r.PutChallenge(ctx, c); err != nil {
return diag.Errorf("put challenge: %s", err)
}
diags = append(diags, resourceChallengeRead(ctx, d, m)...)
return diags
}

func flattenFiles(files []rctf.ChallengeFile) []map[string]interface{} {
var f []map[string]interface{}
for _, file := range files {
f = append(f, map[string]interface{}{
"name": file.Name,
"url": file.Url,
})
}
return f
}

func resourceChallengeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
func resourceChallengeRead(ctx context.Context, d *schema.ResourceData, m interface{}) (diags diag.Diagnostics) {
r := m.(*rctf.Client)
var diags diag.Diagnostics
id := d.Id()
c, err := r.Challenge(ctx, id)
if err != nil {
rctfErr := &rctf.Error{}
if errors.As(err, rctfErr) && rctfErr.Kind == "badChallenge" {
d.SetId("")
return
}
return diag.Errorf("get challenge: %s", err)
}
if err := d.Set("id", c.Id); err != nil {
return diag.FromErr(err)
}
if err := d.Set("name", c.Name); err != nil {
return diag.FromErr(err)
}
if err := d.Set("description", c.Description); err != nil {
return diag.FromErr(err)
}
if err := d.Set("category", c.Category); err != nil {
return diag.FromErr(err)
}
if err := d.Set("author", c.Author); err != nil {
return diag.FromErr(err)
}
if err := d.Set("file", flattenFiles(c.Files)); err != nil {
return diag.FromErr(err)
}
if err := d.Set("min_points", c.Points.Min); err != nil {
return diag.FromErr(err)
}
if err := d.Set("max_points", c.Points.Max); err != nil {
return diag.FromErr(err)
}
if err := d.Set("flag", c.Flag); err != nil {
return diag.FromErr(err)
}
if err := d.Set("tiebreak_eligible", c.TiebreakEligible); err != nil {
return diag.FromErr(err)
}
if err := d.Set("sort_weight", c.SortWeight); err != nil {
return diag.FromErr(err)
d.Set("id", c.Id)
d.Set("name", c.Name)
d.Set("description", c.Description)
d.Set("category", c.Category)
d.Set("author", c.Author)
var f []map[string]interface{}
for _, file := range c.Files {
f = append(f, map[string]interface{}{
"name": file.Name,
"url": file.Url,
})
}
return diags
d.Set("file", f)
d.Set("min_points", c.Points.Min)
d.Set("max_points", c.Points.Max)
d.Set("flag", c.Flag)
d.Set("tiebreak_eligible", c.TiebreakEligible)
d.Set("sort_weight", c.SortWeight)
return
}

func resourceChallengeDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
func resourceChallengeDelete(ctx context.Context, d *schema.ResourceData, m interface{}) (diags diag.Diagnostics) {
r := m.(*rctf.Client)
var diags diag.Diagnostics
id := d.Id()
if err := r.DeleteChallenge(ctx, id); err != nil {
return diag.Errorf("delete challenge: %s", err)
}
return diags
return
}
11 changes: 4 additions & 7 deletions internal/rctf/challenge.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package rctf

import (
"context"
"errors"
"net/url"
)

Expand Down Expand Up @@ -48,21 +47,19 @@ func (c *Client) Challenge(ctx context.Context, id string) (Challenge, error) {
return Challenge{}, err
}
if res.Kind != "goodChallenges" {
return Challenge{}, errors.New(res.String())
return Challenge{}, res.err()
}
return res.Data, nil
}

func (c *Client) PutChallenge(ctx context.Context, challenge Challenge) error {
req := challengeRequest{Data: challenge}
res := response{}
req := challengeRequest{
Data: challenge,
}
if err := c.req(ctx, "PUT", challengeUrl(challenge.Id), &req, &res); err != nil {
return err
}
if res.Kind != "goodChallengeUpdate" {
return errors.New(res.String())
return res.err()
}
return nil
}
Expand All @@ -73,7 +70,7 @@ func (c *Client) DeleteChallenge(ctx context.Context, id string) error {
return err
}
if res.Kind != "goodChallengeDelete" {
return errors.New(res.String())
return res.err()
}
return nil
}
35 changes: 22 additions & 13 deletions internal/rctf/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,31 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/redpwn/terraform-provider-rctf/internal/version"
"net/http"
"net/url"

"github.com/redpwn/terraform-provider-rctf/internal/version"
)

type Client struct {
BaseUrl string
AuthToken string
http *http.Client
BaseUrl string
Header http.Header
http *http.Client
}

func New(baseUrl, authToken string) (*Client, error) {
u, err := url.Parse(baseUrl)
if err != nil {
return nil, err
}
h := http.Header{}
h.Set("user-agent", "terraform-provider-rctf/"+version.Version)
h.Set("content-type", "application/json")
h.Set("authorization", "Bearer "+authToken)
c := &Client{
BaseUrl: fmt.Sprintf("%s://%s/api/v1/", u.Scheme, u.Host),
AuthToken: authToken,
http: http.DefaultClient,
BaseUrl: fmt.Sprintf("%s://%s/api/v1/", u.Scheme, u.Host),
Header: h,
http: http.DefaultClient,
}
return c, nil
}
Expand All @@ -34,12 +39,18 @@ type response struct {
Message string `json:"message"`
}

func (r response) String() string {
return fmt.Sprintf("rctf response: %s: %s", r.Kind, r.Message)
type Error response

func (e Error) Error() string {
return fmt.Sprintf("rctf error: %s: %s", e.Kind, e.Message)
}

func (r response) err() error {
return Error(r)
}

func (c *Client) req(ctx context.Context, method, uri string, reqBody, resBody interface{}) error {
body := new(bytes.Buffer)
body := &bytes.Buffer{}
if reqBody != nil {
if err := json.NewEncoder(body).Encode(reqBody); err != nil {
return err
Expand All @@ -49,9 +60,7 @@ func (c *Client) req(ctx context.Context, method, uri string, reqBody, resBody i
if err != nil {
return err
}
req.Header.Set("user-agent", "terraform-provider-rctf/"+version.Version)
req.Header.Set("content-type", "application/json")
req.Header.Set("authorization", "Bearer "+c.AuthToken)
req.Header = c.Header
res, err := c.http.Do(req)
if err != nil {
return fmt.Errorf("do request %s %s: %w", method, uri, err)
Expand Down

0 comments on commit 4a43137

Please sign in to comment.