func (repo CloudControllerServiceRepository) FindServicePlanByDescription(planDescription resources.ServicePlanDescription) (string, error) { path := fmt.Sprintf("/v2/services?inline-relations-depth=1&q=%s", url.QueryEscape("label:"+planDescription.ServiceLabel+";provider:"+planDescription.ServiceProvider)) offerings, err := repo.getServiceOfferings(path) if err != nil { return "", err } for _, serviceOfferingResource := range offerings { for _, servicePlanResource := range serviceOfferingResource.Plans { if servicePlanResource.Name == planDescription.ServicePlanName { return servicePlanResource.GUID, nil } } } return "", errors.NewModelNotFoundError("Plan", planDescription.String()) }
func (cmd *MigrateServiceInstances) Execute(c flags.FlagContext) error { v1 := resources.ServicePlanDescription{ ServiceLabel: c.Args()[0], ServiceProvider: c.Args()[1], ServicePlanName: c.Args()[2], } v2 := resources.ServicePlanDescription{ ServiceLabel: c.Args()[3], ServicePlanName: c.Args()[4], } force := c.Bool("f") v1GUID, err := cmd.serviceRepo.FindServicePlanByDescription(v1) switch err.(type) { case nil: case *errors.ModelNotFoundError: return errors.New(T("Plan {{.ServicePlanName}} cannot be found", map[string]interface{}{ "ServicePlanName": terminal.EntityNameColor(v1.String()), })) default: return err } v2GUID, err := cmd.serviceRepo.FindServicePlanByDescription(v2) switch err.(type) { case nil: case *errors.ModelNotFoundError: return errors.New(T("Plan {{.ServicePlanName}} cannot be found", map[string]interface{}{ "ServicePlanName": terminal.EntityNameColor(v2.String()), })) default: return err } count, err := cmd.serviceRepo.GetServiceInstanceCountForServicePlan(v1GUID) if err != nil { return err } else if count == 0 { return errors.New(T("Plan {{.ServicePlanName}} has no service instances to migrate", map[string]interface{}{"ServicePlanName": terminal.EntityNameColor(v1.String())})) } cmd.ui.Warn(migrateServiceInstanceWarning()) serviceInstancesPhrase := pluralizeServiceInstances(count) if !force { response := cmd.ui.Confirm( T("Really migrate {{.ServiceInstanceDescription}} from plan {{.OldServicePlanName}} to {{.NewServicePlanName}}?>", map[string]interface{}{ "ServiceInstanceDescription": serviceInstancesPhrase, "OldServicePlanName": terminal.EntityNameColor(v1.String()), "NewServicePlanName": terminal.EntityNameColor(v2.String()), })) if !response { return nil } } cmd.ui.Say(T("Attempting to migrate {{.ServiceInstanceDescription}}...", map[string]interface{}{"ServiceInstanceDescription": serviceInstancesPhrase})) changedCount, err := cmd.serviceRepo.MigrateServicePlanFromV1ToV2(v1GUID, v2GUID) if err != nil { return err } cmd.ui.Say(T("{{.CountOfServices}} migrated.", map[string]interface{}{"CountOfServices": pluralizeServiceInstances(changedCount)})) cmd.ui.Ok() return nil }
func (cmd *MigrateServiceInstances) Run(c *cli.Context) { v1 := resources.ServicePlanDescription{ ServiceLabel: c.Args()[0], ServiceProvider: c.Args()[1], ServicePlanName: c.Args()[2], } v2 := resources.ServicePlanDescription{ ServiceLabel: c.Args()[3], ServicePlanName: c.Args()[4], } force := c.Bool("f") v1Guid, apiErr := cmd.serviceRepo.FindServicePlanByDescription(v1) switch apiErr.(type) { case nil: case *errors.ModelNotFoundError: cmd.ui.Failed("Plan %s cannot be found", terminal.EntityNameColor(v1.String())) return default: cmd.ui.Failed(apiErr.Error()) return } v2Guid, apiErr := cmd.serviceRepo.FindServicePlanByDescription(v2) switch apiErr.(type) { case nil: case *errors.ModelNotFoundError: cmd.ui.Failed("Plan %s cannot be found", terminal.EntityNameColor(v2.String())) return default: cmd.ui.Failed(apiErr.Error()) return } count, apiErr := cmd.serviceRepo.GetServiceInstanceCountForServicePlan(v1Guid) if apiErr != nil { cmd.ui.Failed(apiErr.Error()) return } else if count == 0 { cmd.ui.Failed("Plan %s has no service instances to migrate", terminal.EntityNameColor(v1.String())) return } cmd.ui.Warn("WARNING: This operation is internal to Cloud Foundry; service brokers will not be contacted and" + " resources for service instances will not be altered. The primary use case for this operation is" + " to replace a service broker which implements the v1 Service Broker API with a broker which" + " implements the v2 API by remapping service instances from v1 plans to v2 plans. We recommend" + " making the v1 plan private or shutting down the v1 broker to prevent additional instances from" + " being created. Once service instances have been migrated, the v1 services and plans can be" + " removed from Cloud Foundry.") serviceInstancesPhrase := pluralizeServiceInstances(count) if !force { response := cmd.ui.Confirm("Really migrate %s from plan %s to %s?>", serviceInstancesPhrase, terminal.EntityNameColor(v1.String()), terminal.EntityNameColor(v2.String()), ) if !response { return } } cmd.ui.Say("Attempting to migrate %s...", serviceInstancesPhrase) changedCount, apiErr := cmd.serviceRepo.MigrateServicePlanFromV1ToV2(v1Guid, v2Guid) if apiErr != nil { cmd.ui.Failed(apiErr.Error()) } cmd.ui.Say("%s migrated.", pluralizeServiceInstances(changedCount)) cmd.ui.Ok() return }