Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

github/provider: introduce owner #464

Merged
merged 6 commits into from
Jun 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/acceptance-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
with:
RUN_FILTER: ${{ env.RUN_FILTER }}
GITHUB_BASE_URL: "https://api.github.com/"
GITHUB_ORGANIZATION: terraformtesting
GITHUB_OWNER: terraformtesting
GITHUB_TEST_USER: github-terraform-test-user
GITHUB_TEST_USER_NAME: "Test User"
GITHUB_TEST_USER_EMAIL: [email protected]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Once the token has been created, it must be exported in your environment as `GIT

### GitHub organization
If you do not have an organization already that you are comfortable running tests against, you will need to [create one](https://help.github.com/en/articles/creating-a-new-organization-from-scratch). The free "Team for Open Source" org type is fine for these tests. The name of the
organization must then be exported in your environment as `GITHUB_ORGANIZATION`. If you are interested in using and/or testing Github's [Team synchronization](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/synchronizing-teams-between-your-identity-provider-and-github) feature, you will need to have an organization that uses Github Enterprise Cloud in addition to the requirements defined in the Github docs and set the environment variable `ENTERPRISE_ACCOUNT` to `true`.
organization must then be exported in your environment as `GITHUB_OWNER`. If you are interested in using and/or testing Github's [Team synchronization](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/synchronizing-teams-between-your-identity-provider-and-github) feature, you will need to have an organization that uses Github Enterprise Cloud in addition to the requirements defined in the Github docs and set the environment variable `ENTERPRISE_ACCOUNT` to `true`.

### Test repositories
In the organization you are using above, create the following test repositories:
Expand Down
101 changes: 31 additions & 70 deletions github/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package github

import (
"context"
"crypto/tls"
"fmt"
"net/http"
"net/url"
"path"
Expand All @@ -15,65 +13,33 @@ import (
)

type Config struct {
Token string
Organization string
BaseURL string
Insecure bool
Individual bool
Anonymous bool
Token string
Owner string
BaseURL string
}

type Organization struct {
name string
id int64
v3client *github.Client
v4client *githubv4.Client
StopContext context.Context
type Owner struct {
name string
id int64
v3client *github.Client
v4client *githubv4.Client
StopContext context.Context
IsOrganization bool
}

// Clients configures and returns a fully initialized GithubClient and Githubv4Client
func (c *Config) Clients() (interface{}, error) {
var org Organization
var owner Owner
var ts oauth2.TokenSource
var tc *http.Client

ctx := context.Background()

if c.Insecure {
insecureClient := insecureHttpClient()
ctx = context.WithValue(ctx, oauth2.HTTPClient, insecureClient)
}

// Either Organization needs to be set, or Individual needs to be true
if c.Organization != "" && c.Individual {
return nil, fmt.Errorf("If `individual` is true, `organization` cannot be set.")
}
if c.Organization == "" && !c.Individual {
return nil, fmt.Errorf("If `individual` is false, `organization` is required.")
}

// Either run as anonymous, or run with a Token
if c.Token != "" && c.Anonymous {
return nil, fmt.Errorf("If `anonymous` is true, `token` cannot be set.")
}
if c.Token == "" && !c.Anonymous {
return nil, fmt.Errorf("If `anonymous` is false, `token` is required.")
}

if !c.Anonymous {
ts = oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: c.Token},
)
}

ts = oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: c.Token},
)
tc = oauth2.NewClient(ctx, ts)

if c.Anonymous {
tc.Transport = http.DefaultTransport
} else {
tc.Transport = NewEtagTransport(tc.Transport)
}

tc.Transport = NewEtagTransport(tc.Transport)
tc.Transport = NewRateLimitTransport(tc.Transport)
tc.Transport = logging.NewTransport("Github", tc.Transport)

Expand All @@ -99,30 +65,25 @@ func (c *Config) Clients() (interface{}, error) {
}
v3client.BaseURL = uv3

org.v3client = v3client
org.v4client = v4client
owner.v3client = v3client
owner.v4client = v4client

if c.Individual {
org.name = ""
} else {
org.name = c.Organization

remoteOrg, _, err := org.v3client.Organizations.Get(ctx, org.name)
owner.name = c.Owner
if owner.name == "" {
// Discover authenticated user
user, _, err := owner.v3client.Users.Get(ctx, "")
if err != nil {
return nil, err
}
org.id = remoteOrg.GetID()
}

return &org, nil
}

func insecureHttpClient() *http.Client {
return &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
owner.name = user.GetLogin()
} else {
remoteOrg, _, err := owner.v3client.Organizations.Get(ctx, owner.name)
if err == nil {
if remoteOrg != nil {
owner.id = remoteOrg.GetID()
owner.IsOrganization = true
}
}
}
return &owner, nil
}
4 changes: 2 additions & 2 deletions github/data_source_github_actions_public_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ func dataSourceGithubActionsPublicKeyRead(d *schema.ResourceData, meta interface
}

repository := d.Get("repository").(string)
owner := meta.(*Organization).name
owner := meta.(*Owner).name
log.Printf("[INFO] Refreshing GitHub Actions Public Key from: %s/%s", owner, repository)

client := meta.(*Organization).v3client
client := meta.(*Owner).v3client
ctx := context.Background()

publicKey, _, err := client.Actions.GetPublicKey(ctx, owner, repository)
Expand Down
8 changes: 8 additions & 0 deletions github/data_source_github_actions_public_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import (
)

func TestAccGithubActionsPublicKeyDataSource_noMatchReturnsError(t *testing.T) {
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

repo := "non-existent"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
Expand All @@ -26,6 +30,10 @@ func TestAccGithubActionsPublicKeyDataSource_noMatchReturnsError(t *testing.T) {
}

func TestAccCheckGithubActionsPublicKeyDataSource_existing(t *testing.T) {
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

repo := os.Getenv("GITHUB_TEMPLATE_REPOSITORY")
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
Expand Down
4 changes: 2 additions & 2 deletions github/data_source_github_branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ func dataSourceGithubBranchRead(d *schema.ResourceData, meta interface{}) error
return err
}

client := meta.(*Organization).v3client
orgName := meta.(*Organization).name
client := meta.(*Owner).v3client
orgName := meta.(*Owner).name
repoName := d.Get("repository").(string)
branchName := d.Get("branch").(string)
branchRefName := "refs/heads/" + branchName
Expand Down
3 changes: 3 additions & 0 deletions github/data_source_github_branch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
)

func TestAccGithubBranchDataSource_basic(t *testing.T) {
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

var (
name = "main"
Expand Down
2 changes: 1 addition & 1 deletion github/data_source_github_collaborators.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func dataSourceGithubCollaborators() *schema.Resource {

func dataSourceGithubCollaboratorsRead(d *schema.ResourceData, meta interface{}) error {

client := meta.(*Organization).v3client
client := meta.(*Owner).v3client
ctx := context.Background()

owner := d.Get("owner").(string)
Expand Down
6 changes: 5 additions & 1 deletion github/data_source_github_collaborators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import (
)

func TestAccGithubCollaboratorsDataSource_basic(t *testing.T) {
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

dsn := "data.github_collaborators.test"
repoName := fmt.Sprintf("tf-acc-test-collab-%s", acctest.RandString(5))

Expand Down Expand Up @@ -39,5 +43,5 @@ data "github_collaborators" "test" {
owner = "%s"
repository = "${github_repository.test.name}"
}
`, repo, testOrganization)
`, repo, testOwner)
}
2 changes: 1 addition & 1 deletion github/data_source_github_ip_ranges.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func dataSourceGithubIpRanges() *schema.Resource {
}

func dataSourceGithubIpRangesRead(d *schema.ResourceData, meta interface{}) error {
org := meta.(*Organization)
org := meta.(*Owner)

api, _, err := org.v3client.APIMeta(org.StopContext)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions github/data_source_github_membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ func dataSourceGithubMembershipRead(d *schema.ResourceData, meta interface{}) er
username := d.Get("username").(string)
log.Printf("[INFO] Refreshing GitHub membership: %s", username)

client := meta.(*Organization).v3client
orgName := meta.(*Organization).name
client := meta.(*Owner).v3client
orgName := meta.(*Owner).name

ctx := context.Background()

Expand Down
4 changes: 4 additions & 0 deletions github/data_source_github_membership_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ func TestAccGithubMembershipDataSource_existing(t *testing.T) {
if testUser == "" {
t.Skip("This test requires you to set the test user (set it by exporting GITHUB_TEST_USER)")
}
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
Expand Down
4 changes: 2 additions & 2 deletions github/data_source_github_organization_team_sync_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ func dataSourceGithubOrganizationTeamSyncGroups() *schema.Resource {
func dataSourceGithubOrganizationTeamSyncGroupsRead(d *schema.ResourceData, meta interface{}) error {
log.Print("[INFO] Refreshing GitHub Organization Team-Sync Groups")

client := meta.(*Organization).v3client
client := meta.(*Owner).v3client
ctx := context.Background()

orgName := meta.(*Organization).name
orgName := meta.(*Owner).name
options := &github.ListCursorOptions{PerPage: maxPerPage}

groups := make([]interface{}, 0)
Expand Down
2 changes: 1 addition & 1 deletion github/data_source_github_release.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func dataSourceGithubReleaseRead(d *schema.ResourceData, meta interface{}) error
repository := d.Get("repository").(string)
owner := d.Get("owner").(string)

client := meta.(*Organization).v3client
client := meta.(*Owner).v3client
ctx := context.Background()

var err error
Expand Down
20 changes: 16 additions & 4 deletions github/data_source_github_release_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ func TestAccGithubReleaseDataSource_fetchByLatestNoReleaseReturnsError(t *testin
}

func TestAccGithubReleaseDataSource_latestExisting(t *testing.T) {
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

repo := os.Getenv("GITHUB_TEMPLATE_REPOSITORY")
owner := os.Getenv("GITHUB_ORGANIZATION")
owner := os.Getenv("GITHUB_OWNER")
retrieveBy := "latest"
expectedUrl := regexp.MustCompile(fmt.Sprintf("%s/%s", owner, repo))
expectedTarball := regexp.MustCompile(fmt.Sprintf("%s/%s/tarball", owner, repo))
Expand Down Expand Up @@ -68,8 +72,12 @@ func TestAccGithubReleaseDataSource_fetchByIdWithNoIdReturnsError(t *testing.T)
}

func TestAccGithubReleaseDataSource_fetchByIdExisting(t *testing.T) {
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

repo := os.Getenv("GITHUB_TEMPLATE_REPOSITORY")
owner := os.Getenv("GITHUB_ORGANIZATION")
owner := os.Getenv("GITHUB_OWNER")
retrieveBy := "id"
expectedUrl := regexp.MustCompile(fmt.Sprintf("%s/%s", owner, repo))
expectedTarball := regexp.MustCompile(fmt.Sprintf("%s/%s/tarball", owner, repo))
Expand All @@ -94,7 +102,7 @@ func TestAccGithubReleaseDataSource_fetchByIdExisting(t *testing.T) {

func TestAccGithubReleaseDataSource_fetchByTagNoTagReturnsError(t *testing.T) {
repo := os.Getenv("GITHUB_TEMPLATE_REPOSITORY")
owner := os.Getenv("GITHUB_ORGANIZATION")
owner := os.Getenv("GITHUB_OWNER")
retrieveBy := "tag"
id := int64(0)
resource.ParallelTest(t, resource.TestCase{
Expand All @@ -112,8 +120,12 @@ func TestAccGithubReleaseDataSource_fetchByTagNoTagReturnsError(t *testing.T) {
}

func TestAccGithubReleaseDataSource_fetchByTagExisting(t *testing.T) {
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

repo := os.Getenv("GITHUB_TEMPLATE_REPOSITORY")
owner := os.Getenv("GITHUB_ORGANIZATION")
owner := os.Getenv("GITHUB_OWNER")
retrieveBy := "tag"
tag := "v1.0"
expectedUrl := regexp.MustCompile(fmt.Sprintf("%s/%s", owner, repo))
Expand Down
2 changes: 1 addition & 1 deletion github/data_source_github_repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func dataSourceGithubRepositoriesRead(d *schema.ResourceData, meta interface{})
return err
}

client := meta.(*Organization).v3client
client := meta.(*Owner).v3client

query := d.Get("query").(string)
opt := &github.SearchOptions{
Expand Down
12 changes: 12 additions & 0 deletions github/data_source_github_repositories_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import (
)

func TestAccGithubRepositoriesDataSource_basic(t *testing.T) {
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

query := "org:hashicorp repository:terraform"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
Expand All @@ -28,6 +32,10 @@ func TestAccGithubRepositoriesDataSource_basic(t *testing.T) {
})
}
func TestAccGithubRepositoriesDataSource_Sort(t *testing.T) {
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
Expand Down Expand Up @@ -55,6 +63,10 @@ func TestAccGithubRepositoriesDataSource_Sort(t *testing.T) {
}

func TestAccGithubRepositoriesDataSource_noMatch(t *testing.T) {
if err := testAccCheckOrganization(); err != nil {
t.Skipf("Skipping because %s.", err.Error())
}

query := "klsafj_23434_doesnt_exist"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
Expand Down
4 changes: 2 additions & 2 deletions github/data_source_github_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ func dataSourceGithubRepositoryRead(d *schema.ResourceData, meta interface{}) er
return err
}

client := meta.(*Organization).v3client
orgName := meta.(*Organization).name
client := meta.(*Owner).v3client
orgName := meta.(*Owner).name
var repoName string

if fullName, ok := d.GetOk("full_name"); ok {
Expand Down
Loading