Commit b9649213 authored by AlanCoding's avatar AlanCoding

added functionality for WFJT schema creation

parent 0f4c7ccd
......@@ -37,17 +37,28 @@ Auto-creation of the success node, only knowing the parent node id
tower-cli node assocate_success 8 --job-template="Hello world"
### Bulk Creation
### Node Network Bulk Management
To print out a YAML representation of the nodes of a workflow, you can
use the following command:
tower-cli workflow schema my_workflow
where "my_workflow" is the name of the workflow.
To bulk-create a workflow node network, use the workflow schema command
the schema is JSON or YAML content, and can be passed in the CLI
argument, or pointed to a file.
argument, or pointed to a file. The schema is passed as a second positional
argument, where the first argument references the workflow.
tower-cli workflow schema @file.yml
tower-cli workflow schema my_workflow @file.yml
- job template: hello world
- sucess:
- project: examples
- job_template: Hello world
job_template: Followup job template
......@@ -54,7 +54,7 @@ class Resource(models.Resource):
def __getattribute__(self, attr):
method = super(Resource, self).__getattribute__(attr)
if attr in ['create', 'modify']:
if attr in ['create', 'modify', 'list']:
return unified_job_template_options(method)
return method
......@@ -83,7 +83,7 @@ class Resource(models.Resource):
def _assoc_or_create(self, relationship, parent, child, **kwargs):
if child is None:
child_data = self._get_or_create_child(parent, 'success', **kwargs)
child = child_data['id']
return child_data
return self._assoc(relationship, parent, child)
......@@ -17,6 +17,8 @@ from __future__ import absolute_import, unicode_literals
from tower_cli import models, resources, get_resource
from tower_cli.utils import types
from tower_cli.utils.parser import string_to_dict
from tower_cli.utils.exceptions import BadRequest
from tower_cli.conf import settings
from tower_cli.resources.node import NODE_STANDARD_FIELDS, JOB_TYPES
......@@ -125,21 +127,41 @@ class Resource(models.Resource):
def create_node_recursive(node_branch):
create_data = {}
for fd in NODE_STANDARD_FIELDS + JOB_TYPES.values():
if fd in node_branch:
create_data[fd] = node_branch[fd]
node_data = node_res.create(create_data)
if fd in JOB_TYPES.values():
ujt_res = get_resource(fd)
ujt_data = ujt_res.get(name=node_branch[fd])
create_data[fd] = ujt_data['id']
create_data[fd] = node_branch[fd]
create_data['workflow_job_template'] = wfjt
# TODO: handle case of pre-existing node
node_data = node_res.create(**create_data)
for key in node_branch:
for rel in ['success', 'failure', 'always']:
if key.startswith(rel):
for sub_branch in node_branch[key]:
if isinstance(sub_branch, basestring):
raise BadRequest(
'Sublists in spec must be lists.'
'Encountered in {0} at {1}'.format(
key, sub_branch))
sub_node_data = create_node_recursive(sub_branch)
print "\n".join(['success_nodes', str(node_data),
'success_nodes', node_data['id'],
return node_data
if hasattr(node_network, 'read'):
node_network =
node_network = string_to_dict(
node_network, allow_kv=False, require_dict=False)
for base_node in node_network:
......@@ -68,7 +68,7 @@ def parse_kv(var_string):
return return_dict
def string_to_dict(var_string, allow_kv=True):
def string_to_dict(var_string, allow_kv=True, require_dict=True):
"""Returns a dictionary given a string with yaml or json syntax.
If data is not present in a key: value format, then it return
an empty dictionary.
......@@ -84,7 +84,8 @@ def string_to_dict(var_string, allow_kv=True):
# Accept all JSON and YAML
return_dict = yaml.load(var_string)
assert type(return_dict) is dict
if require_dict:
assert type(return_dict) is dict
except (AttributeError, yaml.YAMLError, AssertionError):
# if these fail, parse by key=value syntax
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment