Skip to content

Commit

Permalink
Add Codespaces Organization Secret Repositories Resource.
Browse files Browse the repository at this point in the history
  • Loading branch information
garnertb committed Aug 13, 2023
1 parent db8ab33 commit 55f3119
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ export TF_LOG=DEBUG
# enable testing of organization scenarios instead of individual or anonymous
export GITHUB_ORGANIZATION=

# enable testing of individual scenarios instead of organizaiton or anonymous
# enable testing of individual scenarios instead of organization or anonymous
export GITHUB_OWNER=

# enable testing of enterprise appliances
Expand Down
1 change: 1 addition & 0 deletions github/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func Provider() terraform.ResourceProvider {
"github_branch_protection": resourceGithubBranchProtection(),
"github_branch_protection_v3": resourceGithubBranchProtectionV3(),
"github_codespaces_organization_secret": resourceGithubCodespacesOrganizationSecret(),
"github_codespaces_organization_secret_repositories": resourceGithubCodespacesOrganizationSecretRepositories(),
"github_codespaces_secret": resourceGithubCodespacesSecret(),
"github_codespaces_user_secret": resourceGithubCodespacesUserSecret(),
"github_dependabot_organization_secret": resourceGithubDependabotOrganizationSecret(),
Expand Down
122 changes: 122 additions & 0 deletions github/resource_github_codespaces_organization_secret_repositories.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package github

import (
"context"

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

func resourceGithubCodespacesOrganizationSecretRepositories() *schema.Resource {
return &schema.Resource{
Create: resourceGithubCodespaceOrganizationSecretRepositoriesCreateOrUpdate,
Read: resourceGithubCodespaceOrganizationSecretRepositoriesRead,
Update: resourceGithubCodespaceOrganizationSecretRepositoriesCreateOrUpdate,
Delete: resourceGithubCodespaceOrganizationSecretRepositoriesDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"secret_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "Name of the existing secret.",
ValidateFunc: validateSecretNameFunc,
},
"selected_repository_ids": {
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
Set: schema.HashInt,
Required: true,
Description: "An array of repository ids that can access the organization secret.",
},
},
}
}

func resourceGithubCodespaceOrganizationSecretRepositoriesCreateOrUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Owner).v3client
owner := meta.(*Owner).name
ctx := context.Background()

err := checkOrganization(meta)
if err != nil {
return err
}

secretName := d.Get("secret_name").(string)
selectedRepositories := d.Get("selected_repository_ids")

selectedRepositoryIDs := []int64{}

ids := selectedRepositories.(*schema.Set).List()
for _, id := range ids {
selectedRepositoryIDs = append(selectedRepositoryIDs, int64(id.(int)))
}

_, err = client.Codespaces.SetSelectedReposForOrgSecret(ctx, owner, secretName, selectedRepositoryIDs)
if err != nil {
return err
}

d.SetId(secretName)
return resourceGithubCodespaceOrganizationSecretRepositoriesRead(d, meta)
}

func resourceGithubCodespaceOrganizationSecretRepositoriesRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Owner).v3client
owner := meta.(*Owner).name
ctx := context.Background()

err := checkOrganization(meta)
if err != nil {
return err
}

selectedRepositoryIDs := github.SelectedRepoIDs{}
opt := &github.ListOptions{
PerPage: maxPerPage,
}
for {
results, resp, err := client.Codespaces.ListSelectedReposForOrgSecret(ctx, owner, d.Id(), opt)
if err != nil {
return err
}

for _, repo := range results.Repositories {
selectedRepositoryIDs = append(selectedRepositoryIDs, repo.GetID())
}

if resp.NextPage == 0 {
break
}
opt.Page = resp.NextPage
}

d.Set("selected_repository_ids", selectedRepositoryIDs)

return nil
}

func resourceGithubCodespaceOrganizationSecretRepositoriesDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Owner).v3client
owner := meta.(*Owner).name
ctx := context.WithValue(context.Background(), ctxId, d.Id())

err := checkOrganization(meta)
if err != nil {
return err
}

selectedRepositoryIDs := github.SelectedRepoIDs{}
_, err = client.Codespaces.SetSelectedReposForOrgSecret(ctx, owner, d.Id(), selectedRepositoryIDs)
if err != nil {
return err
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package github

import (
"fmt"
"os"
"testing"

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

func TestAccGithubCodespacesOrganizationSecretRepositories(t *testing.T) {
const ORG_SECRET_NAME = "ORG_SECRET_NAME"
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
secret_name, exists := os.LookupEnv(ORG_SECRET_NAME)

t.Run("set repository allowlist for an organization secret", func(t *testing.T) {
if !exists {
t.Skipf("%s environment variable is missing", ORG_SECRET_NAME)
}

config := fmt.Sprintf(`
resource "github_repository" "test_repo_1" {
name = "tf-acc-test-%s-1"
visibility = "internal"
}
resource "github_repository" "test_repo_2" {
name = "tf-acc-test-%s-2"
visibility = "internal"
}
resource "github_codespaces_organization_secret_repositories" "org_secret_repos" {
secret_name = "%s"
selected_repository_ids = [
github_repository.test_repo_1.repo_id,
github_repository.test_repo_2.repo_id
]
}
`, randomID, randomID, secret_name)

check := resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(
"github_codespaces_organization_secret_repositories.org_secret_repos", "secret_name",
),
resource.TestCheckResourceAttr(
"github_codespaces_organization_secret_repositories.org_secret_repos", "selected_repository_ids.#", "2",
),
)

testCase := func(t *testing.T, mode string) {
resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessMode(t, mode) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: check,
},
},
})
}

t.Run("with an anonymous account", func(t *testing.T) {
t.Skip("anonymous account not supported for this operation")
})

t.Run("with an individual account", func(t *testing.T) {
t.Skip("individual account not supported for this operation")
})

t.Run("with an organization account", func(t *testing.T) {
testCase(t, organization)
})
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
layout: "github"
page_title: "GitHub: github_codespaces_organization_secret_repositories"
description: |-
Manages repository allow list for a Codespaces Secret within a GitHub organization
---

# github_codespaces_organization_secret_repositories

This resource allows you to manage repository allow list for existing GitHub Codespaces secrets within your GitHub organization.

You must have write access to an organization secret to use this resource.

This resource is only applicable when `visibility` of the existing organization secret has been set to `selected`.

## Example Usage

```hcl
data "github_repository" "repo" {
full_name = "my-org/repo"
}
resource "github_codespaces_organization_secret_repositories" "org_secret_repos" {
secret_name = "existing_secret_name"
selected_repository_ids = [data.github_repository.repo.repo_id]
}
```

## Argument Reference

The following arguments are supported:

* `secret_name` - (Required) Name of the existing secret
* `selected_repository_ids` - (Required) An array of repository ids that can access the organization secret.

## Import

This resource can be imported using an ID made up of the secret name:

```
$ terraform import github_codespaces_organization_secret_repositories.org_secret_repos existing_secret_name
```
3 changes: 3 additions & 0 deletions website/github.erb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@
<li>
<a href="/docs/providers/github/d/codespaces_organization_secrets.html">github_codespaces_organization_secrets</a>
</li>
<li>
<a href="/docs/providers/github/d/codespaces_organization_secret_repositories.html">github_codespaces_organization_secret_repositories</a>
</li>
<li>
<a href="/docs/providers/github/d/codespaces_public_key.html">github_codespaces_public_key</a>
</li>
Expand Down

0 comments on commit 55f3119

Please sign in to comment.