Files
zeekayandHanzo Dev cbf668a980 Build on Go 1.27
go fix applied the modernizers: promoted-field keys in struct literals,
strings.Cut, SplitSeq, new(expr), slices and maps helpers, wg.Go, reflect.TypeFor
and errors.AsType. omitzero is left out, since omitting a zero struct such as
time.Time{} is a per-field wire decision and not a mechanical one.

Two changes the modernizers could not make for themselves. AsType needs its type
argument to be an error, so the git exit-status reader embeds error in the
interface it asks for. And an error built by concatenating a tag list into its
own format string now says so with a verb, which is what vet was pointing at.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-17 01:47:46 -07:00

124 lines
2.9 KiB
Go

package generator
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/hanzoai/cd/hack/gen-resources/util"
"k8s.io/client-go/kubernetes"
)
type Repo struct {
Id int `json:"id"`
Url string `json:"html_url"` //nolint:revive //FIXME(var-naming)
}
type RepoGenerator struct {
clientSet *kubernetes.Clientset
bar *util.Bar
}
func NewRepoGenerator(clientSet *kubernetes.Clientset) Generator {
return &RepoGenerator{clientSet: clientSet, bar: &util.Bar{}}
}
func fetchRepos(ctx context.Context, token string, page int) ([]Repo, error) {
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://api.github.com/repos/hanzocd/example-apps/forks?per_page=100&page=%v", page), http.NoBody)
req.Header.Set("Authorization", token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var repos []Repo
err = json.Unmarshal(body, &repos)
if err != nil {
return nil, errors.New("failed to retrieve repos, reason: " + string(body))
}
return repos, nil
}
func FetchRepos(token string, samples int) ([]Repo, error) {
log.Print("Fetch repos started")
var (
ctx = context.Background()
repos []Repo
page = 1
)
for {
if page%10 == 0 {
log.Printf("Fetch repos, page: %v", page)
}
fetchedRepos, err := fetchRepos(ctx, token, page)
if err != nil {
return nil, err
}
if len(fetchedRepos) == 0 {
break
}
if len(repos)+len(fetchedRepos) > samples {
repos = append(repos, fetchedRepos[0:samples-len(repos)]...)
break
}
repos = append(repos, fetchedRepos...)
page++
}
return repos, nil
}
func (rg *RepoGenerator) Generate(opts *util.GenerateOpts) error {
repos, err := FetchRepos(opts.GithubToken, opts.RepositoryOpts.Samples)
if err != nil {
return err
}
secrets := rg.clientSet.CoreV1().Secrets(opts.Namespace)
rg.bar.NewOption(0, int64(len(repos)))
for _, repo := range repos {
_, err = secrets.Create(context.TODO(), &corev1.Secret{
GenerateName: "repo-",
Namespace: opts.Namespace,
Labels: map[string]string{
"app.kubernetes.io/generated-by": "cd-generator",
"cd.hanzo.ai/secret-type": "repository",
},
Annotations: map[string]string{
"managed-by": "cd.hanzo.ai",
},
Data: map[string][]byte{
"type": []byte("git"),
"url": []byte(repo.Url),
"project": []byte("default"),
},
}, metav1.CreateOptions{})
rg.bar.Increment()
rg.bar.Play()
}
rg.bar.Finish()
if err != nil {
return err
}
return nil
}
func (rg *RepoGenerator) Clean(opts *util.GenerateOpts) error {
log.Print("Clean repos")
secrets := rg.clientSet.CoreV1().Secrets(opts.Namespace)
return secrets.DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{
LabelSelector: "app.kubernetes.io/generated-by=cd-generator",
})
}