This project is an SDK for Crayon's CloudIQ API that can be used in Python scripts and applications. Provides a simple interface to authenticate with the API using Oauth2. It can be used to create tenants, create licensing subscriptions, and monitor billing. Anything that can be done in the Cloud-IQ portal can be automated using this package.
Includes several pre-configured data schema and API methods. Custom blocks of data can be posted to the API as Python dictionaries. REST methods: GET, POST, PATCH, PUT, and DELETE can be called with an API endpoint and data dictionary as arguments.
- Install the crayon-cloudiq-sdk package with the following command:
pip install crayon-cloudiq-sdk
How to Create Cloud-IQ API Client Credentials
- Login to Cloud IQ
- Choose Manage -> API Management from the top menu
- Press the + Add Client button
- Choose a name of the client
- Choose Resource Flow as the authentication type
- Save the Client ID and the Client Secret
-
Create a new python script
-
Import the CloudIQ class
from cloudiq import CloudIQ
-
Initialize an instance of the CloudIQ class with valid user credentials:
from cloudiq import CloudIQ CLIENT_ID = xxxxxxx-xxxx-xxxx-xxxx-xxxxxx CLIENT_SECRET = xxxxxxx-xxxx-xxxx-xxxx-xxxxxx USERNAME = "[email protected]" PASSWORD = "Password123456" crayon_api = CloudIQ(CLIENT_ID,CLIENT_SECRET,USERNAME,PASSWORD)
The prefered way of importing credentials is through ENV variables.
from os import getenv from cloudiq import CloudIQ CLIENT_ID = getenv('CLIENT_ID') CLIENT_SECRET = getenv('CLIENT_SECRET') USERNAME = getenv('CLOUDIQ_USER') PASSWORD = getenv('CLOUDIQ_PW') crayon_api = CloudIQ(CLIENT_ID,CLIENT_SECRET,USERNAME,PASSWORD)
ENV variables can be set using various methods including injection if using containers and pipelines or through a secrets manager such as Azure KeyVault. To set them on a local system using bash run the following commands:
export CLIENT_ID="xxxxxxx-xxxx-xxxx-xxxx-xxxxxx" export CLIENT_SECRET="xxxxxxx-xxxx-xxxx-xxxx-xxxxxx" export USERNAME="[email protected]" export PASSWORD="Password123456"
An alternative method is to use a config.ini file containing the credentials and retrieve them using the configparser module.
import configparser from cloudiq import CloudIQ # Parse configuration file try: config = configparser.ConfigParser() config.read('config.ini') ID = config['CRAYON_API']['ID'] SECRET = config['CRAYON_API']['SECRET'] USER = config['CRAYON_API']['USER'] PASS = config['CRAYON_API']['PASS'] except configparser.Error: print("Configuration Error...config.ini not found") exit() except KeyError: print("Configuration Error...configuration not found in config.ini") exit() crayon_api = CloudIQ(CLIENT_ID,CLIENT_SECRET,USERNAME,PASSWORD)
See examples folder for authentication demos using configparser, ENV variables, and Azure DevOps Pipelines
Data that is returned by the API is saved into a response object (except for getToken and validateToken). The response object contains values such as the status_code, headers, cookies, and the text returned by the API call.
-
To return the json data from the response use response.json() class method
-
To return the status code use the response.status_code variable
-
All successful API calls either return 200 OK, 201 Created, or 204 No Content
-
Most error responses also provide a detailed error message in JSON form
-
If you receive a 500 error, the data Schema payload is most likely the issue. It may be formatted incorrectly or missing required fields.
Remember to handle error statuses when writing automations
response = crayon_api.me()
if(int(response.status_code) == 200):
# Handle JSON data
print(response.json())
else:
# Handle Error
print(response.status_code)
exit(1)
For a full explanation of the fields within a response object, please review the information in the following links:
-
Official Requests.Response class documentation: https://docs.python-requests.org/en/latest/api/#requests.Response
-
W3 Schools: https://www.w3schools.com/PYTHON/ref_requests_response.asp
-
Make an unauthenticated test ping to the API
response = crayon_api.ping() print(response,json())
-
Get information about the currently authenticated user
response = crayon_api.me() print(response.json())
-
Make a raw GET request:
# retrieves all products in the Azure Active Directory product family within Org 123456 params = { 'OrganizationId': 123456, 'Include.ProductFamilyNames': 'Azure Active Directory' } # make a GET request to https://api.crayon.com/api/v1/AgreementProducts response = crayon_api.get("https://api.crayon.com/api/v1/AgreementProducts",params) print(response.json())
Data can be sent to the API as a standard Python dictionary object
-
Retrieve a valid authorization token:
response = crayon_api.getToken() print(response)
-
Create a tenant using the CustomerTenantDetailed schema:
# Set Unique Tenant Variables tenant_name = "tenant_name" domain_prefix = "domain_prefix" # Initialize Tenant and Agreement objects tenant = crayon_api.CustomerTenantDetailed( tenant_name=tenant_name, domain_prefix=domain_prefix, org_id=111111, org_name="Fake Org", invoice_profile_id=80408, # Default contact_firstname="First", contact_lastname="Last", contact_email="[email protected]", contact_phone="5555555555", address_firstname="First", address_lastname="Last", address_address="75 NoWhere Lane", address_city="Boston", address_countrycode="US", address_region="MA", address_zipcode="02109" ) agreement = crayon_api.CustomerTenantAgreement( firstname="First", lastname="Last", phone_number="5555555555", email="[email protected]" ) #Create New Tenant new_tenant = crayon_api.createTenant(tenant.tenant) print(new_tenant.json()) # Agree to Microsoft Customer Agreement tenant_id = new_tenant["Tenant"]["Id"] agreement = crayon_api.createTenantAgreement(tenant_id,agreement.agreement) print(agreement.json())
-
Buy a Microsoft license for a tenant using the SubscriptionDetailed schema:
tenant_id=123456 # Create Subscription objects azure_subscription = crayon_api.SubscriptionDetailed( name="Azure P2 Subscription", tenant_id=tenant_id, part_number="CFQ7TTC0LFK5:0001", quantity=1, billing_cycle=1, duration="P1M" ) # Create Azure P2 Subscription subscription = crayon_api.createSubscription(azure_subscription.subscription) print(subscription.json)
from cloudiq import CloudIQ
help(CloudIQ)
- Crayon API Documentation: https://apidocs.crayon.com/
- Swagger UI (includes all valid schemas): https://api.crayon.com/docs/index.html
- CustomerTenantDetailed
- CustomerTenantAgreement
- SubscriptionDetailed
- get
- ping
- me
- getToken
- validateToken
- getOrganizations
- getOrganization
- getOrganizationSalesContact
- getAgreementProducts
- getActivityLogs
- getOrganizationHasAccess
- getAddresses
- getAddress
- getSupportedBillingCycles
- getAgreements
- getAgreementReports
- getCustomerTenants
- getCustomerTenant
- getCustomerTenantDetails
- getCustomerTenantAzurePlan
- getCustomerTenantAgreements
- getBillingCycles
- getProductVariantBillingCycles
- getBillingCyclesNameDictionary
- getBillingStatements
- getGroupedBillingStatements
- getBillingStatementExcel
- getBillingStatementCSV
- getBillingStatementJSON
- getBlogItems
- getClients
- getClient
- getConsumers
- getConsumer
- getCrayonAccounts
- getCrayonAccount
- getGroupings
- getGrouping
- getInvoiceProfiles
- getInvoiceProfile
- getProductContainers
- getProductContainer
- getProductContainerRowIssues
- getProductContainerShoppingCart
- getPrograms
- getProgram
- getPublishers
- getPublisher
- getRegions
- getRegionByCode
- getUsers
- getUser
- getUsername
- getUsageCost
- delete
- patch
- post
- put
- createClient
- deleteClient
- createTenant
- createSubscription
- createTenantAgreement