Price Info and Cloud Driver API - cloud-barista/cb-spider GitHub Wiki

※ CB-Spider Multi-Cloud Price Information Documentation


Multi-Cloud Price Info Features and Cloud Driver API

◉ CB-Spider Price Info Specification V0.1

[Notice]

※ CB-Spider가 제공하는 모든 가격 정보는 대상 CSP API를 활용하여 제공한다.
  - 가격 및 요금 산정 기준 등에 대한 세부 정보는 CSP가 제공하는 관련 정보를 참고한다.

※ 대상 CSP의 모든 제품에 대한 가격 정보를 제공하지 못할 수도 있다.
  - 이 경우 대상 CSP가 API를 통해서 제공하지 않는 정보일 수도 있고,
  - CB-Spider의 제공 범위가 아닐 수도 있다.
  - 또한, 추상화 과정에서 누락 되었을 수도 있다.

※ API 반환 결과에는 대상 CSP에 따라 일부 정보가 제공 되지 않는 경우가 있다. 
  - 이 경우 'NA'로 표시될 수 있다. (NA: Not Applicable)
  - 이러한 경우는 주로 대상 CSP에게는 과금에 영향을 주지 않는 정보 이거나, 
    - 대상 CSP API로 제공되지 않는 정보일 수 있다.
    - 또한, 추상화 변환 과정에서 누락 되었을 수도 있다.

※ 제공 되는 가격은 실제 제공 받을 수 있는 가격과는 차이가 발생할 수도 있다.
  - 이 경우 대상 CSP가 제공하는 가격 정보 산출 조건 입력이 달라서 발생할 수도 있다.
  - 또한, 프로모션 등의 반영 되지 않은 가격일 수 있다.
  - 따라서, 정밀한 클라우드 예산 계획에 활용 시에는 이러한 오차 가능성을 고려할 필요가 있다.

1. CB-Spider 가격 정보 개요

  • CB-Spider는 연동 대상 클라우드(CSP)가 제공하는 컴퓨팅 인프라의 가격 정보(Price Info)를
    • 동일한 API를 사용하여 동일한 방법으로 제공한다.
    • filter 검색을 제공하며, 검색 결과는 JSON 포맷으로 제공한다.
      • filter 적용 가능한 대상 field는 모든 CSP가 동일하게 제공할 수 있는 field로 제한 된다.
    • 가격을 결정 짓는 조건 및 과금 정책 조건 등
      • 가격 정보 특성 상 CSP가 제공하는 가격 정보에 대한 추상화 및 변환을 최소화 하고,
      • CSP별로 가격 및 과금에 의미 있는 정보는 대상 CSP 원형 정보를 그대로 포함하여 제공한다.
  • 가격 정보 제공 구조
    • CB-Spider가 제공하는 가격 정보 제공 구조는 다음 그림과 같고, 주요 처리 흐름은 다음과 같다.
    • 사용자는 Global Schema View(JSON 구조)를 대상으로 API를 사용하여 filter 기반 질의(G-Query; Global-Query) 요청
    • Driver는 대상 CSP가 제공하는 Local Schema(JSON 구조)를 대상으로 CSP API를 사용하여 질의(L-Query; Local-Query) 요청
    • Driver는 L-Query 질의 결과를 Global Schema View를 준수하는 JSON 구조로 변환하여 제공

2. CB-Spider 가격 정보 제공 대상 서비스 분류(제품 Family or 제품 Category)

  • CB-Spider가 제공하는 가격 정보 제공 대상 제품은 컴퓨팅 인프라 관련 서비스이며,
    • CSP별로 컴퓨팅 인프라 서비스 분류(제품 Family or 제품 Category)는 다를 수 있다.
  • CB-Spider는 대상 CSP API를 이용하여 CSP가 제공하는 제품 Family(Category) 목록을 추출 및 제공하며,
    • AWS 경우 CB-Spider API가 제공하는 제품 Family 예시가 다음과 같다.
      "CPU Credits"
      "Compute Instance (bare metal)"
      "Compute Instance"
      "Data Transfer"
      "Dedicated Host"
      "EBS direct API Requests"
      "Elastic Graphics"
      "Fast Snapshot Restore"
      "Fee"
      "IP Address"
      "Load Balancer"
      "Load Balancer-Application"
      "Load Balancer-Network"
      "NAT Gateway"
      "Provisioned Throughput"
      "Storage Snapshot"
      "Storage"                   // EBS(Data-Disk)
      "System Operation"
      
  • ListProductFamily() API관련:
    • ProductFamily 이름은 CSP가 제공하는 이름을 그대로 제공하며,
    • 제공하는 목록은 현재 Driver가 제공하는 ProductFamily 목록을 제공한다.

