mirror of
https://github.com/openziti/zrok.git
synced 2025-01-10 16:08:20 +01:00
updated 'zrok copy' (#438)
This commit is contained in:
parent
a975b69541
commit
cbb69373f4
118
cmd/zrok/copy.go
Normal file
118
cmd/zrok/copy.go
Normal file
@ -0,0 +1,118 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/openziti/zrok/environment"
|
||||
"github.com/openziti/zrok/environment/env_core"
|
||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||
"github.com/openziti/zrok/tui"
|
||||
"github.com/openziti/zrok/util/sync"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(newCopyCommand().cmd)
|
||||
}
|
||||
|
||||
type copyCommand struct {
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
func newCopyCommand() *copyCommand {
|
||||
cmd := &cobra.Command{
|
||||
Use: "copy <source> [<target>]",
|
||||
Short: "Copy zrok drive contents from <source> to <target> ('file://' and 'zrok://' supported)",
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
}
|
||||
command := ©Command{cmd: cmd}
|
||||
cmd.Run = command.run
|
||||
return command
|
||||
}
|
||||
|
||||
func (cmd *copyCommand) run(_ *cobra.Command, args []string) {
|
||||
sourceUrl, err := url.Parse(args[0])
|
||||
if err != nil {
|
||||
tui.Error(fmt.Sprintf("invalid source URL '%v'", args[0]), err)
|
||||
}
|
||||
if sourceUrl.Scheme != "zrok" && sourceUrl.Scheme != "file" {
|
||||
tui.Error("source URL must be 'file://' or 'zrok://", nil)
|
||||
}
|
||||
|
||||
targetStr := "file://."
|
||||
if len(args) == 2 {
|
||||
targetStr = args[1]
|
||||
}
|
||||
targetUrl, err := url.Parse(targetStr)
|
||||
if err != nil {
|
||||
tui.Error(fmt.Sprintf("invalid target URL '%v'", targetStr), err)
|
||||
}
|
||||
if targetUrl.Scheme != "zrok" && targetUrl.Scheme != "file" {
|
||||
tui.Error("target URL must be 'file://' or 'zrok://", nil)
|
||||
}
|
||||
|
||||
if sourceUrl.Scheme != "zrok" && targetUrl.Scheme != "zrok" {
|
||||
tui.Error("either <source> or <target> must be a 'zrok://' URL", nil)
|
||||
}
|
||||
if targetUrl.Scheme != "file" && sourceUrl.Scheme != "file" {
|
||||
tui.Error("either <source> or <target> must be a 'file://' URL", nil)
|
||||
}
|
||||
|
||||
root, err := environment.LoadRoot()
|
||||
if err != nil {
|
||||
tui.Error("error loading root", err)
|
||||
}
|
||||
|
||||
var access *sdk.Access
|
||||
if sourceUrl.Scheme == "zrok" {
|
||||
access, err = sdk.CreateAccess(root, &sdk.AccessRequest{ShareToken: sourceUrl.Host})
|
||||
if err != nil {
|
||||
tui.Error("error creating access", err)
|
||||
}
|
||||
}
|
||||
if targetUrl.Scheme == "zrok" {
|
||||
access, err = sdk.CreateAccess(root, &sdk.AccessRequest{ShareToken: targetUrl.Host})
|
||||
if err != nil {
|
||||
tui.Error("error creating access", err)
|
||||
}
|
||||
}
|
||||
defer func() {
|
||||
err := sdk.DeleteAccess(root, access)
|
||||
if err != nil {
|
||||
tui.Error("error deleting access", err)
|
||||
}
|
||||
}()
|
||||
|
||||
source, err := cmd.createTarget(sourceUrl, root)
|
||||
if err != nil {
|
||||
tui.Error("error creating target", err)
|
||||
}
|
||||
target, err := cmd.createTarget(targetUrl, root)
|
||||
if err != nil {
|
||||
tui.Error("error creating target", err)
|
||||
}
|
||||
|
||||
if err := sync.Synchronize(source, target); err != nil {
|
||||
tui.Error("error copying", err)
|
||||
}
|
||||
|
||||
fmt.Println("copy complete!")
|
||||
}
|
||||
|
||||
func (cmd *copyCommand) createTarget(t *url.URL, root env_core.Root) (sync.Target, error) {
|
||||
switch t.Scheme {
|
||||
case "zrok":
|
||||
target, err := sync.NewWebDAVTarget(&sync.WebDAVTargetConfig{URL: t, Username: "", Password: "", Root: root})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return target, nil
|
||||
|
||||
case "file":
|
||||
return sync.NewFilesystemTarget(&sync.FilesystemTargetConfig{Root: t.Path}), nil
|
||||
|
||||
default:
|
||||
return nil, errors.Errorf("invalid scheme")
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/openziti/zrok/util/sync"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
copyCmd.AddCommand(newCopyFromCommand().cmd)
|
||||
}
|
||||
|
||||
type copyFromCommand struct {
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
func newCopyFromCommand() *copyFromCommand {
|
||||
cmd := &cobra.Command{
|
||||
Use: "from <share> [<destination>]",
|
||||
Short: "Copy files from zrok drive to destination",
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
}
|
||||
command := ©FromCommand{cmd: cmd}
|
||||
cmd.Run = command.run
|
||||
return command
|
||||
}
|
||||
|
||||
func (cmd *copyFromCommand) run(_ *cobra.Command, args []string) {
|
||||
target := "."
|
||||
if len(args) == 2 {
|
||||
target = args[1]
|
||||
}
|
||||
|
||||
dst := sync.NewFilesystemTarget(&sync.FilesystemTargetConfig{
|
||||
Root: target,
|
||||
})
|
||||
src, err := sync.NewWebDAVTarget(&sync.WebDAVTargetConfig{
|
||||
URL: args[0],
|
||||
Username: "",
|
||||
Password: "",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := sync.Synchronize(src, dst); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/openziti/zrok/util/sync"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
copyCmd.AddCommand(newCopyToCommand().cmd)
|
||||
}
|
||||
|
||||
type copyToCommand struct {
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
func newCopyToCommand() *copyToCommand {
|
||||
cmd := &cobra.Command{
|
||||
Use: "to <share> <source>",
|
||||
Short: "Copy files to a zrok drive from source",
|
||||
Args: cobra.ExactArgs(2),
|
||||
}
|
||||
command := ©ToCommand{cmd: cmd}
|
||||
cmd.Run = command.run
|
||||
return command
|
||||
}
|
||||
|
||||
func (cmd *copyToCommand) run(_ *cobra.Command, args []string) {
|
||||
dst, err := sync.NewWebDAVTarget(&sync.WebDAVTargetConfig{
|
||||
URL: args[0],
|
||||
Username: "",
|
||||
Password: "",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
src := sync.NewFilesystemTarget(&sync.FilesystemTargetConfig{
|
||||
Root: args[1],
|
||||
})
|
||||
|
||||
if err := sync.Synchronize(src, dst); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
@ -26,7 +26,6 @@ func init() {
|
||||
testCmd.AddCommand(loopCmd)
|
||||
rootCmd.AddCommand(adminCmd)
|
||||
rootCmd.AddCommand(configCmd)
|
||||
rootCmd.AddCommand(copyCmd)
|
||||
rootCmd.AddCommand(shareCmd)
|
||||
rootCmd.AddCommand(testCmd)
|
||||
transport.AddAddressParser(tcp.AddressParser{})
|
||||
@ -80,11 +79,6 @@ var configCmd = &cobra.Command{
|
||||
Short: "Configure your zrok environment",
|
||||
}
|
||||
|
||||
var copyCmd = &cobra.Command{
|
||||
Use: "copy",
|
||||
Short: "Copy files to/from zrok drives",
|
||||
}
|
||||
|
||||
var loopCmd = &cobra.Command{
|
||||
Use: "loopback",
|
||||
Aliases: []string{"loop"},
|
||||
|
@ -2,18 +2,21 @@ package sync
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/openziti/zrok/environment/env_core"
|
||||
"github.com/openziti/zrok/util/sync/webdavClient"
|
||||
"github.com/pkg/errors"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
type WebDAVTargetConfig struct {
|
||||
URL string
|
||||
URL *url.URL
|
||||
Username string
|
||||
Password string
|
||||
Root env_core.Root
|
||||
}
|
||||
|
||||
type WebDAVTarget struct {
|
||||
@ -21,7 +24,10 @@ type WebDAVTarget struct {
|
||||
}
|
||||
|
||||
func NewWebDAVTarget(cfg *WebDAVTargetConfig) (*WebDAVTarget, error) {
|
||||
c := webdavClient.NewClient(cfg.URL, cfg.Username, cfg.Password)
|
||||
c, err := webdavClient.NewZrokClient(cfg.URL, cfg.Root, webdavClient.NewAutoAuth(cfg.Username, cfg.Password))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.Connect(); err != nil {
|
||||
return nil, errors.Wrap(err, "error connecting to webdav target")
|
||||
}
|
||||
|
@ -2,9 +2,13 @@ package webdavClient
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/openziti/zrok/environment/env_core"
|
||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@ -29,6 +33,35 @@ func NewClient(uri, user, pw string) *Client {
|
||||
return NewAuthClient(uri, NewAutoAuth(user, pw))
|
||||
}
|
||||
|
||||
func NewZrokClient(zrokUrl *url.URL, root env_core.Root, auth Authorizer) (*Client, error) {
|
||||
conn, err := sdk.NewDialer(zrokUrl.Host, root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transport := http.DefaultTransport.(*http.Transport).Clone()
|
||||
transport.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {
|
||||
return conn, nil
|
||||
}
|
||||
c := &http.Client{
|
||||
Transport: transport,
|
||||
CheckRedirect: func(rq *http.Request, via []*http.Request) error {
|
||||
if len(via) >= 10 {
|
||||
return ErrTooManyRedirects
|
||||
}
|
||||
if via[0].Header.Get(XInhibitRedirect) != "" {
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
httpUrl, err := url.Parse(zrokUrl.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
httpUrl.Scheme = "http"
|
||||
return &Client{root: FixSlash(httpUrl.String()), headers: make(http.Header), interceptor: nil, c: c, auth: auth}, nil
|
||||
}
|
||||
|
||||
// NewAuthClient creates a new client instance with a custom Authorizer
|
||||
func NewAuthClient(uri string, auth Authorizer) *Client {
|
||||
c := &http.Client{
|
||||
|
Loading…
Reference in New Issue
Block a user