Skip to content

Commit

Permalink
provider/github: Implements github_branch_protection
Browse files Browse the repository at this point in the history
  • Loading branch information
alindeman committed Mar 26, 2017
1 parent 86d599c commit 329e810
Show file tree
Hide file tree
Showing 5 changed files with 574 additions and 0 deletions.
1 change: 1 addition & 0 deletions builtin/providers/github/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func Provider() terraform.ResourceProvider {
"github_organization_webhook": resourceGithubOrganizationWebhook(),
"github_repository_collaborator": resourceGithubRepositoryCollaborator(),
"github_issue_label": resourceGithubIssueLabel(),
"github_branch_protection": resourceGithubBranchProtection(),
},

ConfigureFunc: providerConfigure,
Expand Down
278 changes: 278 additions & 0 deletions builtin/providers/github/resource_github_branch_protection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
package github

import (
"context"
"errors"

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

func resourceGithubBranchProtection() *schema.Resource {
return &schema.Resource{
Create: resourceGithubBranchProtectionCreate,
Read: resourceGithubBranchProtectionRead,
Update: resourceGithubBranchProtectionUpdate,
Delete: resourceGithubBranchProtectionDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"repository": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"branch": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"required_status_checks": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"include_admins": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"strict": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"contexts": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
"required_pull_request_reviews": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"include_admins": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
},
},
"restrictions": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"users": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"teams": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
}
}

func resourceGithubBranchProtectionCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
r := d.Get("repository").(string)
b := d.Get("branch").(string)

protectionRequest, err := buildProtectionRequest(d)
if err != nil {
return err
}

_, _, err = client.Repositories.UpdateBranchProtection(context.TODO(), meta.(*Organization).name, r, b, protectionRequest)
if err != nil {
return err
}
d.SetId(buildTwoPartID(&r, &b))

return resourceGithubBranchProtectionRead(d, meta)
}

func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
r, b := parseTwoPartID(d.Id())

githubProtection, _, err := client.Repositories.GetBranchProtection(context.TODO(), meta.(*Organization).name, r, b)
if err != nil {
d.SetId("")
return nil
}

d.Set("repository", r)
d.Set("branch", b)

rsc := githubProtection.RequiredStatusChecks
if rsc != nil {
d.Set("required_status_checks", []interface{}{
map[string]interface{}{
"include_admins": rsc.IncludeAdmins,
"strict": rsc.Strict,
"contexts": rsc.Contexts,
},
})
} else {
d.Set("required_status_checks", []interface{}{})
}

rprr := githubProtection.RequiredPullRequestReviews
if rprr != nil {
d.Set("required_pull_request_reviews", []interface{}{
map[string]interface{}{
"include_admins": rprr.IncludeAdmins,
},
})
} else {
d.Set("required_pull_request_reviews", []interface{}{})
}

restrictions := githubProtection.Restrictions
if restrictions != nil {
var userLogins []string
for _, u := range restrictions.Users {
if u.Login != nil {
userLogins = append(userLogins, *u.Login)
}
}
var teamSlugs []string
for _, t := range restrictions.Teams {
if t.Slug != nil {
teamSlugs = append(teamSlugs, *t.Slug)
}
}

d.Set("restrictions", []interface{}{
map[string]interface{}{
"users": userLogins,
"teams": teamSlugs,
},
})
} else {
d.Set("restrictions", []interface{}{})
}

return nil
}

func resourceGithubBranchProtectionUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
r, b := parseTwoPartID(d.Id())

protectionRequest, err := buildProtectionRequest(d)
if err != nil {
return err
}

_, _, err = client.Repositories.UpdateBranchProtection(context.TODO(), meta.(*Organization).name, r, b, protectionRequest)
if err != nil {
return err
}
d.SetId(buildTwoPartID(&r, &b))

return resourceGithubBranchProtectionRead(d, meta)
}

func resourceGithubBranchProtectionDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Organization).client
r, b := parseTwoPartID(d.Id())

_, err := client.Repositories.RemoveBranchProtection(context.TODO(), meta.(*Organization).name, r, b)
return err
}

func buildProtectionRequest(d *schema.ResourceData) (*github.ProtectionRequest, error) {
protectionRequest := new(github.ProtectionRequest)

if v, ok := d.GetOk("required_status_checks"); ok {
vL := v.([]interface{})
if len(vL) > 1 {
return nil, errors.New("cannot specify required_status_checks more than one time")
}

for _, v := range vL {
m := v.(map[string]interface{})

rsc := new(github.RequiredStatusChecks)
rsc.IncludeAdmins = m["include_admins"].(bool)
rsc.Strict = m["strict"].(bool)

rsc.Contexts = []string{}
if contexts, ok := m["contexts"].([]interface{}); ok {
for _, c := range contexts {
rsc.Contexts = append(rsc.Contexts, c.(string))
}
}

protectionRequest.RequiredStatusChecks = rsc
}
}

if v, ok := d.GetOk("required_pull_request_reviews"); ok {
vL := v.([]interface{})
if len(vL) > 1 {
return nil, errors.New("cannot specify required_pull_request_reviews more than one time")
}

for _, v := range vL {
m := v.(map[string]interface{})

rprr := new(github.RequiredPullRequestReviews)
rprr.IncludeAdmins = m["include_admins"].(bool)

protectionRequest.RequiredPullRequestReviews = rprr
}
}

if v, ok := d.GetOk("restrictions"); ok {
vL := v.([]interface{})
if len(vL) > 1 {
return nil, errors.New("cannot specify restrictions more than one time")
}

for _, v := range vL {
m := v.(map[string]interface{})

restrictions := new(github.BranchRestrictionsRequest)

restrictions.Users = []string{}
if users, ok := m["users"].([]interface{}); ok {
for _, u := range users {
restrictions.Users = append(restrictions.Users, u.(string))
}
}

restrictions.Teams = []string{}
if teams, ok := m["teams"].([]interface{}); ok {
for _, t := range teams {
restrictions.Teams = append(restrictions.Teams, t.(string))
}
}

protectionRequest.Restrictions = restrictions
}
}

return protectionRequest, nil
}
Loading

0 comments on commit 329e810

Please sign in to comment.