add_azure_account_and_set_role_assignment.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import numpy as np
  2. import boto3
  3. import requests
  4. import sys
  5. import json
  6. import time
  7. import uuid
  8. """
  9. To run this you use python add_azure_account.py <CloudCheckrApiKey> <NameOfCloudCheckrAccount> <AzureDirectoryId> <AzureSubscriptionId> <AzureAdminApplicationId> <AzureAdminApplicationSecret> <AzureCloudCheckrApplicationName> <AzureCloudCheckrApplicationSecret>
  10. To run this are the following input parameters cloudcheckr-admin-api-key unique-account-name-in-cloudcheckr azure-active-directory-id azure-subscription-id azure-admin-application-id azure-admin-application-secret
  11. The CloudCheckr admin api key is a 64 character string.
  12. The CloudCheckr Account name is the name of the new account in CloudCheckr.
  13. The azure-active-directory-id is the GUID directory id. This will generally be the same for all subscriptions that have the same parent. (Parent being their associated CSP or EA account that contains cost data)
  14. The azure-subscription-id is the GUID that corresponds to the id of the subscription. This subscription will be different for every account that is added to CloudCheckr.
  15. The azure-admin-application-id is the GUID id of the application that was created previously that has admin permissions. It needs to be able to set application role assignments for the specified subscriptoin. It needs to be able to read from the Microsoft Graph API with Application.Read.All, Application.ReadWrite.All, Directory.Read.All permissions.
  16. The azure-application-secret is the secret key that was created previously for the application with admin permissions. This is shown only once when generating the key. It can last 1 year, 2 years, or forever.
  17. The azure-cloudcheckr-application-name is the name of the application that was created specifically for CloudCheckr. It will get the reader role assigned to it.
  18. The azure-cloudcheckr-application-secret is the secret key that was created previously for the CloudCheckr application. This is shown only once when generating the key. It can last 1 year, 2 years, or forever.
  19. """
  20. def create_azure_account(env, CloudCheckrApiKey, account_name, AzureDirectoryId, AzureCloudCheckrApplicationId,
  21. AzureCloudCheckrApplicationSecret, AzureSubscriptionId):
  22. """
  23. Creates an Azure Account in CloudCheckr. It will populate it with azure subscription credentials that were provided.
  24. """
  25. api_url = env + "/api/account.json/add_azure_inventory_account"
  26. add_azure_account_info = json.dumps(
  27. {"account_name": account_name, "azure_ad_id": AzureDirectoryId, "azure_app_id": AzureCloudCheckrApplicationId,
  28. "azure_api_access_key": AzureCloudCheckrApplicationSecret, "azure_subscription_id": AzureSubscriptionId})
  29. r7 = requests.post(api_url, headers={"Content-Type": "application/json", "access_key": CloudCheckrApiKey},
  30. data=add_azure_account_info)
  31. print(r7.json())
  32. def get_azure_reader_role_id(AzureApiBearerToken, AzureSubscriptionId):
  33. """
  34. Gets the id of the reader role for this subscription.
  35. https://docs.microsoft.com/en-us/rest/api/authorization/roleassignments/list
  36. """
  37. api_url = "https://management.azure.com/subscriptions/" + AzureSubscriptionId + "/providers/Microsoft.Authorization/roleDefinitions?api-version=2015-07-01&$filter=roleName eq 'Reader'"
  38. authorization_value = "Bearer " + AzureApiBearerToken
  39. response = requests.get(api_url, headers={"Authorization": authorization_value})
  40. if "value" in response.json():
  41. value = (response.json()["value"])[0]
  42. if "id" in value:
  43. return value["id"]
  44. print("Failed to get the Azure Reader Role Id")
  45. return None
  46. def get_azure_cloudcheckr_service_principal_id(AzureGraphApiBearerToken, AzureCloudCheckrApplicationName):
  47. """
  48. Gets the service principal id Azure Application that was specifically created for CloudCheckr.
  49. Note: This is not the application id. The service principal id is required for the role assignment.
  50. This uses the microsoft Graph API.
  51. https://docs.microsoft.com/en-us/graph/api/serviceprincipal-list?view=graph-rest-1.0&tabs=http
  52. """
  53. api_url = "https://graph.microsoft.com/v1.0/servicePrincipals?$filter=displayName eq '" + AzureCloudCheckrApplicationName + "'"
  54. authorization_value = "Bearer " + AzureGraphApiBearerToken
  55. response = requests.get(api_url, headers={"Authorization": authorization_value})
  56. if "value" in response.json():
  57. value = (response.json()["value"])[0]
  58. if ("id" in value) and ("appId" in value):
  59. return value["id"], value["appId"]
  60. print("Failed to get the Azure CloudCheckr Application Service principal Id")
  61. return None
  62. def set_azure_cloudcheckr_application_service_assignment(AzureApiBearerToken, AzureReaderRoleId,
  63. AzureCloudCheckrApplicationServicePrincipalId,
  64. AzureSubscriptionId):
  65. """
  66. Sets the previously created CloudCheckr application to have a reader role assignment.
  67. https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-rest
  68. """
  69. RoleAssignmentId = str(uuid.uuid1())
  70. api_url = "https://management.azure.com/subscriptions/" + AzureSubscriptionId + "/providers/Microsoft.Authorization/roleAssignments/" + RoleAssignmentId + "?api-version=2015-07-01"
  71. authorization_value = "Bearer " + AzureApiBearerToken
  72. role_assignment_data = json.dumps({"properties": {"principalId": AzureCloudCheckrApplicationServicePrincipalId,
  73. "roleDefinitionId": AzureReaderRoleId}})
  74. response = requests.put(api_url, headers={"Authorization": authorization_value, "Content-Type": "application/json"},
  75. data=role_assignment_data)
  76. print(response.json())
  77. if "properties" in response.json():
  78. properties = response.json()["properties"]
  79. if "roleDefinitionId" in properties:
  80. return properties["roleDefinitionId"]
  81. print("Failed to set role assignment for the CloudCheckr Application to the specified subscription")
  82. return None
  83. def get_azure_bearer_token(resource_url, azure_directory_id, azure_admin_application_id,
  84. azure_admin_application_secret):
  85. """
  86. Uses OAuth 2.0 to get the bearer token based on the client id and client secret.
  87. """
  88. api_url = "https://login.microsoftonline.com/" + azure_directory_id + "/oauth2/token"
  89. client = {'grant_type': 'client_credentials',
  90. 'client_id': azure_admin_application_id,
  91. 'client_secret': azure_admin_application_secret,
  92. 'resource': resource_url,
  93. }
  94. response = requests.post(api_url, data=client)
  95. if "access_token" in response.json():
  96. return response.json()["access_token"]
  97. print("Could not get Bearer token")
  98. return None
  99. def main():
  100. try:
  101. CloudCheckrApiKey = str(sys.argv[1])
  102. except IndexError:
  103. print("Must include an admin api key in the command line")
  104. return
  105. try:
  106. NameOfCloudCheckrAccount = str(sys.argv[2])
  107. except IndexError:
  108. print("Must include a cloudcheckr account name")
  109. return
  110. try:
  111. AzureDirectoryId = str(sys.argv[3])
  112. except IndexError:
  113. print("Must include an Azure Directory Id")
  114. return
  115. try:
  116. AzureSubscriptionId = str(sys.argv[4])
  117. except IndexError:
  118. print("Must include an Azure Subscription Id")
  119. return
  120. try:
  121. AzureAdminApplicationId = str(sys.argv[5])
  122. except IndexError:
  123. print("Must include an Azure Admin ApplictApi Id")
  124. return
  125. try:
  126. AzureAdminApplicationSecret = str(sys.argv[6])
  127. except IndexError:
  128. print("Must include an Azure Admin Application Secret")
  129. return
  130. try:
  131. AzureCloudCheckrApplicationName = str(sys.argv[7])
  132. except IndexError:
  133. print("Must include an Azure CloudCheckr Application Name")
  134. return
  135. try:
  136. AzureCloudCheckrApplicationSecret = str(sys.argv[8])
  137. except IndexError:
  138. print("Must include an Azure CloudCheckr Application Secret")
  139. return
  140. env = "https://glacier.cloudcheckr.com"
  141. AzureApiBearerToken = get_azure_bearer_token("https://management.azure.com/", AzureDirectoryId,
  142. AzureAdminApplicationId, AzureAdminApplicationSecret)
  143. AzureGraphApiBearerToken = get_azure_bearer_token("https://graph.microsoft.com/", AzureDirectoryId,
  144. AzureAdminApplicationId, AzureAdminApplicationSecret)
  145. AzureReaderRoleId = get_azure_reader_role_id(AzureApiBearerToken, AzureSubscriptionId)
  146. AzureCloudCheckrApplicationServicePrincipalId, AzureCloudCheckrApplicationId = get_azure_cloudcheckr_service_principal_id(
  147. AzureGraphApiBearerToken, AzureCloudCheckrApplicationName)
  148. set_azure_cloudcheckr_application_service_assignment(AzureApiBearerToken, AzureReaderRoleId,
  149. AzureCloudCheckrApplicationServicePrincipalId,
  150. AzureSubscriptionId)
  151. create_azure_account(env, CloudCheckrApiKey, NameOfCloudCheckrAccount, AzureDirectoryId,
  152. AzureCloudCheckrApplicationId, AzureCloudCheckrApplicationSecret, AzureSubscriptionId)
  153. if __name__ == "__main__":
  154. main()