// 2017 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 dcx is designed to integrate DCX related actions into the MigrationDB collections and updates. package dcx import ( "math" "net/http" "strings" "sync" "github.com/go-redis/redis/v7" dcmTools "github.rackspace.com/DCM/tools" "github.rackspace.com/DCM/migration/pkg/collection/dp" "github.rackspace.com/DCM/migration/pkg/collection/mongo" "github.rackspace.com/DCM/migration/pkg/tools" "github.rackspace.com/gorax/clients/dcxAutohost" ) // routines to use for importing of data. Each call will spawn x number of routines // to run the calls to populate the database. const routines = 10 const ( redisInfraDeviceKey = "migration.dcx.device.%s" redisInfraDeviceTTL = 3600 //redisInfraZoneKey = "migration.dcx.zone.%s" //redisInfraZoneTTL = 3600 ) type ( // IPStruct type is a collection of all the address types that we model within // the database. IPStruct struct { IPv6 []dcmTools.IPv6AddressDetails `json:"ipv6_addresses" bson:"ipv6_addresses"` DRAC dcmTools.IPMapping `json:"drac_ips" bson:"drac_ips"` MBU dcmTools.IPMapping `json:"mbu_ips" bson:"mbu_ips"` ServiceNet dcmTools.IPMapping `json:"service_net_ips" bson:"service_net_ips"` VMManagement dcmTools.IPMapping `json:"vmnet_management" bson:"vmnet_management"` VMotion dcmTools.IPMapping `json:"vmnet_vmotion" bson:"vmnet_vmotion"` } // VLAN type is the reference to the types of VLANs that is collected within the // migration database VLAN struct { Source VlanStruct `json:"source" bson:"source"` Migration VlanStruct `json:"migration" bson:"migration"` } // VlanStruct is the abstracted VLAN information collected on each parent type. VlanStruct struct { Number int `json:"vlan_number" bson:"vlan_number"` Name string `json:"zone_name" bson:"zone_name"` Segments string `json:"network_segments" bson:"network_segments"` } ) // Client type represents client references to third-party resources required // for the methods within this package. type Client struct { sync.RWMutex Collection string MigrationType string RackspaceMigDC bool db *mongo.Client r *redis.Client dcx *dcxAutohost.Client ldp *dp.Client dcMap map[string]string } type ( // Opt defines the different types of options passed into the New function Opt func(c *Options) // Options defines data you can optionally set during client creation Options struct { collection string migrationType string raxMigDC bool } ) // MigrationZones type is used as a list of searchable criteria in an IP addresses // zone name to determine if the IP is a migration IP. var MigrationZones = []string{ "hkg5", // All HKG5 zones "lon3", // All LON7 Migration Zones "lon5", // All LON6 Migration Zones "iad3", // All IAD4 Migration Zones "nyc2", // IAD4 > NYC Migration Zones "sjc3", // ALL SJC2 Migration Zones } // SetCollection sets the collection name // nolint:unused func SetCollection(collection string) Opt { return func(o *Options) { o.collection = collection } } // SetMigrationType sets the migration type // nolint:unused func SetMigrationType(migType string) Opt { return func(o *Options) { if migType == "" { return } o.migrationType = migType } } // SetRaxMigDC sets the migration type // nolint:unused func SetRaxMigDC(isRaxMigDC bool) Opt { return func(o *Options) { o.raxMigDC = isRaxMigDC } } // NewContext function will take a pointer to a Request, and pull the client references // from the Context() offered within the default net/http package. func NewContext(r *http.Request, opts ...Opt) *Client { // Apply default options and generate a new options type. opt := &Options{ migrationType: dcmTools.MigTypeRackspace, raxMigDC: true, } // Apply all options for _, o := range opts { o(opt) } return &Client{ db: mongo.NewContext(r), dcx: dcxAutohost.FromContext(r.Context()), ldp: dp.NewContext(r), r: tools.FromCtxRedis(r.Context()), dcMap: make(map[string]string), Collection: opt.collection, MigrationType: opt.migrationType, RackspaceMigDC: opt.raxMigDC, } } // Chunk is a small internal function to break a list of Device types into // smaller chunks that we can send to go routines. func Chunk(str []string, rtns int) (chunk [][]string) { float := float64(len(str)) / float64(rtns) chunkSize := int(math.Ceil(float)) for i := 0; i < len(str); i += chunkSize { end := i + chunkSize if end > len(str) { end = len(str) } chunk = append(chunk, str[i:end]) } return } // IsMigrationIP function will take a zone name and determine if it // contains one of the searchable MigrationZones strings. func IsMigrationIP(zone string) bool { for _, data := range MigrationZones { if strings.Contains(strings.ToLower(zone), data) { return true } } return false }