Skip to content

Commit

Permalink
feat: extend keys api with name parameter
Browse files Browse the repository at this point in the history
Adds support for a new `name` parameter.

Ref: LOG-12918
Signed-off-by: Jacob Hull <[email protected]>
  • Loading branch information
jakedipity committed Jun 1, 2022
1 parent 51a328a commit 49ec4d8
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 16 deletions.
12 changes: 9 additions & 3 deletions docs/resources/logdna_key.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ provider "logdna" {
resource "logdna_key" "service-key" {
type = "service"
name = "terraform-my_service_key"
lifecycle {
create_before_destroy = true
Expand All @@ -19,14 +20,17 @@ resource "logdna_key" "service-key" {
resource "logdna_key" "ingestion-key" {
type = "ingestion"
name = "terraform-my_ingestion_key"
lifecycle {
create_before_destroy = true
}
}
```

The `create_before_destroy` and `lifecycle` meta-argument are not required, but ensure a valid key is always available so there's no disruption of service.
The `create_before_destroy` and `lifecycle` meta-argument are not required; however, these options ensure a valid key is always available when a key is being recreated. This helps avoid any disruptions in service.

~> **NOTE:** We recommend prefixing the name of your terraform resources so they can be distinguished from other resources in the UI.

## Key Rotation

Expand All @@ -41,15 +45,17 @@ $ terraform apply -replace="logdna_key.my_key"

The following arguments are supported:

- `type`: **string** _(Required)_ The type of key to be used. Should be either `service` or `ingestion`.
- `type`: **string** _(Required)_ The type of key to be used. Can be one of either `service` or `ingestion`.
- `name`: **string** _(Optional)_ A non-unique name for the key. If not supplied, a default one is generated.

## Attributes Reference

In addition to all the arguments above, the following attributes are exported:

- `id`: **string** The unique identifier of this key.
- `key`: **string** The actual key value.
- `type`: **string** The type of key.
- `name`: **string** The name of the key.
- `type`: **string** The type of key. Can be one of either `service` or `ingestion`.
- `created`: **int** The date the key was created in Unix time milliseconds.

## Import
Expand Down
17 changes: 15 additions & 2 deletions logdna/request_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ type categoryRequest struct {
Type string `json:"type,omitempty"`
}

type keyRequest struct {
Name string `json:"name,omitempty"`
}

func (view *viewRequest) CreateRequestBody(d *schema.ResourceData) diag.Diagnostics {
// This function pulls from the schema in preparation to JSON marshal
var diags diag.Diagnostics
Expand Down Expand Up @@ -85,11 +89,20 @@ func (alert *alertRequest) CreateRequestBody(d *schema.ResourceData) diag.Diagno
return diags
}

func (categoty *categoryRequest) CreateRequestBody(d *schema.ResourceData) diag.Diagnostics {
func (category *categoryRequest) CreateRequestBody(d *schema.ResourceData) diag.Diagnostics {
var diags diag.Diagnostics

// Scalars
category.Name = d.Get("name").(string)

return diags
}

func (key *keyRequest) CreateRequestBody(d *schema.ResourceData) diag.Diagnostics {
var diags diag.Diagnostics

// Scalars
categoty.Name = d.Get("name").(string)
key.Name = d.Get("name").(string)

return diags
}
Expand Down
52 changes: 49 additions & 3 deletions logdna/resource_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,25 @@ import (

"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"
)

func resourceKeyCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
pc := m.(*providerConfig)

keyType := d.Get("type").(string)
key := keyRequest{}

if diags = key.CreateRequestBody(d); diags.HasError() {
return diags
}

req := newRequestConfig(
pc,
"POST",
fmt.Sprintf("/v1/config/keys?type=%s", keyType),
nil,
key,
)

body, err := req.MakeRequest()
Expand All @@ -41,6 +48,35 @@ func resourceKeyCreate(ctx context.Context, d *schema.ResourceData, m interface{
return resourceKeyRead(ctx, d, m)
}

func resourceKeyUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
pc := m.(*providerConfig)
keyID := d.Id()

key := keyRequest{}
if diags = key.CreateRequestBody(d); diags.HasError() {
return diags
}

req := newRequestConfig(
pc,
"PUT",
fmt.Sprintf("/v1/config/keys/%s", keyID),
key,
)

body, err := req.MakeRequest()
log.Printf("[DEBUG] %s %s, payload is: %s", req.method, req.apiURL, body)

if err != nil {
return diag.FromErr(err)
}

log.Printf("[DEBUG] %s %s SUCCESS. Remote resource updated.", req.method, req.apiURL)

return resourceKeyRead(ctx, d, m)
}

func resourceKeyRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics

Expand Down Expand Up @@ -80,6 +116,7 @@ func resourceKeyRead(ctx context.Context, d *schema.ResourceData, m interface{})

// Top level keys can be set directly
appendError(d.Set("type", key.Type), &diags)
appendError(d.Set("name", key.Name), &diags)
appendError(d.Set("id", key.KeyID), &diags)
appendError(d.Set("key", key.Key), &diags)
appendError(d.Set("created", key.Created), &diags)
Expand Down Expand Up @@ -112,6 +149,7 @@ func resourceKeyDelete(ctx context.Context, d *schema.ResourceData, m interface{
func resourceKey() *schema.Resource {
return &schema.Resource{
CreateContext: resourceKeyCreate,
UpdateContext: resourceKeyUpdate,
ReadContext: resourceKeyRead,
DeleteContext: resourceKeyDelete,
Importer: &schema.ResourceImporter{
Expand All @@ -120,9 +158,17 @@ func resourceKey() *schema.Resource {

Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"ingestion", "service"}, false),
},
"name": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
Optional: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return new == ""
},
},
"id": {
Type: schema.TypeString,
Expand Down
40 changes: 39 additions & 1 deletion logdna/resource_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestKey_ErrorResourceTypeInvalid(t *testing.T) {
Steps: []resource.TestStep{
{
Config: fmtTestConfigResource("key", "new", []string{serviceKey, apiHostUrl}, args, nilOpt, nilLst),
ExpectError: regexp.MustCompile("Error: POST .+?, status 400 NOT OK!"),
ExpectError: regexp.MustCompile(`Error: expected type to be one of \[ingestion service\], got incorrect`),
},
},
})
Expand All @@ -41,10 +41,22 @@ func TestKey_ErrorResourceTypeInvalid(t *testing.T) {
func TestKey_Basic(t *testing.T) {
serviceArgs := map[string]string{
"type": `"service"`,
"name": `"my first name"`,
}

serviceUpdateArgs := map[string]string{
"type": `"service"`,
"name": `"my new name"`,
}

ingestionArgs := map[string]string{
"type": `"ingestion"`,
"name": `"my first name"`,
}

ingestionUpdateArgs := map[string]string{
"type": `"ingestion"`,
"name": `"my new name"`,
}

resource.Test(t, resource.TestCase{
Expand All @@ -56,6 +68,19 @@ func TestKey_Basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testResourceExists("key", "new-service-key"),
resource.TestCheckResourceAttr("logdna_key.new-service-key", "type", strings.Replace(serviceArgs["type"], "\"", "", 2)),
resource.TestCheckResourceAttr("logdna_key.new-service-key", "name", strings.Replace(serviceArgs["name"], "\"", "", 2)),
resource.TestCheckResourceAttrSet("logdna_key.new-service-key", "id"),
resource.TestCheckResourceAttrSet("logdna_key.new-service-key", "key"),
resource.TestCheckResourceAttrSet("logdna_key.new-service-key", "created"),
),
},
{
// NOTE It tests a service key update operation
Config: fmtTestConfigResource("key", "new-service-key", []string{serviceKey, apiHostUrl}, serviceUpdateArgs, nilOpt, nilLst),
Check: resource.ComposeTestCheckFunc(
testResourceExists("key", "new-service-key"),
resource.TestCheckResourceAttr("logdna_key.new-service-key", "type", strings.Replace(serviceUpdateArgs["type"], "\"", "", 2)),
resource.TestCheckResourceAttr("logdna_key.new-service-key", "name", strings.Replace(serviceUpdateArgs["name"], "\"", "", 2)),
resource.TestCheckResourceAttrSet("logdna_key.new-service-key", "id"),
resource.TestCheckResourceAttrSet("logdna_key.new-service-key", "key"),
resource.TestCheckResourceAttrSet("logdna_key.new-service-key", "created"),
Expand All @@ -72,6 +97,19 @@ func TestKey_Basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testResourceExists("key", "new-ingestion-key"),
resource.TestCheckResourceAttr("logdna_key.new-ingestion-key", "type", strings.Replace(ingestionArgs["type"], "\"", "", 2)),
resource.TestCheckResourceAttr("logdna_key.new-ingestion-key", "name", strings.Replace(ingestionArgs["name"], "\"", "", 2)),
resource.TestCheckResourceAttrSet("logdna_key.new-ingestion-key", "id"),
resource.TestCheckResourceAttrSet("logdna_key.new-ingestion-key", "key"),
resource.TestCheckResourceAttrSet("logdna_key.new-ingestion-key", "created"),
),
},
{
// NOTE It tests an ingestion key update operation
Config: fmtTestConfigResource("key", "new-ingestion-key", []string{serviceKey, apiHostUrl}, ingestionUpdateArgs, nilOpt, nilLst),
Check: resource.ComposeTestCheckFunc(
testResourceExists("key", "new-ingestion-key"),
resource.TestCheckResourceAttr("logdna_key.new-ingestion-key", "type", strings.Replace(ingestionUpdateArgs["type"], "\"", "", 2)),
resource.TestCheckResourceAttr("logdna_key.new-ingestion-key", "name", strings.Replace(ingestionUpdateArgs["name"], "\"", "", 2)),
resource.TestCheckResourceAttrSet("logdna_key.new-ingestion-key", "id"),
resource.TestCheckResourceAttrSet("logdna_key.new-ingestion-key", "key"),
resource.TestCheckResourceAttrSet("logdna_key.new-ingestion-key", "created"),
Expand Down
14 changes: 7 additions & 7 deletions logdna/resource_view_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ func TestView_PresetAlert(t *testing.T) {
{
Config: iniCfg,
Check: resource.ComposeTestCheckFunc(
testResourceExists("view", "test-view"),
testResourceExists("view", "test_view"),
resource.TestCheckResourceAttr("logdna_view.test_view", "name", "test"),
resource.TestCheckResourceAttr("logdna_view.test_view", "query", "test"),
resource.TestCheckResourceAttr("logdna_view.test_view", "apps.#", "2"),
Expand Down Expand Up @@ -595,7 +595,7 @@ func TestView_PresetAlert(t *testing.T) {
{
Config: updCfg,
Check: resource.ComposeTestCheckFunc(
testResourceExists("view", "test-view"),
testResourceExists("view", "test_view"),
resource.TestCheckResourceAttr("logdna_view.test_view", "name", "test2"),
resource.TestCheckResourceAttr("logdna_view.test_view", "query", "query2"),
resource.TestCheckResourceAttr("logdna_view.test_view", "apps.0", "app3"),
Expand Down Expand Up @@ -634,10 +634,10 @@ func TestView_ErrorsConflictPresetId(t *testing.T) {
}

rsArgs := cloneDefaults(rsDefaults["view"])
rsArgs["apps"] = `["app1", "app2"]`
rsArgs["hosts"] = `["host1", "host2"]`
rsArgs["levels"] = `["fatal", "critical"]`
rsArgs["tags"] = `["tags1", "tags2"]`
rsArgs["apps"] = `["app1", "app2"]`
rsArgs["hosts"] = `["host1", "host2"]`
rsArgs["levels"] = `["fatal", "critical"]`
rsArgs["tags"] = `["tags1", "tags2"]`
rsArgs["presetid"] = `"1q2w3e4r5t"`

incCfg := fmtTestConfigResource("view", "test_view", globalPcArgs, rsArgs, chArgs, nilLst)
Expand All @@ -646,7 +646,7 @@ func TestView_ErrorsConflictPresetId(t *testing.T) {
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: incCfg,
Config: incCfg,
ExpectError: regexp.MustCompile("Error: Conflicting configuration arguments"),
},
},
Expand Down
1 change: 1 addition & 0 deletions logdna/response_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type alertResponse struct {
type keyResponse struct {
KeyID string `json:"id"`
Key string `json:"key"`
Name string `json:"name"`
Type string `json:"type"`
Created int `json:"created,omitempty"`
}
Expand Down

0 comments on commit 49ec4d8

Please sign in to comment.