github.com/swisscom/cloudfoundry-cli@v7.1.0+incompatible/cf/commands/application/copy_source.go (about)

     1  package application
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"code.cloudfoundry.org/cli/cf/api/applications"
     9  	"code.cloudfoundry.org/cli/cf/api/authentication"
    10  	"code.cloudfoundry.org/cli/cf/api/copyapplicationsource"
    11  	"code.cloudfoundry.org/cli/cf/api/organizations"
    12  	"code.cloudfoundry.org/cli/cf/api/spaces"
    13  	"code.cloudfoundry.org/cli/cf/commandregistry"
    14  	"code.cloudfoundry.org/cli/cf/configuration/coreconfig"
    15  	"code.cloudfoundry.org/cli/cf/flags"
    16  	. "code.cloudfoundry.org/cli/cf/i18n"
    17  	"code.cloudfoundry.org/cli/cf/models"
    18  	"code.cloudfoundry.org/cli/cf/requirements"
    19  	"code.cloudfoundry.org/cli/cf/terminal"
    20  )
    21  
    22  type CopySource struct {
    23  	ui                terminal.UI
    24  	config            coreconfig.Reader
    25  	authRepo          authentication.Repository
    26  	appRepo           applications.Repository
    27  	orgRepo           organizations.OrganizationRepository
    28  	spaceRepo         spaces.SpaceRepository
    29  	copyAppSourceRepo copyapplicationsource.Repository
    30  	appRestart        Restarter
    31  }
    32  
    33  func init() {
    34  	commandregistry.Register(&CopySource{})
    35  }
    36  
    37  func (cmd *CopySource) MetaData() commandregistry.CommandMetadata {
    38  	fs := make(map[string]flags.FlagSet)
    39  	fs["no-restart"] = &flags.BoolFlag{Name: "no-restart", Usage: T("Override restart of the application in target environment after copy-source completes")}
    40  	fs["o"] = &flags.StringFlag{ShortName: "o", Usage: T("Org that contains the target application")}
    41  	fs["s"] = &flags.StringFlag{ShortName: "s", Usage: T("Space that contains the target application")}
    42  
    43  	return commandregistry.CommandMetadata{
    44  		Name:        "copy-source",
    45  		Description: T("Copies the source code of an application to another existing application (and restarts that application)"),
    46  		Usage: []string{
    47  			T("   CF_NAME copy-source SOURCE-APP TARGET-APP [-s TARGET-SPACE [-o TARGET-ORG]] [--no-restart]\n"),
    48  		},
    49  		Flags: fs,
    50  	}
    51  }
    52  
    53  func (cmd *CopySource) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) ([]requirements.Requirement, error) {
    54  	usageReq := requirementsFactory.NewUsageRequirement(commandregistry.CLICommandUsagePresenter(cmd),
    55  		T("Requires SOURCE-APP TARGET-APP as arguments"),
    56  		func() bool {
    57  			return len(fc.Args()) != 2
    58  		},
    59  	)
    60  
    61  	reqs := []requirements.Requirement{
    62  		usageReq,
    63  		requirementsFactory.NewLoginRequirement(),
    64  		requirementsFactory.NewTargetedSpaceRequirement(),
    65  	}
    66  
    67  	return reqs, nil
    68  }
    69  
    70  func (cmd *CopySource) SetDependency(deps commandregistry.Dependency, pluginCall bool) commandregistry.Command {
    71  	cmd.ui = deps.UI
    72  	cmd.config = deps.Config
    73  	cmd.authRepo = deps.RepoLocator.GetAuthenticationRepository()
    74  	cmd.appRepo = deps.RepoLocator.GetApplicationRepository()
    75  	cmd.orgRepo = deps.RepoLocator.GetOrganizationRepository()
    76  	cmd.spaceRepo = deps.RepoLocator.GetSpaceRepository()
    77  	cmd.copyAppSourceRepo = deps.RepoLocator.GetCopyApplicationSourceRepository()
    78  
    79  	//get command from registry for dependency
    80  	commandDep := commandregistry.Commands.FindCommand("restart")
    81  	commandDep = commandDep.SetDependency(deps, false)
    82  	cmd.appRestart = commandDep.(Restarter)
    83  
    84  	return cmd
    85  }
    86  
    87  func (cmd *CopySource) Execute(c flags.FlagContext) error {
    88  	sourceAppName := c.Args()[0]
    89  	targetAppName := c.Args()[1]
    90  
    91  	targetOrg := c.String("o")
    92  	targetSpace := c.String("s")
    93  
    94  	if targetOrg != "" && targetSpace == "" {
    95  		return errors.New(T("Please provide the space within the organization containing the target application"))
    96  	}
    97  
    98  	_, err := cmd.authRepo.RefreshAuthToken()
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	sourceApp, err := cmd.appRepo.Read(sourceAppName)
   104  	if err != nil {
   105  		return err
   106  	}
   107  
   108  	var targetOrgName, targetSpaceName, spaceGUID, copyStr string
   109  	var spaceFields models.SpaceFields
   110  	if targetOrg != "" && targetSpace != "" {
   111  		spaceFields, err = cmd.findSpaceFields(targetOrg, targetSpace)
   112  		spaceGUID = spaceFields.GUID
   113  		if err != nil {
   114  			return err
   115  		}
   116  
   117  		targetOrgName = targetOrg
   118  		targetSpaceName = spaceFields.Name
   119  	} else if targetSpace != "" {
   120  		var space models.Space
   121  		space, err = cmd.spaceRepo.FindByName(targetSpace)
   122  		if err != nil {
   123  			return err
   124  		}
   125  		spaceGUID = space.GUID
   126  		targetOrgName = cmd.config.OrganizationFields().Name
   127  		targetSpaceName = space.Name
   128  	} else {
   129  		spaceGUID = cmd.config.SpaceFields().GUID
   130  		targetOrgName = cmd.config.OrganizationFields().Name
   131  		targetSpaceName = cmd.config.SpaceFields().Name
   132  	}
   133  
   134  	copyStr = buildCopyString(sourceAppName, targetAppName, targetOrgName, targetSpaceName, cmd.config.Username())
   135  
   136  	targetApp, err := cmd.appRepo.ReadFromSpace(targetAppName, spaceGUID)
   137  	if err != nil {
   138  		return err
   139  	}
   140  
   141  	cmd.ui.Say(copyStr)
   142  	cmd.ui.Say(T("Note: this may take some time"))
   143  	cmd.ui.Say("")
   144  
   145  	err = cmd.copyAppSourceRepo.CopyApplication(sourceApp.GUID, targetApp.GUID)
   146  	if err != nil {
   147  		return err
   148  	}
   149  
   150  	if !c.Bool("no-restart") {
   151  		cmd.appRestart.ApplicationRestart(targetApp, targetOrgName, targetSpaceName)
   152  	}
   153  
   154  	cmd.ui.Ok()
   155  	return nil
   156  }
   157  
   158  func (cmd *CopySource) findSpaceFields(targetOrg, targetSpace string) (models.SpaceFields, error) {
   159  	org, err := cmd.orgRepo.FindByName(targetOrg)
   160  	if err != nil {
   161  		return models.SpaceFields{}, err
   162  	}
   163  
   164  	var spaceFields models.SpaceFields
   165  	var foundSpace bool
   166  	for _, s := range org.Spaces {
   167  		if strings.EqualFold(s.Name, targetSpace) {
   168  			spaceFields = s
   169  			foundSpace = true
   170  		}
   171  	}
   172  
   173  	if !foundSpace {
   174  		return models.SpaceFields{}, fmt.Errorf(T("Could not find space {{.Space}} in organization {{.Org}}",
   175  			map[string]interface{}{
   176  				"Space": terminal.EntityNameColor(targetSpace),
   177  				"Org":   terminal.EntityNameColor(targetOrg),
   178  			},
   179  		))
   180  	}
   181  
   182  	return spaceFields, nil
   183  }
   184  
   185  func buildCopyString(sourceAppName, targetAppName, targetOrgName, targetSpaceName, username string) string {
   186  	return fmt.Sprintf(T("Copying source from app {{.SourceApp}} to target app {{.TargetApp}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...",
   187  		map[string]interface{}{
   188  			"SourceApp": terminal.EntityNameColor(sourceAppName),
   189  			"TargetApp": terminal.EntityNameColor(targetAppName),
   190  			"OrgName":   terminal.EntityNameColor(targetOrgName),
   191  			"SpaceName": terminal.EntityNameColor(targetSpaceName),
   192  			"Username":  terminal.EntityNameColor(username),
   193  		},
   194  	))
   195  
   196  }