github.com/oam-dev/kubevela@v1.9.11/pkg/addon/reader_gitlab.go (about)

     1  /*
     2  Copyright 2021 The KubeVela Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package addon
    18  
    19  import (
    20  	"encoding/base64"
    21  
    22  	"github.com/xanzy/go-gitlab"
    23  
    24  	"github.com/oam-dev/kubevela/pkg/utils"
    25  )
    26  
    27  var _ AsyncReader = &gitlabReader{}
    28  
    29  // gitlabReader helps get addon's file by git
    30  type gitlabReader struct {
    31  	h *gitlabHelper
    32  }
    33  
    34  // gitlabHelper helps get addon's file by git
    35  type gitlabHelper struct {
    36  	Client *gitlab.Client
    37  	Meta   *utils.Content
    38  }
    39  
    40  // GitLabItem  addon's sub item
    41  type GitLabItem struct {
    42  	basePath string
    43  	tp       string
    44  	path     string
    45  	name     string
    46  }
    47  
    48  // GetType get addon's sub item type
    49  func (g GitLabItem) GetType() string {
    50  	return g.tp
    51  }
    52  
    53  // GetPath get addon's sub item path
    54  func (g GitLabItem) GetPath() string {
    55  	return g.path[len(g.basePath)+1:]
    56  }
    57  
    58  // GetName get addon's sub item name
    59  func (g GitLabItem) GetName() string {
    60  	return g.name
    61  }
    62  
    63  // GetRef ref is empty , use default branch master
    64  func (g *gitlabReader) GetRef() string {
    65  	var ref = "master"
    66  	if g.h.Meta.GitlabContent.Ref != "" {
    67  		return g.h.Meta.GitlabContent.Ref
    68  	}
    69  	return ref
    70  }
    71  
    72  // GetProjectID get gitlab project id
    73  func (g *gitlabReader) GetProjectID() int {
    74  	return g.h.Meta.GitlabContent.PId
    75  }
    76  
    77  // GetProjectPath get gitlab project path
    78  func (g *gitlabReader) GetProjectPath() string {
    79  	return g.h.Meta.GitlabContent.Path
    80  }
    81  
    82  // ListAddonMeta relative path to repoURL/basePath
    83  func (g *gitlabReader) ListAddonMeta() (addonCandidates map[string]SourceMeta, err error) {
    84  	addonCandidates = make(map[string]SourceMeta)
    85  	path := g.GetProjectPath()
    86  	ref := g.GetRef()
    87  	page := 1
    88  	perPage := 100
    89  	tree := []*gitlab.TreeNode{}
    90  
    91  	// This ListTree changed to keyset-based pagination in GitLab 15.0, so we need to get all the pagination lists
    92  	for {
    93  		t, resp, err := g.h.Client.Repositories.ListTree(g.GetProjectID(), &gitlab.ListTreeOptions{
    94  			ListOptions: gitlab.ListOptions{Page: page, PerPage: perPage},
    95  			Path:        &path,
    96  			Ref:         &ref,
    97  		})
    98  		if err != nil {
    99  			return nil, err
   100  		}
   101  		tree = append(tree, t...)
   102  		if page == resp.TotalPages {
   103  			break
   104  		}
   105  		page++
   106  	}
   107  
   108  	for _, node := range tree {
   109  		if node.Type == TreeType {
   110  			items, err := g.listAddonItem(make([]Item, 0), node.Path)
   111  			if err != nil {
   112  				return nil, err
   113  			}
   114  			addonCandidates[node.Name] = SourceMeta{
   115  				Name:  node.Name,
   116  				Items: items,
   117  			}
   118  		}
   119  	}
   120  
   121  	return addonCandidates, nil
   122  }
   123  
   124  func (g *gitlabReader) listAddonItem(item []Item, path string) ([]Item, error) {
   125  	ref := g.GetRef()
   126  	tree, _, err := g.h.Client.Repositories.ListTree(g.GetProjectID(), &gitlab.ListTreeOptions{Path: &path, Ref: &ref})
   127  	if err != nil {
   128  		return item, err
   129  	}
   130  	for _, node := range tree {
   131  		switch node.Type {
   132  		case TreeType:
   133  			item, err = g.listAddonItem(item, node.Path)
   134  			if err != nil {
   135  				return nil, err
   136  			}
   137  		case BlobType:
   138  			item = append(item, &GitLabItem{
   139  				basePath: g.GetProjectPath(),
   140  				tp:       FileType,
   141  				path:     node.Path,
   142  				name:     node.Name,
   143  			})
   144  		}
   145  	}
   146  	return item, nil
   147  }
   148  
   149  // ReadFile read file content from gitlab
   150  func (g *gitlabReader) ReadFile(path string) (content string, err error) {
   151  	ref := g.GetRef()
   152  	getFile, _, err := g.h.Client.RepositoryFiles.GetFile(g.GetProjectID(), g.GetProjectPath()+"/"+path, &gitlab.GetFileOptions{Ref: &ref})
   153  	if err != nil {
   154  		return "", err
   155  	}
   156  	decodeString, err := base64.StdEncoding.DecodeString(getFile.Content)
   157  	if err != nil {
   158  		return "", err
   159  	}
   160  	return string(decodeString), nil
   161  }
   162  
   163  func (g *gitlabReader) RelativePath(item Item) string {
   164  	return item.GetPath()
   165  }