Skip to content

Commit

Permalink
Add consumer_jwt resource
Browse files Browse the repository at this point in the history
  • Loading branch information
scastrianni committed Jan 6, 2024
1 parent b318bad commit 9e10be1
Show file tree
Hide file tree
Showing 4 changed files with 226 additions and 0 deletions.
27 changes: 27 additions & 0 deletions konnect/client/consumer_jwt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package client

import "strings"

const (
ConsumerJWTPath = ControlPlanePathGet + "/core-entities/consumers/%s/jwt"
ConsumerJWTPathGet = ConsumerJWTPath + "/%s"
)

type ConsumerJWT struct {
ControlPlaneId string `json:"-"`
ConsumerId string `json:"-"`
Id string `json:"id"`
Key string `json:"key,omitempty"`
Algorithm string `json:"algorithm"`
RSAPublicKey string `json:"rsa_public_key,omitempty"`
Secret string `json:"secret,omitempty"`
}

func (cj *ConsumerJWT) ConsumerJWTEncodeId() string {
return cj.ControlPlaneId + IdSeparator + cj.ConsumerId + IdSeparator + cj.Id
}

func ConsumerJWTDecodeId(s string) (string, string, string) {
tokens := strings.Split(s, IdSeparator)
return tokens[0], tokens[1], tokens[2]
}
1 change: 1 addition & 0 deletions konnect/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func Provider() *schema.Provider {
"konnect_consumer_acl": resourceConsumerACL(),
"konnect_consumer_basic": resourceConsumerBasic(),
"konnect_consumer_hmac": resourceConsumerHMAC(),
"konnect_consumer_jwt": resourceConsumerJWT(),
"konnect_plugin": resourcePlugin(),
},
DataSourcesMap: map[string]*schema.Resource{
Expand Down
192 changes: 192 additions & 0 deletions konnect/resource_consumer_jwt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package konnect

import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/go-http-utils/headers"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/scastria/terraform-provider-konnect/konnect/client"
"net/http"
)

