github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/gitlab/project.go (about) 1 // Copyright 2020 The Terraformer Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package gitlab 16 17 import ( 18 "context" 19 "fmt" 20 "log" 21 "strconv" 22 "strings" 23 24 "github.com/GoogleCloudPlatform/terraformer/terraformutils" 25 "github.com/xanzy/go-gitlab" 26 ) 27 28 type ProjectGenerator struct { 29 GitLabService 30 } 31 32 // Generate TerraformResources from gitlab API, 33 func (g *ProjectGenerator) InitResources() error { 34 ctx := context.Background() 35 client, err := g.createClient() 36 if err != nil { 37 return err 38 } 39 40 group := g.Args["group"].(string) 41 g.Resources = append(g.Resources, createProjects(ctx, client, group)...) 42 43 return nil 44 } 45 46 func createProjects(ctx context.Context, client *gitlab.Client, group string) []terraformutils.Resource { 47 resources := []terraformutils.Resource{} 48 opt := &gitlab.ListGroupProjectsOptions{ 49 ListOptions: gitlab.ListOptions{ 50 PerPage: 100, 51 }, 52 } 53 54 for { 55 projects, resp, err := client.Groups.ListGroupProjects(group, opt, gitlab.WithContext(ctx)) 56 if err != nil { 57 log.Println(err) 58 return nil 59 } 60 61 for _, project := range projects { 62 resource := terraformutils.NewSimpleResource( 63 strconv.FormatInt(int64(project.ID), 10), 64 getProjectResourceName(project), 65 "gitlab_project", 66 "gitlab", 67 []string{}, 68 ) 69 70 // NOTE: mirror fields from API doesn't match with the ones from terraform provider 71 resource.IgnoreKeys = []string{"mirror_trigger_builds", "only_mirror_protected_branches", "mirror", "mirror_overwrites_diverged_branches"} 72 73 resource.SlowQueryRequired = true 74 resources = append(resources, resource) 75 resources = append(resources, createProjectVariables(ctx, client, project)...) 76 resources = append(resources, createBranchProtections(ctx, client, project)...) 77 resources = append(resources, createTagProtections(ctx, client, project)...) 78 resources = append(resources, createProjectMembership(ctx, client, project)...) 79 } 80 81 if resp.NextPage == 0 { 82 break 83 } 84 opt.Page = resp.NextPage 85 } 86 return resources 87 } 88 func createProjectVariables(ctx context.Context, client *gitlab.Client, project *gitlab.Project) []terraformutils.Resource { 89 resources := []terraformutils.Resource{} 90 opt := &gitlab.ListProjectVariablesOptions{} 91 92 for { 93 projectVariables, resp, err := client.ProjectVariables.ListVariables(project.ID, opt, gitlab.WithContext(ctx)) 94 if err != nil { 95 log.Println(err) 96 return nil 97 } 98 99 for _, projectVariable := range projectVariables { 100 101 resource := terraformutils.NewSimpleResource( 102 fmt.Sprintf("%d:%s:%s", project.ID, projectVariable.Key, projectVariable.EnvironmentScope), 103 fmt.Sprintf("%s___%s___%s", getProjectResourceName(project), projectVariable.Key, projectVariable.EnvironmentScope), 104 "gitlab_project_variable", 105 "gitlab", 106 []string{}, 107 ) 108 resource.SlowQueryRequired = true 109 resources = append(resources, resource) 110 } 111 112 if resp.NextPage == 0 { 113 break 114 } 115 opt.Page = resp.NextPage 116 } 117 return resources 118 } 119 120 func createBranchProtections(ctx context.Context, client *gitlab.Client, project *gitlab.Project) []terraformutils.Resource { 121 resources := []terraformutils.Resource{} 122 opt := &gitlab.ListProtectedBranchesOptions{} 123 124 for { 125 protectedBranches, resp, err := client.ProtectedBranches.ListProtectedBranches(project.ID, opt, gitlab.WithContext(ctx)) 126 if err != nil { 127 log.Println(err) 128 return nil 129 } 130 131 for _, protectedBranch := range protectedBranches { 132 133 resource := terraformutils.NewSimpleResource( 134 fmt.Sprintf("%d:%s", project.ID, protectedBranch.Name), 135 fmt.Sprintf("%s___%s", getProjectResourceName(project), protectedBranch.Name), 136 "gitlab_branch_protection", 137 "gitlab", 138 []string{}, 139 ) 140 resource.SlowQueryRequired = true 141 resources = append(resources, resource) 142 } 143 144 if resp.NextPage == 0 { 145 break 146 } 147 opt.Page = resp.NextPage 148 } 149 return resources 150 } 151 152 func createTagProtections(ctx context.Context, client *gitlab.Client, project *gitlab.Project) []terraformutils.Resource { 153 resources := []terraformutils.Resource{} 154 opt := &gitlab.ListProtectedTagsOptions{} 155 156 for { 157 protectedTags, resp, err := client.ProtectedTags.ListProtectedTags(project.ID, opt, gitlab.WithContext(ctx)) 158 if err != nil { 159 log.Println(err) 160 return nil 161 } 162 163 for _, protectedTag := range protectedTags { 164 165 resource := terraformutils.NewSimpleResource( 166 fmt.Sprintf("%d:%s", project.ID, protectedTag.Name), 167 fmt.Sprintf("%s___%s", getProjectResourceName(project), protectedTag.Name), 168 "gitlab_tag_protection", 169 "gitlab", 170 []string{}, 171 ) 172 resource.SlowQueryRequired = true 173 resources = append(resources, resource) 174 } 175 176 if resp.NextPage == 0 { 177 break 178 } 179 opt.Page = resp.NextPage 180 } 181 return resources 182 } 183 184 func createProjectMembership(ctx context.Context, client *gitlab.Client, project *gitlab.Project) []terraformutils.Resource { 185 resources := []terraformutils.Resource{} 186 opt := &gitlab.ListProjectMembersOptions{} 187 188 for { 189 projectMembers, resp, err := client.ProjectMembers.ListProjectMembers(project.ID, opt, gitlab.WithContext(ctx)) 190 if err != nil { 191 log.Println(err) 192 return nil 193 } 194 195 for _, projectMember := range projectMembers { 196 197 resource := terraformutils.NewSimpleResource( 198 fmt.Sprintf("%d:%d", project.ID, projectMember.ID), 199 fmt.Sprintf("%s___%s", getProjectResourceName(project), projectMember.Username), 200 "gitlab_project_membership", 201 "gitlab", 202 []string{}, 203 ) 204 resource.SlowQueryRequired = true 205 resources = append(resources, resource) 206 } 207 208 if resp.NextPage == 0 { 209 break 210 } 211 opt.Page = resp.NextPage 212 } 213 return resources 214 } 215 216 func getProjectResourceName(project *gitlab.Project) string { 217 return fmt.Sprintf("%d___%s", project.ID, strings.ReplaceAll(project.PathWithNamespace, "/", "__")) 218 }