Skip to content

Commit

Permalink
Merge pull request #120 from terraform-providers/f-user-gpg-key
Browse files Browse the repository at this point in the history
New Resource: github_user_gpg_key
  • Loading branch information
radeksimko authored Aug 10, 2018
2 parents 20cf0d4 + 5f24c0c commit c6a6e49
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 5 deletions.
1 change: 1 addition & 0 deletions github/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func Provider() terraform.ResourceProvider {
"github_team": resourceGithubTeam(),
"github_team_membership": resourceGithubTeamMembership(),
"github_team_repository": resourceGithubTeamRepository(),
"github_user_gpg_key": resourceGithubUserGpgKey(),
"github_user_ssh_key": resourceGithubUserSshKey(),
},

Expand Down
77 changes: 77 additions & 0 deletions github/resource_github_user_gpg_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package github

import (
"context"
"log"
"strconv"

"github.com/hashicorp/terraform/helper/schema"
)

func resourceGithubUserGpgKey() *schema.Resource {
return &schema.Resource{
Create: resourceGithubUserGpgKeyCreate,
Read: resourceGithubUserGpgKeyRead,
Delete: resourceGithubUserGpgKeyDelete,

Schema: map[string]*schema.Schema{
"armored_public_key": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"key_id": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceGithubUserGpgKeyCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client

pubKey := d.Get("armored_public_key").(string)

key, _, err := client.Users.CreateGPGKey(context.TODO(), pubKey)
if err != nil {
return err
}

d.SetId(strconv.FormatInt(*key.ID, 10))

return resourceGithubUserGpgKeyRead(d, meta)
}

func resourceGithubUserGpgKeyRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client

id, err := strconv.ParseInt(d.Id(), 10, 64)
if err != nil {
return unconvertibleIdErr(d.Id(), err)
}

key, _, err := client.Users.GetGPGKey(context.TODO(), id)
if err != nil {
log.Printf("[WARN] GitHub User GPG Key (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

d.Set("key_id", key.KeyID)

return nil
}

func resourceGithubUserGpgKeyDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client

id, err := strconv.ParseInt(d.Id(), 10, 64)
if err != nil {
return unconvertibleIdErr(d.Id(), err)
}

_, err = client.Users.DeleteGPGKey(context.TODO(), id)

return err
}
91 changes: 91 additions & 0 deletions github/resource_github_user_gpg_key_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package github

import (
"context"
"fmt"
"path/filepath"
"regexp"
"strconv"
"testing"

"github.com/google/go-github/github"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccGithubUserGpgKey_basic(t *testing.T) {
var key github.GPGKey
keyRe := regexp.MustCompile("^-----BEGIN PGP PUBLIC KEY BLOCK-----")
pubKeyPath := filepath.Join("test-fixtures", "gpg-pubkey.asc")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGithubUserGpgKeyDestroy,
Steps: []resource.TestStep{
{
Config: testAccGithubUserGpgKeyConfig(pubKeyPath),
Check: resource.ComposeTestCheckFunc(
testAccCheckGithubUserGpgKeyExists("github_user_gpg_key.test", &key),
resource.TestMatchResourceAttr("github_user_gpg_key.test", "armored_public_key", keyRe),
resource.TestCheckResourceAttr("github_user_gpg_key.test", "key_id", "AC541D2D1709CD33"),
),
},
},
})
}

func testAccCheckGithubUserGpgKeyExists(n string, key *github.GPGKey) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not Found: %s", n)
}

id, err := strconv.ParseInt(rs.Primary.ID, 10, 64)
if err != nil {
return unconvertibleIdErr(rs.Primary.ID, err)
}

org := testAccProvider.Meta().(*Organization)
receivedKey, _, err := org.client.Users.GetGPGKey(context.TODO(), id)
if err != nil {
return err
}
*key = *receivedKey
return nil
}
}

func testAccCheckGithubUserGpgKeyDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*Organization).client

