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  }