// 2019 Rackspace, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package copysegments import ( "log" "strings" "time" "github.rackspace.com/DCM/migration/pkg/collection/mongo" "github.rackspace.com/DCM/tools" "github.rackspace.com/gorax/clients/migrationAPI" "github.com/sirupsen/logrus" "github.rackspace.com/DCM/gomigrate/core" "github.rackspace.com/DCM/gomigrate/shared" "github.rackspace.com/gorax/clients/dcxAutohost" "github.rackspace.com/gorax/gokeys" ) var ( argDevices *[]int argMoveGroup *string ) // Plugin function will return a argparse.Command type back to the parent parser // nolint:typecheck func Plugin(p *core.Parser) core.Plugin { // Create a argument for the DCX Translations logic cmd := p.NewCommand("copy_segments", "Copy source VLAN-port associations to mig ports in EM") argDevices = shared.ArgDevices(cmd) argMoveGroup = shared.ArgMoveGroup(cmd) return core.Plugin{CMD: cmd, Func: pluginFunc} } // pluginFunc function will prompt for a list of device, then run the DCX migration // locations for each device func pluginFunc(cfg gokeys.Settings) { // Pull a Identity token from the users gokeys keychain iKey, err := cfg.Identity(false) if err != nil { log.Fatal(err) } coreKey, err := cfg.Core(false) if err != nil { log.Fatal(err) } // Pull SSO creds from the gokeys keychain sso, err := cfg.SSO() if err != nil { log.Fatal(err) } var devices []tools.Device if *argMoveGroup != "" { if len(*argDevices) > 0 { logrus.Warn("preferring move-group over device list") } devices, err = shared.MongoDevices([]string{*argMoveGroup}, nil, nil, "", coreKey.Password, nil) if err != nil { logrus.Fatal(err) } } else if len(*argDevices) > 0 { devices, err = shared.MongoDevices(nil, nil, *argDevices, "", coreKey.Password, nil) if err != nil { logrus.Fatal(err) } } else { logrus.Fatal("Must pass either a move-group or a device list") } logrus.Infof("%s: found %d devices with locations ...", *argMoveGroup, len(devices)) dcx, err := dcxAutohost.New(dcxAutohost.WithToken(iKey.Password), false) if err != nil { log.Fatal(err) } m := migrationAPI.New(iKey.Password, false) for _, d := range shared.SortDevices(devices) { err := dcx.CopyMigrationPortsSegments(d.ID) var errMsg string if err == nil { logrus.Infof("%d: segment associations mapped", d.ID) } else { switch dcxErr := err.(type) { case dcxAutohost.DCXErr: logrus.Errorf("%d: %s", d.ID, dcxErr.Errors) errMsg = strings.Join(dcxErr.Errors, ",") default: logrus.Errorf("%d: %s", d.ID, dcxErr) errMsg = dcxErr.Error() } } statusUpdate(d, sso.Username, errMsg, m) } } func statusUpdate(d tools.Device, username, errMsg string, m *migrationAPI.Client) { collection := shared.GetCollection(d.MoveGroup) if collection == "" { logrus.Errorf("%d: unable to find collection from MG, not recording status update", d.ID) return } payload := []mongo.StatusCopySegments{ { ID: d.ID, Username: username, Timestamp: time.Now().Unix(), Error: errMsg, }, } if err := m.StatusUpdateCopySegments(collection, "not_used", payload); err != nil { logrus.Errorf("%d: error updating status results: %s", d.ID, err) } }