package generate import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "github.com/Akilan1999/p2p-rendering-computation/p2p" "github.com/go-git/go-git/v5" "golang.org/x/crypto/ssh" "io/ioutil" "os" ) // GenerateFiles Generates all the files needed to setup P2PRC func GenerateFiles(rootNodes ...p2p.IpAddress) (err error) { err = GenerateIPTableFile(rootNodes) if err != nil { return err } err = GenerateDockerFiles() if err != nil { return err } err = GeneratePluginDirectory() if err != nil { return err } err = GenerateClientTrackContainers() return } // GenerateIPTableFile Generates the IPTable file with the appropirate root node func GenerateIPTableFile(rootNodes []p2p.IpAddress) (err error) { var rootnodes p2p.IpAddresses var rootnode p2p.IpAddress err = CreateIPTableFolderStructure() if err != nil { return err } // If root node addresses are not provided as optional parameters if len(rootNodes) <= 0 { rootnode.Name = "Node1" rootnode.ServerPort = "8078" rootnode.NAT = "False" rootnode.Ipv4 = "139.59.162.154" rootnodes.IpAddress = append(rootnodes.IpAddress, rootnode) } else { // if root nodes are provided then override them as the optional parameter for i := range rootNodes { rootnodes.IpAddress = append(rootnodes.IpAddress, rootNodes[i]) } } err = rootnodes.WriteIpTable() return } // CreateIPTableFolderStructure Create folder structure for IPTable func CreateIPTableFolderStructure() (err error) { path, err := GetCurrentPath() if err != nil { return err } if _, err = os.Stat(path + "p2p"); os.IsNotExist(err) { if err = os.Mkdir(path+"p2p", os.ModePerm); err != nil { return err } } if _, err = os.Stat(path + "p2p/iptable"); os.IsNotExist(err) { if err = os.Mkdir(path+"p2p/iptable", os.ModePerm); err != nil { return err } } if _, err = os.Stat(path + "p2p/iptable/ip_table.json"); os.IsNotExist(err) { _, err = os.Create(path + "p2p/iptable/ip_table.json") if err != nil { return err } } return } // GenerateDockerFiles Generate default docker files func GenerateDockerFiles() (err error) { path, err := GetCurrentPath() if err != nil { return err } if _, err = os.Stat(path + "server"); os.IsNotExist(err) { if err = os.Mkdir(path+"server", os.ModePerm); err != nil { return err } if _, err = os.Stat(path + "server/docker"); os.IsNotExist(err) { if err = os.Mkdir(path+"server/docker", os.ModePerm); err != nil { return err } } if _, err = os.Stat(path + "server/docker/containers"); os.IsNotExist(err) { if err = os.Mkdir(path+"server/docker/containers", os.ModePerm); err != nil { return err } } if _, err = os.Stat(path + "server/docker/containers"); os.IsNotExist(err) { if err = os.Mkdir(path+"server/docker/containers", os.ModePerm); err != nil { return err } } if _, err = os.Stat(path + "server/docker/containers/docker-ubuntu-sshd"); os.IsNotExist(err) { if err = os.Mkdir(path+"server/docker/containers/docker-ubuntu-sshd", os.ModePerm); err != nil { return err } } } // Clone base docker image _, err = git.PlainClone(path+"server/docker/containers/docker-ubuntu-sshd", false, &git.CloneOptions{ URL: "https://github.com/Akilan1999/docker-ubuntu-sshd", Progress: os.Stdout, }) if err != nil { return err } return } // GeneratePluginDirectory Generates plugin directory structure func GeneratePluginDirectory() (err error) { path, err := GetCurrentPath() if err != nil { return err } if _, err = os.Stat(path + "plugin"); os.IsNotExist(err) { if err = os.Mkdir(path+"plugin", os.ModePerm); err != nil { return err } if _, err = os.Stat(path + "plugin/deploy"); os.IsNotExist(err) { if err = os.Mkdir(path+"plugin/deploy", os.ModePerm); err != nil { return err } } } return } func GenerateClientTrackContainers() (err error) { path, err := GetCurrentPath() if err != nil { return err } if _, err = os.Stat(path + "client"); os.IsNotExist(err) { if err = os.Mkdir(path+"client", os.ModePerm); err != nil { return err } if err = os.Mkdir(path+"client/trackcontainers", os.ModePerm); err != nil { return err } if _, err = os.Stat(path + "client/trackcontainers/trackcontainers.json"); os.IsNotExist(err) { _, err = os.Create(path + "client/trackcontainers/trackcontainers.json") if err != nil { return err } _, err = os.Create(path + "client/trackcontainers/grouptrackcontainers.json") if err != nil { return err } } } return } // MakeSSHKeyPair make a pair of public and private keys for SSH access. // Public key is encoded in the format for inclusion in an OpenSSH authorized_keys file. // Private Key generated is PEM encoded // source: https://gist.github.com/goliatone/e9c13e5f046e34cef6e150d06f20a34c func MakeSSHKeyPair(pubKeyPath, privateKeyPath string) error { privateKey, err := rsa.GenerateKey(rand.Reader, 1024) if err != nil { return err } // generate and write private key as PEM privateKeyFile, err := os.Create(privateKeyPath) defer privateKeyFile.Close() if err != nil { return err } // Set permission to private key to SSH into docker machine err = os.Chmod(privateKeyPath, 600) if err != nil { return err } privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)} if err := pem.Encode(privateKeyFile, privateKeyPEM); err != nil { return err } // generate and write public key pub, err := ssh.NewPublicKey(&privateKey.PublicKey) if err != nil { return err } return ioutil.WriteFile(pubKeyPath, ssh.MarshalAuthorizedKey(pub), 0655) } // FileExists exists returns whether the given file or directory exists // source: https://stackoverflow.com/questions/10510691/how-to-check-whether-a-file-or-directory-exists func FileExists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err }