// Package tools: 2020 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 tools import ( "context" "regexp" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" ) type ( // Metadata type represents details about a given move group Metadata struct { ID string `json:"_id" bson:"_id"` Start struct { Datetime string `json:"datetime" bson:"datetime"` Timestamp int64 `json:"timestamp" bson:"timestamp"` } `json:"start" bson:"start"` End struct { Datetime string `json:"datetime" bson:"datetime"` Timestamp int64 `json:"timestamp" bson:"timestamp"` } `json:"end" bson:"end"` Devices []int `json:"devices" bson:"devices"` Accounts []int `json:"accounts" bson:"accounts"` Environments []string `json:"environments" bson:"environments"` Collection string `json:"collection" bson:"collection"` FiltersCollection string `json:"filters_collection" bson:"filters_collection"` DataCenter string `json:"data_center" bson:"data_center"` DefaultTimezone string `json:"default_timezone" bson:"default_timezone"` ManualImport bool `json:"manual_import" bson:"manual_import"` MigrationDC string `json:"migrationDC" bson:"migrationDC"` Name string `json:"name" bson:"name"` Description string `json:"description" bson:"description"` FullDC bool `json:"full_dc_migration" bson:"full_dc_migration"` Active bool `json:"active" bson:"active"` Type string `json:"type" bson:"type"` RackspaceMigrationDC bool `json:"rackspace_migration_dc" bson:"rackspace_migration_dc"` } ) var ( oldMG = regexp.MustCompile(`(?i)(\w{4}-N\S-\w{2,3})`) newMG = regexp.MustCompile(`(?i)(\w{4}-\d+-[JN]\w{2})`) // projection that excludes the devices, accounts, and env arrays metaProjection = bson.D{ {"devices", 0}, {"accounts", 0}, {"environments", 0}, } ) // CollectMetadata method will query the move-group Mongo collection and return a list of // move-groups. func (c *Client) CollectMetadata(collectionFilter *string, allFields bool) (metadata []Metadata, err error) { query := bson.D{{"active", true}} if collectionFilter != nil { query = append(query, bson.E{"collection", *collectionFilter}) } return c.getMetadata(query, allFields) } // CollectMetadataByMG method will query the move-group Mongo collection and return a list of // move-groups. It will return an err if no matches are found. func (c *Client) CollectMetadataByMG(movegroups []string, allFields bool) (metadata []Metadata, err error) { return c.getMetadata( bson.D{{"_id", bson.D{{"$in", movegroups}}}, {"active", true}}, allFields, ) } // FindDevice method will query the metadata collection looking for a given device ID, then // return the list of move-groups that the device is associated with. func (c *Client) FindDevice(device int, allFields bool) (metadata []Metadata, err error) { return c.getMetadata( bson.D{{"devices", bson.D{{"$in", []int{device}}}}, {"active", true}}, allFields, ) } func (c *Client) getMetadata(query bson.D, allFields bool) (metadata []Metadata, err error) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() opts := options.Find() if !allFields { opts = options.Find().SetProjection(metaProjection) } cursor, err := c.db.Database(migrationDB).Collection(MetaCollection).Find(ctx, query, opts) if err != nil { return } metadata = make([]Metadata, 0) err = cursor.All(ctx, &metadata) return } // 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 }