github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/github/resource_github_branch_protection.go (about)

     1  package github
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"net/http"
     7  
     8  	"github.com/google/go-github/github"
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  )
    11  
    12  func resourceGithubBranchProtection() *schema.Resource {
    13  	return &schema.Resource{
    14  		Create: resourceGithubBranchProtectionCreate,
    15  		Read:   resourceGithubBranchProtectionRead,
    16  		Update: resourceGithubBranchProtectionUpdate,
    17  		Delete: resourceGithubBranchProtectionDelete,
    18  		Importer: &schema.ResourceImporter{
    19  			State: schema.ImportStatePassthrough,
    20  		},
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"repository": {
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  			"branch": {
    29  				Type:     schema.TypeString,
    30  				Required: true,
    31  				ForceNew: true,
    32  			},
    33  			"required_status_checks": {
    34  				Type:     schema.TypeList,
    35  				Optional: true,
    36  				MaxItems: 1,
    37  				Elem: &schema.Resource{
    38  					Schema: map[string]*schema.Schema{
    39  						"include_admins": {
    40  							Type:     schema.TypeBool,
    41  							Optional: true,
    42  							Default:  false,
    43  						},
    44  						"strict": {
    45  							Type:     schema.TypeBool,
    46  							Optional: true,
    47  							Default:  false,
    48  						},
    49  						"contexts": {
    50  							Type:     schema.TypeList,
    51  							Optional: true,
    52  							Elem: &schema.Schema{
    53  								Type: schema.TypeString,
    54  							},
    55  						},
    56  					},
    57  				},
    58  			},
    59  			"required_pull_request_reviews": {
    60  				Type:     schema.TypeList,
    61  				Optional: true,
    62  				MaxItems: 1,
    63  				Elem: &schema.Resource{
    64  					Schema: map[string]*schema.Schema{
    65  						"include_admins": {
    66  							Type:     schema.TypeBool,
    67  							Optional: true,
    68  							Default:  false,
    69  						},
    70  					},
    71  				},
    72  			},
    73  			"restrictions": {
    74  				Type:     schema.TypeList,
    75  				Optional: true,
    76  				MaxItems: 1,
    77  				Elem: &schema.Resource{
    78  					Schema: map[string]*schema.Schema{
    79  						"users": {
    80  							Type:     schema.TypeList,
    81  							Optional: true,
    82  							Elem:     &schema.Schema{Type: schema.TypeString},
    83  						},
    84  						"teams": {
    85  							Type:     schema.TypeList,
    86  							Optional: true,
    87  							Elem:     &schema.Schema{Type: schema.TypeString},
    88  						},
    89  					},
    90  				},
    91  			},
    92  		},
    93  	}
    94  }
    95  
    96  func resourceGithubBranchProtectionCreate(d *schema.ResourceData, meta interface{}) error {
    97  	client := meta.(*Organization).client
    98  	r := d.Get("repository").(string)
    99  	b := d.Get("branch").(string)
   100  
   101  	protectionRequest, err := buildProtectionRequest(d)
   102  	if err != nil {
   103  		return err
   104  	}
   105  
   106  	_, _, err = client.Repositories.UpdateBranchProtection(context.TODO(), meta.(*Organization).name, r, b, protectionRequest)
   107  	if err != nil {
   108  		return err
   109  	}
   110  	d.SetId(buildTwoPartID(&r, &b))
   111  
   112  	return resourceGithubBranchProtectionRead(d, meta)
   113  }
   114  
   115  func resourceGithubBranchProtectionRead(d *schema.ResourceData, meta interface{}) error {
   116  	client := meta.(*Organization).client
   117  	r, b := parseTwoPartID(d.Id())
   118  
   119  	githubProtection, _, err := client.Repositories.GetBranchProtection(context.TODO(), meta.(*Organization).name, r, b)
   120  	if err != nil {
   121  		if err, ok := err.(*github.ErrorResponse); ok && err.Response.StatusCode == http.StatusNotFound {
   122  			d.SetId("")
   123  			return nil
   124  		}
   125  
   126  		return err
   127  	}
   128  
   129  	d.Set("repository", r)
   130  	d.Set("branch", b)
   131  
   132  	rsc := githubProtection.RequiredStatusChecks
   133  	if rsc != nil {
   134  		d.Set("required_status_checks", []interface{}{
   135  			map[string]interface{}{
   136  				"include_admins": rsc.IncludeAdmins,
   137  				"strict":         rsc.Strict,
   138  				"contexts":       rsc.Contexts,
   139  			},
   140  		})
   141  	} else {
   142  		d.Set("required_status_checks", []interface{}{})
   143  	}
   144  
   145  	rprr := githubProtection.RequiredPullRequestReviews
   146  	if rprr != nil {
   147  		d.Set("required_pull_request_reviews", []interface{}{
   148  			map[string]interface{}{
   149  				"include_admins": rprr.IncludeAdmins,
   150  			},
   151  		})
   152  	} else {
   153  		d.Set("required_pull_request_reviews", []interface{}{})
   154  	}
   155  
   156  	restrictions := githubProtection.Restrictions
   157  	if restrictions != nil {
   158  		var userLogins []string
   159  		for _, u := range restrictions.Users {
   160  			if u.Login != nil {
   161  				userLogins = append(userLogins, *u.Login)
   162  			}
   163  		}
   164  		var teamSlugs []string
   165  		for _, t := range restrictions.Teams {
   166  			if t.Slug != nil {
   167  				teamSlugs = append(teamSlugs, *t.Slug)
   168  			}
   169  		}
   170  
   171  		d.Set("restrictions", []interface{}{
   172  			map[string]interface{}{
   173  				"users": userLogins,
   174  				"teams": teamSlugs,
   175  			},
   176  		})
   177  	} else {
   178  		d.Set("restrictions", []interface{}{})
   179  	}
   180  
   181  	return nil
   182  }
   183  
   184  func resourceGithubBranchProtectionUpdate(d *schema.ResourceData, meta interface{}) error {
   185  	client := meta.(*Organization).client
   186  	r, b := parseTwoPartID(d.Id())
   187  
   188  	protectionRequest, err := buildProtectionRequest(d)
   189  	if err != nil {
   190  		return err
   191  	}
   192  
   193  	_, _, err = client.Repositories.UpdateBranchProtection(context.TODO(), meta.(*Organization).name, r, b, protectionRequest)
   194  	if err != nil {
   195  		return err
   196  	}
   197  	d.SetId(buildTwoPartID(&r, &b))
   198  
   199  	return resourceGithubBranchProtectionRead(d, meta)
   200  }
   201  
   202  func resourceGithubBranchProtectionDelete(d *schema.ResourceData, meta interface{}) error {
   203  	client := meta.(*Organization).client
   204  	r, b := parseTwoPartID(d.Id())
   205  
   206  	_, err := client.Repositories.RemoveBranchProtection(context.TODO(), meta.(*Organization).name, r, b)
   207  	return err
   208  }
   209  
   210  func buildProtectionRequest(d *schema.ResourceData) (*github.ProtectionRequest, error) {
   211  	protectionRequest := new(github.ProtectionRequest)
   212  
   213  	if v, ok := d.GetOk("required_status_checks"); ok {
   214  		vL := v.([]interface{})
   215  		if len(vL) > 1 {
   216  			return nil, errors.New("cannot specify required_status_checks more than one time")
   217  		}
   218  
   219  		for _, v := range vL {
   220  			m := v.(map[string]interface{})
   221  
   222  			rsc := new(github.RequiredStatusChecks)
   223  			rsc.IncludeAdmins = m["include_admins"].(bool)
   224  			rsc.Strict = m["strict"].(bool)
   225  
   226  			rsc.Contexts = []string{}
   227  			if contexts, ok := m["contexts"].([]interface{}); ok {
   228  				for _, c := range contexts {
   229  					rsc.Contexts = append(rsc.Contexts, c.(string))
   230  				}
   231  			}
   232  
   233  			protectionRequest.RequiredStatusChecks = rsc
   234  		}
   235  	}
   236  
   237  	if v, ok := d.GetOk("required_pull_request_reviews"); ok {
   238  		vL := v.([]interface{})
   239  		if len(vL) > 1 {
   240  			return nil, errors.New("cannot specify required_pull_request_reviews more than one time")
   241  		}
   242  
   243  		for _, v := range vL {
   244  			m := v.(map[string]interface{})
   245  
   246  			rprr := new(github.RequiredPullRequestReviews)
   247  			rprr.IncludeAdmins = m["include_admins"].(bool)
   248  
   249  			protectionRequest.RequiredPullRequestReviews = rprr
   250  		}
   251  	}
   252  
   253  	if v, ok := d.GetOk("restrictions"); ok {
   254  		vL := v.([]interface{})
   255  		if len(vL) > 1 {
   256  			return nil, errors.New("cannot specify restrictions more than one time")
   257  		}
   258  
   259  		for _, v := range vL {
   260  			m := v.(map[string]interface{})
   261  
   262  			restrictions := new(github.BranchRestrictionsRequest)
   263  
   264  			restrictions.Users = []string{}
   265  			if users, ok := m["users"].([]interface{}); ok {
   266  				for _, u := range users {
   267  					restrictions.Users = append(restrictions.Users, u.(string))
   268  				}
   269  			}
   270  
   271  			restrictions.Teams = []string{}
   272  			if teams, ok := m["teams"].([]interface{}); ok {
   273  				for _, t := range teams {
   274  					restrictions.Teams = append(restrictions.Teams, t.(string))
   275  				}
   276  			}
   277  
   278  			protectionRequest.Restrictions = restrictions
   279  		}
   280  	}
   281  
   282  	return protectionRequest, nil
   283  }