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 }