Skip to content

Commit

Permalink
Merge pull request #74 from bendrucker/add-api-key
Browse files Browse the repository at this point in the history
Add resource: api_key
  • Loading branch information
ttsangAtlassian authored Jun 4, 2020
2 parents 4225b26 + f2a8f01 commit ddcbc51
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 0 deletions.
1 change: 1 addition & 0 deletions pkg/artifactory/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func Provider() terraform.ResourceProvider {
"artifactory_replication_config": resourceArtifactoryReplicationConfig(),
"artifactory_single_replication_config": resourceArtifactorySingleReplicationConfig(),
"artifactory_certificate": resourceArtifactoryCertificate(),
"artifactory_api_key": resourceArtifactoryApiKey(),
// Deprecated. Remove in V3
"artifactory_permission_targets": resourceArtifactoryPermissionTargets(),
},
Expand Down
90 changes: 90 additions & 0 deletions pkg/artifactory/resource_artifactory_api_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package artifactory

import (
"context"
"fmt"
"net/http"
"strconv"

"github.com/atlassian/go-artifactory/v2/artifactory"
v1 "github.com/atlassian/go-artifactory/v2/artifactory/v1"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceArtifactoryApiKey() *schema.Resource {
return &schema.Resource{
Create: resourceApiKeyCreate,
Read: resourceApiKeyRead,
Delete: resourceApiKeyDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"api_key": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
},
}
}

func unpackApiKey(s *schema.ResourceData) *v1.ApiKey {
d := &ResourceData{s}
apiKey := new(v1.ApiKey)
apiKey.ApiKey = d.getStringRef("api_key", false)

return apiKey
}

func packApiKey(apiKey *v1.ApiKey, d *schema.ResourceData) error {
hasErr := false
logErr := cascadingErr(&hasErr)

logErr(d.Set("api_key", apiKey.ApiKey))

if hasErr {
return fmt.Errorf("failed to pack api key")
}

return nil
}

func resourceApiKeyCreate(d *schema.ResourceData, m interface{}) error {
c := m.(*artifactory.Artifactory)

apiKey, _, err := c.V1.Security.CreateApiKey(context.Background())
if err != nil {
return err
}

d.SetId(strconv.Itoa(hashcode.String(*apiKey.ApiKey)))
return resourceApiKeyRead(d, m)
}

func resourceApiKeyRead(d *schema.ResourceData, m interface{}) error {
c := m.(*artifactory.Artifactory)

apiKey, resp, err := c.V1.Security.GetApiKey(context.Background())
if resp.StatusCode == http.StatusNotFound {
d.SetId("")
return nil
} else if err != nil {
return err
}

return packApiKey(apiKey, d)
}

func resourceApiKeyDelete(d *schema.ResourceData, m interface{}) error {
c := m.(*artifactory.Artifactory)
_, resp, err := c.V1.Security.RevokeApiKey(context.Background())
if resp.StatusCode == http.StatusNotFound {
return nil
}

return err
}
52 changes: 52 additions & 0 deletions pkg/artifactory/resource_artifactory_api_key_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package artifactory

import (
"context"
"fmt"
"testing"

"github.com/atlassian/go-artifactory/v2/artifactory"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

const apiKey = `
resource "artifactory_api_key" "foobar" {}
`

func TestAccApiKey(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
CheckDestroy: testAccCheckApiKeyDestroy("artifactory_api_key.foobar"),
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: apiKey,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("artifactory_api_key.foobar", "api_key"),
),
},
},
})
}

func testAccCheckApiKeyDestroy(id string) func(*terraform.State) error {
return func(s *terraform.State) error {
client := testAccProvider.Meta().(*artifactory.Artifactory)
rs, ok := s.RootModule().Resources[id]

if !ok {
return fmt.Errorf("err: Resource id[%s] not found", id)
}

key, _, err := client.V1.Security.GetApiKey(context.Background())

if err != nil {
return fmt.Errorf("error: Request failed: %s", err.Error())
} else if key.ApiKey != nil {
return fmt.Errorf("error: API key %s still exists", rs.Primary.ID)
}

return nil
}
}
36 changes: 36 additions & 0 deletions website/docs/r/artifactory_api_key.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
layout: "artifactory"
page_title: "Artifactory: artifactory_api_key"
sidebar_current: "docs-artifactory-resource-api-key"
description: |-
Provides an API key resource.
---

# artifactory_api_key

Provides an Artifactory API key resource. This can be used to create and manage Artifactory API keys.

~> **Note:** API keys will be stored in the raw state as plain-text. [Read more about sensitive data in
state](https://www.terraform.io/docs/state/sensitive-data.html).


## Example Usage

```hcl
# Create a new Artifactory API key for the configured user
resource "artifactory_api_key" "ci" {}
```

## Attribute Reference

The following attributes are exported:

* `api_key` - The API key.

## Import

A user's API key can be imported using any identifier, e.g.

```
$ terraform import artifactory_api_key.test import
```

0 comments on commit ddcbc51

Please sign in to comment.