for _, rs := range s.RootModule().Resources {
if rs.Type != "github_user_gpg_key" {
continue
}

id, err := strconv.ParseInt(rs.Primary.ID, 10, 64)
if err != nil {
return unconvertibleIdErr(rs.Primary.ID, err)
}

_, resp, err := conn.Users.GetGPGKey(context.TODO(), id)
if err == nil {
return fmt.Errorf("GPG key %s still exists", rs.Primary.ID)
}
if resp.StatusCode != 404 {
return err
}
return nil
}
return nil
}

func testAccGithubUserGpgKeyConfig(pubKeyPath string) string {
return fmt.Sprintf(`
resource "github_user_gpg_key" "test" {
armored_public_key = "${file("%s")}"
}
`, pubKeyPath)
}
53 changes: 53 additions & 0 deletions github/test-fixtures/gpg-pubkey.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----

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
=FSt9
-----END PGP PUBLIC KEY BLOCK-----
40 changes: 40 additions & 0 deletions website/docs/r/user_gpg_key.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
layout: "github"
page_title: "GitHub: github_user_gpg_key"
sidebar_current: "docs-github-resource-user-gpg-key"
description: |-
Provides a GitHub user's GPG key resource.
---

# github_user_gpg_key

Provides a GitHub user's GPG key resource.

This resource allows you to add/remove GPG keys from your user account.

## Example Usage

```hcl
resource "github_user_gpg_key" "example" {
armored_public_key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n...\n-----END PGP PUBLIC KEY BLOCK-----"
}
```

## Argument Reference

The following arguments are supported:

* `armored_public_key` - (Required) Your pulic GPG key, generated in ASCII-armored format.
See [Generating a new GPG key](https://help.github.com/articles/generating-a-new-gpg-key/) for help on creating a GPG key.

## Attributes Reference

The following attributes are exported:

* `id` - The GitHub ID of the GPG key, e.g. `401586`
* `key_id` - The key ID of the GPG key, e.g. `3262EFF25BA0D270`

## Import

GPG keys are not importable due to the fact that [API](https://developer.github.com/v3/users/gpg_keys/#gpg-keys)
does not return previously uploaded GPG key.
13 changes: 8 additions & 5 deletions website/github.erb
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,15 @@
<li<%= sidebar_current("docs-github-resource-branch-protection") %>>
<a href="/docs/providers/github/r/branch_protection.html">github_branch_protection</a>
</li>
<li<%= sidebar_current("docs-github-resource-issue-label") %>>
<a href="/docs/providers/github/r/issue_label.html">github_issue_label</a>
</li>
<li<%= sidebar_current("docs-github-resource-membership") %>>
<a href="/docs/providers/github/r/membership.html">github_membership</a>
</li>
<li<%= sidebar_current("docs-github-resource-organization-project") %>>
<a href="/docs/providers/github/r/organization_project.html">github_organization_project</a>
</li>
<li<%= sidebar_current("docs-github-resource-organization-webhook") %>>
<a href="/docs/providers/github/r/organization_webhook.html">github_organization_webhook</a>
</li>
Expand Down Expand Up @@ -64,11 +70,8 @@
<li<%= sidebar_current("docs-github-resource-team-repository") %>>
<a href="/docs/providers/github/r/team_repository.html">github_team_repository</a>
</li>
<li<%= sidebar_current("docs-github-resource-issue-label") %>>
<a href="/docs/providers/github/r/issue_label.html">github_issue_label</a>
</li>
<li<%= sidebar_current("docs-github-resource-organization-project") %>>
<a href="/docs/providers/github/r/organization_project.html">github_organization_project</a>
<li<%= sidebar_current("docs-github-resource-user-gpg-key") %>>
<a href="/docs/providers/github/r/user_gpg_key.html">github_user_gpg_key</a>
</li>
<li<%= sidebar_current("docs-github-resource-user-ssh-key") %>>
<a href="/docs/providers/github/r/user_ssh_key.html">github_user_ssh_key</a>
Expand Down

0 comments on commit c6a6e49

Please sign in to comment.