Generated Parameter Options

One of the most common ways for users to customize the order experience is to constrain one or more parameters to a list of optional values an end-user can select from. There are several ways to do this in CloudBolt.

List of Options Configured Directly in the UI

A list of possible values for a parameter that should be presented to an end-user can be configured on the Blueprint, the Group and/or the Environment the end-user is interacting with at order time. Defining those options is done in the Parameters tab of the details page for the Blueprint (manage blueprint view), Group and Environment. It’s important to know how these three source for optional values interact.

Out-of-the-box Order of Precedence for Parameter Options

If options for a parameter are defined in the Blueprint then that is the list of options that gets presented to the user. If there are no Blueprint options then the list presented to the user will be the union of all the options present in the Group and all the options present in the Environment.

Using Orchestration Actions to Generate Parameter Options

In addition to limiting a parameter to predefined options from the UI, it is also possible to dynamically generate the options for a parameter using an orchestration action. This can be done by adding an orchestration action specifically to handle the parameter options generation or by including in a CloudBolt plug-in action if the parameter is an action input for the plug-in.

Plug-ins that generate parameter options

There are two ways to generate parameter options and both approaches require a Plug-in added at Admin > Orchestration Actions > Other > Generated Parameter Options and associated with the custom field in question.

Synchronously: all options are returned by the plug-in and rendered as a dropdown. Plug-in must implement get_options_list(custom_field, **kwargs).

Asynchronously: only options matching what the user has typed are returned by the plug-in and rendered in a dropdown. Plug-in must implement suggest_options(custom_field, query, **kwargs). query is the string the user has typed that should be used to search for matches. Plug-in must also define a get_options_list(custom_field, **kwargs) that simply does return None.

Plug-ins that generate action input options

The method signature when the generation of options is embedded in a CloudBolt Plug-in is generate_options_for_<custom_field_name>(**kwargs).

Notice that the method name in the case of the embedded method is dependent on the parameter (action input) name. You can learn more about action inputs here.

Note

The resulting list of options is still subject to further processing. If a parameter has dynamically generated options, those options will still be filtered against any options defined in the UI, respecting the order of precedence described above, and only options that intersect will be what are ultimately used. To override this behavior refer to the Advanced Option Returns section below.

Dynamic Method Keyword Arguments

The possible keyword arguments available to any method, stand alone or embedded, are dependent on the context in which the method is being called. The following table lists the most common keyword arguments and the context in which they are available.

Keyword Availability Context
group
  • setting options on a Group.
  • determining what options should be present at blueprint ordering time.
  • determining what options should be present for any server modification action.
environment
  • setting options on an Environment.
  • determining what options should be present at blueprint ordering time.
  • determining what options should be present for any server modification action.
server determining what options should be present for any server modification action.
profile profile represents the currently logged in user and is available in all contexts.
blueprint
  • setting options on a Blueprint.
  • determining what options should be present for any resource modification action
resource determining what options should be present for any resource modification action.

Advanced Option Returns

List of Tuples

The most common return of a generated parameter orchestration action is a list of tuples. The tuples are expected to always contain two elements. The first element should be the actual value for the parameter and the second element is the human-readable, friendly description of the option.

Dictionary

Sometimes it is necessary to return a dictionary in order to override the out-of-the-box behavior. CloudBolt accepts a dictionary return and understands the following keys:

Key Type Purpose
options list the actual list of tuples as expected in the simplest use case of this action.
initial_value string the initial value that should be selected from the resulting options, if present.
override boolean If True then the resulting options will NOT be subject to further processing.

None

One may choose to only generate parameter options in a specific context while at the same time relying on the out-of-the-box options for all other uses of the parameter. This can be accomplished by explicitly returning None from the orchestration action.

Example

In this fictional scenario, someone has determined that the parameter vmware_datastore should be presented to users with very specific rules and conditions. Note that some conditions might seem arbitrary but the intention is to demonstrate all possible use-cases in a single file.

The business rules to be enforced are:

  1. When adding disks to a server, one should always use the same datastore of the root disk
  2. When provisioning a new server, if the ordering group has it’s own dedicated list of datastores, we should start with that list, but also take into consideration the environment options.
  3. When determining what options can be added in a group or environment, default to the out-of-the-box behavior.
# sample orchestration for documentation purposes

from resourcehandlers.vmware.models import VmwareDatastore

def get_options_list(
    field, blueprint=None, environment=None, group=None, server=None, **kwargs):

    if server:
        # we are dealing with a server modification event, we want to complete override the
        # out-of-the-box behavior
        storage = server.disks.first().disk_storage
        options = [(storage.id, storage.name)]
        return {'options': options, 'override': True}

    elif group and environment and blueprint:
        # this is a provisioning event (the only time all three objects are available at the
        # same time)

        # get group options for this field using the default heirarchy (with inherited options from parents).
        group_options = group.get_custom_field_options(field=field)

        # get the intersection of environment and group options
        options = set(environment.custom_field_options.filter(field=field).all())
        options = options.intersection(group_options)

        # convert the parameter values to a list of tuples
        ret_list = []
        for cfv in options:
            ret_list.append((cfv.value.id, cfv.display_value))

        return ret_list


     # default to the out-of-the-box behavior in all other contexts
      return None

Alternately, if you wish to only retrieve options from the group (excluding inherited options):

group.custom_field_options.filter(field=field)