argo-cd
125 строк · 2.9 Кб
1package generator
2
3import (
4"context"
5"encoding/json"
6"errors"
7"fmt"
8"io"
9"log"
10"net/http"
11
12v1 "k8s.io/api/core/v1"
13v1meta "k8s.io/apimachinery/pkg/apis/meta/v1"
14
15"github.com/argoproj/argo-cd/v2/hack/gen-resources/util"
16
17"k8s.io/client-go/kubernetes"
18)
19
20type Repo struct {
21Id int `json:"id"`
22Url string `json:"html_url"`
23}
24
25type RepoGenerator struct {
26clientSet *kubernetes.Clientset
27bar *util.Bar
28}
29
30func NewRepoGenerator(clientSet *kubernetes.Clientset) Generator {
31return &RepoGenerator{clientSet: clientSet, bar: &util.Bar{}}
32}
33
34func fetchRepos(token string, page int) ([]Repo, error) {
35client := &http.Client{}
36req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("https://api.github.com/repos/argoproj/argocd-example-apps/forks?per_page=100&page=%v", page), nil)
37req.Header.Set("Authorization", token)
38resp, err := client.Do(req)
39if err != nil {
40return nil, err
41}
42body, err := io.ReadAll(resp.Body)
43if err != nil {
44return nil, err
45}
46var repos []Repo
47err = json.Unmarshal(body, &repos)
48if err != nil {
49return nil, errors.New("failed to retrieve repos, reason: " + string(body))
50}
51return repos, nil
52}
53
54func FetchRepos(token string, samples int) ([]Repo, error) {
55log.Print("Fetch repos started")
56var (
57repos []Repo
58page = 1
59)
60
61for {
62if page%10 == 0 {
63log.Printf("Fetch repos, page: %v", page)
64}
65fetchedRepos, err := fetchRepos(token, page)
66if err != nil {
67return nil, err
68}
69if len(fetchedRepos) == 0 {
70break
71}
72if len(repos)+len(fetchedRepos) > samples {
73repos = append(repos, fetchedRepos[0:samples-len(repos)]...)
74break
75}
76repos = append(repos, fetchedRepos...)
77page++
78}
79return repos, nil
80}
81
82func (rg *RepoGenerator) Generate(opts *util.GenerateOpts) error {
83repos, err := FetchRepos(opts.GithubToken, opts.RepositoryOpts.Samples)
84if err != nil {
85return err
86}
87
88secrets := rg.clientSet.CoreV1().Secrets(opts.Namespace)
89rg.bar.NewOption(0, int64(len(repos)))
90for _, repo := range repos {
91_, err = secrets.Create(context.TODO(), &v1.Secret{
92ObjectMeta: v1meta.ObjectMeta{
93GenerateName: "repo-",
94Namespace: opts.Namespace,
95Labels: map[string]string{
96"app.kubernetes.io/generated-by": "argocd-generator",
97"argocd.argoproj.io/secret-type": "repository",
98},
99Annotations: map[string]string{
100"managed-by": "argocd.argoproj.io",
101},
102},
103Data: map[string][]byte{
104"type": []byte("git"),
105"url": []byte(repo.Url),
106"project": []byte("default"),
107},
108}, v1meta.CreateOptions{})
109rg.bar.Increment()
110rg.bar.Play()
111}
112rg.bar.Finish()
113if err != nil {
114return err
115}
116return nil
117}
118
119func (rg *RepoGenerator) Clean(opts *util.GenerateOpts) error {
120log.Printf("Clean repos")
121secrets := rg.clientSet.CoreV1().Secrets(opts.Namespace)
122return secrets.DeleteCollection(context.TODO(), v1meta.DeleteOptions{}, v1meta.ListOptions{
123LabelSelector: "app.kubernetes.io/generated-by=argocd-generator",
124})
125}
126