// 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 mongo import ( "context" "errors" "regexp" "strings" "time" "github.rackspace.com/DCM/tools/migMeta" "github.rackspace.com/DCM/tools" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" "github.com/sirupsen/logrus" ) var ( oldMG = regexp.MustCompile(`(?i)(\w{4}-[JN]\S-\w{2,3})`) newMG = regexp.MustCompile(`(?i)(\w{4}-\d+-[JN]\w{2})`) ) // CollectMetadata method is stub function to tools method. Keeping this to simplify // changes to the rest of the repo. func (c *Client) CollectMetadata(collection string) (metadata []tools.Metadata, err error) { t := tools.New(c.db3, nil) return t.CollectMetadata(&collection, true) } // CollectMetadataByMG method is stub function to tools method. Keeping this to simplify // changes to the rest of the repo. func (c *Client) CollectMetadataByMG(movegroups []string) (metadata []tools.Metadata, err error) { t := tools.New(c.db3, nil) return t.CollectMetadataByMG(movegroups, true) } // CollectMigrationMetadata method returns migrationMetadata for matching collection func (c *Client) CollectMigrationMetadata(query bson.M) ([]migMeta.Migration, error) { return migMeta.New(c.db3).Get(query) } // FindDevice method is stub function to tools method. Keeping this to simplify // changes to the rest of the repo. func (c *Client) FindDevice(device int) (metadata []tools.Metadata, err error) { t := tools.New(c.db3, nil) return t.FindDevice(device, true) } // UpdateMetaDevices method will update the migration/metadata collection with a list of devices // per move-group (_id) func (c *Client) UpdateMetaDevices(col string) error { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() cursor, err := c.db3.Database(database).Collection(tools.MetaCollection).Find( ctx, bson.D{{"collection", col}, {"active", true}}, options.Find().SetProjection(bson.D{{"collection", 1}, {"start", 1}, {"end", 1}}), ) if err != nil { return err } mPayload := make([]tools.Metadata, 0) if err := cursor.All(ctx, &mPayload); err != nil { return err } logrus.Infof("updating device list in %s-metadata for %d move-groups", col, len(mPayload)) var errs []string for _, move := range mPayload { cursor, err := c.db3.Database(database).Collection(move.Collection).Find( ctx, bson.D{{"move_group", move.ID}, DeletedNETrue}, options.Find().SetProjection(bson.D{{"account.number", 1}, {"environment.number", 1}}), ) if err != nil { return err } dPayload := make([]tools.Device, 0) if err := cursor.All(ctx, &dPayload); err != nil { return err } var ( deviceList []int accountList []int envList []string check = make(map[int]bool) envCheck = make(map[string]bool) ) for _, d := range dPayload { if _, ok := check[d.Account.Number]; !ok { if d.Account.Number != 0 { check[d.Account.Number] = true accountList = append(accountList, d.Account.Number) } } if _, ok := envCheck[d.Environment.Number]; !ok { if d.Environment.Number != "" { envCheck[d.Environment.Number] = true envList = append(envList, d.Environment.Number) } } deviceList = append(deviceList, d.ID) } query := bson.D{{"_id", move.ID}} update := bson.D{{ "$set", bson.D{ {"devices", deviceList}, {"accounts", accountList}, {"environments", envList}, {"active", func() bool { // Return true if the move-group timestamp is still greater than the // current timestamp -24 hours, else return false return move.End.Timestamp > time.Now().Add(-24*time.Hour).Unix() }()}, }, }} if _, err := c.db3.Database(database).Collection(tools.MetaCollection).UpdateOne(ctx, query, update); err != nil { logrus.Errorf("UpdateMetaDevices:%s", err) errs = append(errs, err.Error()) } } if len(errs) != 0 { return errors.New(strings.Join(errs, ",")) } return nil } // IsNotMovingGroup will regex the move-group string to check for the "not moving" // indicator in the move-group. func IsNotMovingGroup(g string) bool { if newMG.MatchString(g) { return true } if oldMG.MatchString(g) { return true } return false }