Shell Plus

Shell Plus is an interactive Python shell on the Cloud Management Platform (CMP) appliance, with every model already imported

Shell Plus is a Django management command, so it loads CMP’s models and settings before handing you an IPython prompt. Run a line of code and see the result immediately. Use it to find out what an object holds and work out the queries a plugin will make.

Launch Shell Plus

  1. On the CMP appliance, switch to the root user.

    sudo su -
    

    The - gives you a root login shell with the environment manage.py expects.

  2. Launch the shell.

    /opt/cloudbolt/manage.py shell_plus
    

Run your first commands

Retrieve the environments:

Environment.objects.all()

What comes back is a Django QuerySet:

<CustomFieldAsAttributeQuerySet [<Environment: Unassigned>, <Environment: (vCenter CS) CS>]>

Store it in a variable to work with it:

envs = Environment.objects.all()

IPython also keeps the previous result in _, so you can capture something you have already run:

envs = _

Then index into it. This takes the second environment; the first is normally the built-in Unassigned one:

envs[1]

Make changes

Methods on a model perform the same work as the interface. Calling reboot() on a server connects to its resource handler and reboots the machine.

Reboot one server by hostname:

server = Server.objects.get(hostname="devtest0032")
server.reboot()

Reassign every server owned by one user to another:

lisa = UserProfile.objects.get(user__username='lisa')
Server.objects.filter(owner__user__username='david').update(owner=lisa)

Reboot many servers in a loop:

for server in Server.objects.filter(hostname__icontains="dev-"):
    server.reboot()

Query models

A Django model is a Python class that maps to a database table. CMP has one for everything it manages, including Server, Environment, and ResourceHandler. See Models for more information.

Query a model through its default manager, objects. Filtering returns a QuerySet:

# Jobs where status is queued
Job.objects.filter(status='QUEUED')

# Jobs where status is active
# uses __in and the Job.ACTIVE_STATUSES constant
Job.objects.filter(status__in=Job.ACTIVE_STATUSES)

# vSphere Resource Handlers
ResourceHandler.objects.filter(resource_technology__name='VMware vCenter')

Narrow a QuerySet to one object with .first(), .last(), or a known ID:

# Get a server object by hostname
Server.objects.filter(hostname="samvm1").first()

# Get a server object by id
Server.objects.get(id=58)

Or iterate over it. A model may also offer helper methods:

for server in Server.objects.filter(hostname__icontains="prod"):
    print(server.hostname, server.ip)

# Fetch all Model objects
OSFamily.objects.all()

# Model helper methods may be available
OSFamily.all_families_descendants_first()

Inspect an object

Almost everything about an object is available four ways: __dict__ for values it holds, _meta.fields for its schema, help() for its documentation, and tab completion for what you can call on it.

# Second CloudBolt environment
env = Environment.objects.all()[1]

# Model instance data
env.__dict__

# Model instance schema
env._meta.fields

help() works on a class as well as an instance:

# Server Model
help(Server)

CMP mixins

A mixin is a small reusable class that adds behavior to a model. Use help() on a class to list them:

class Environment(common.mixins.HasCustomFieldValuesMixin, costs.models.HasRateMixin, common.classes.AutoCompleteMixin, common.mixins.GlobalIDForAPIMixin)

Two of CMP’s mixins are used frequently.

HasSubModelsMixin

Adds cast(), which returns the object as its technology-specific subclass. A query against a base model such as ResourceHandler gives you base instances, and the important fields are usually on the subclass:

# Access model subclasses using .cast()

env.resource_handler
#<ResourceHandler: vCenter CS>

env.resource_handler.cast()
# <VsphereResourceHandler: vCenter CS>

HasCustomFieldValuesMixin

Lets you read and write parameter values as ordinary attributes, so object.{parameter_name} gets or sets the value of that parameter:

# Getting parameter value object.{parameter_name}
env.annotation

# Setting parameter value
env.annotation = "Server built by CMP"

# Unknown parameter (CustomField)
env.nothere
# AttributeError: 'Environment' object has no attribute 'nothere'
  • Models: The CMP models you are most likely to query and how they relate.
  • Use Django ORM: Useful query patterns for when you move this code into a plugin.
  • Making queries and IPython: The upstream documentation for the query syntax and the shell.