Skip to content

Commit

Permalink
Add new datasource to get GitHub App token (integrations#1671)
Browse files Browse the repository at this point in the history
* Add new datasource to get GitHub App token

* Add new datasource to get GitHub App token

* Fix merge error

---------

Co-authored-by: Keegan Campbell <me@kfcampbell.com>
  • Loading branch information
phillebaba and kfcampbell authored Jun 15, 2023
1 parent 42a596a commit caf6167
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 0 deletions.
15 changes: 15 additions & 0 deletions examples/app_token/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
terraform {
required_providers {
github = {
source = "integrations/github"
}
}
}

provider "github" {}

data "github_app_token" "this" {
app_id = var.app_id
installation_id = var.installation_id
pem_file = file(var.pem_file_path)
}
11 changes: 11 additions & 0 deletions examples/app_token/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
variable "app_id" {
type = string
}

variable "installation_id" {
type = string
}

variable "pem_file_path" {
type = string
}
63 changes: 63 additions & 0 deletions github/data_source_github_app_token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package github

import (
"strings"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func dataSourceGithubAppToken() *schema.Resource {
return &schema.Resource{
Read: dataSourceGithubAppTokenRead,

Schema: map[string]*schema.Schema{
"app_id": {
Type: schema.TypeString,
Required: true,
Description: descriptions["app_auth.id"],
},
"installation_id": {
Type: schema.TypeString,
Required: true,
Description: descriptions["app_auth.installation_id"],
},
"pem_file": {
Type: schema.TypeString,
Required: true,
Description: descriptions["app_auth.pem_file"],
},
"token": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
Description: "The generated token from the credentials.",
},
},
}
}

func dataSourceGithubAppTokenRead(d *schema.ResourceData, meta interface{}) error {
appID := d.Get("app_id").(string)
installationID := d.Get("installation_id").(string)
pemFile := d.Get("pem_file").(string)

baseURL := meta.(*Owner).v3client.BaseURL.String()

// The Go encoding/pem package only decodes PEM formatted blocks
// that contain new lines. Some platforms, like Terraform Cloud,
// do not support new lines within Environment Variables.
// Any occurrence of \n in the `pem_file` argument's value
// (explicit value, or default value taken from
// GITHUB_APP_PEM_FILE Environment Variable) is replaced with an
// actual new line character before decoding.
pemFile = strings.Replace(pemFile, `\n`, "\n", -1)

token, err := GenerateOAuthTokenFromApp(baseURL, appID, installationID, pemFile)
if err != nil {
return err
}
d.Set("token", token)
d.SetId("id")

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

import (
"fmt"
"net/http"
"net/url"
"os"
"testing"

"github.com/google/go-github/v53/github"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/stretchr/testify/assert"
)

func TestAccGithubAppTokenDataSource(t *testing.T) {
expectedAccessToken := "W+2e/zjiMTweDAr2b35toCF+h29l7NW92rJIPvFrCJQK"

owner := "test-owner"

pemData, err := os.ReadFile(testGitHubAppPrivateKeyFile)
assert.Nil(t, err)

t.Run("creates a application token without error", func(t *testing.T) {
ts := githubApiMock([]*mockResponse{
{
ExpectedUri: fmt.Sprintf("/api/v3/app/installations/%s/access_tokens", testGitHubAppInstallationID),
ExpectedHeaders: map[string]string{
"Accept": "application/vnd.github.v3+json",
},
ResponseBody: fmt.Sprintf(`{"token": "%s"}`, expectedAccessToken),
StatusCode: 201,
},
})
defer ts.Close()

httpCl := http.DefaultClient
httpCl.Transport = http.DefaultTransport

client := github.NewClient(httpCl)
u, _ := url.Parse(ts.URL + "/")
client.BaseURL = u

meta := &Owner{
name: owner,
v3client: client,
}

testSchema := map[string]*schema.Schema{
"app_id": {Type: schema.TypeString},
"installation_id": {Type: schema.TypeString},
"pem_file": {Type: schema.TypeString},
"token": {Type: schema.TypeString},
}

schema := schema.TestResourceDataRaw(t, testSchema, map[string]interface{}{
"app_id": testGitHubAppID,
"installation_id": testGitHubAppInstallationID,
"pem_file": string(pemData),
"token": "",
})

err := dataSourceGithubAppTokenRead(schema, meta)
assert.Nil(t, err)
assert.Equal(t, expectedAccessToken, schema.Get("token"))
})
}
1 change: 1 addition & 0 deletions github/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ func Provider() terraform.ResourceProvider {
"github_actions_secrets": dataSourceGithubActionsSecrets(),
"github_actions_variables": dataSourceGithubActionsVariables(),
"github_app": dataSourceGithubApp(),
"github_app_token": dataSourceGithubAppToken(),
"github_branch": dataSourceGithubBranch(),
"github_branch_protection_rules": dataSourceGithubBranchProtectionRules(),
"github_collaborators": dataSourceGithubCollaborators(),
Expand Down
36 changes: 36 additions & 0 deletions website/docs/d/app_token.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
layout: "github"
page_title: "GitHub: github_app_token"
description: |-
Generate a GitHub APP JWT.
---

# github\_app\_token

Use this data source to generate a [GitHub App JWT](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app).

## Example Usage

```hcl
data "github_app_token" "this" {
app_id = "123456"
installation_id = "78910"
pem_file = file("foo/bar.pem")
}
```

## Argument Reference

The following arguments are supported:

* `app_id` - (Required) This is the ID of the GitHub App.

* `installation_id` - (Required) This is the ID of the GitHub App installation.

* `pem_file` - (Required) This is the contents of the GitHub App private key PEM file.

## Attribute Reference

The following additional attributes are exported:

* `token` - The generated GitHub APP JWT.
3 changes: 3 additions & 0 deletions website/github.erb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
<li>
<a href="/docs/providers/github/d/app.html">github_app</a>
</li>
<li>
<a href="/docs/providers/github/d/app_token.html"></a>
</li>
<li>
<a href="/docs/providers/github/d/branch.html">github_branch</a>
</li>
Expand Down

0 comments on commit caf6167

Please sign in to comment.