3. CB-Spider 가격 정보 구조 및 추상화 개요

  • CB-Spider가 제공하는 가격 정보 주요 구조(JSON 구조)는 그림과 같다.

    • (1) 클라우드 가격 리스트(json:"cloudPriceList")
      • (2) CSP 이름(3) 가격 리스트 정보를 한 세트로 Array 형태로 반복 포함한다.
    • (2) CSP 이름(json:"cloudName")
      • 가격 정보를 포함시킬 대상 CSP 이름(Cloud 이름)
    • (3) 가격 리스트(json:"priceList")
      • (4) 제품 정보(5) 가격 정보를 한 세트로 Array 형태로 반복 포함한다.
    • (4) 제품 정보(json:"productInfo")
      • 제품을 이해할 수 있는 제품 ID, 제공 리전 이름 및 제품의 속성 정보 등을 포함한다.
    • (5) 가격 정보(json:"priceInfo")
      • 가격 정보는 사용자가 선택할 수 있는 여러 종류의 (6) 가격 정책을 포함한다.
    • (6) 가격 정책(json:"pricePolicies")
      • 제품 사용 시 과금 책정 방법 및 비용 등의 정보를 포함한다.
  • CB-Spider 가격 정보 추상화 구조 및 CSP 원본 정보

    • CB-Spider가 제공하는 가격 정보 예시(JSON format)는 다음과 같다.

      {
          "meta": {
              "version": "v0.1",
              "description": "Multi-Cloud Price Info"
          },
          "cloudPriceList": [
              {
                  "cloudName": "AWS",
                  "priceList": [
                      {
                          "productInfo": {
                              "productId": "2223RRAP6Z3VBN3N",
                              "regionName": "us-east-1",
                              "zoneName": "NA",
                              "instanceType": "c5d.2xlarge",
                              "vcpu": "8",
                              "memory": "16 GiB",
                              "storage": "1 x 200 NVMe SSD",
                              "gpu": "2", 
                              "gpuMemory": "NA",
                              "operatingSystem": "RHEL",
                              "preInstalledSw": "SQL Web",
                              "description": "Any helpful information",
                              + "cspProductInfo": { ... }            <=====
                          }, 
                          "priceInfo": {                        
                              "pricingPolicies": [
                                  {
                                      "pricingId": "2223B6PCG6QAUYY6.JRTCKXETXF",
                                      "pricingPolicy": "OnDemand",                                
                                      "unit": "Hrs",
                                      "currency": "USD",
                                      "price" : "0.2773000000",
                                      "description": "$0.2773 per Dedicated Windows with SQL Web c6i.large Instance Hour"
                                  },
                                  {
                                      "pricingId": "2223B6PCG6QAUYY6.7NE97W5U4E",
                                      "pricingPolicy": "Reserved",
                                      "pricingPolicyInfo": {
                                          "LeaseContractLength": "1yr",
                                          "OfferingClass": "convertible",
                                          "PurchaseOption": "No Upfront"
                                      },
                                      "unit": "Hrs",
                                      "currency": "USD",
                                      "price" : "0.2489500000",
                                      "description": "Windows with SQL Server Web (Amazon VPC), c6i.large reserved instance applied"
                                  }
                              ],
                              + "cspPriceInfo": { ... }         <====                            
                          }
                      }
                  ]
              }
          ]
      }
      
    • 예시에 표시된 다음 2가지 정보를 제외한 모든 정보들은 추상화된 정보이다.

      • (1) 제품 정보(productInfo)에 포함된 cspProductInfo: 대상 CSP가 제공하는 제품 관련 원본 정보를 포함(JSON 구조, CSP별 자체 구조 제공)
      • (2) 가격 정보(priceInfo)에 포함된 cspPriceInfo: 대상 CSP가 제공하는 가격 관련 원본 정보를 포함(JSON 구조, CSP별 자체 구조 제공)
    • 추상화된 정보는 모든 CSP에 대해서 가능한 동일한 구조의 정보를 제공하며,

    • 사용자는 추상화된 정보에 대해서만 Filter 검색을 요청할 수있다.

    • CB-Spider JSON 포맷의 AWS 가격 정보 예시(※ AWS 원본 정보 구조는 AWS Driver 개발 시 변경 될 수 있음)

      {
          "meta": {
              "version": "v0.1",
              "description": "Multi-Cloud Price Info"
          },
          "cloudPriceList": [
              {
                  "cloudName": "AWS",
                  "priceList": [
                      {
                          "productInfo": {
                              "productId": "2223RRAP6Z3VBN3N",
                              "regionName": "us-east-1",
                              "zoneName": "NA",
                              "instanceType": "c5d.2xlarge",
                              "vcpu": "8",
                              "memory": "16 GiB",
                              "storage": "1 x 200 NVMe SSD",
                              "gpu": "2", 
                              "gpuMemory": "NA",
                              "operatingSystem": "RHEL",
                              "preInstalledSw": "SQL Web",
                              "description": "Any helpful information",
                              "cspProductInfo": {
                                  "productFamily": "Compute Instance",
                                  "attributes": {
                                      "enhancedNetworkingSupported": "Yes",
                                      "intelTurboAvailable": "Yes",
                                      "memory": "16 GiB",
                                      "dedicatedEbsThroughput": "Up to 2250 Mbps",
                                      "vcpu": "8",
                                      "classicnetworkingsupport": "false",
                                      "capacitystatus": "Used",
                                      "locationType": "AWS Region",
                                      "storage": "1 x 200 NVMe SSD",
                                      "instanceFamily": "Compute optimized",
                                      "operatingSystem": "RHEL",
                                      "intelAvx2Available": "Yes",
                                      "regionCode": "us-east-1",
                                      "physicalProcessor": "Intel Xeon Platinum 8124M",
                                      "clockSpeed": "3 GHz",
                                      "ecu": "39",
                                      "networkPerformance": "Up to 10 Gigabit",
                                      "servicename": "Amazon Elastic Compute Cloud",
                                      "gpuMemory": "NA",
                                      "vpcnetworkingsupport": "true",
                                      "instanceType": "c5d.2xlarge",
                                      "tenancy": "Shared",
                                      "usagetype": "BoxUsage:c5d.2xlarge",
                                      "normalizationSizeFactor": "16",
                                      "intelAvxAvailable": "Yes",
                                      "processorFeatures": "Intel AVX; Intel AVX2; Intel AVX512; Intel Turbo",
                                      "servicecode": "AmazonEC2",
                                      "licenseModel": "No License required",
                                      "currentGeneration": "Yes",
                                      "preInstalledSw": "SQL Web",
                                      "location": "US East (N. Virginia)",
                                      "processorArchitecture": "64-bit",
                                      "marketoption": "OnDemand",
                                      "operation": "RunInstances: 0210",
                                      "availabilityzone": "NA"
                                  },
                                  "sku": "2223RRAP6Z3VBN3N"
                              }
                          }, 
                          "priceInfo": {                        
                              "pricingPolicies": [
                                  {
                                      "pricingId": "2223B6PCG6QAUYY6.JRTCKXETXF",
                                      "pricingPolicy": "OnDemand",                                
                                      "unit": "Hrs",
                                      "currency": "USD",
                                      "price" : "0.2773000000",
                                      "description": "$0.2773 per Dedicated Windows with SQL Web c6i.large Instance Hour"
                                  },
                                  {
                                      "pricingId": "2223B6PCG6QAUYY6.7NE97W5U4E",
                                      "pricingPolicy": "Reserved",
                                      "pricingPolicyInfo": {
                                          "LeaseContractLength": "1yr",
                                          "OfferingClass": "convertible",
                                          "PurchaseOption": "No Upfront"
                                      },
                                      "unit": "Hrs",
                                      "currency": "USD",
                                      "price" : "0.2489500000",
                                      "description": "Windows with SQL Server Web (Amazon VPC), c6i.large reserved instance applied"
                                  }
                              ],
                              "cspPriceInfo": {
                                  "OnDemand": {
                                      "2223B6PCG6QAUYY6.JRTCKXETXF": {
                                          "priceDimensions": {
                                              "2223B6PCG6QAUYY6.JRTCKXETXF.6YS6EN2CT7": {
                                                  "unit": "Hrs",
                                                  "endRange": "Inf",
                                                  "description": "$0.2773 per Dedicated Windows with SQL Web c6i.large Instance Hour",
                                                  "appliesTo": [],
                                                  "rateCode": "2223B6PCG6QAUYY6.JRTCKXETXF.6YS6EN2CT7",
                                                  "beginRange": "0",
                                                  "pricePerUnit": {
                                                      "USD": "0.2773000000"
                                                  }
                                              }
                                          },
                                          "sku": "2223B6PCG6QAUYY6",
                                          "effectiveDate": "2023-11-01T00: 00: 00Z",
                                          "offerTermCode": "JRTCKXETXF",
                                          "termAttributes": {}
                                      }
                                  },
                                  "Reserved": {
                                      "2223B6PCG6QAUYY6.7NE97W5U4E": {
                                          "priceDimensions": {
                                              "2223B6PCG6QAUYY6.7NE97W5U4E.6YS6EN2CT7": {
                                                  "unit": "Hrs",
                                                  "endRange": "Inf",
                                                  "description": "Windows with SQL Server Web (Amazon VPC), c6i.large reserved instance applied",
                                                  "appliesTo": [],
                                                  "rateCode": "2223B6PCG6QAUYY6.7NE97W5U4E.6YS6EN2CT7",
                                                  "beginRange": "0",
                                                  "pricePerUnit": {
                                                      "USD": "0.2489500000"
                                                  }
                                              }
                                          },
                                          "sku": "2223B6PCG6QAUYY6",
                                          "effectiveDate": "2022-04-01T00: 00: 00Z",
                                          "offerTermCode": "7NE97W5U4E",
                                          "termAttributes": {
                                              "LeaseContractLength": "1yr",
                                              "OfferingClass": "convertible",
                                              "PurchaseOption": "No Upfront"
                                          }
                                      },
                                      "2223B6PCG6QAUYY6.4NA7Y494T4": {
                                          "priceDimensions": {
                                              "2223B6PCG6QAUYY6.4NA7Y494T4.6YS6EN2CT7": {
                                                  "unit": "Hrs",
                                                  "endRange": "Inf",
                                                  "description": "Windows with SQL Server Web (Amazon VPC), c6i.large reserved instance applied",
                                                  "appliesTo": [],
                                                  "rateCode": "2223B6PCG6QAUYY6.4NA7Y494T4.6YS6EN2CT7",
                                                  "beginRange": "0",
                                                  "pricePerUnit": {
                                                      "USD": "0.2372200000"
                                                  }
                                              }
                                          },
                                          "sku": "2223B6PCG6QAUYY6",
                                          "effectiveDate": "2022-04-01T00: 00: 00Z",
                                          "offerTermCode": "4NA7Y494T4",
                                          "termAttributes": {
                                              "LeaseContractLength": "1yr",
                                              "OfferingClass": "standard",
                                              "PurchaseOption": "No Upfront"
                                          }
                                      }
                                  }
                              }
                          }
                      }
                  ]
              }
          ]
      }
      
  • 제품 종류별(Product Family or Category 등) productInfo 추상화 정보 구조

    • 제품 Family 대상에 따라 제공되는 정보가 다르며, 그 구조가 다음과 같다.

    • Compute Instance Family(Category) 추상화 정보 구조

      "productInfo": {
          "productId": "2223RRAP6Z3VBN3N",
          "regionName": "us-east-1",
          "zoneName": "NA",
      
          "instanceType": "c5d.2xlarge",
          "vcpu": "8",
          "memory": "16 GiB",
          "storage": "1 x 200 NVMe SSD",
          "gpu": "2", 
          "gpuMemory": "NA",
          "operatingSystem": "RHEL",
          "preInstalledSw": "SQL Web",
      
          "description": "Any helpful information",
          + "cspProductInfo": { ... }            <=====
      }, 
      
    • Storage(Data-Disk) Family(Category) 추상화 정보 구조

      "productInfo": {
          "productId": "2223RRAP6Z3VBN3N",
          "regionName": "us-east-1",
          "zoneName": "NA",
      
          "volumeType": "Magnetic",
          "storageMedia": "HDD-backed",
          "maxVolumeSize": "1 TiB",
          "maxIopsvolume": "40 - 200",
          "maxThroughputvolume": "40 - 90 MB/sec",
      
          "description": "Any helpful information",
          + "cspProductInfo": { ... }            <=====
      }
      
    • 그 외 제품들에 대한 추상화 정보 구조

      "productInfo": {
          "productId": "2223RRAP6Z3VBN3N",
          "regionName": "us-east-1",
          "zoneName": "NA",
          "description": "Any helpful information",
          + "cspProductInfo": { ... }            <=====
      }, 
      
  • API Filter 규격/조건

    • 가격 정보를 제공하는 API는 인자로 Filter 설정을 제공한다.
    • Filter는 KeyValue Array로 설정할 수 있으며, (Strict Match)
    • API는 Array에 포함된 KeyValue 조건을 모두 만족(AND Condition)하는 가격 정보를 제공한다.
    • Filter는 모든 CSP에 적용하기 위해서 추상화된 Field(Key)에만 적용 가능하다.

