2
0

pricesheetclient.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package azure
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "net/url"
  8. "time"
  9. "github.com/Azure/azure-sdk-for-go/sdk/azcore"
  10. "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
  11. armruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime"
  12. "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
  13. "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
  14. "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
  15. )
  16. const (
  17. moduleName = "armconsumption"
  18. moduleVersion = "v1.0.0"
  19. )
  20. // At the moment the consumption pricesheet download API is not a)
  21. // documented or b) supported by the SDK. This is an implementation of
  22. // a client in the style of the Azure go SDK - once the API is
  23. // supported this will be removed.
  24. // PriceSheetClient contains the methods for the PriceSheet group.
  25. // Don't use this type directly, use NewPriceSheetClient() instead.
  26. type PriceSheetClient struct {
  27. host string
  28. billingAccountID string
  29. pl runtime.Pipeline
  30. }
  31. // NewPriceSheetClient creates a new instance of PriceSheetClient with the specified values.
  32. // billingAccountId - Azure Billing Account ID.
  33. // credential - used to authorize requests. Usually a credential from azidentity.
  34. // options - pass nil to accept the default values.
  35. func NewPriceSheetClient(billingAccountID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*PriceSheetClient, error) {
  36. if options == nil {
  37. options = &arm.ClientOptions{}
  38. }
  39. ep := cloud.AzurePublic.Services[cloud.ResourceManager].Endpoint
  40. if c, ok := options.Cloud.Services[cloud.ResourceManager]; ok {
  41. ep = c.Endpoint
  42. }
  43. pl, err := armruntime.NewPipeline(moduleName, moduleVersion, credential, runtime.PipelineOptions{}, options)
  44. if err != nil {
  45. return nil, err
  46. }
  47. client := &PriceSheetClient{
  48. billingAccountID: billingAccountID,
  49. host: ep,
  50. pl: pl,
  51. }
  52. return client, nil
  53. }
  54. // BeginDownloadByBillingPeriod - requests a pricesheet for a specific billing period `yyyymm`.
  55. // Returns a Poller that will provide the download URL when the pricesheet is ready.
  56. // If the operation fails it returns an *azcore.ResponseError type.
  57. // Generated from API version 2022-06-01
  58. // billingPeriodName - Billing Period Name `yyyymm`.
  59. func (client *PriceSheetClient) BeginDownloadByBillingPeriod(ctx context.Context, billingPeriodName string) (*runtime.Poller[PriceSheetClientDownloadResponse], error) {
  60. resp, err := client.downloadByBillingPeriodOperation(ctx, billingPeriodName)
  61. if err != nil {
  62. return nil, err
  63. }
  64. return runtime.NewPoller[PriceSheetClientDownloadResponse](resp, client.pl, nil)
  65. }
  66. type PriceSheetClientDownloadResponse struct {
  67. ID string `json:"id"`
  68. Name string `json:"name"`
  69. StartTime time.Time `json:"startTime"`
  70. EndTime time.Time `json:"endTime"`
  71. Status string `json:"status"`
  72. Properties PriceSheetClientDownloadProperties `json:"properties"`
  73. }
  74. type PriceSheetClientDownloadProperties struct {
  75. DownloadURL string `json:"downloadUrl"`
  76. ValidTill string `json:"validTill"`
  77. }
  78. func (client *PriceSheetClient) downloadByBillingPeriodOperation(ctx context.Context, billingPeriodName string) (*http.Response, error) {
  79. req, err := client.downloadByBillingPeriodCreateRequest(ctx, billingPeriodName)
  80. if err != nil {
  81. return nil, err
  82. }
  83. resp, err := client.pl.Do(req)
  84. if err != nil {
  85. return nil, err
  86. }
  87. if !runtime.HasStatusCode(resp, http.StatusOK, http.StatusAccepted) {
  88. return nil, runtime.NewResponseError(resp)
  89. }
  90. return resp, nil
  91. }
  92. const downloadByBillingPeriodTemplate = "/providers/Microsoft.Billing/billingAccounts/%s/billingPeriods/%s/providers/Microsoft.Consumption/pricesheets/download"
  93. // downloadByBillingPeriodCreateRequest creates the DownloadByBillingPeriod request.
  94. func (client *PriceSheetClient) downloadByBillingPeriodCreateRequest(ctx context.Context, billingPeriodName string) (*policy.Request, error) {
  95. if client.billingAccountID == "" {
  96. return nil, errors.New("parameter client.billingAccountID cannot be empty")
  97. }
  98. if billingPeriodName == "" {
  99. return nil, errors.New("parameter billingPeriodName cannot be empty")
  100. }
  101. urlPath := fmt.Sprintf(downloadByBillingPeriodTemplate, url.PathEscape(client.billingAccountID), url.PathEscape(billingPeriodName))
  102. req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
  103. if err != nil {
  104. return nil, err
  105. }
  106. reqQP := req.Raw().URL.Query()
  107. reqQP.Set("api-version", "2022-06-01")
  108. reqQP.Set("ln", "en")
  109. req.Raw().URL.RawQuery = reqQP.Encode()
  110. req.Raw().Header["Accept"] = []string{"*/*"}
  111. return req, nil
  112. }