// 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 changedc is a small helper to change the CORE DC for multiple devices by feeding it // a comma separated list of devices. package changedc import ( "strconv" "github.com/jokelyo/argparse" "github.com/sirupsen/logrus" "github.rackspace.com/DCM/gomigrate/core" "github.rackspace.com/DCM/gomigrate/shared" "github.rackspace.com/gorax/clients/goctk" "github.rackspace.com/gorax/gokeys" ) // DC type is a representation of // a datacenter object type DC struct { City string `json:"city"` Symbol string `json:"symbol"` ID int `json:"id"` } var ( argDevices *[]int argDestDC *string argMG *string ) // Plugin function will return a argparse.Command type back to the parent parser // nolint:typecheck func Plugin(p *core.Parser) core.Plugin { cmd := p.NewCommand("change_dc", "Updates the DC assignment in CORE") argDevices = shared.ArgDevices(cmd) argDestDC = cmd.String("", "dc", &argparse.Options{Help: "Destination DC (Required). ie HKG2", Required: true}) argMG = cmd.String("", "mg", &argparse.Options{Help: "Move Group"}) return core.Plugin{CMD: cmd, Func: pluginFunc} } // pluginFunc function will prompt for a destination DC by name, then a list of CORE devices to change the DC on. // Once provided, we will iterate through the list of devices and update the DC using CTK. func pluginFunc(cfg gokeys.Settings) { // Pull a core token from the users gokeys keychain key, err := cfg.Core(false) if err != nil { logrus.Fatal(err) } ctk, err := goctk.NewCTK(goctk.Token(key.Password)) if err != nil { logrus.Fatal(err) } if *argDestDC == "" { logrus.Fatal("Destination DC is required.") } if (argDevices == nil || len(*argDevices) == 0) && *argMG == "" { logrus.Fatal("Must define either -d or --mg") } if *argMG != "" { devices, err := shared.MongoDevices([]string{*argMG}, nil, nil, "", key.Password, make(map[string]interface{})) if err != nil { logrus.Fatal(err) } *argDevices = make([]int, 0) for _, d := range devices { *argDevices = append(*argDevices, d.ID) } } else { if argDevices != nil && len(*argDevices) == 0 { logrus.Fatal("No devices defined") } } dcs, err := ctk.NetworkDatacenter(*argDestDC) if err != nil { logrus.Fatal(err) } if len(dcs) == 0 { logrus.Fatalf("Unable to find CORE DC for %s", *argDestDC) } dc := dcs[0] logrus.Infof("%v:%v (%v) selected as destination", dc.Symbol, dc.ID, dc.City) logrus.Infof("Running change-dc on %d devices...", len(*argDevices)) for _, dev := range *argDevices { _, err := ctk.ChangeDataCenter(strconv.Itoa(dev), dc.ID) if err != nil { logrus.Errorf("dc update for %d (%s)", dev, err.Error()) continue } logrus.Infof("dc updated to %v (%s) for %d", dc.Symbol, dc.City, dev) } }