github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/builtin/providers/github/resource_github_repository_collaborator.go (about) 1 package github 2 3 import ( 4 "context" 5 6 "github.com/google/go-github/github" 7 "github.com/hashicorp/terraform/helper/schema" 8 ) 9 10 func resourceGithubRepositoryCollaborator() *schema.Resource { 11 return &schema.Resource{ 12 Create: resourceGithubRepositoryCollaboratorCreate, 13 Read: resourceGithubRepositoryCollaboratorRead, 14 // editing repository collaborators are not supported by github api so forcing new on any changes 15 Delete: resourceGithubRepositoryCollaboratorDelete, 16 Importer: &schema.ResourceImporter{ 17 State: schema.ImportStatePassthrough, 18 }, 19 20 Schema: map[string]*schema.Schema{ 21 "username": { 22 Type: schema.TypeString, 23 Required: true, 24 ForceNew: true, 25 }, 26 "repository": { 27 Type: schema.TypeString, 28 Required: true, 29 ForceNew: true, 30 }, 31 "permission": { 32 Type: schema.TypeString, 33 Optional: true, 34 ForceNew: true, 35 Default: "push", 36 ValidateFunc: validateValueFunc([]string{"pull", "push", "admin"}), 37 }, 38 }, 39 } 40 } 41 42 func resourceGithubRepositoryCollaboratorCreate(d *schema.ResourceData, meta interface{}) error { 43 client := meta.(*Organization).client 44 u := d.Get("username").(string) 45 r := d.Get("repository").(string) 46 p := d.Get("permission").(string) 47 48 _, err := client.Repositories.AddCollaborator(context.TODO(), meta.(*Organization).name, r, u, 49 &github.RepositoryAddCollaboratorOptions{Permission: p}) 50 51 if err != nil { 52 return err 53 } 54 55 d.SetId(buildTwoPartID(&r, &u)) 56 57 return resourceGithubRepositoryCollaboratorRead(d, meta) 58 } 59 60 func resourceGithubRepositoryCollaboratorRead(d *schema.ResourceData, meta interface{}) error { 61 client := meta.(*Organization).client 62 r, u := parseTwoPartID(d.Id()) 63 64 // First, check if the user has been invited but has not yet accepted 65 invitation, err := findRepoInvitation(client, meta.(*Organization).name, r, u) 66 if err != nil { 67 return err 68 } else if invitation != nil { 69 permName, err := getInvitationPermission(invitation) 70 if err != nil { 71 return err 72 } 73 74 d.Set("repository", r) 75 d.Set("username", u) 76 d.Set("permission", permName) 77 return nil 78 } 79 80 // Next, check if the user has accepted the invite and is a full collaborator 81 opt := &github.ListOptions{PerPage: maxPerPage} 82 for { 83 collaborators, resp, err := client.Repositories.ListCollaborators(context.TODO(), meta.(*Organization).name, r, opt) 84 if err != nil { 85 return err 86 } 87 88 for _, c := range collaborators { 89 if *c.Login == u { 90 permName, err := getRepoPermission(c.Permissions) 91 if err != nil { 92 return err 93 } 94 95 d.Set("repository", r) 96 d.Set("username", u) 97 d.Set("permission", permName) 98 return nil 99 } 100 } 101 102 if resp.NextPage == 0 { 103 break 104 } 105 opt.Page = resp.NextPage 106 } 107 108 // The user is neither invited nor a collaborator 109 d.SetId("") 110 return nil 111 } 112 113 func resourceGithubRepositoryCollaboratorDelete(d *schema.ResourceData, meta interface{}) error { 114 client := meta.(*Organization).client 115 u := d.Get("username").(string) 116 r := d.Get("repository").(string) 117 118 // Delete any pending invitations 119 invitation, err := findRepoInvitation(client, meta.(*Organization).name, r, u) 120 if err != nil { 121 return err 122 } else if invitation != nil { 123 _, err = client.Repositories.DeleteInvitation(context.TODO(), meta.(*Organization).name, r, *invitation.ID) 124 return err 125 } 126 127 _, err = client.Repositories.RemoveCollaborator(context.TODO(), meta.(*Organization).name, r, u) 128 return err 129 } 130 131 func findRepoInvitation(client *github.Client, owner string, repo string, collaborator string) (*github.RepositoryInvitation, error) { 132 opt := &github.ListOptions{PerPage: maxPerPage} 133 for { 134 invitations, resp, err := client.Repositories.ListInvitations(context.TODO(), owner, repo, opt) 135 if err != nil { 136 return nil, err 137 } 138 139 for _, i := range invitations { 140 if *i.Invitee.Login == collaborator { 141 return i, nil 142 } 143 } 144 145 if resp.NextPage == 0 { 146 break 147 } 148 opt.Page = resp.NextPage 149 } 150 return nil, nil 151 }