4. Price Info Driver Common API

  • Source Tree

    $tree cb-spider/cloud-control-manager/cloud-driver/interfaces/
    cb-spider/cloud-control-manager/cloud-driver/interfaces/
    |-- CloudDriver.go
    |-- README.md
    |-- connect
    |   `-- CloudConnect.go
    `-- resources
        |-- AnyCallHandler.go
        |-- ClusterHandler.go
        |-- DiskHandler.go
        |-- IId.go
        |-- ImageHandler.go
        |-- KeyPairHandler.go
        |-- KeyValue.go
        |-- MyImageHandler.go
        |-- NLBHandler.go
        |-- PriceInfoHandler.go    <================= Price Info Driver API
        |-- RegionZoneHandler.go
        |-- SecurityHandler.go
        |-- VMHandler.go
        |-- VMSpecHandler.go
        `-- VPCHandler.go
    
    
  • Driver API Spec (latest)

          // Cloud Driver Interface of CB-Spider.
          // The CB-Spider is a sub-Framework of the Cloud-Barista Multi-Cloud Project.
          // The CB-Spider Mission is to connect all the clouds with a single interface.
          //
          //      * Cloud-Barista: https://github.com/cloud-barista
          //
          // This is Resouces interfaces of Cloud Driver.
          //
          // by CB-Spider Team, 2023.11.
    
          package resources
    
          type CloudPriceData struct {
                  Meta           Meta         `json:"meta"`
                  CloudPriceList []CloudPrice `json:"cloudPriceList"`
          }
    
          type Meta struct {
                  Version     string `json:"version"`
                  Description string `json:"description"`
          }
    
          type CloudPrice struct {
                  CloudName string  `json:"cloudName"`
                  PriceList []Price `json:"priceList"`
          }
    
          type Price struct {
                  ProductInfo ProductInfo `json:"productInfo"`
                  PriceInfo   PriceInfo   `json:"priceInfo"`
          }
    
          type ProductInfo struct {
                  ProductId  string `json:"productId"`
                  RegionName string `json:"regionName"`
                  ZoneName   string `json:"zoneName"`
    
                  //--------- Compute Instance
                  InstanceType    string `json:"instanceType,omitempty"`
                  Vcpu            string `json:"vcpu,omitempty"`
                  Memory          string `json:"memory,omitempty"`
                  Storage         string `json:"storage,omitempty"`        // Root-Disk
                  Gpu             string `json:"gpu,omitempty"`
                  GpuMemory       string `json:"gpuMemory,omitempty"`
                  OperatingSystem string `json:"operatingSystem,omitempty"`
                  PreInstalledSw  string `json:"preInstalledSw,omitempty"`
                  //--------- Compute Instance
    
                  //--------- Storage  // Data-Disk(AWS:EBS)
                  VolumeType          string `json:"volumeType,omitempty"`
                  StorageMedia        string `json:"storageMedia,omitempty"`
                  MaxVolumeSize       string `json:"maxVolumeSize,omitempty"`
                  MaxIOPSVolume       string `json:"maxIopsvolume,omitempty"`
                  MaxThroughputVolume string `json:"maxThroughputvolume,omitempty"`
                  //--------- Storage. // Data-Disk(AWS:EBS)
    
                  Description    string      `json:"description"`
                  CSPProductInfo interface{} `json:"cspProductInfo"`
          }
    
          type PriceInfo struct {
                  PricingPolicies []PricingPolicies `json:"pricingPolicies"`
                  CSPPriceInfo    interface{}       `json:"cspPriceInfo"`
          }
    
          type PricingPolicies struct {
                  PricingId         string             `json:"pricingId"`
                  PricingPolicy     string             `json:"pricingPolicy"`
                  Unit              string             `json:"unit"`
                  Currency          string             `json:"currency"`
                  Price             string             `json:"price"`
                  Description       string             `json:"description"`
                  PricingPolicyInfo *PricingPolicyInfo `json:"pricingPolicyInfo,omitempty"`
          }
    
          type PricingPolicyInfo struct {
                  LeaseContractLength string `json:"LeaseContractLength"`
                  OfferingClass       string `json:"OfferingClass"`
                  PurchaseOption      string `json:"PurchaseOption"`
          }
    
          type PriceInfoHandler interface {
                  ListProductFamily(regionName string) ([]string, error)
                  GetPriceInfo(productFamily string, regionName string, filterList []KeyValue) (string, error) // return string: json format
          }
    
    

5. CB-Spider 가격 정보 API 활용 순서

  • 사용자의 단순 API 호출에도 내부에서 많은 가격 정보에 대한 변환으로 인한 높은 부하가 매번 발생하므로,
  • 일단, 가격 정보 제공하는 API는 대상 제품 Family(Category)와 대상 Region을 필수 입력 인자로 받는다.
  1. ListProductFamily() API를 통해서 product family(category) 목록을 얻고, 원하는 대상 제품 family를 선택한다.
  2. 가격 정보를 원하는 대상 Region을 선택한다. 필요시 Spider RegionZone API 활용한다.
  3. 선택한 product family 정보와 Region 이름 그리고, 필요시 Filter를 설정하여 가격 정보 API를 호출한다.
  4. 반환된 결과 JSON 구조를 보고 Filter를 개선하여 재 요청하여 반환 결과의 품질을 향상 시킨다.

Cloud Driver 개발 가이드

  • Cloud Driver 1차 개발 대상

    • AWS
    • GCP
    • Alibaba
    • Tencent
    • Azure
    • IBM VPC
    • NCP Classic
    • NCP VPC
    • 제외 CSP(분석 정보 참고)
      • OpenStack: 기능을 제공하지 않음
      • NHN, KT Classic, KT VPC: API를 제공하지 않음
  • CB-Spider의 가격 정보 JSON 구조는 기본적으로 AWS가 제공하는 JSON 구조를 많이 참고 및 반영하였습니다.

    • 사유: 가장 잘 정의되어 있고, AWS의 경우 제공하는 정보 수가 많아서 가급적 변환 부하 최소화 고려
    • 하지만, 타 CSP들의 정보들도 표현이 되어야 하므로,
    • 위에서 보이는 가격 정보 구조와 같이 약한 추상화와 주요 정보에 대해서는 CSP 원본 정보를 포함시켜서,
    • 사용자가 API 및 API 결과를 익숙해가면서 필요한 정보를 잘 활용할 수 있도록 설계 하였습니다.
  • 제품 정보 추상화의 경우 대상 CSP에서는 유용한 정보인데 추상화된 Field(Key)가 없을 경우에는

    • description field에 추가해주시기 바랍니다.
    • 여러가지가 있을 경우 comma 등으로 추가해주시기 바랍니다.
    • 사용자가 검색 결과에서 활용하기 위함입니다.
  • Key(Field) 이름은 가급적 camelCase 준수해 주시기 바랍니다.

    • 소문자로 시작, 2단어 이상일 경우 2번째 단어부터 첫글자 대문자
    • 예시: serviceName 등
    • 예외: CSP 원본 정보를 그대로 추가하는 cspProductInfocspPriceInfo에 포함되는 경우
  • 드라이버 내부 변환 시에는 가급적 향후 변경될만한 정보는 static하게 채우지 마시고, API로 얻은 값을 활용해 주시기 바랍니다.

    • 사유: 가격 제공 정보는 변경될 확률이 많음, static하게 직접 입력시 향후에 잘못된 정보를 제공할 수 있음. 가격 관련 잘못된 정보는 민감할 수 있음
    • 예시: productFamily 목록, API로 얻은 정보에서 추출하여 제공, product family가 추가 및 변경 될 수 있음
  • 대상 CSP의 경우 적절한 값이 없는 경우 NA로 표시(N/A 아님)

  • AWS가 아닌 CSP의 경우 추상화 구조에 입력 되는 값 변환 시에 가이드 되지 않은 값 들은

    • 가급적 AWS 기준으로 적용해주시기 바랍니다. (예: GB => GiB)
    • 관련하여, aws cli 및 price 정보를 이용한 AWS 가격 정보 활용 예시들 입니다. 필요시 참고하시기 바랍니다.
      # sku 값이 2223B6PCG6QAUYY6인 모든 product 중 1개 출력
      aws pricing get-products --max-results 1 --service-code AmazonEC2 --filters Type=TERM_MATCH,Field=sku,Value=2223B6PCG6QAUYY6 | jq '.PriceList[] | fromjson'
      
      # sku 값이 2223B6PCG6QAUYY6인 모든 product 출력 => 1개임
      aws pricing get-products --service-code AmazonEC2 --filters Type=TERM_MATCH,Field=sku,Value=2223B6PCG6QAUYY6 | jq '.PriceList[] | fromjson'
      
      # "CPU Credits" 제품 가격 정보 (Reserved 가격 정책이 없음)
      aws pricing get-products --service-code AmazonEC2 --filters Type=TERM_MATCH,Field=productFamily,Value="CPU Credits" | jq '.PriceList[] | fromjson'
      
      # "Load Balancer" 제품 가격 정보 (Reserved 가격 정책이 없음)
      aws pricing get-products --service-code AmazonEC2 --filters Type=TERM_MATCH,Field=productFamily,Value="Load Balancer" | jq '.PriceList[] | fromjson'
      
      # "Load Balancer"를 제공하는 Region 수 => 26
      aws pricing get-products --service-code AmazonEC2 --filters Type=TERM_MATCH,Field=productFamily,Value="Load Balancer" | jq '.PriceList[] | fromjson' | grep regionCode | sort | uniq |wc -l
      26
      
      # "Data Transfer" product 5개 출력
       aws pricing get-products --max-results 5 --service-code AmazonEC2 --filters Type=TERM_MATCH,Field="productFamily",Value="Data Transfer" | jq '.PriceList[] | fromjson'
      
          # 제공되는 모든 product family list: 모든 EC2 가격 정보 다운로드 후 활용 가능
            (※ 주의: download 내용이 aws cli로 얻었을 때와 대소문자 구분 및 field 이름이 다른(복수) 경우가 있음)
      $ wget https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/index.json
          $ grep productFamily index.json | sort | uniq
      # 사용되는 unit 값들 확인: 'Hours'와 'Hrs'가 혼용
      $ grep unit index.json | sort | uniq
          # 계약 기간 종류 확인 : '1 yr'과 '1yr'과 같이 space가 포함, 미포함이 혼용
          $ grep LeaseContractLength index.json | sort | uniq
      
      # S3 제품 및 가격 정보 출력
      $ aws pricing get-products --max-results 5 --service-code AmazonS3 --filters "Type=TERM_MATCH,Field=location,Value='US East (N. Virginia)'" | jq '.PriceList[] | fromjson'
      
      # S3 Product Family 출력
      $ aws pricing get-products --service-code AmazonS3 --filters "Type=TERM_MATCH,Field=location,Value='US East (N. Virginia)'" | jq '.PriceList[] | fromjson' |grep productFamily |sort |uniq
                "productFamily": "API Request",
                "productFamily": "Fee",
                "productFamily": "Storage",
      
  • API 호출 비용 및 QPS(Query/Sec)고려하여

    • 가급적, 최소 횟수의 CSP API 호출 개발 필요(호출 결과 반복 사용 등)
  • 통화(currency) 관련

    • 기본적으로 USD 값으로만 제공
    • 대상 CSP가 USD 값 획득 불가시,
      • CSP가 제공하는 default 통화 정보로 제공(환율 적용한 변환 금지)
  • Driver Price Info Interface에 포함된 Struct들은 드라이버 내부에서 필요시 활용하시기 바랍니다.

    • 검증이 100%된 struct들이 아니어서, 활용에 문제가 있으면 이슈 신고 부탁 드립니다.
    • struct은 안쓰셔도, 반환 정보를 위에서 제공해드린 JSON 구조로 반환해주시면 되겠습니다.
  • 아마도, 변환 과정이 포함되어 API 소요 시간이 오래 걸릴 걸로 예상됩니다.

    • Driver 개발 진행 시에 1분 이상 소요 되는 경우 공유 부탁 드립니다.
  • 아마도, AWS 외에 CSP들의 경우 가격 정보 구조가 다르거나 변환이 모호한 부분이 있을 거라 생각합니다.

    • Driver 개발 진행 시에 관련된 정보나 이슈를 공유해주시면 함께 고민해보도록하겠습니다.

[Filter Test Case 및 Filter에 따른 예상 결과]

  • Filter 적용 조건 및 결과에 대한 명확한 이해를 위해서 Mock Driver 기반 시험 케이스를 추가했습니다.
    • 위치: cb-spider/cloud-control-manager/cloud-driver/drivers/mock/test/priceinfo_test.go
    • 시험 항목: Compute Instance, Storage, Network Load Balance 3종의 Product Family에 대한 Filter 적용 시험
    • 모든 product family 시험 실행 방법:
      • json 결과 출력을 원할 때: ./test-v-log-info-priceinfo_test.go.sh
      • 간단히 시험 로그만 출력을 원할 때: ./test-v-log-error-priceinfo_test.go.sh
    • Compute Instance 시험만 실행 방법:
      • json 결과 출력을 원할 때: ./test-v-log-info-priceinfo_compute_instance_test.go.sh
      • 간단히 시험 로그만 출력을 원할 때: ./test-v-log-error-priceinfo_compute_instance_test.go.sh
  • Filter 조건은 결과 json의 cloudPriceList.priceList에 포함될 제품/가격정책 즉, {productInfo, priceInfo}을 결정하며,
    • GetPriceInfo() 제공하는 결과는 filter 조건을 만족하는 결과가 없을 경우에도 다음과 같은
      • empty cloudPriceList를 포함하는 Json을 반환한다.
      {
          "meta": {
              "version": "v0.1",
              "description": "Multi-Cloud Price Info"
          },
          "cloudPriceList": []
      } 
      
      • filter 조건을 만족하는 제품/가격정책이 존재하는 경우 동일 구조의 Json에 cloudPriceList에 배열 형태로 포함되어,
      • GetPriceInfo() API 결과는 본 가이드에서 제안하고 있는 하나의 json 문자열로 반환된다.
  • Filter Test Case 및 예상 결과(예상 결과는 CSP별로 다를 수 있으며, CSP별로 개별 검증이 필요)
    • Driver 배포 전 다음과 같은 최소 6 종류의 Filter Test 자체 검증 필요

      • CSP별로 filter 조건이 다를 수도 있으며, filter 결과로 포함되는 제품/가격정책 갯수가 다를 수 있음
    • (1) filter가 nil 일때: 전체 제품/가격정책 포함한 출력

      • ex) handler.GetPriceInfo(productFamily, regionName, nil)
    • (2) filter가 Empty Array 일때: 전체 제품/가격정책 포함한 출력 (nil일 경우와 동일)

      • ex) handler.GetPriceInfo(productFamily, regionName, []irs.KeyValue{})
    • (3) productId key와 value 설정: Key-Value 값과 동일한 field를 포함하는 제품/가격정책을 포함한 출력

      • ex) handler.GetPriceInfo(productFamily, regionName, []irs.KeyValue{{Key: "productId", Value: "mock.enhnace1.mercury"}})
    • (4) product 정보와 관련된 key와 value 설정: Key-Value 값과 동일한 field를 포함하는 제품/가격정책을 포함한 출력

      • ex) handler.GetPriceInfo(productFamily, regionName, []irs.KeyValue{{Key: "vcpu", Value: "8"}})
    • (5) 존재하지 않는 key 설정: 제품/가격정책을 포함하지 않는 빈 cloudPriceList를 포함하는 결과 출력

      • ex) handler.GetPriceInfo(productFamily, regionName, []irs.KeyValue{{Key: "noField", Value: "mock.enhnace1.mercury"}})
    • (6) price policy key와 value 설정: Key-Value 값과 동일한 제품/가격정책을 포함한 출력

      • ex) handler.GetPriceInfo(productFamily, regionName, []irs.KeyValue{{Key: "pricingPolicy", Value: "OnDemand"}})
    • (7) lease contract length key와 value 설정: Key-Value 값과 동일한 제품/가격정책을 포함한 출력

      • ex) handler.GetPriceInfo(productFamily, regionName, []irs.KeyValue{{Key: "LeaseContractLength", Value: "1 Year"}})

[Price Info Mock Driver 참고] Json Struct 기반 개발/변환 등 예시

  • PriceInfo Driver Interface에 포함된 Go Struct을 활용한 Price Info 변환을 처리하는 드라이버 개발 예시입니다.

  • 실제 CSP 드라이버는 훨씬 복잡하고 이슈가 많겠지만, 필요시 기본 골격 또는 처리 기준 정도를 참고해주시기 바랍니다.

  • Mock 드라이버에서는 제품 및 가격 정보를 다음 위치에 file로 저장된 정보를 활용하여 에뮬레이션 하고 있습니다.

  • 위 파일 정보를 CSP의 raw 가격 정보처럼 활용해서 Spider Price Info(Global view json)로 맵핑(변환)하고 있습니다.

    • 주요 맵핑 방법:

      • (1) Mock CSP가 제공하는 가격 정보의 Json 구조(Local view)를 local Go struct으로 파싱(Json 구조의 Object-tree 형태)
      • (2) (1)의 파싱된 객체 트리를 이용하여 Spider Price info Json 구조(Global view)를 준수하는 global Go struct(Driver interface에 포함) 객체 트리로 맵핑/변환
      • (3) (2) 과정에서 맵핑/변환은 product 및 pricePolicy 단위로 처리 되며, 각 단위 처리 과정에서 유효한 filter 정보가 존재할 경우,
        • filter를 만족하는 경우에만 현재 처리 중인 productpricePolicy
        • (2)의 global Go struct 객체 트리(최종 결과가 될)의 cloudPriceList.priceList에 추가
      • product 및 pricePolicy 맵핑이 완료된 후 최종적으로는 global Go struct 객체 트리로 부터 전체 json string 결과를 얻을 수 있습니다.
        • 코드내 다음 부분 참고: globalJsonData, err := json.MarshalIndent(gPriceInfo, "", " ")
      • 실제로는 좀더 복잡하지만, 모든 내용을 정리하기가 쉽지는 않네요.☺︎
    • 세부 내용: Price Info Driver GetPriceInfo() 구현 부분 참고

[CB-Spider Price Info Rest API 활용 참고]

  • REST API 규격: CCTM v0.8.2
  • curl 활용 예시
    • List ProductFamily

      curl -sX GET "http://localhost:1024/spider/productfamily/mercury?ConnectionName=mock-config-01" | json_pp
      
      {
         "productfamily" : [
            "Compute Instance",
            "Storage",
            "Network Load Balancer"
         ]
      }
      
    • Get PriceInfo (no Filter)

      curl -sX GET "http://localhost:1024/spider/priceinfo/Compute%20Instance/mercury?ConnectionName=mock-config-01" | jq -r
      
      {
        "meta": {
          "version": "v0.1",
          "description": "Multi-Cloud Price Info"
        },
        "cloudPriceList": [
          {
            "cloudName": "Mock",
            "priceList": [
              {
                "productInfo": {
                  "productId": "mock.enhnace1.mercury",
                  "regionName": "mercury",
                  "zoneName": "NA",
                  "instanceType": "mock.enhnace1",
                  "vcpu": "8",
      
                  ... 중략 ...
      
    • Get PriceInfo (W/ Filter)

      curl -sX GET "http://localhost:1024/spider/priceinfo/Compute%20Instance/mercury?ConnectionName=mock-config-01" \
         -H 'Content-Type: application/json' \
         -d '{
            "FilterList": [{"Key":"vcpu", "Value":"8"}
            ]
          }' \
         | jq -r
      
      {
        "meta": {
          "version": "v0.1",
          "description": "Multi-Cloud Price Info"
        },
        "cloudPriceList": [
          {
            "cloudName": "Mock",
            "priceList": [
              {
                "productInfo": {
                  "productId": "mock.enhnace1.mercury",
                  "regionName": "mercury",
                  "zoneName": "NA",
                  "instanceType": "mock.enhnace1",
                  "vcpu": "8",
      
                  ... 중략 ...
      
  • Filter Test Case에 대한 curl Test 예시(결과 생략)
    • (1) filter가 nil 일때: 전체 제품/가격정책 포함한 출력

    • (2) filter가 Empty Array 일때: 전체 제품/가격정책 포함한 출력 (nil일 경우와 동일)

    • => (1), (2) Case는 no Filter 요청 시험

      curl -sX GET "http://localhost:1024/spider/priceinfo/Compute%20Instance/mercury?ConnectionName=mock-config-01" | jq -r
      
    • (3) productId key와 value 설정: Key-Value 값과 동일한 field를 포함하는 제품/가격정책을 포함한 출력

      curl -sX GET "http://localhost:1024/spider/priceinfo/Compute%20Instance/mercury?ConnectionName=mock-config-01" \
           -H 'Content-Type: application/json' \
           -d '{
                 "FilterList": [
                   {"Key":"productId", "Value":"mock.enhnace1.mercury"}
                 ]
               }' \
           | jq -r
      
    • (4) product 정보와 관련된 key와 value 설정: Key-Value 값과 동일한 field를 포함하는 제품/가격정책을 포함한 출력

      curl -sX GET "http://localhost:1024/spider/priceinfo/Compute%20Instance/mercury?ConnectionName=mock-config-01" \
           -H 'Content-Type: application/json' \
           -d '{
              "FilterList": [{"Key":"vcpu", "Value":"8"}
              ]
            }' \
           | jq -r
      
    • (5) 존재하지 않는 key 설정: 제품/가격정책을 포함하지 않는 빈 cloudPriceList를 포함하는 결과 출력

      curl -sX GET "http://localhost:1024/spider/priceinfo/Compute%20Instance/mercury?ConnectionName=mock-config-01" \
           -H 'Content-Type: application/json' \
           -d '{
              "FilterList": [{"Key":"noField", "Value":"mock.enhnace1.mercury"}
              ]
            }' \
           | jq -r
      
    • (6) price policy key와 value 설정: Key-Value 값과 동일한 제품/가격정책을 포함한 출력

      curl -sX GET "http://localhost:1024/spider/priceinfo/Compute%20Instance/mercury?ConnectionName=mock-config-01" \
           -H 'Content-Type: application/json' \
           -d '{
              "FilterList": [{"Key":"pricingPolicy", "Value":"OnDemand"}
              ]
            }' \
           | jq -r
      
    • (7) lease contract length key와 value 설정: Key-Value 값과 동일한 제품/가격정책을 포함한 출력

      curl -sX GET "http://localhost:1024/spider/priceinfo/Compute%20Instance/mercury?ConnectionName=mock-config-01" \
           -H 'Content-Type: application/json' \
           -d '{
              "FilterList": [{"Key":"LeaseContractLength", "Value":"1 Year"}
              ]
            }' \
           | jq -r