Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transfer config - allow providing the src work dir #763

Merged
merged 3 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 48 additions & 19 deletions artifactory/commands/transferconfig/transferconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ const (

type TransferConfigCommand struct {
commandsUtils.TransferConfigBase
dryRun bool
force bool
verbose bool
preChecks bool
workingDir string
dryRun bool
force bool
verbose bool
preChecks bool
sourceWorkingDir string
targetWorkingDir string
}

func NewTransferConfigCommand(sourceServer, targetServer *config.ServerDetails) *TransferConfigCommand {
Expand Down Expand Up @@ -72,8 +73,13 @@ func (tcc *TransferConfigCommand) SetPreChecks(preChecks bool) *TransferConfigCo
return tcc
}

func (tcc *TransferConfigCommand) SetWorkingDir(workingDir string) *TransferConfigCommand {
tcc.workingDir = workingDir
func (tcc *TransferConfigCommand) SetSourceWorkingDir(workingDir string) *TransferConfigCommand {
tcc.sourceWorkingDir = workingDir
return tcc
}

func (tcc *TransferConfigCommand) SetTargetWorkingDir(workingDir string) *TransferConfigCommand {
tcc.targetWorkingDir = workingDir
return tcc
}

Expand Down Expand Up @@ -161,6 +167,32 @@ func (tcc *TransferConfigCommand) Run() (err error) {
return
}

// Create the directory containing the Artifactory export content
// Return values:
// exportPath - The export path
// unsetTempDir - Clean up function
// err - Error if any
func (tcc *TransferConfigCommand) createExportPath() (exportPath string, unsetTempDir func(), err error) {
if tcc.sourceWorkingDir != "" {
// Set the base temp dir according to the value of the --source-working-dir flag
oldTempDir := fileutils.GetTempDirBase()
fileutils.SetTempDirBase(tcc.sourceWorkingDir)
unsetTempDir = func() {
fileutils.SetTempDirBase(oldTempDir)
}
} else {
unsetTempDir = func() {}
}

// Create temp directory that will contain the export directory
exportPath, err = fileutils.CreateTempDir()
if err != nil {
return "", unsetTempDir, err
}

return exportPath, unsetTempDir, errorutils.CheckError(os.Chmod(exportPath, 0777))
}

func (tcc *TransferConfigCommand) runPreChecks() error {
// Warn if default admin:password credentials are exist in the source server
_, err := tcc.IsDefaultCredentials()
Expand Down Expand Up @@ -311,39 +343,36 @@ func (tcc *TransferConfigCommand) getEncryptedItems(selectedSourceRepos map[util
// Return the path to the export directory, a cleanup function and an error.
func (tcc *TransferConfigCommand) exportSourceArtifactory() (string, func() error, error) {
// Create temp directory that will contain the export directory
tempDir, err := fileutils.CreateTempDir()
exportPath, unsetTempDir, err := tcc.createExportPath()
defer unsetTempDir()
if err != nil {
return "", func() error { return nil }, err
}

if err = os.Chmod(tempDir, 0777); err != nil {
return "", func() error { return nil }, errorutils.CheckError(err)
}

// Do export
trueValue := true
falseValue := false
exportParams := services.ExportParams{
ExportPath: tempDir,
ExportPath: exportPath,
IncludeMetadata: &falseValue,
Verbose: &tcc.verbose,
ExcludeContent: &trueValue,
}
cleanUp := func() error { return fileutils.RemoveTempDir(tempDir) }
cleanUp := func() error { return fileutils.RemoveTempDir(exportPath) }
if err = tcc.SourceArtifactoryManager.Export(exportParams); err != nil {
return "", cleanUp, err
}

// Make sure only the export directory contained in the temp directory
files, err := fileutils.ListFiles(tempDir, true)
files, err := fileutils.ListFiles(exportPath, true)
if err != nil {
return "", cleanUp, err
}
if len(files) == 0 {
return "", cleanUp, errorutils.CheckErrorf("couldn't find the export directory in '%s'. Please make sure to run this command inside the source Artifactory machine", tempDir)
return "", cleanUp, errorutils.CheckErrorf("couldn't find the export directory in '%s'. Please make sure to run this command inside the source Artifactory machine", exportPath)
}
if len(files) > 1 {
return "", cleanUp, errorutils.CheckErrorf("only the exported directory is expected to be in the export directory %s, but found %q", tempDir, files)
return "", cleanUp, errorutils.CheckErrorf("only the exported directory is expected to be in the export directory %s, but found %q", exportPath, files)
}

// Return the export directory and the cleanup function
Expand Down Expand Up @@ -493,8 +522,8 @@ func (tcc *TransferConfigCommand) updateServerDetails() error {
}

func (tcc *TransferConfigCommand) getWorkingDirParam() string {
if tcc.workingDir != "" {
return "?params=workingDir=" + tcc.workingDir
if tcc.targetWorkingDir != "" {
return "?params=workingDir=" + tcc.targetWorkingDir
}
return ""
}
Expand Down
43 changes: 40 additions & 3 deletions artifactory/commands/transferconfig/transferconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ import (
"net/http"
"os"
"path/filepath"
"strings"
"testing"

commandUtils "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/utils"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
commonTests "github.com/jfrog/jfrog-cli-core/v2/common/tests"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/tests"
"github.com/jfrog/jfrog-client-go/artifactory/services"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"github.com/stretchr/testify/assert"
)

Expand All @@ -40,13 +43,18 @@ func TestExportSourceArtifactory(t *testing.T) {
})
defer testServer.Close()

// Create working dir
tmpDir, createTempDirCallback := tests.CreateTempDirWithCallbackAndAssert(t)
defer createTempDirCallback()

// Test export source artifactory
transferConfigCmd := createTransferConfigCommand(t, serverDetails, nil)
transferConfigCmd := createTransferConfigCommand(t, serverDetails, nil).SetSourceWorkingDir(tmpDir)
exportDir, cleanUp, err := transferConfigCmd.exportSourceArtifactory()
assert.NoError(t, err)
assert.DirExists(t, exportDir)
assert.NoError(t, cleanUp())
assert.NoDirExists(t, exportDir)
assert.True(t, strings.HasPrefix(exportDir, tmpDir))
}

func TestImportToTargetArtifactory(t *testing.T) {
Expand Down Expand Up @@ -144,7 +152,7 @@ func TestValidateTargetServer(t *testing.T) {

func TestVerifyConfigImportPluginNotInstalled(t *testing.T) {
// Create transfer config command
testServer, serverDetails, _ := commonTests.CreateRtRestsMockServer(t, func(w http.ResponseWriter, r *http.Request) {
testServer, serverDetails, _ := commonTests.CreateRtRestsMockServer(t, func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusNotFound)
_, err := w.Write([]byte("Not found"))
assert.NoError(t, err)
Expand All @@ -158,7 +166,7 @@ func TestVerifyConfigImportPluginNotInstalled(t *testing.T) {

func TestVerifyConfigImportPluginForbidden(t *testing.T) {
// Create transfer config command
testServer, serverDetails, _ := commonTests.CreateRtRestsMockServer(t, func(w http.ResponseWriter, r *http.Request) {
testServer, serverDetails, _ := commonTests.CreateRtRestsMockServer(t, func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusForbidden)
_, err := w.Write([]byte("An admin user is required"))
assert.NoError(t, err)
Expand All @@ -170,6 +178,35 @@ func TestVerifyConfigImportPluginForbidden(t *testing.T) {
assert.ErrorContains(t, err, "Response from Artifactory: 403 Forbidden.")
}

func TestCreateExportPath(t *testing.T) {
transferConfigBase := NewTransferConfigCommand(nil, nil)

// Create export path and check results
exportPath, unsetTempDir, err := transferConfigBase.createExportPath()
unsetTempDir()
assert.NoError(t, err)
assert.NotEmpty(t, exportPath)
assert.DirExists(t, exportPath)

// Create working dir
const testExportDir = "test-export-dir"
tmpDir, createTempDirCallback := tests.CreateTempDirWithCallbackAndAssert(t)
defer createTempDirCallback()
tmpDir = filepath.Join(tmpDir, testExportDir)
assert.NoError(t, os.MkdirAll(tmpDir, 0700))
transferConfigBase.sourceWorkingDir = tmpDir

// Create export path with custom working dir
exportPath, unsetTempDir, err = transferConfigBase.createExportPath()
unsetTempDir()
assert.NoError(t, err)
assert.True(t, strings.HasPrefix(exportPath, tmpDir))
assert.DirExists(t, exportPath)

// Ensure unsetTempDir did work
assert.NotContains(t, fileutils.GetTempDirBase(), testExportDir)
}

func createTransferConfigCommand(t *testing.T, sourceServerDetails, targetServerDetails *config.ServerDetails) *TransferConfigCommand {
transferConfigBase := NewTransferConfigCommand(sourceServerDetails, targetServerDetails)
var err error
Expand Down
Loading