package common import ( "errors" "fmt" "io" "os" "strings" "code.gitea.io/sdk/gitea" "github.com/go-git/go-billy/v5" "github.com/go-git/go-git/v5" gitconf "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/go-git/go-git/v5/storage/memory" ) type CertManMode int const ( Server CertManMode = iota Client ) type GitWorkspace struct { Domain string URL string Repo *git.Repository Storage *memory.Storage FS billy.Filesystem WorkTree *git.Worktree } type GitSource int const ( Github GitSource = iota Gitlab Gitea Gogs Bitbucket CodeCommit ) var GitSourceName = map[GitSource]string{ Github: "github", Gitlab: "gitlab", Gitea: "gitea", Gogs: "gogs", Bitbucket: "bitbucket", CodeCommit: "code-commit", } func StrToGitSource(s string) (GitSource, error) { for k, v := range GitSourceName { if v == s { return k, nil } } return GitSource(0), errors.New("invalid gitsource name") } //func createGithubClient() *github.Client { // return github.NewClient(nil).WithAuthToken(config.GetString("Git.api_token")) //} func CreateGiteaClient(config *AppConfig) *gitea.Client { client, err := gitea.NewClient(config.Git.Server, gitea.SetToken(config.Git.APIToken)) if err != nil { fmt.Printf("Error connecting to gitea instance: %v\n", err) return nil } return client } //func createGithubRepo(domain *Domain, Client *github.Client) string { // name := domain.name // owner := domain.config.GetString("Repo.owner") // description := domain.description // private := true // includeAllBranches := false // // ctx := context.Background() // template := &github.TemplateRepoRequest{ // Name: name, // Owner: &owner, // Description: description, // Private: &private, // IncludeAllBranches: &includeAllBranches, // } // repo, _, err := Client.Repositories.CreateFromTemplate(ctx, config.GetString("Git.org_name"), config.GetString("Git.template_name"), template) // if err != nil { // fmt.Println("Error creating repository from template,", err) // return "" // } // return *repo.CloneURL //} func CreateGiteaRepo(domain string, giteaClient *gitea.Client, config *AppConfig, domainConfig *DomainConfig) string { options := gitea.CreateRepoOption{ Name: domain + domainConfig.Repo.RepoSuffix, Description: "Certificate storage for " + domain, Private: true, IssueLabels: "", AutoInit: false, Template: false, Gitignores: "", License: "", Readme: "", DefaultBranch: "master", TrustModel: gitea.TrustModelDefault, } giteaRepo, _, err := giteaClient.CreateOrgRepo(config.Git.OrgName, options) if err != nil { fmt.Printf("Error creating repo: %v\n", err) return "" } return giteaRepo.CloneURL } func (ws *GitWorkspace) InitRepo() error { var err error ws.Repo, err = git.Init(ws.Storage, ws.FS) if err != nil { fmt.Printf("Error initializing local repo: %v\n", err) return err } _, err = ws.Repo.CreateRemote(&gitconf.RemoteConfig{ Name: "origin", URLs: []string{ws.URL}, }) if err != nil && !errors.Is(err, git.ErrRemoteExists) { fmt.Printf("Error creating remote origin repo: %v\n", err) return err } ws.WorkTree, err = ws.Repo.Worktree() if err != nil { fmt.Printf("Error getting worktree from local repo: %v\n", err) return err } return nil } func (ws *GitWorkspace) CloneRepo(certmanMode CertManMode, config *AppConfig) error { creds := &http.BasicAuth{ Username: config.Git.Username, Password: config.Git.APIToken, } var err error ws.Repo, err = git.Clone(ws.Storage, ws.FS, &git.CloneOptions{URL: ws.URL, Auth: creds}) if err != nil { fmt.Printf("Error cloning repo: %v\n", err) } ws.WorkTree, err = ws.Repo.Worktree() if err != nil { fmt.Printf("Error getting worktree from cloned repo: %v\n", err) return err } if certmanMode == Server { serverIdFile, err := ws.FS.OpenFile("/SERVER_ID", os.O_RDWR, 0640) if err != nil { if os.IsNotExist(err) { fmt.Printf("server ID file not found for %s, adopting domain\n", ws.URL) return nil } return err } serverIdBytes, err := io.ReadAll(serverIdFile) if err != nil { return err } serverId := strings.TrimSpace(string(serverIdBytes)) if serverId != config.App.UUID { return fmt.Errorf("domain is already managed by server with uuid %s", serverId) } } return nil }