How To Use CIT in conjunction with XaaS

Overview

CITs, or Continuous Infrastructure Tests, are vital to any self-service offerings, a true health check to one’s blueprints and orchestrations. The purpose of this document is to show how one can leverage CIT beyond a compute provision to Anything ( X ) as a Service, a.k.a. action based, blueprint.

In order to make it easier to understand how to use CIT with XaaS we’ll use a real example Blueprint for deploying an RDS Aurora in AWS, a Database Resource Type

Best Practice

Step 1 Create a blueprint and associate with the resource type

  1. Provision Action

  2. Discovery Action (brown-field support)

  3. Lifecycle (Day-2) Actions
    To be added at a later time.

  4. Tear-down actions

  5. Deploy the Blueprint thru the CloudBolt UI

Step 2 Create an API deployment Connection Info

  1. Add a new API specific ConnectionInfo object

Step 3 Create a CIT Action-based Test

  1. Add a new CIT Test

  2. Use the following template:

    import json
    import logging
    import re
    import uuid
    
    from api.api_samples.python_client.api_client import CloudBoltAPIClient
    from api.api_samples.python_client.samples.api_helpers import wait_for_order_completion
    from common.methods import set_progress
    from servicecatalog.models import ServiceBlueprint
    from utilities.exceptions import CloudBoltException
    from utilities.models import ConnectionInfo
    from orders.models import Order
    
    
    # suppress logging from requests module
    logger = logging.getLogger('requests')
    logger.setLevel(40)
    logger = logging.getLogger('py.warnings')
    logger.setLevel(40)
    
    API_CLIENT_CI = "CIT API Client"
    
    BLUEPRINT = %BP_ID%
    
    unique_identifier = str(uuid.uuid4())[:8]
    AURORA_DB = "AuroraDbCluster" + unique_identifier
    AURORA_MYSQL_DB = "AuroraMysqlCluster" + unique_identifier
    AURORA_POSTGRES_DB = "AuroraPsqlCluster" + unique_identifier
    
    BP_PAYLOADS = [
        %PAYLOAD_1%,
        %PAYLOAD_2%,
        %PAYLOAD_3%,
    ]
    
    
    def get_order_id_from_href(order_href):
        mo = re.search("/orders/([0-9]+)", order_href)
        return int(mo.groups()[0])
    
    
    def test_order_blueprint(client):
        # In the case that an order fails, the test writer should be able to run the output
        # of the BP_PAYLOAD in Admin > API Browser > Orders.
        set_progress("Ordering for the API using the following BP_PAYLOAD:")
        set_progress(BP_PAYLOADS)
        
        orders_ids = []
        for BP_PAYLOAD in BP_PAYLOADS:
            JSON_PAYLOAD = json.dumps(BP_PAYLOAD)
            order = json.loads(client.post('/api/v2/orders/', body=JSON_PAYLOAD))
            order_href = order['_links']['self']['href']
            order_id = get_order_id_from_href(order_href)
            result = wait_for_order_completion(client, order_id, 6000, 10)
            if result != 0:
                raise CloudBoltException("Blueprint Deployment order {} did not succeed.".format(order_id))
            set_progress("Blueprint deployment order {} completed successfully.".format(order_id))
            orders_ids.append(order_id)
        return orders_ids
    
    
    def test_delete_resource(client, resource):
        body = "{}"
        delete = json.loads(client.post(
            '/api/v2/resources/{}/{}/actions/1/'.format(resource.resource_type.name, resource.id), body=body))
    
    
    def get_api_client():
        ci = ConnectionInfo.objects.get(name=API_CLIENT_CI)
        return CloudBoltAPIClient(
            ci.username, ci.password, ci.ip, ci.port, protocol=ci.protocol)
    
    
    def run(job, *args, **kwargs):
        bp = ServiceBlueprint.objects.get(id=BLUEPRINT)
        set_progress(
            "Running Continuous Infrastructure Test for blueprint {}".format(bp)
        )
    
        client = get_api_client()
    
        # Order the BP
        set_progress("### ORDERING BLUEPRINT ###", tasks_done=0, total_tasks=3)
        orders_ids = test_order_blueprint(client)
        for order_id in orders_ids:
            order = Order.objects.get(id=order_id)
            resource = order.orderitem_set.first().cast().get_resource()
        
            db_cluster_identifier = resource.db_cluster_identifier
            id = resource.id
            
            # Delete the resource from the database only
            set_progress(f"### DELETING RESOURCE {resource}")
            resource.delete()
            set_progress("### DISCOVERING RESOURCES FOR BLUEPRINT ###", tasks_done=1)
            bp.sync_resources()
            
            # should be able to get the resource since the sync should have created it
            resources = bp.resource_set.filter(lifecycle='ACTIVE', blueprint=bp)
            
            set_progress("### DELETING RESOURCE FOR BLUEPRINT ###", tasks_done=2)
        
            [test_delete_resource(client, resource) for resource in resources if resource.db_cluster_identifier.lower() == db_cluster_identifier.lower()]
            
        set_progress("ALL Tests completed!", tasks_done=3)
    
  3. Add BP specific sample payload from the UI
    for %PAYLOAD_1%, %PAYLOAD_2% and %PAYLOAD_#% use the API button from previous order details

  4. Run the CIT Test

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.