Skip to content

Commit

Permalink
🐱 clone using GH api
Browse files Browse the repository at this point in the history
Clone repo using GH api if possible
  • Loading branch information
petar-cvit authored Apr 18, 2024
2 parents 43c14b9 + 564f0f1 commit 75316b2
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 5 deletions.
65 changes: 65 additions & 0 deletions cyclops-ctrl/internal/template/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/cyclops-ui/cycops-ctrl/internal/mapper"
"github.com/cyclops-ui/cycops-ctrl/internal/models"
"github.com/cyclops-ui/cycops-ctrl/internal/models/helm"
"github.com/cyclops-ui/cycops-ctrl/internal/template/gitproviders"
)

func (r Repo) LoadTemplate(repoURL, path, commit string) (*models.Template, error) {
Expand All @@ -43,6 +44,17 @@ func (r Repo) LoadTemplate(repoURL, path, commit string) (*models.Template, erro
return cached, nil
}

if gitproviders.IsGitHubSource(repoURL) {
ghTemplate, err := r.mapGitHubRepoTemplate(repoURL, path, commitSHA, creds)
if err != nil {
return nil, err
}

r.cache.SetTemplate(repoURL, path, commitSHA, ghTemplate)

return ghTemplate, nil
}

fs, err := clone(repoURL, commit, creds)
if err != nil {
return nil, err
Expand Down Expand Up @@ -149,6 +161,17 @@ func (r Repo) LoadInitialTemplateValues(repoURL, path, commit string) (map[inter
return cached, nil
}

if gitproviders.IsGitHubSource(repoURL) {
ghInitialValues, err := r.mapGitHubRepoInitialValues(repoURL, path, commitSHA, creds)
if err != nil {
return nil, err
}

r.cache.SetTemplateInitialValues(repoURL, path, commitSHA, ghInitialValues)

return ghInitialValues, nil
}

fs, err := clone(repoURL, commit, creds)
if err != nil {
return nil, err
Expand Down Expand Up @@ -435,6 +458,48 @@ func readFiles(path string, fs billy.Filesystem) ([]*chart.File, error) {
return chartFiles, nil
}

func (r Repo) mapGitHubRepoTemplate(repoURL, path, commitSHA string, creds *auth.Credentials) (*models.Template, error) {
tgzData, err := gitproviders.GitHubClone(repoURL, commitSHA, creds)
if err != nil {
return nil, err
}

ghRepoFiles, err := unpackTgzInMemory(tgzData)
if err != nil {
return nil, err
}

ghRepoFiles = gitproviders.SanitizeGHFiles(ghRepoFiles, path)

template, err := r.mapHelmChart(path, ghRepoFiles)
if err != nil {
return nil, err
}

return template, nil
}

func (r Repo) mapGitHubRepoInitialValues(repoURL, path, commitSHA string, creds *auth.Credentials) (map[interface{}]interface{}, error) {
tgzData, err := gitproviders.GitHubClone(repoURL, commitSHA, creds)
if err != nil {
return nil, err
}

ghRepoFiles, err := unpackTgzInMemory(tgzData)
if err != nil {
return nil, err
}

ghRepoFiles = gitproviders.SanitizeGHFiles(ghRepoFiles, path)

initial, err := r.mapHelmChartInitialValues(ghRepoFiles)
if err != nil {
return nil, err
}

return initial, nil
}

func httpBasicAuthCredentials(creds *auth.Credentials) *http.BasicAuth {
if creds == nil {
return nil
Expand Down
104 changes: 104 additions & 0 deletions cyclops-ctrl/internal/template/gitproviders/github.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package gitproviders

import (
"fmt"
"github.com/cyclops-ui/cycops-ctrl/internal/auth"
"github.com/pkg/errors"
"io/ioutil"
"net/http"
"net/url"
path2 "path"
"path/filepath"
"strings"
)

func IsGitHubSource(repoURL string) bool {
host, err := url.Parse(repoURL)
if err != nil {
return false
}

return host.Host == "github.com"
}

func GitHubClone(repoURL, commitSHA string, creds *auth.Credentials) ([]byte, error) {
repoURLparsed, err := url.Parse(repoURL)
if err != nil {
return nil, err
}

pathParts := strings.Split(repoURLparsed.Path, "/")
var organization, repository string
if len(pathParts) == 3 {
organization = pathParts[1]
repository = pathParts[2]
} else {
return nil, errors.New("invalid github repo URL; should be https://github.com/<org>/<repo>")
}

return gitHubTarball(organization, repository, commitSHA, creds)
}

func gitHubTarball(org, repo, commitSHA string, creds *auth.Credentials) ([]byte, error) {
req, err := http.NewRequest(
http.MethodGet,
fmt.Sprintf("https://api.github.com/repos/%v/%v/tarball/%v", org, repo, commitSHA),
nil,
)
if err != nil {
return nil, err
}

token := authToken(creds)
if len(token) != 0 {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", token))
}

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

return ioutil.ReadAll(resp.Body)
}

func authToken(creds *auth.Credentials) string {
if creds == nil {
return ""
}

return creds.Password
}

func SanitizeGHFiles(files map[string][]byte, path string) map[string][]byte {
out := make(map[string][]byte, len(files))

for key, value := range files {
repoFileName := removeFirstSegment(key)
if len(repoFileName) == 0 {
continue
}

if !strings.HasPrefix(repoFileName, fmt.Sprintf("%v/", path)) {
continue
}

trimmed := strings.TrimPrefix(repoFileName, path)
_, folder := path2.Split(path)
out[path2.Join(folder, trimmed)] = value
}

return out
}

func removeFirstSegment(path string) string {
segments := strings.Split(path, `/`)

if len(segments) <= 1 {
return ""
}

return filepath.Join(segments[1:]...)
}
12 changes: 7 additions & 5 deletions cyclops-ctrl/internal/template/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import (
"path"
"strings"

"github.com/cyclops-ui/cycops-ctrl/internal/mapper"
json "github.com/json-iterator/go"
"gopkg.in/yaml.v2"
helmchart "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/registry"

"github.com/cyclops-ui/cycops-ctrl/internal/mapper"
"github.com/cyclops-ui/cycops-ctrl/internal/models"
"github.com/cyclops-ui/cycops-ctrl/internal/models/helm"
)
Expand Down Expand Up @@ -195,12 +195,14 @@ func (r Repo) mapHelmChart(chartName string, files map[string][]byte) (*models.T

}

if len(schemaBytes) == 0 {
return nil, errors.New("could not read 'values.schema.json' file; it should be placed in the repo/path you provided; make sure you provided the correct path")
}

var schema helm.Property
// unmarshal values schema only if present
if len(schemaBytes) != 0 {
if err := json.Unmarshal(schemaBytes, &schema); err != nil {
return &models.Template{}, err
}
if err := json.Unmarshal(schemaBytes, &schema); err != nil {
return &models.Template{}, err
}

var metadata helmchart.Metadata
Expand Down

0 comments on commit 75316b2

Please sign in to comment.