func()

in tools/instance_mapper/instance_mapper.go [293:428]


func (im *InstanceMapper) LoadGCPInstanceTypes(ctx context.Context, projectId string, priceList *GcpPriceList, debug bool) error {
	im.InstanceData.GcpInstances = make(map[string]map[string]InstanceType, 0)
	im.InstanceData.GcpInstances["all"] = make(map[string]InstanceType, 0)

	httpClient, err := im.getHttpClient(ctx, debug)
	if err != nil {
		return err
	}

	c, err := compute.NewMachineTypesRESTClient(ctx, option.WithHTTPClient(httpClient))
	if err != nil {
		return err
	}
	defer c.Close()

	req := &computepb.AggregatedListMachineTypesRequest{
		Project: projectId,
	}

	var pricingHoursPerMonth float64 = 730.0
	var allRegions []string
	var allInstanceTypes []string
	it := c.AggregatedList(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		region := strings.TrimPrefix(resp.Key[0:len(resp.Key)-2], "zones/")
		if _, found := im.InstanceData.GcpInstances[region]; !found {
			im.InstanceData.GcpInstances[region] = make(map[string]InstanceType, 0)
		}
		if !im.stringInSlice(region, allRegions) {
			allRegions = append(allRegions, region)
		}

		for _, mt := range resp.Value.MachineTypes {
			gpus := 0
			gpuType := ""
			if len(mt.GetAccelerators()) > 0 {
				for _, accl := range mt.GetAccelerators() {
					gpus = gpus + int(*accl.GuestAcceleratorCount)
					if gpuType == "" {
						gpuType = *accl.GuestAcceleratorType
					}
				}
			}

			family := strings.SplitN(mt.GetName(), "-", 2)
			it := InstanceType{
				InstanceTypeId: mt.GetName(),
				InstanceFamily: family[0],
				Region:         region,
				Description:    mt.GetDescription(),
				BareMetal:      false,
				SharedTenancy:  strings.HasPrefix(mt.GetName(), "e2-"), // to be un-hardcoded
				GPUs:           gpus,
				GPUMemory:      0,
				GPUType:        gpuType,
				Memory:         int(mt.GetMemoryMb()),
				VCPUs:          int(mt.GetGuestCpus()),
				GHz:            3.0,
				Bandwidth:      0,
			}
			if !im.stringInSlice(it.InstanceTypeId, allInstanceTypes) {
				allInstanceTypes = append(allInstanceTypes, it.InstanceTypeId)
			}

			if priceList != nil {
				instancePricePerHour, err := it.GetHourlyPrice(priceList)
				if err == nil {
					if _sustainedUseTiers, ok := priceList.PriceList["sustained_use_tiers_new"]; ok {
						sustainedUseTiers := _sustainedUseTiers.(map[string]interface{})
						if sustainedUseTier, ok := sustainedUseTiers[strings.ToLower(it.InstanceFamily)]; ok {
							price := make(map[string]float64, 1)
							// Total 730 hours per month, calculate per sustained use tier
							price[region] = 0.0
							var pricingHoursPerTier float64 = pricingHoursPerMonth / float64(len(sustainedUseTier.(map[string]interface{})))
							for _, tierMultiplier := range sustainedUseTier.(map[string]interface{}) {
								var multiplier float64
								if k := reflect.TypeOf(tierMultiplier).Kind(); k == reflect.Float64 {
									multiplier = tierMultiplier.(float64)
								} else if k == reflect.Float32 {
									multiplier = float64(tierMultiplier.(float32))
								} else if k == reflect.Int {
									multiplier = float64(tierMultiplier.(int))
								} else {
									panic("unknown data type in tiers")
								}
								price[region] += instancePricePerHour * multiplier * pricingHoursPerTier
							}
							it.PricingPerRegion = &price
						} else {
							price := make(map[string]float64, 1)
							// Total 730 hours per month, no SUDs
							price[region] += instancePricePerHour * 730.0
							it.PricingPerRegion = &price
						}
					} else {
						log.Warningf("Could not find sustained use tiers configuration in price list")
					}
				} else {
					log.Warningf("Could not find pricing in region %s for: %s", it.Region, it.InstanceTypeId)

				}
			}
			im.InstanceData.GcpInstances[it.Region][it.InstanceTypeId] = it
			log.Infof("GCP instance type (region: %s): %s\n", it.Region, it.String())
		}
	}

	for _, instanceType := range allInstanceTypes {
		var instance *InstanceType
		for _, region := range allRegions {
			if regionInstance, ok := im.InstanceData.GcpInstances[region][instanceType]; ok {
				if instance == nil {
					instance = &regionInstance
				}
				if regionInstance.PricingPerRegion != nil {
					var ppr *map[string]float64 = instance.PricingPerRegion
					for r, price := range *regionInstance.PricingPerRegion {
						(*ppr)[r] = price
					}
				}
			}
		}
		if instance != nil {
			im.InstanceData.GcpInstances["all"][instance.InstanceTypeId] = *instance
		}
	}

	return nil
}