diff --git a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go index 43a39aeb3..0669609de 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go @@ -1751,7 +1751,7 @@ func handlePriceInfo() { // Type : [TERM_CONTAIN, ANY_OF, TERM_MATCH, NONE_OF, CONTAINS, EQUALS] // filterList = append(filterList, irs.KeyValue{Key: "filter", Value: "{\"Field\":\"instanceType\",\"Type\":\"TERM_MATCH\",\"Value\":\"t2.nano\"}"}) // filterList = append(filterList, irs.KeyValue{Key: "filter", Value: "{\"Field\":\"operatingSystem\",\"Type\":\"TERM_MATCH\",\"Value\":\"Linux\"}"}) - filterList = append(filterList, irs.KeyValue{Key: "filter", Value: "{\"Field\":\"sku\",\"Type\":\"TERM_MATCH\",\"Value\":\"24MKFUYR8UGHCNGB\"}"}) + //filterList = append(filterList, irs.KeyValue{Key: "filter", Value: "{\"Field\":\"sku\",\"Type\":\"TERM_MATCH\",\"Value\":\"24MKFUYR8UGHCNGB\"}"}) // TEST seraach data // instanceType = t2.nano @@ -1760,7 +1760,9 @@ func handlePriceInfo() { // cli 에서 아래 명령어를 통해 attribute를 검색할 수 있음. // aws pricing get-attribute-values --service-code AmazonEC2 --attribute-name instanceType - result, err := handler.GetPriceInfo("AmazonEC2", "ap-northeast-2", filterList) + //result, err := handler.GetPriceInfo("AmazonEC2", "ap-northeast-2", filterList) + result, err := handler.GetPriceInfo("AmazonEC2", "us-west-1", filterList) + if err != nil { cblogger.Infof("GetPriceInfo 조회 실패 : ", err) } else { @@ -1926,6 +1928,8 @@ func readConfigFile() Config { rootPath := os.Getenv("CBSPIDER_PATH") cblogger.Infof("Test Data 설정파일 : [%s]", rootPath+"/config/config.yaml") data, err := ioutil.ReadFile(rootPath + "/config/config.yaml") + data, err = ioutil.ReadFile("/Users/mzc01-swy/projects/feature_aws_filter_swy_240130/cloud-control-manager/cloud-driver/drivers/aws/main/Sample/config/config.yaml") + if err != nil { panic(err) } @@ -1953,6 +1957,6 @@ func main() { // handleVMSpec() // handleNLB() // handleCluster() - // handleRegionZone() + //handleRegionZone() handlePriceInfo() } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go index 98d186238..911799880 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go @@ -715,14 +715,16 @@ func DescribeRegions(client *ec2.EC2, AllRegionsBool bool, regionName string) (* // AllRegions option to show next 3 status(opt-in-not-required | opted-in | not-opted-in). // true = opt-in-not-required | opted-in | not-opted-in // false = opted-in - AllRegions: aws.Bool(AllRegionsBool), + + //AllRegions: aws.Bool(AllRegionsBool), } } else { RegionsInput = &ec2.DescribeRegionsInput{ // AllRegions option to show next 3 status(opt-in-not-required | opted-in | not-opted-in). // true = opt-in-not-required | opted-in | not-opted-in // false = opted-in - AllRegions: aws.Bool(AllRegionsBool), + + //AllRegions: aws.Bool(AllRegionsBool), RegionNames: []*string{ aws.String(regionName), // 여기에 필터로 사용할 Region을 추가합니다. }, @@ -754,12 +756,12 @@ func DescribeAvailabilityZones(client *ec2.EC2, AllRegionsBool bool) (*ec2.Descr ErrorMSG: "", } - ZonesInput := &ec2.DescribeAvailabilityZonesInput{ - AllAvailabilityZones: aws.Bool(AllRegionsBool), // (true -> for all AZ) | (false -> for all Zone, include not avail ) - } - + // ZonesInput := &ec2.DescribeAvailabilityZonesInput{ + // AllAvailabilityZones: aws.Bool(AllRegionsBool), // (true -> for all AZ) | (false -> for all Zone, include not avail ) + // } + // Opt-in 넣으면 credential 에러 -> nil 변경 (20240130) callLogStart := call.Start() - respZones, err := client.DescribeAvailabilityZones(ZonesInput) + respZones, err := client.DescribeAvailabilityZones(nil) //ZonesInput callLogInfo.ElapsedTime = call.Elapsed(callLogStart) callogger.Info(call.String(callLogInfo)) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/PriceInfoHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/PriceInfoHandler.go index 12782d9a1..2163e8077 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/PriceInfoHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/PriceInfoHandler.go @@ -8,7 +8,6 @@ import ( irs "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/resources" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/pricing" ) @@ -23,168 +22,513 @@ type AwsPriceInfoHandler struct { // getPricingClient에 Client *pricing.Pricing 정의 func (priceInfoHandler *AwsPriceInfoHandler) ListProductFamily(regionName string) ([]string, error) { var result []string - input := &pricing.GetAttributeValuesInput{ - AttributeName: aws.String("productfamily"), - MaxResults: aws.Int64(32), // 2024.01 기준 32개 - ServiceCode: aws.String("AmazonEC2"), - } - for { - attributeValues, err := priceInfoHandler.Client.GetAttributeValues(input) - if err != nil { - if aerr, ok := err.(awserr.Error); ok { - switch aerr.Code() { - case pricing.ErrCodeInternalErrorException: - cblogger.Error(pricing.ErrCodeInternalErrorException, aerr.Error()) - case pricing.ErrCodeInvalidParameterException: - cblogger.Error(pricing.ErrCodeInvalidParameterException, aerr.Error()) - case pricing.ErrCodeNotFoundException: - cblogger.Error(pricing.ErrCodeNotFoundException, aerr.Error()) - case pricing.ErrCodeInvalidNextTokenException: - cblogger.Error(pricing.ErrCodeInvalidNextTokenException, aerr.Error()) - case pricing.ErrCodeExpiredNextTokenException: - cblogger.Error(pricing.ErrCodeExpiredNextTokenException, aerr.Error()) - default: - cblogger.Error(aerr.Error()) - } - } else { - // Prnit the error, cast err to awserr.Error to get the Code and - // Message from an error. - cblogger.Error(err.Error()) - } - } - for _, attributeValue := range attributeValues.AttributeValues { - result = append(result, *attributeValue.Value) - } - if attributeValues.NextToken != nil { - input = &pricing.GetAttributeValuesInput{ - NextToken: attributeValues.NextToken, - } - } else { - break - } - } + result = append(result, "AmazonEC2") return result, nil } // AWS에서는 ListProductFamily를 통해 ProductFamily와 AttributeName을 수집하고, // GetAttributeValues를 통해 AttributeValue를 수집하여 필터로 사용합니다. -// GetPriceInfo는 DescribeServices를 통해 옳바른 productFamily 인자만 검사합니다. -> AttributeName에 오류가 있을경우 빈값을 리턴 +// GetPriceInfo는 DescribeServices를 통해 올바른 productFamily 인자만 검사합니다. -> AttributeName에 오류가 있을경우 빈값을 리턴 + func (priceInfoHandler *AwsPriceInfoHandler) GetPriceInfo(productFamily string, regionName string, filterList []irs.KeyValue) (string, error) { + result := &irs.CloudPriceData{} + result.Meta.Version = "v0.1" + result.Meta.Description = "Multi-Cloud Price Info" + + priceMap := make(map[string]irs.Price) // 전체 price를 id로 구분한 map + cblogger.Info("productFamily======", productFamily) + + cblogger.Info("filter value : ", filterList) describeServicesinput := &pricing.DescribeServicesInput{ ServiceCode: aws.String(productFamily), MaxResults: aws.Int64(1), } + services, err := priceInfoHandler.Client.DescribeServices(describeServicesinput) + if services == nil { cblogger.Error("No services in given productFamily. CHECK productFamily!") return "", err } + if err != nil { cblogger.Error(err) return "", err } - getProductsinputfilters := []*pricing.Filter{} + requestProductsInputFilters, err := setProductsInputRequestFilter(filterList) - if filterList != nil { - for _, filter := range filterList { - var getProductsinputfilter pricing.Filter - err := json.Unmarshal([]byte(filter.Value), &getProductsinputfilter) - getProductsinputfilters = append(getProductsinputfilters, &getProductsinputfilter) - if err != nil { - cblogger.Error(err) - return "", err - } - } - } + // filter조건에 region 지정. if regionName != "" { - getProductsinputfilters = append(getProductsinputfilters, &pricing.Filter{ + requestProductsInputFilters = append(requestProductsInputFilters, &pricing.Filter{ Field: aws.String("regionCode"), Type: aws.String("EQUALS"), Value: aws.String(regionName), }) + } else { + requestProductsInputFilters = append(requestProductsInputFilters, &pricing.Filter{ + Field: aws.String("regionCode"), + Type: aws.String("EQUALS"), + Value: aws.String(priceInfoHandler.Region.Region), + }) } - getProductsinput := &pricing.GetProductsInput{ - Filters: getProductsinputfilters, + getProductsRequest := &pricing.GetProductsInput{ + Filters: requestProductsInputFilters, ServiceCode: aws.String(productFamily), } - - priceinfos, err := priceInfoHandler.Client.GetProducts(getProductsinput) + cblogger.Info("get Products request", getProductsRequest) + priceinfos, err := priceInfoHandler.Client.GetProducts(getProductsRequest) if err != nil { cblogger.Error(err) return "", err } + cblogger.Info("get Products response", priceinfos) - result := &irs.CloudPriceData{} - result.Meta.Version = "v0.1" - result.Meta.Description = "Multi-Cloud Price Info" - - for _, price := range priceinfos.PriceList { - jsonString, err := json.MarshalIndent(price["product"].(map[string]interface{})["attributes"], "", " ") + for _, awsPrice := range priceinfos.PriceList { + productInfo, err := ExtractProductInfo(awsPrice) if err != nil { cblogger.Error(err) + continue } - var productInfo irs.ProductInfo - ReplaceEmptyWithNA(&productInfo) - err = json.Unmarshal(jsonString, &productInfo) - if err != nil { - cblogger.Error(err) - } + // termsKey : OnDemand, Reserved + for termsKey, termsValue := range awsPrice["terms"].(map[string]interface{}) { + for _, policyValue := range termsValue.(map[string]interface{}) { + // OnDemand, Reserved 일 때, 항목이 다름. + priceDemensions := make(map[string]interface{}) + termAttributes := make(map[string]interface{}) + sku := "" + if priceDemensionsVal, ok := policyValue.(map[string]interface{})["priceDimensions"]; ok { + priceDemensions = priceDemensionsVal.(map[string]interface{}) + } + if termAttributesVal, ok := policyValue.(map[string]interface{})["termAttributes"]; ok { + termAttributes = termAttributesVal.(map[string]interface{}) + } + if skuVal, ok := policyValue.(map[string]interface{})["sku"]; ok { + skuValString, ok := skuVal.(string) + if ok { + sku = skuValString + } + } - productInfo.ProductId = fmt.Sprintf("%s", price["product"].(map[string]interface{})["sku"]) - productInfo.RegionName = fmt.Sprintf("%s", price["product"].(map[string]interface{})["attributes"].(map[string]interface{})["regionCode"]) - productInfo.Description = fmt.Sprintf("productFamily= %s, version= %s", price["product"].(map[string]interface{})["productFamily"], price["version"]) - productInfo.CSPProductInfo = price["product"] - productInfo.ZoneName = "NA" // AWS zone is Not Applicable - 202401 - - var priceInfo irs.PriceInfo - priceInfo.CSPPriceInfo = price["terms"] - for termsKey, termsValue := range price["terms"].(map[string]interface{}) { - for _, policyvalue := range termsValue.(map[string]interface{}) { - var pricingPolicy irs.PricingPolicies - for innerpolicyKey, innerpolicyValue := range policyvalue.(map[string]interface{}) { - if innerpolicyKey == "priceDimensions" { - for priceDimensionsKey, priceDimensionsValue := range innerpolicyValue.(map[string]interface{}) { - pricingPolicy.PricingId = priceDimensionsKey - pricingPolicy.PricingPolicy = termsKey - pricingPolicy.Description = fmt.Sprintf("%s", priceDimensionsValue.(map[string]interface{})["description"]) - for key, val := range priceDimensionsValue.(map[string]interface{})["pricePerUnit"].(map[string]interface{}) { - pricingPolicy.Currency = key - pricingPolicy.Price = fmt.Sprintf("%s", val) - // USD is Default. - // if NO USD data, accept other currency. - if key == "USD" { - break - } + if termsKey == "OnDemand" { + for priceDimensionsKey, priceDimensionsValue := range priceDemensions { + isFiltered := OnDemandPolicyFilter(priceDimensionsKey, priceDimensionsValue.(map[string]interface{}), termAttributes, sku, filterList) + if isFiltered { + continue + } + + var pricingPolicy irs.PricingPolicies + pricingPolicy.PricingId = priceDimensionsKey + pricingPolicy.PricingPolicy = termsKey + pricingPolicy.Description = fmt.Sprintf("%s", priceDimensionsValue.(map[string]interface{})["description"]) + for key, val := range priceDimensionsValue.(map[string]interface{})["pricePerUnit"].(map[string]interface{}) { + pricingPolicy.Currency = key + pricingPolicy.Price = fmt.Sprintf("%s", val) + // USD is Default. + // if NO USD data, accept other currency. + if key == "USD" { + break } - pricingPolicy.Unit = fmt.Sprintf("%s", priceDimensionsValue.(map[string]interface{})["unit"]) - priceInfo.PricingPolicies = append(priceInfo.PricingPolicies, pricingPolicy) + } + pricingPolicy.Unit = fmt.Sprintf("%s", priceDimensionsValue.(map[string]interface{})["unit"]) + + // policy 추출하여 추가 + aPrice, ok := AppendPolicyToPrice(priceMap, productInfo, pricingPolicy, awsPrice) + if !ok { + priceMap[productInfo.ProductId] = aPrice + } + } + + } else if termsKey == "Reserved" { + + for priceDimensionsKey, priceDimensionsValue := range priceDemensions { + isFiltered := ReservedPolicyFilter(priceDimensionsKey, priceDimensionsValue.(map[string]interface{}), termAttributes, sku, filterList) + if isFiltered { + continue + } + + var pricingPolicy irs.PricingPolicies + pricingPolicy.PricingId = priceDimensionsKey + pricingPolicy.PricingPolicy = termsKey + pricingPolicy.Description = fmt.Sprintf("%s", priceDimensionsValue.(map[string]interface{})["description"]) + for key, val := range priceDimensionsValue.(map[string]interface{})["pricePerUnit"].(map[string]interface{}) { + pricingPolicy.Currency = key + pricingPolicy.Price = fmt.Sprintf("%s", val) + // USD is Default. + // if NO USD data, accept other currency. + if key == "USD" { + break + } + } + pricingPolicy.Unit = fmt.Sprintf("%s", priceDimensionsValue.(map[string]interface{})["unit"]) + + pricingPolicyInfo := irs.PricingPolicyInfo{} + if leaseContractLength, ok := termAttributes["LeaseContractLength"]; ok { + pricingPolicyInfo.LeaseContractLength = leaseContractLength.(string) + } + if offeringClass, ok := termAttributes["OfferingClass"]; ok { + pricingPolicyInfo.OfferingClass = offeringClass.(string) + } + if purchaseOption, ok := termAttributes["PurchaseOption"]; ok { + pricingPolicyInfo.PurchaseOption = purchaseOption.(string) + } + + // policy 추출하여 추가 + aPrice, ok := AppendPolicyToPrice(priceMap, productInfo, pricingPolicy, awsPrice) + if !ok { + priceMap[productInfo.ProductId] = aPrice } } } } } - // price info - var priceListone irs.Price - priceListone.ProductInfo = productInfo - priceListone.PriceInfo = priceInfo + } - priceone := irs.CloudPrice{ - CloudName: "AWS", - } - priceone.PriceList = append(priceone.PriceList, priceListone) - result.CloudPriceList = append(result.CloudPriceList, priceone) + priceList := []irs.Price{} + for _, value := range priceMap { + priceList = append(priceList, value) + } + + priceone := irs.CloudPrice{ + CloudName: "AWS", } + priceone.PriceList = priceList + result.CloudPriceList = append(result.CloudPriceList, priceone) + resultString, err := json.Marshal(result) if err != nil { cblogger.Error(err) return "", err } - return string(resultString), nil } + +// 가져온 결과에서 product 추출 +func ExtractProductInfo(jsonValue aws.JSONValue) (irs.ProductInfo, error) { + var productInfo irs.ProductInfo + + jsonString, err := json.MarshalIndent(jsonValue["product"].(map[string]interface{})["attributes"], "", " ") + if err != nil { + cblogger.Error(err) + return productInfo, err + } + + ReplaceEmptyWithNA(&productInfo) + err = json.Unmarshal(jsonString, &productInfo) + if err != nil { + cblogger.Error(err) + return productInfo, err + } + + productId := fmt.Sprintf("%s", jsonValue["product"].(map[string]interface{})["sku"]) + productInfo.ProductId = productId + productInfo.RegionName = fmt.Sprintf("%s", jsonValue["product"].(map[string]interface{})["attributes"].(map[string]interface{})["regionCode"]) + productInfo.Description = fmt.Sprintf("productFamily= %s, version= %s", jsonValue["product"].(map[string]interface{})["productFamily"], jsonValue["version"]) + productInfo.CSPProductInfo = jsonValue["product"] + productInfo.ZoneName = "NA" // AWS zone is Not Applicable - 202401 + + return productInfo, nil + +} + +// price에 해당 product가 있으면 append, 없으면 추가 +func AppendPolicyToPrice(priceMap map[string]irs.Price, productInfo irs.ProductInfo, pricingPolicy irs.PricingPolicies, jsonValue aws.JSONValue) (irs.Price, bool) { + productId := productInfo.ProductId + aPrice, ok := priceMap[productId] + + if ok { // product가 존재하면 policy 추가 + cblogger.Info("product exist ", productId) + aPrice.PriceInfo.PricingPolicies = append(aPrice.PriceInfo.PricingPolicies, pricingPolicy) + priceMap[productId] = aPrice + return aPrice, true + } else { // product가 없으면 price 추가 + cblogger.Info("product not exist ", productId) + + newPriceInfo := irs.PriceInfo{} + newPolicies := []irs.PricingPolicies{} + newPolicies = append(newPolicies, pricingPolicy) + + newPriceInfo.PricingPolicies = newPolicies + newPriceInfo.CSPPriceInfo = jsonValue // 새로운 가격이면 terms아래값을 넣는다. + + newPrice := irs.Price{} + newPrice.PriceInfo = newPriceInfo + newPrice.ProductInfo = productInfo + + priceMap[productId] = newPrice + + return newPrice, true + } +} + +// 요청시 필요한 filter Set. +func setProductsInputRequestFilter(filterList []irs.KeyValue) ([]*pricing.Filter, error) { + requestFilters := []*pricing.Filter{} + + if filterList != nil { + for _, filter := range filterList { + if filter.Key == "instanceType" { + requestFilters = append(requestFilters, &pricing.Filter{ + Field: aws.String("instanceType"), + Type: aws.String("TERM_MATCH"), + Value: aws.String(filter.Value), + }) + } + + if filter.Key == "operatingSystem" { + requestFilters = append(requestFilters, &pricing.Filter{ + Field: aws.String("operatingSystem"), + Type: aws.String("TERM_MATCH"), + Value: aws.String(filter.Value), + }) + } + if filter.Key == "vcpu" { + requestFilters = append(requestFilters, &pricing.Filter{ + Field: aws.String("vcpu"), + Type: aws.String("TERM_MATCH"), + Value: aws.String(filter.Value), + }) + } + if filter.Key == "productId" { + requestFilters = append(requestFilters, &pricing.Filter{ + Field: aws.String("sku"), + Type: aws.String("TERM_MATCH"), + Value: aws.String(filter.Value), + }) + } + if filter.Key == "memory" { + requestFilters = append(requestFilters, &pricing.Filter{ + Field: aws.String("memory"), + Type: aws.String("TERM_MATCH"), + Value: aws.String(filter.Value), + }) + } + if filter.Key == "storage" { + requestFilters = append(requestFilters, &pricing.Filter{ + Field: aws.String("storage"), + Type: aws.String("TERM_MATCH"), + Value: aws.String(filter.Value), + }) + } + if filter.Key == "gpu" { + requestFilters = append(requestFilters, &pricing.Filter{ + Field: aws.String("gpu"), + Type: aws.String("TERM_MATCH"), + Value: aws.String(filter.Value), + }) + } + if filter.Key == "gpuMemory" { + requestFilters = append(requestFilters, &pricing.Filter{ + Field: aws.String("gpuMemory"), + Type: aws.String("TERM_MATCH"), + Value: aws.String(filter.Value), + }) + } + if filter.Key == "preInstalledSw" { + requestFilters = append(requestFilters, &pricing.Filter{ + Field: aws.String("preInstalledSw"), + Type: aws.String("TERM_MATCH"), + Value: aws.String(filter.Value), + }) + } + } //end of for + } // end of if + return requestFilters, nil +} + +// 결과에서 filter. filter에 걸리면 true, 안걸리면 false +func OnDemandPolicyFilter(priceDimensionsKey string, priceDimensions map[string]interface{}, termAttributes map[string]interface{}, sku string, filterList []irs.KeyValue) bool { + isFiltered := false + + hasPricingPolicy := false + pricingPolicyVal := "" + + hasPriceDimension := false + priceDemensionVal := "" + + hasUnit := false + unitVal := "" + + // reserved only options + hasLeaseContractLength := false + hasOfferingClass := false + hasPurchaseOption := false + + if filterList != nil { + + for _, filter := range filterList { + // find filter conditions + if filter.Key == "pricingPolicy" { + hasPricingPolicy = true + pricingPolicyVal = filter.Value + continue + } + + if filter.Key == "pricingId" { + hasPriceDimension = true + priceDemensionVal = filter.Value + continue + } + if filter.Key == "unit" { + hasUnit = true + unitVal = filter.Value + continue + } + if filter.Key == "leaseContractLength" { + hasLeaseContractLength = true + break + } + if filter.Key == "offeringClass" { + hasOfferingClass = true + break + } + if filter.Key == "purchaseOption" { + hasPurchaseOption = true + break + } + } + // check filters + } + + if hasLeaseContractLength || hasOfferingClass || hasPurchaseOption { // reserved 전용 filter 임. + cblogger.Info("filtered by reserved options ", hasLeaseContractLength, hasOfferingClass, hasPurchaseOption) + return true + } + + if hasPricingPolicy { + if pricingPolicyVal != "OnDemand" { + cblogger.Info("filtered by pricingPolicy ", pricingPolicyVal, priceDimensions["pricingPolicy"]) + return true + } + } + if hasUnit { + for key, val := range priceDimensions["pricePerUnit"].(map[string]interface{}) { + // USD is Default. + // if NO USD data, accept other currency. + if key == "USD" { + if unitVal != val { + cblogger.Info("filtered by price per unit ", unitVal, priceDimensions["pricePerUnit"]) + return true + } + break + } + } + } + + if hasPriceDimension { + if priceDemensionVal != priceDimensionsKey { // priceId + cblogger.Info("filtered by priceDimension ", priceDemensionVal, priceDimensionsKey) + return true + } + } + return isFiltered +} + +// filter에 걸리면 true +func ReservedPolicyFilter(priceDimensionsKey string, priceDimensionsValue map[string]interface{}, termAttributes map[string]interface{}, sku string, filterList []irs.KeyValue) bool { + isFiltered := false + + hasPricingPolicy := false + pricingPolicyVal := "" + + hasPriceDimension := false + priceDemensionVal := "" + + hasUnit := false + unitVal := "" + + hasLeaseContractLength := false + leaseContractLengthVal := "" + + hasOfferingClass := false + offeringClassVal := "" + + hasPurchaseOption := false + purchaseOptionVal := "" + + if filterList != nil { + + for _, filter := range filterList { + // find filter conditions + if filter.Key == "pricingPolicy" { + hasPricingPolicy = true + pricingPolicyVal = filter.Value + continue + } + + if filter.Key == "pricingId" { + hasPriceDimension = true + priceDemensionVal = filter.Value + continue + } + if filter.Key == "unit" { + hasUnit = true + unitVal = filter.Value + continue + } + if filter.Key == "leaseContractLength" { + hasLeaseContractLength = true + leaseContractLengthVal = filter.Value + continue + } + if filter.Key == "offeringClass" { + hasOfferingClass = true + offeringClassVal = filter.Value + continue + } + if filter.Key == "purchaseOption" { + hasPurchaseOption = true + purchaseOptionVal = filter.Value + continue + } + } + } + + if hasPriceDimension { + if priceDemensionVal != priceDimensionsKey { // priceId + return true + } + } + + if hasPricingPolicy { + if pricingPolicyVal != "Reserved" { + return true + } + } + if hasUnit { + for key, val := range priceDimensionsValue["pricePerUnit"].(map[string]interface{}) { + // USD is Default. + // if NO USD data, accept other currency. + if key == "USD" { + if unitVal != val { + return true + } + break + } + + } + } + + if hasLeaseContractLength { + if leaseContractLengthVal != termAttributes["LeaseContractLength"] { + return true + } + } + + if hasOfferingClass { + if offeringClassVal != termAttributes["OfferingClass"] { + return true + } + } + if hasPurchaseOption { + if purchaseOptionVal != termAttributes["PurchaseOption"] { + return true + } + } + return isFiltered +} diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/RegionZoneHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/RegionZoneHandler.go index 261933228..cdd925bf6 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/RegionZoneHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/RegionZoneHandler.go @@ -5,6 +5,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" + "github.com/davecgh/go-spew/spew" "github.com/aws/aws-sdk-go/service/ec2" @@ -39,7 +40,7 @@ func (regionZoneHandler *AwsRegionZoneHandler) ListRegionZone() ([]*irs.RegionZo } tempclient := ec2.New(sess) - responseZones, err := DescribeAvailabilityZones(tempclient, true) + responseZones, err := DescribeAvailabilityZones(tempclient, false) if err != nil { cblogger.Errorf("AuthFailure on [%s]", *region.RegionName) cblogger.Error(err) @@ -89,7 +90,7 @@ func (regionZoneHandler *AwsRegionZoneHandler) ListRegionZone() ([]*irs.RegionZo } func (regionZoneHandler *AwsRegionZoneHandler) GetRegionZone(Name string) (irs.RegionZoneInfo, error) { - responseRegions, err := DescribeRegions(regionZoneHandler.Client, true, Name) + responseRegions, err := DescribeRegions(regionZoneHandler.Client, false, Name) if err != nil { cblogger.Error(err) return irs.RegionZoneInfo{}, err @@ -97,15 +98,18 @@ func (regionZoneHandler *AwsRegionZoneHandler) GetRegionZone(Name string) (irs.R var regionZoneInfo irs.RegionZoneInfo for _, region := range responseRegions.Regions { + spew.Dump("####################", region.RegionName) sess, err := session.NewSession(&aws.Config{ Region: region.RegionName, + //Region: aws.String("us-west-1"), + }) if err != nil { cblogger.Error(err) } tempclient := ec2.New(sess) - responseZones, err := DescribeAvailabilityZones(tempclient, true) + responseZones, err := DescribeAvailabilityZones(tempclient, false) if err != nil { cblogger.Errorf("AuthFailure on [%s]", *region.RegionName) cblogger.Error(err) @@ -182,7 +186,7 @@ func (regionZoneHandler *AwsRegionZoneHandler) ListOrgZone() (string, error) { } else { tempclient := ec2.New(sess) - responseZones, err := DescribeAvailabilityZones(tempclient, true) + responseZones, err := DescribeAvailabilityZones(tempclient, false) if err != nil { cblogger.Errorf("DescribeAvailabilityZones err %s", *region.RegionName) cblogger.Error(err)