123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- package util
- import (
- "crypto/rand"
- "crypto/rsa"
- "crypto/x509"
- "encoding/pem"
- "errors"
- "fmt"
- "io"
- fs "io/ioutil"
- "net"
- "net/url"
- "os"
- "path/filepath"
- "regexp"
- "github.com/chzyer/readline"
- homedir "github.com/mitchellh/go-homedir"
- "golang.org/x/crypto/ssh"
- )
- func Keygen(publicPath, privatePath string, bits int) error {
- privateKey, err := rsa.GenerateKey(rand.Reader, bits)
- if err != nil {
- return err
- }
- // generate and write private key as PEM
- privateFile, err := os.OpenFile(privatePath, os.O_RDWR|os.O_CREATE, 0600)
- if err != nil {
- return err
- }
- defer privateFile.Close()
- privatePEM := &pem.Block{
- Type: "RSA PRIVATE KEY",
- Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
- }
- if err := pem.Encode(privateFile, privatePEM); err != nil {
- return err
- }
- // generate and write public key
- publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
- if err != nil {
- return err
- }
- return fs.WriteFile(publicPath, ssh.MarshalAuthorizedKey(publicKey), 0600)
- }
- func JoinHostPort(host, port string) string {
- if port != "" {
- return fmt.Sprintf("%s:%s", host, port)
- }
- return host
- }
- func SplitHostPort(host string) (string, string) {
- h, p, err := net.SplitHostPort(host)
- if err != nil {
- return host, ""
- }
- return h, p
- }
- var ScpRe = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`)
- var Schemes = []string{"git", "https", "http", "git+ssh", "ssh"}
- func ParseURL(repo string) (*url.URL, error) {
- var err error
- var repoURL *url.URL
- if m := ScpRe.FindStringSubmatch(repo); m != nil {
- repoURL = &url.URL{
- Scheme: "ssh",
- User: url.User(m[1]),
- Host: m[2],
- Path: m[3],
- }
- } else {
- repoURL, err = url.Parse(repo)
- if err != nil {
- return nil, err
- }
- }
- for _, scheme := range Schemes {
- if repoURL.Scheme == scheme {
- return repoURL, nil
- }
- }
- return nil, errors.New(repoURL.Scheme + " is not supported")
- }
- type PromptConfig struct {
- Prompt string
- Default string
- Silent bool
- }
- func (c *PromptConfig) String() string {
- if c.Default != "" {
- return fmt.Sprintf("%s(%s) ", c.Prompt, c.Default)
- }
- return c.Prompt
- }
- func CheckError(err error) {
- if err == nil {
- return
- }
- fmt.Printf("\x1b[31;1m%s\x1b[0m\n", fmt.Sprintf("Error: %s", err))
- os.Exit(1)
- }
- func Prompt(cfg *PromptConfig) string {
- r, err := readline.NewEx(&readline.Config{
- Prompt: cfg.String(),
- EnableMask: cfg.Silent,
- MaskRune: 42,
- })
- CheckError(err)
- defer r.Close()
- for {
- line, err := r.Readline()
- CheckError(err)
- if line != "" {
- return line
- }
- if cfg.Default != "" {
- return cfg.Default
- }
- }
- }
- func IsExist(path string) bool {
- p, err := homedir.Expand(path)
- if err != nil {
- return false
- }
- if _, err := os.Stat(p); os.IsNotExist(err) {
- return false
- }
- return true
- }
- func Mkdir(paths ...string) (string, error) {
- p, err := homedir.Expand(filepath.Join(paths...))
- if err != nil {
- return "", err
- }
- if err := os.MkdirAll(p, 0755); err != nil {
- return "", err
- }
- return p, nil
- }
- func JoinPath(paths ...string) (string, error) {
- p, err := homedir.Expand(filepath.Join(paths...))
- if err != nil {
- return "", err
- }
- return p, nil
- }
- func Copy(src, dst string) error {
- in, err := os.Open(src)
- if err != nil {
- return err
- }
- defer in.Close()
- out, err := os.Create(dst)
- if err != nil {
- return err
- }
- defer out.Close()
- _, err = io.Copy(out, in)
- if err != nil {
- return err
- }
- return out.Close()
- }
- func SysSSHConfig() (string, error) {
- keypairs := []string{"~/.ssh/id_rsa", "~/.ssh/id_ed25519"}
- for _, k := range keypairs {
- if IsExist(k) && IsExist(k+".pub") {
- return homedir.Expand(k)
- }
- }
- return "", errors.New("System ssh config not found")
- }
|