Add Github Organization provider.
Allows for managing organization membership, teams, team membership, and team repositories.
This commit is contained in:
parent
203171744f
commit
c1b373ad5f
|
@ -20,5 +20,6 @@ website/node_modules
|
||||||
*~
|
*~
|
||||||
.*.swp
|
.*.swp
|
||||||
.idea
|
.idea
|
||||||
|
*.iml
|
||||||
*.test
|
*.test
|
||||||
*.iml
|
*.iml
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/builtin/providers/github"
|
||||||
|
"github.com/hashicorp/terraform/plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
plugin.Serve(&plugin.ServeOpts{
|
||||||
|
ProviderFunc: github.Provider,
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
package main
|
|
@ -0,0 +1,29 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Token string
|
||||||
|
Organization string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Organization struct {
|
||||||
|
name string
|
||||||
|
client *github.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client configures and returns a fully initialized GithubClient
|
||||||
|
func (c *Config) Client() (interface{}, error) {
|
||||||
|
var org Organization
|
||||||
|
org.name = c.Organization
|
||||||
|
ts := oauth2.StaticTokenSource(
|
||||||
|
&oauth2.Token{AccessToken: c.Token},
|
||||||
|
)
|
||||||
|
tc := oauth2.NewClient(oauth2.NoContext, ts)
|
||||||
|
|
||||||
|
org.client = github.NewClient(tc)
|
||||||
|
return &org, nil
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Provider returns a terraform.ResourceProvider.
|
||||||
|
func Provider() terraform.ResourceProvider {
|
||||||
|
|
||||||
|
// The actual provider
|
||||||
|
return &schema.Provider{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"token": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("GITHUB_TOKEN", nil),
|
||||||
|
Description: descriptions["token"],
|
||||||
|
},
|
||||||
|
"organization": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("GITHUB_ORGANIZATION", nil),
|
||||||
|
Description: descriptions["organization"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
|
"github_team": resourceGithubTeam(),
|
||||||
|
"github_team_membership": resourceGithubTeamMembership(),
|
||||||
|
"github_team_repository": resourceGithubTeamRepository(),
|
||||||
|
"github_membership": resourceGithubMembership(),
|
||||||
|
},
|
||||||
|
|
||||||
|
ConfigureFunc: providerConfigure,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var descriptions map[string]string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
descriptions = map[string]string{
|
||||||
|
"token": "The OAuth token used to connect to GitHub.",
|
||||||
|
|
||||||
|
"organization": "The GitHub organization name to manage.",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
||||||
|
config := Config{
|
||||||
|
Token: d.Get("token").(string),
|
||||||
|
Organization: d.Get("organization").(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.Client()
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testAccProviders map[string]terraform.ResourceProvider
|
||||||
|
var testAccProvider *schema.Provider
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
testAccProvider = Provider().(*schema.Provider)
|
||||||
|
testAccProviders = map[string]terraform.ResourceProvider{
|
||||||
|
"github": testAccProvider,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProvider(t *testing.T) {
|
||||||
|
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProvider_impl(t *testing.T) {
|
||||||
|
var _ terraform.ResourceProvider = Provider()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccPreCheck(t *testing.T) {
|
||||||
|
if v := os.Getenv("GITHUB_TOKEN"); v == "" {
|
||||||
|
t.Fatal("GITHUB_TOKEN must be set for acceptance tests")
|
||||||
|
}
|
||||||
|
if v := os.Getenv("GITHUB_ORGANIZATION"); v == "" {
|
||||||
|
t.Fatal("GITHUB_ORGANIZATION must be set for acceptance tests")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceGithubMembership() *schema.Resource {
|
||||||
|
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceGithubMembershipCreate,
|
||||||
|
Read: resourceGithubMembershipRead,
|
||||||
|
Update: resourceGithubMembershipUpdate,
|
||||||
|
Delete: resourceGithubMembershipDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"username": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"role": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ValidateFunc: validateRoleValueFunc([]string{"member", "admin"}),
|
||||||
|
Default: "member",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubMembershipCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
n := d.Get("username").(string)
|
||||||
|
r := d.Get("role").(string)
|
||||||
|
|
||||||
|
membership, _, err := client.Organizations.EditOrgMembership(n, meta.(*Organization).name,
|
||||||
|
&github.Membership{Role: &r})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(buildTwoPartID(membership.Organization.Login, membership.User.Login))
|
||||||
|
|
||||||
|
return resourceGithubMembershipRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubMembershipRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
|
||||||
|
membership, _, err := client.Organizations.GetOrgMembership(d.Get("username").(string), meta.(*Organization).name)
|
||||||
|
if err != nil {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
username := membership.User.Login
|
||||||
|
roleName := membership.Role
|
||||||
|
|
||||||
|
d.Set("username", *username)
|
||||||
|
d.Set("role", *roleName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubMembershipUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
n := d.Get("username").(string)
|
||||||
|
r := d.Get("role").(string)
|
||||||
|
|
||||||
|
_, _, err := client.Organizations.EditOrgMembership(n, meta.(*Organization).name, &github.Membership{
|
||||||
|
Role: &r,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubMembershipDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
n := d.Get("username").(string)
|
||||||
|
|
||||||
|
_, err := client.Organizations.RemoveOrgMembership(n, meta.(*Organization).name)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccGithubMembership_basic(t *testing.T) {
|
||||||
|
var membership github.Membership
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckGithubMembershipDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGithubMembershipConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGithubMembershipExists("github_membership.test_org_membership", &membership),
|
||||||
|
testAccCheckGithubMembershipRoleState("github_membership.test_org_membership", &membership),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubMembershipDestroy(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*Organization).client
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "github_membership" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
o, u := parseTwoPartID(rs.Primary.ID)
|
||||||
|
|
||||||
|
membership, resp, err := conn.Organizations.GetOrgMembership(u, o)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
if membership != nil &&
|
||||||
|
buildTwoPartID(membership.Organization.Login, membership.User.Login) == rs.Primary.ID {
|
||||||
|
return fmt.Errorf("Organization membership still exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 404 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubMembershipExists(n string, membership *github.Membership) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not Found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No membership ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*Organization).client
|
||||||
|
o, u := parseTwoPartID(rs.Primary.ID)
|
||||||
|
|
||||||
|
githubMembership, _, err := conn.Organizations.GetOrgMembership(u, o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*membership = *githubMembership
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubMembershipRoleState(n string, membership *github.Membership) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not Found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No membership ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*Organization).client
|
||||||
|
o, u := parseTwoPartID(rs.Primary.ID)
|
||||||
|
|
||||||
|
githubMembership, _, err := conn.Organizations.GetOrgMembership(u, o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceRole := membership.Role
|
||||||
|
actualRole := githubMembership.Role
|
||||||
|
|
||||||
|
if *resourceRole != *actualRole {
|
||||||
|
return fmt.Errorf("Membership role %v in resource does match actual state of %v", *resourceRole, *actualRole)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccGithubMembershipConfig = `
|
||||||
|
resource "github_membership" "test_org_membership" {
|
||||||
|
username = "TerraformDummyUser"
|
||||||
|
role = "member"
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,90 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceGithubTeam() *schema.Resource {
|
||||||
|
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceGithubTeamCreate,
|
||||||
|
Read: resourceGithubTeamRead,
|
||||||
|
Update: resourceGithubTeamUpdate,
|
||||||
|
Delete: resourceGithubTeamDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"description": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
n := d.Get("name").(string)
|
||||||
|
desc := d.Get("description").(string)
|
||||||
|
githubTeam, _, err := client.Organizations.CreateTeam(meta.(*Organization).name, &github.Team{
|
||||||
|
Name: &n,
|
||||||
|
Description: &desc,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
d.SetId(fromGithubID(githubTeam.ID))
|
||||||
|
return resourceGithubTeamRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
|
||||||
|
team, err := getGithubTeam(d, client)
|
||||||
|
if err != nil {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
d.Set("description", team.Description)
|
||||||
|
d.Set("name", team.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
team, err := getGithubTeam(d, client)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
description := d.Get("description").(string)
|
||||||
|
team.Description = &description
|
||||||
|
team.Name = &name
|
||||||
|
|
||||||
|
team, _, err = client.Organizations.EditTeam(*team.ID, team)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
d.SetId(fromGithubID(team.ID))
|
||||||
|
return resourceGithubTeamRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
id := toGithubID(d.Id())
|
||||||
|
_, err := client.Organizations.DeleteTeam(id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getGithubTeam(d *schema.ResourceData, github *github.Client) (*github.Team, error) {
|
||||||
|
id := toGithubID(d.Id())
|
||||||
|
team, _, err := github.Organizations.GetTeam(id)
|
||||||
|
return team, err
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceGithubTeamMembership() *schema.Resource {
|
||||||
|
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceGithubTeamMembershipCreate,
|
||||||
|
Read: resourceGithubTeamMembershipRead,
|
||||||
|
// editing team memberships are not supported by github api so forcing new on any changes
|
||||||
|
Delete: resourceGithubTeamMembershipDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"team_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"username": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"role": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Default: "member",
|
||||||
|
ValidateFunc: validateRoleValueFunc([]string{"member", "maintainer"}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamMembershipCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
t := d.Get("team_id").(string)
|
||||||
|
n := d.Get("username").(string)
|
||||||
|
r := d.Get("role").(string)
|
||||||
|
|
||||||
|
_, _, err := client.Organizations.AddTeamMembership(toGithubID(t), n,
|
||||||
|
&github.OrganizationAddTeamMembershipOptions{Role: r})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(buildTwoPartID(&t, &n))
|
||||||
|
|
||||||
|
return resourceGithubTeamMembershipRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamMembershipRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
t := d.Get("team_id").(string)
|
||||||
|
n := d.Get("username").(string)
|
||||||
|
|
||||||
|
membership, _, err := client.Organizations.GetTeamMembership(toGithubID(t), n)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
team, user := getTeamAndUserFromURL(membership.URL)
|
||||||
|
|
||||||
|
d.Set("username", user)
|
||||||
|
d.Set("role", membership.Role)
|
||||||
|
d.Set("team_id", team)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamMembershipDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
t := d.Get("team_id").(string)
|
||||||
|
n := d.Get("username").(string)
|
||||||
|
|
||||||
|
_, err := client.Organizations.RemoveTeamMembership(toGithubID(t), n)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTeamAndUserFromURL(url *string) (string, string) {
|
||||||
|
var team, user string
|
||||||
|
|
||||||
|
urlSlice := strings.Split(*url, "/")
|
||||||
|
for v := range urlSlice {
|
||||||
|
if urlSlice[v] == "teams" {
|
||||||
|
team = urlSlice[v+1]
|
||||||
|
}
|
||||||
|
if urlSlice[v] == "memberships" {
|
||||||
|
user = urlSlice[v+1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return team, user
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccGithubTeamMembership_basic(t *testing.T) {
|
||||||
|
var membership github.Membership
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckGithubTeamMembershipDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGithubTeamMembershipConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGithubTeamMembershipExists("github_team_membership.test_team_membership", &membership),
|
||||||
|
testAccCheckGithubTeamMembershipRoleState("github_team_membership.test_team_membership", "member", &membership),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGithubTeamMembershipUpdateConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGithubTeamMembershipExists("github_team_membership.test_team_membership", &membership),
|
||||||
|
testAccCheckGithubTeamMembershipRoleState("github_team_membership.test_team_membership", "maintainer", &membership),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubTeamMembershipDestroy(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*Organization).client
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "github_team_membership" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
t, u := parseTwoPartID(rs.Primary.ID)
|
||||||
|
membership, resp, err := conn.Organizations.GetTeamMembership(toGithubID(t), u)
|
||||||
|
if err == nil {
|
||||||
|
if membership != nil {
|
||||||
|
return fmt.Errorf("Team membership still exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 404 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubTeamMembershipExists(n string, membership *github.Membership) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not Found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No team membership ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*Organization).client
|
||||||
|
t, u := parseTwoPartID(rs.Primary.ID)
|
||||||
|
|
||||||
|
teamMembership, _, err := conn.Organizations.GetTeamMembership(toGithubID(t), u)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*membership = *teamMembership
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubTeamMembershipRoleState(n, expected string, membership *github.Membership) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not Found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No team membership ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*Organization).client
|
||||||
|
t, u := parseTwoPartID(rs.Primary.ID)
|
||||||
|
|
||||||
|
teamMembership, _, err := conn.Organizations.GetTeamMembership(toGithubID(t), u)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceRole := membership.Role
|
||||||
|
actualRole := teamMembership.Role
|
||||||
|
|
||||||
|
if *resourceRole != expected {
|
||||||
|
return fmt.Errorf("Team membership role %v in resource does match expected state of %v", *resourceRole, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *resourceRole != *actualRole {
|
||||||
|
return fmt.Errorf("Team membership role %v in resource does match actual state of %v", *resourceRole, *actualRole)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccGithubTeamMembershipConfig = `
|
||||||
|
resource "github_membership" "test_org_membership" {
|
||||||
|
username = "TerraformDummyUser"
|
||||||
|
role = "member"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team" "test_team" {
|
||||||
|
name = "foo"
|
||||||
|
description = "Terraform acc test group"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team_membership" "test_team_membership" {
|
||||||
|
team_id = "${github_team.test_team.id}"
|
||||||
|
username = "TerraformDummyUser"
|
||||||
|
role = "member"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccGithubTeamMembershipUpdateConfig = `
|
||||||
|
resource "github_membership" "test_org_membership" {
|
||||||
|
username = "TerraformDummyUser"
|
||||||
|
role = "member"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team" "test_team" {
|
||||||
|
name = "foo"
|
||||||
|
description = "Terraform acc test group"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team_membership" "test_team_membership" {
|
||||||
|
team_id = "${github_team.test_team.id}"
|
||||||
|
username = "TerraformDummyUser"
|
||||||
|
role = "maintainer"
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,129 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
const pullPermission string = "pull"
|
||||||
|
const pushPermission string = "push"
|
||||||
|
const adminPermission string = "admin"
|
||||||
|
|
||||||
|
func resourceGithubTeamRepository() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceGithubTeamRepositoryCreate,
|
||||||
|
Read: resourceGithubTeamRepositoryRead,
|
||||||
|
Update: resourceGithubTeamRepositoryUpdate,
|
||||||
|
Delete: resourceGithubTeamRepositoryDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"team_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"repository": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"permission": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Default: "pull",
|
||||||
|
ValidateFunc: validateRoleValueFunc([]string{"pull", "push", "admin"}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamRepositoryCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
t := d.Get("team_id").(string)
|
||||||
|
r := d.Get("repository").(string)
|
||||||
|
p := d.Get("permission").(string)
|
||||||
|
|
||||||
|
_, err := client.Organizations.AddTeamRepo(toGithubID(t), meta.(*Organization).name, r,
|
||||||
|
&github.OrganizationAddTeamRepoOptions{Permission: p})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(buildTwoPartID(&t, &r))
|
||||||
|
|
||||||
|
return resourceGithubTeamRepositoryRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamRepositoryRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
t := d.Get("team_id").(string)
|
||||||
|
r := d.Get("repository").(string)
|
||||||
|
|
||||||
|
repo, _, repoErr := client.Organizations.IsTeamRepo(toGithubID(t), meta.(*Organization).name, r)
|
||||||
|
|
||||||
|
if repoErr != nil {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
repositoryName := repo.Name
|
||||||
|
|
||||||
|
d.Set("team_id", t)
|
||||||
|
d.Set("repository", repositoryName)
|
||||||
|
|
||||||
|
permName, permErr := getRepoPermission(repo.Permissions)
|
||||||
|
|
||||||
|
if permErr != nil {
|
||||||
|
return permErr
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("permission", permName)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamRepositoryUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
t := d.Get("team_id").(string)
|
||||||
|
r := d.Get("repository").(string)
|
||||||
|
p := d.Get("permission").(string)
|
||||||
|
|
||||||
|
// the go-github library's AddTeamRepo method uses the add/update endpoint from Github API
|
||||||
|
_, err := client.Organizations.AddTeamRepo(toGithubID(t), meta.(*Organization).name, r,
|
||||||
|
&github.OrganizationAddTeamRepoOptions{Permission: p})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return resourceGithubTeamRepositoryRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceGithubTeamRepositoryDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*Organization).client
|
||||||
|
t := d.Get("team_id").(string)
|
||||||
|
r := d.Get("repository").(string)
|
||||||
|
|
||||||
|
_, err := client.Organizations.RemoveTeamRepo(toGithubID(t), meta.(*Organization).name, r)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRepoPermission(p *map[string]bool) (string, error) {
|
||||||
|
|
||||||
|
// Permissions are returned in this map format such that if you have a certain level
|
||||||
|
// of permission, all levels below are also true. For example, if a team has push
|
||||||
|
// permission, the map will be: {"pull": true, "push": true, "admin": false}
|
||||||
|
if (*p)[adminPermission] {
|
||||||
|
return adminPermission, nil
|
||||||
|
} else if (*p)[pushPermission] {
|
||||||
|
return pushPermission, nil
|
||||||
|
} else {
|
||||||
|
if (*p)[pullPermission] {
|
||||||
|
return pullPermission, nil
|
||||||
|
}
|
||||||
|
return "", errors.New("At least one permission expected from permissions map.")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccGithubTeamRepository_basic(t *testing.T) {
|
||||||
|
var repository github.Repository
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckGithubTeamRepositoryDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGithubTeamRepositoryConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGithubTeamRepositoryExists("github_team_repository.test_team_test_repo", &repository),
|
||||||
|
testAccCheckGithubTeamRepositoryRoleState("pull", &repository),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGithubTeamRepositoryUpdateConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGithubTeamRepositoryExists("github_team_repository.test_team_test_repo", &repository),
|
||||||
|
testAccCheckGithubTeamRepositoryRoleState("push", &repository),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccCheckGetPermissions(t *testing.T) {
|
||||||
|
pullMap := map[string]bool{"pull": true, "push": false, "admin": false}
|
||||||
|
pushMap := map[string]bool{"pull": true, "push": true, "admin": false}
|
||||||
|
adminMap := map[string]bool{"pull": true, "push": true, "admin": true}
|
||||||
|
errorMap := map[string]bool{"pull": false, "push": false, "admin": false}
|
||||||
|
|
||||||
|
pull, _ := getRepoPermission(&pullMap)
|
||||||
|
if pull != "pull" {
|
||||||
|
t.Fatalf("Expected pull permission, actual: %s", pull)
|
||||||
|
}
|
||||||
|
|
||||||
|
push, _ := getRepoPermission(&pushMap)
|
||||||
|
if push != "push" {
|
||||||
|
t.Fatalf("Expected push permission, actual: %s", push)
|
||||||
|
}
|
||||||
|
|
||||||
|
admin, _ := getRepoPermission(&adminMap)
|
||||||
|
if admin != "admin" {
|
||||||
|
t.Fatalf("Expected admin permission, actual: %s", admin)
|
||||||
|
}
|
||||||
|
|
||||||
|
errPerm, err := getRepoPermission(&errorMap)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Expected an error getting permissions, actual: %v", errPerm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubTeamRepositoryRoleState(role string, repository *github.Repository) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
resourceRole, err := getRepoPermission(repository.Permissions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resourceRole != role {
|
||||||
|
return fmt.Errorf("Team repository role %v in resource does match expected state of %v", resourceRole, role)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubTeamRepositoryExists(n string, repository *github.Repository) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not Found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No team repository ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*Organization).client
|
||||||
|
t, r := parseTwoPartID(rs.Primary.ID)
|
||||||
|
|
||||||
|
repo, _, err := conn.Organizations.IsTeamRepo(toGithubID(t),
|
||||||
|
testAccProvider.Meta().(*Organization).name, r)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*repository = *repo
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubTeamRepositoryDestroy(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*Organization).client
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "github_team_repository" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
t, r := parseTwoPartID(rs.Primary.ID)
|
||||||
|
|
||||||
|
repo, resp, err := conn.Organizations.IsTeamRepo(toGithubID(t),
|
||||||
|
testAccProvider.Meta().(*Organization).name, r)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
if repo != nil &&
|
||||||
|
buildTwoPartID(&t, repo.Name) == rs.Primary.ID {
|
||||||
|
return fmt.Errorf("Team repository still exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 404 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccGithubTeamRepositoryConfig = `
|
||||||
|
resource "github_team" "test_team" {
|
||||||
|
name = "foo"
|
||||||
|
description = "Terraform acc test group"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team_repository" "test_team_test_repo" {
|
||||||
|
team_id = "${github_team.test_team.id}"
|
||||||
|
repository = "test-repo"
|
||||||
|
permission = "pull"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccGithubTeamRepositoryUpdateConfig = `
|
||||||
|
resource "github_team" "test_team" {
|
||||||
|
name = "foo"
|
||||||
|
description = "Terraform acc test group"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team_repository" "test_team_test_repo" {
|
||||||
|
team_id = "${github_team.test_team.id}"
|
||||||
|
repository = "test-repo"
|
||||||
|
permission = "push"
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,108 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccGithubTeam_basic(t *testing.T) {
|
||||||
|
var team github.Team
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckGithubTeamDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGithubTeamConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGithubTeamExists("github_team.foo", &team),
|
||||||
|
testAccCheckGithubTeamAttributes(&team, "foo", "Terraform acc test group"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccGithubTeamUpdateConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGithubTeamExists("github_team.foo", &team),
|
||||||
|
testAccCheckGithubTeamAttributes(&team, "foo2", "Terraform acc test group - updated"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubTeamExists(n string, team *github.Team) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not Found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No Team ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*Organization).client
|
||||||
|
githubTeam, _, err := conn.Organizations.GetTeam(toGithubID(rs.Primary.ID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*team = *githubTeam
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubTeamAttributes(team *github.Team, name, description string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
if *team.Name != name {
|
||||||
|
return fmt.Errorf("Team name does not match: %s, %s", *team.Name, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *team.Description != description {
|
||||||
|
return fmt.Errorf("Team description does not match: %s, %s", *team.Description, description)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGithubTeamDestroy(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*Organization).client
|
||||||
|
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "github_team" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
team, resp, err := conn.Organizations.GetTeam(toGithubID(rs.Primary.ID))
|
||||||
|
if err == nil {
|
||||||
|
if team != nil &&
|
||||||
|
fromGithubID(team.ID) == rs.Primary.ID {
|
||||||
|
return fmt.Errorf("Team still exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 404 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccGithubTeamConfig = `
|
||||||
|
resource "github_team" "foo" {
|
||||||
|
name = "foo"
|
||||||
|
description = "Terraform acc test group"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccGithubTeamUpdateConfig = `
|
||||||
|
resource "github_team" "foo" {
|
||||||
|
name = "foo2"
|
||||||
|
description = "Terraform acc test group - updated"
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,47 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func toGithubID(id string) int {
|
||||||
|
githubID, _ := strconv.Atoi(id)
|
||||||
|
return githubID
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromGithubID(id *int) string {
|
||||||
|
return strconv.Itoa(*id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateRoleValueFunc(roles []string) schema.SchemaValidateFunc {
|
||||||
|
return func(v interface{}, k string) (we []string, errors []error) {
|
||||||
|
value := v.(string)
|
||||||
|
valid := false
|
||||||
|
for _, role := range roles {
|
||||||
|
if value == role {
|
||||||
|
valid = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !valid {
|
||||||
|
errors = append(errors, fmt.Errorf("%s is an invalid Github role type for %s", value, k))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the pieces of id `a:b` as a, b
|
||||||
|
func parseTwoPartID(id string) (string, string) {
|
||||||
|
parts := strings.SplitN(id, ":", 2)
|
||||||
|
return parts[0], parts[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// format the strings into an id `a:b`
|
||||||
|
func buildTwoPartID(a, b *string) string {
|
||||||
|
return fmt.Sprintf("%s:%s", *a, *b)
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccGithubUtilRole_validation(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Value string
|
||||||
|
ErrCount int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Value: "invalid",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "valid_one",
|
||||||
|
ErrCount: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "valid_two",
|
||||||
|
ErrCount: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
validationFunc := validateRoleValueFunc([]string{"valid_one", "valid_two"})
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
_, errors := validationFunc(tc.Value, "github_membership")
|
||||||
|
|
||||||
|
if len(errors) != tc.ErrCount {
|
||||||
|
t.Fatalf("Expected github_membership to trigger a validation error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccGithubUtilTwoPartID(t *testing.T) {
|
||||||
|
partOne, partTwo := "foo", "bar"
|
||||||
|
|
||||||
|
id := buildTwoPartID(&partOne, &partTwo)
|
||||||
|
|
||||||
|
if id != "foo:bar" {
|
||||||
|
t.Fatalf("Expected two part id to be foo:bar, actual: %s", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedPartOne, parsedPartTwo := parseTwoPartID(id)
|
||||||
|
|
||||||
|
if parsedPartOne != "foo" {
|
||||||
|
t.Fatalf("Expected parsed part one foo, actual: %s", parsedPartOne)
|
||||||
|
}
|
||||||
|
|
||||||
|
if parsedPartTwo != "bar" {
|
||||||
|
t.Fatalf("Expected parsed part two bar, actual: %s", parsedPartTwo)
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ body.layout-dme,
|
||||||
body.layout-dnsimple,
|
body.layout-dnsimple,
|
||||||
body.layout-docker,
|
body.layout-docker,
|
||||||
body.layout-dyn,
|
body.layout-dyn,
|
||||||
|
body.layout-github,
|
||||||
body.layout-google,
|
body.layout-google,
|
||||||
body.layout-heroku,
|
body.layout-heroku,
|
||||||
body.layout-mailgun,
|
body.layout-mailgun,
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
---
|
||||||
|
layout: "github"
|
||||||
|
page_title: "Provider: Github"
|
||||||
|
sidebar_current: "docs-github-index"
|
||||||
|
description: |-
|
||||||
|
The Github provider is used to interact with Github organization resources.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Github Provider
|
||||||
|
|
||||||
|
The Github provider is used to interact with Github organization resources.
|
||||||
|
|
||||||
|
The provider allows you to manage your Github organization's members and teams easily.
|
||||||
|
It needs to be configured with the proper credentials before it can be used.
|
||||||
|
|
||||||
|
Use the navigation to the left to read about the available resources.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
# Configure the Github Provider
|
||||||
|
provider "github" {
|
||||||
|
token = "${var.github_token}"
|
||||||
|
organization = "${var.github_organization}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add a user to the organization
|
||||||
|
resource "github_membership" "membership_for_user_x" {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported in the `provider` block:
|
||||||
|
|
||||||
|
* `token` - (Optional) This is the Github personal access token. It must be provided, but
|
||||||
|
it can also be sourced from the `GITHUB_TOKEN` environment variable.
|
||||||
|
|
||||||
|
* `organization` - (Optional) This is the target Github organization to manage. The account
|
||||||
|
corresponding to the token will need "owner" privileges for this organization. It must be provided, but
|
||||||
|
it can also be sourced from the `GITHUB_ORGANIZATION` environment variable.
|
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
layout: "github"
|
||||||
|
page_title: "Github: github_membership"
|
||||||
|
sidebar_current: "docs-github-resource-membership"
|
||||||
|
description: |-
|
||||||
|
Provides a Github membership resource.
|
||||||
|
---
|
||||||
|
|
||||||
|
# github\_membership
|
||||||
|
|
||||||
|
Provides a Github membership resource.
|
||||||
|
|
||||||
|
This resource allows you to add/remove users from your organization. When applied,
|
||||||
|
an invitation will be sent to the user to become part of the organization. When
|
||||||
|
destroyed, either the invitation will be cancelled or the user will be removed.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
# Add a user to the organization
|
||||||
|
resource "github_membership" "membership_for_some_user" {
|
||||||
|
username = "SomeUser"
|
||||||
|
role = "member"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `username` - (Required) The user to add to the organization.
|
||||||
|
* `role` - (Optional) The role of the user within the organization.
|
||||||
|
Must be one of `member` or `admin`. Defaults to `member`.
|
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
layout: "github"
|
||||||
|
page_title: "Github: github_team"
|
||||||
|
sidebar_current: "docs-github-resource-team"
|
||||||
|
description: |-
|
||||||
|
Provides a Github team resource.
|
||||||
|
---
|
||||||
|
|
||||||
|
# github\_team
|
||||||
|
|
||||||
|
Provides a Github team resource.
|
||||||
|
|
||||||
|
This resource allows you to add/remove teams from your organization. When applied,
|
||||||
|
a new team will be created. When destroyed, that team will be removed.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
# Add a team to the organization
|
||||||
|
resource "github_team" "some_team" {
|
||||||
|
name = "some-team"
|
||||||
|
description = "Some cool team"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The name of the team.
|
||||||
|
* `description` - (Optional) A description of the team.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The ID of the created team.
|
|
@ -0,0 +1,46 @@
|
||||||
|
---
|
||||||
|
layout: "github"
|
||||||
|
page_title: "Github: github_team_membership"
|
||||||
|
sidebar_current: "docs-github-resource-team-membership"
|
||||||
|
description: |-
|
||||||
|
Provides a Github team membership resource.
|
||||||
|
---
|
||||||
|
|
||||||
|
# github\_team_membership
|
||||||
|
|
||||||
|
Provides a Github team membership resource.
|
||||||
|
|
||||||
|
This resource allows you to add/remove users from teams in your organization. When applied,
|
||||||
|
the user will be added to the team. If the user hasn't accepted their invitation to the
|
||||||
|
organization, they won't be part of the team until they do. When
|
||||||
|
destroyed, the user will be removed from the team.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
# Add a user to the organization
|
||||||
|
resource "github_membership" "membership_for_some_user" {
|
||||||
|
username = "SomeUser"
|
||||||
|
role = "member"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team" "some_team" {
|
||||||
|
name = "SomeTeam"
|
||||||
|
description = "Some cool team"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team_membership" "some_team_membership" {
|
||||||
|
team_id = "${github_team.some_team.id}"
|
||||||
|
username = "SomeUser"
|
||||||
|
role = "member"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `team_id` - (Required) The Github team id
|
||||||
|
* `username` - (Required) The user to add to the team.
|
||||||
|
* `role` - (Optional) The role of the user within the team.
|
||||||
|
Must be one of `member` or `maintainer`. Defaults to `member`.
|
|
@ -0,0 +1,39 @@
|
||||||
|
---
|
||||||
|
layout: "github"
|
||||||
|
page_title: "Github: github_team_repository"
|
||||||
|
sidebar_current: "docs-github-resource-team-repository"
|
||||||
|
description: |-
|
||||||
|
Provides a Github team repository resource.
|
||||||
|
---
|
||||||
|
|
||||||
|
# github\_team_repository
|
||||||
|
|
||||||
|
Provides a Github team repository resource.
|
||||||
|
|
||||||
|
This resource allows you to add/remove repositories from teams in your organization. When applied,
|
||||||
|
the repository will be added to the team. When destroyed, the repository will be removed from the team.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
# Add a repository to the team
|
||||||
|
resource "github_team" "some_team" {
|
||||||
|
name = "SomeTeam"
|
||||||
|
description = "Some cool team"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team_repository" "some_team_repo" {
|
||||||
|
team_id = "${github_team.some_team.id}"
|
||||||
|
repository = "our-repo"
|
||||||
|
permission = "pull"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `team_id` - (Required) The Github team id
|
||||||
|
* `repository` - (Required) The repository to add to the team.
|
||||||
|
* `permission` - (Optional) The permissions of team members regarding the repository.
|
||||||
|
Must be one of `pull`, `push`, or `admin`. Defaults to `pull`.
|
|
@ -182,6 +182,10 @@
|
||||||
<a href="/docs/providers/dyn/index.html">Dyn</a>
|
<a href="/docs/providers/dyn/index.html">Dyn</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-providers-github") %>>
|
||||||
|
<a href="/docs/providers/github/index.html">Github</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-providers-google") %>>
|
<li<%= sidebar_current("docs-providers-google") %>>
|
||||||
<a href="/docs/providers/google/index.html">Google Cloud</a>
|
<a href="/docs/providers/google/index.html">Google Cloud</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -218,9 +222,9 @@
|
||||||
<a href="/docs/providers/rundeck/index.html">Rundeck</a>
|
<a href="/docs/providers/rundeck/index.html">Rundeck</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-providers-statuscake") %>>
|
<li<%= sidebar_current("docs-providers-statuscake") %>>
|
||||||
<a href="/docs/providers/statuscake/index.html">StatusCake</a>
|
<a href="/docs/providers/statuscake/index.html">StatusCake</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-providers-template") %>>
|
<li<%= sidebar_current("docs-providers-template") %>>
|
||||||
<a href="/docs/providers/template/index.html">Template</a>
|
<a href="/docs/providers/template/index.html">Template</a>
|
||||||
|
@ -238,9 +242,9 @@
|
||||||
<a href="/docs/providers/vcd/index.html">VMware vCloud Director</a>
|
<a href="/docs/providers/vcd/index.html">VMware vCloud Director</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-providers-vsphere") %>>
|
<li<%= sidebar_current("docs-providers-vsphere") %>>
|
||||||
<a href="/docs/providers/vsphere/index.html">VMware vSphere</a>
|
<a href="/docs/providers/vsphere/index.html">VMware vSphere</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<% wrap_layout :inner do %>
|
||||||
|
<% content_for :sidebar do %>
|
||||||
|
<div class="docs-sidebar hidden-print affix-top" role="complementary">
|
||||||
|
<ul class="nav docs-sidenav">
|
||||||
|
<li<%= sidebar_current("docs-home") %>>
|
||||||
|
<a href="/docs/providers/index.html">« Documentation Home</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-github-index") %>>
|
||||||
|
<a href="/docs/providers/github/index.html">Github Provider</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current(/^docs-github-resource/) %>>
|
||||||
|
<a href="#">Resources</a>
|
||||||
|
<ul class="nav nav-visible">
|
||||||
|
<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-team") %>>
|
||||||
|
<a href="/docs/providers/github/r/team.html">github_team</a>
|
||||||
|
</li>
|
||||||
|
<li<%= sidebar_current("docs-github-resource-team-membership") %>>
|
||||||
|
<a href="/docs/providers/github/r/team_membership.html">github_team_membership</a>
|
||||||
|
</li>
|
||||||
|
<li<%= sidebar_current("docs-github-resource-team-repository") %>>
|
||||||
|
<a href="/docs/providers/github/r/team_repository.html">github_team_repository</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= yield %>
|
||||||
|
<% end %>
|
Loading…
Reference in New Issue