func resourceConsumerJWT() *schema.Resource {
return &schema.Resource{
CreateContext: resourceConsumerJWTCreate,
ReadContext: resourceConsumerJWTRead,
UpdateContext: resourceConsumerJWTUpdate,
DeleteContext: resourceConsumerJWTDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"control_plane_id": {
Type: schema.TypeString,
Required: true,
},
"consumer_id": {
Type: schema.TypeString,
Required: true,
},
"key": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"secret": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"algorithm": {
Type: schema.TypeString,
Optional: true,
Default: "HS256",
ValidateFunc: validation.StringInSlice([]string{"HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "ES256", "ES384"}, false),
},
"rsa_public_key": {
Type: schema.TypeString,
Optional: true,
},
"jwt_id": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func fillConsumerJWT(c *client.ConsumerJWT, d *schema.ResourceData) {
c.ControlPlaneId = d.Get("control_plane_id").(string)
c.ConsumerId = d.Get("consumer_id").(string)
c.Algorithm = d.Get("algorithm").(string)
key, ok := d.GetOk("key")
if ok {
c.Key = key.(string)
}
secret, ok := d.GetOk("secret")
if ok {
c.Secret = secret.(string)
}
rsaPublicKey, ok := d.GetOk("rsa_public_key")
if ok {
c.RSAPublicKey = rsaPublicKey.(string)
}
}

func fillResourceDataFromConsumerJWT(c *client.ConsumerJWT, d *schema.ResourceData) {
d.Set("control_plane_id", c.ControlPlaneId)
d.Set("consumer_id", c.ConsumerId)
d.Set("algorithm", c.Algorithm)
d.Set("key", c.Key)
d.Set("secret", c.Secret)
d.Set("rsa_public_key", c.RSAPublicKey)
d.Set("jwt_id", c.Id)
}

func resourceConsumerJWTCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
c := m.(*client.Client)
buf := bytes.Buffer{}
newConsumerJWT := client.ConsumerJWT{}
fillConsumerJWT(&newConsumerJWT, d)
err := json.NewEncoder(&buf).Encode(newConsumerJWT)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
requestPath := fmt.Sprintf(client.ConsumerJWTPath, newConsumerJWT.ControlPlaneId, newConsumerJWT.ConsumerId)
requestHeaders := http.Header{
headers.ContentType: []string{client.ApplicationJson},
}
body, err := c.HttpRequest(ctx, true, http.MethodPost, requestPath, nil, requestHeaders, &buf)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
retVal := &client.ConsumerJWT{}
err = json.NewDecoder(body).Decode(retVal)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
retVal.ControlPlaneId = newConsumerJWT.ControlPlaneId
retVal.ConsumerId = newConsumerJWT.ConsumerId
d.SetId(retVal.ConsumerJWTEncodeId())
fillResourceDataFromConsumerJWT(retVal, d)
return diags
}

func resourceConsumerJWTRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
controlPlaneId, consumerId, id := client.ConsumerJWTDecodeId(d.Id())
c := m.(*client.Client)
requestPath := fmt.Sprintf(client.ConsumerJWTPathGet, controlPlaneId, consumerId, id)
body, err := c.HttpRequest(ctx, true, http.MethodGet, requestPath, nil, nil, &bytes.Buffer{})
if err != nil {
d.SetId("")
re := err.(*client.RequestError)
if re.StatusCode == http.StatusNotFound {
return diags
}
return diag.FromErr(err)
}
retVal := &client.ConsumerJWT{}
err = json.NewDecoder(body).Decode(retVal)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
retVal.ControlPlaneId = controlPlaneId
retVal.ConsumerId = consumerId
fillResourceDataFromConsumerJWT(retVal, d)
return diags
}

func resourceConsumerJWTUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
controlPlaneId, consumerId, id := client.ConsumerJWTDecodeId(d.Id())
c := m.(*client.Client)
buf := bytes.Buffer{}
upConsumerJWT := client.ConsumerJWT{}
fillConsumerJWT(&upConsumerJWT, d)
// Hide non-updateable fields
//upTeam.IsPredefined = false
err := json.NewEncoder(&buf).Encode(upConsumerJWT)
if err != nil {
return diag.FromErr(err)
}
requestPath := fmt.Sprintf(client.ConsumerJWTPathGet, controlPlaneId, consumerId, id)
requestHeaders := http.Header{
headers.ContentType: []string{client.ApplicationJson},
}
body, err := c.HttpRequest(ctx, true, http.MethodPut, requestPath, nil, requestHeaders, &buf)
if err != nil {
return diag.FromErr(err)
}
retVal := &client.ConsumerJWT{}
err = json.NewDecoder(body).Decode(retVal)
if err != nil {
return diag.FromErr(err)
}
retVal.ControlPlaneId = controlPlaneId
retVal.ConsumerId = consumerId
fillResourceDataFromConsumerJWT(retVal, d)
return diags
}

func resourceConsumerJWTDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
controlPlaneId, consumerId, id := client.ConsumerJWTDecodeId(d.Id())
c := m.(*client.Client)
requestPath := fmt.Sprintf(client.ConsumerJWTPathGet, controlPlaneId, consumerId, id)
_, err := c.HttpRequest(ctx, true, http.MethodDelete, requestPath, nil, nil, &bytes.Buffer{})
if err != nil {
return diag.FromErr(err)
}
d.SetId("")
return diags
}
6 changes: 6 additions & 0 deletions test/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,9 @@ data "konnect_consumer" "C" {
# username = "shawn"
## secret = "pass2"
#}
#resource "konnect_consumer_jwt" "CJWT" {
# control_plane_id = data.konnect_control_plane.RG.id
# consumer_id = data.konnect_consumer.C.consumer_id
# secret = "pass"
# key = "hello"
#}

0 comments on commit 9e10be1

Please sign in to comment.