diff --git a/README.md b/README.md index e681d1d..c887a5d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ # plugin-azure-cost-mgmt-cost-datasource + Plugin for collecting Azure Cost management data --- + ## Azure Service Endpoint(in use) +
 https://*.blob.core.windows.net
 https://management.azure.com
@@ -11,14 +14,16 @@ https://login.microsoftonline.com
 
---- + ## Schema Data + *Schema* -- billing_account_id (str): + +- billing_account_id (str): - tenant_id (str): - client_id (str): - client_secret (str): -- customer_tenants (list):(Optional) Customer's tenant id list - +- customer_tenants (list):(Optional) Customer's tenant id list *Example for EA*
@@ -40,7 +45,7 @@ https://login.microsoftonline.com
     "tenant_id": "*****",
     "client_id": "*****",
     "client_secret": "*****"
-    "customer_tenants":
+    "customer_tenants":                #(optional)
         - "*****"
      
 }
@@ -48,4 +53,5 @@ https://login.microsoftonline.com
 
## Options + Currently, not required. \ No newline at end of file diff --git a/docs/en/GUIDE.md b/docs/en/GUIDE.md index e69de29..48483e4 100644 --- a/docs/en/GUIDE.md +++ b/docs/en/GUIDE.md @@ -0,0 +1,86 @@ +# Getting Started + +All the following are executed with the `spacectl` command. +In this guide you will: + +- Register the datasource with Azure credentials + +## Pre-requisites + +- [spacectl](https://github.com/cloudforet-io/spacectl) +- [Azure role assignment for access to ARM API](https://learn.microsoft.com/en-us/azure/cost-management-billing/automate/cost-management-api-permissions#assign-service-principal-access-to-azure-resource-manager-apis) +- Azure credentials for the billing account + +--- + +## Register the datasource with Azure credentials + +Prepare the yaml file for register the datasource with Azure credentials with name `register_azure_csp_datasource.yaml` + +if you are installed cloudforet version `1.12` + +```yaml +data_source_type: EXTERNAL +provider: azure +name: Azure +plugin_info: + plugin_id: plugin-azure-cost-mgmt-cost-datasource + secret_data: + client_id: { client_id } + client_secret: { client_secret } + tenant_id: { tenant_id } + billing_account_id: { billing_account_id } + options: + collect_resource_id: true + upgrade_mode: AUTO +tags: { } +template: { } +``` + +if you are installed cloudforet version `2.0` + +```yaml +data_source_type: EXTERNAL +provider: azure +name: Azure +plugin_info: + schema_id: azure-client-secret-cost-management + plugin_id: plugin-azure-cost-mgmt-cost-datasource + secret_data: + client_id: { client_id } + client_secret: { client_secret } + tenant_id: { tenant_id } + billing_account_id: { billing_account_id } + options: + collect_resource_id: true + upgrade_mode: AUTO + +tags: { } +template: { } +resource_group: DOMAIN +``` + +and execute the following command + +```bash +spacectl exec register cost_analysis.DataSource -f register_azure_csp_datasource.yaml +``` + +## Sync with your Azure Cost Management data + +We synchronize cost data via our scheduler every day at `16:00 UTC`. +If you want to sync immediately, you can use the following command. + +before execute the following command, you must get the `data_source_id` from the previous step. + +```bash +spacectl list cost_analysis.DataSource --minimal +``` + +and execute the following command
+If you are enterprise customer and have huge data, it may take a long time. + +```bash +spacectl exec sync cost_analysis.DataSource -p data_source_id={ data_source_id } +``` + diff --git a/src/cloudforet/cost_analysis/info/cost_info.py b/src/cloudforet/cost_analysis/info/cost_info.py index 0ca0d31..3efc04a 100644 --- a/src/cloudforet/cost_analysis/info/cost_info.py +++ b/src/cloudforet/cost_analysis/info/cost_info.py @@ -4,32 +4,41 @@ from spaceone.core.pygrpc.message_type import * from spaceone.core import utils -__all__ = ['CostInfo', 'CostsInfo'] +__all__ = ["CostInfo", "CostsInfo"] _LOGGER = logging.getLogger(__name__) + def CostInfo(cost_data): try: info = { - 'cost': float(cost_data['cost']), - 'usage_quantity': float(cost_data.get('usage_quantity')), - 'usage_type': cost_data.get('usage_type'), - 'usage_unit': cost_data.get('usage_unit'), - 'provider': cost_data.get('provider'), - 'region_code': cost_data.get('region_code'), - 'product': cost_data.get('product'), - 'billed_date': cost_data['billed_date'], - 'additional_info': change_struct_type(cost_data['additional_info']) if 'additional_info' in cost_data else None, - 'data': change_struct_type(cost_data['data']) if 'data' in cost_data else None, - 'tags': change_struct_type(cost_data['tags']) if 'tags' in cost_data else None + "cost": float(cost_data["cost"]), + "usage_quantity": float(cost_data.get("usage_quantity")), + "usage_type": cost_data.get("usage_type"), + "usage_unit": cost_data.get("usage_unit"), + "provider": cost_data.get("provider"), + "region_code": cost_data.get("region_code"), + "product": cost_data.get("product"), + "billed_date": cost_data["billed_date"], + "additional_info": change_struct_type(cost_data["additional_info"]) + if "additional_info" in cost_data + else None, + "data": change_struct_type(cost_data["data"]) + if "data" in cost_data + else None, + "tags": change_struct_type(cost_data["tags"]) + if "tags" in cost_data + else None, } return cost_pb2.CostInfo(**info) except Exception as e: - _LOGGER.debug(f'[CostInfo] cost data: {cost_data}') - _LOGGER.debug(f'[CostInfo] error reason: {e}', exc_info=True) + _LOGGER.debug(f"[CostInfo] cost data: {cost_data}") + _LOGGER.debug(f"[CostInfo] error reason: {e}", exc_info=True) raise e def CostsInfo(costs_data, **kwargs): - return cost_pb2.CostsInfo(results=list(map(functools.partial(CostInfo, **kwargs), costs_data))) \ No newline at end of file + return cost_pb2.CostsInfo( + results=list(map(functools.partial(CostInfo, **kwargs), costs_data)) + )