Add task commands to CLI with basic functionality

task create, task list, task show included with this
commit.
This commit is contained in:
Bryan Strassner 2017-07-18 14:32:10 -05:00 committed by Scott Hussey
parent 8c69c9febc
commit 4ead07c737
7 changed files with 178 additions and 4 deletions

View File

@ -22,6 +22,7 @@ from drydock_provisioner.drydock_client.session import DrydockSession
from drydock_provisioner.drydock_client.client import DrydockClient
from .design import commands as design
from .part import commands as part
from .task import commands as task
@click.group()
@click.option('--debug/--no-debug',
@ -75,3 +76,4 @@ def drydock(ctx, debug, token, url):
drydock.add_command(design.design)
drydock.add_command(part.part)
drydock.add_command(task.task)

View File

@ -27,9 +27,11 @@ class DesignList(CliAction): # pylint: disable=too-few-public-methods
class DesignCreate(CliAction): # pylint: disable=too-few-public-methods
""" Action to create designs
:param string base_design: A UUID of the base design to model after
"""
def __init__(self, api_client, base_design=None):
"""
:param string base_design: A UUID of the base design to model after
"""
super().__init__(api_client)
self.logger.debug("DesignCreate action initialized with base_design=%s", base_design)
self.base_design = base_design

View File

@ -74,8 +74,12 @@ def part_show(ctx, source, kind, key):
"""
if not kind:
ctx.fail('The kind must be specified by --kind')
if not key:
ctx.fail('The key must be specified by --key')
click.echo(PartShow(ctx.obj['CLIENT'], design_id=ctx.obj['DESIGN_ID'], kind=kind, key=key, source=source).invoke())
click.echo(PartShow(ctx.obj['CLIENT'],
design_id=ctx.obj['DESIGN_ID'],
kind=kind,
key=key,
source=source).invoke())

View File

@ -0,0 +1,84 @@
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" Actions related to task commands
"""
from drydock_provisioner.cli.action import CliAction
class TaskList(CliAction): # pylint: disable=too-few-public-methods
""" Action to list tasks
"""
def __init__(self, api_client):
"""
:param DrydockClient api_client: The api client used for invocation.
"""
super().__init__(api_client)
self.logger.debug('TaskList action initialized')
def invoke(self):
return self.api_client.get_tasks()
class TaskCreate(CliAction): # pylint: disable=too-few-public-methods
""" Action to create tasks against a design
"""
def __init__(self, api_client, design_id, action_name=None, node_names=None, rack_names=None, node_tags=None):
"""
node_filter : {node_names: [], rack_names:[], node-tags[]}
:param DrydockClient api_client: The api client used for invocation.
:param string design_id: The UUID of the design for which to create a task
:param string action_name: The name of the action being performed for this task
:param List node_names: The list of node names to restrict action application
:param List rack_names: The list of rack names to restrict action application
:param List node_tags: The list of node tags to restrict action application
"""
super().__init__(api_client)
self.design_id = design_id
self.action_name = action_name
self.logger.debug('TaskCreate action initialized for design=%s', design_id)
self.logger.debug('Action is %s', action_name)
if node_names is None:
node_names = []
if rack_names is None:
rack_names = []
if node_tags is None:
node_tags = []
self.logger.debug("Node names = %s", node_names)
self.logger.debug("Rack names = %s", rack_names)
self.logger.debug("Node tags = %s", node_tags)
self.node_filter = {'node_names' : node_names,
'rack_names' : rack_names,
'node_tags' : node_tags
}
def invoke(self):
return self.api_client.create_task(design_id=self.design_id,
task_action=self.action_name,
node_filter=self.node_filter)
class TaskShow(CliAction): # pylint: disable=too-few-public-methods
""" Action to show a task's detial.
"""
def __init__(self, api_client, task_id):
"""
:param DrydockClient api_client: The api client used for invocation.
:param string task_id: the UUID of the task to retrieve
"""
super().__init__(api_client)
self.task_id = task_id
self.logger.debug('TaskShow action initialized for task_id=%s,', task_id)
def invoke(self):
return self.api_client.get_task(task_id=self.task_id)

View File

@ -0,0 +1,81 @@
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" cli.task.commands
Contains commands related to tasks against designs
"""
import click
from drydock_provisioner.cli.task.actions import TaskList
from drydock_provisioner.cli.task.actions import TaskShow
from drydock_provisioner.cli.task.actions import TaskCreate
@click.group()
def task():
""" Drydock task commands
"""
@task.command(name='create')
@click.option('--design-id',
'-d',
help='The design id for this action')
@click.option('--action',
'-a',
help='The action to perform')
@click.option('--node-names',
'-n',
help='The nodes targeted by this action, comma separated')
@click.option('--rack-names',
'-r',
help='The racks targeted by this action, comma separated')
@click.option('--node-tags',
'-t',
help='The nodes by tag name targeted by this action, comma separated')
@click.pass_context
def task_create(ctx, design_id=None, action=None, node_names=None, rack_names=None, node_tags=None):
""" Create a task
"""
if not design_id:
ctx.fail('Error: Design id must be specified using --design-id')
if not action:
ctx.fail('Error: Action must be specified using --action')
click.echo(TaskCreate(ctx.obj['CLIENT'],
design_id=design_id,
action_name=action,
node_names=[x.strip() for x in node_names.split(',')] if node_names else [],
rack_names=[x.strip() for x in rack_names.split(',')] if rack_names else [],
node_tags=[x.strip() for x in node_tags.split(',')] if node_tags else []
).invoke())
@task.command(name='list')
@click.pass_context
def task_list(ctx):
""" List tasks.
"""
click.echo(TaskList(ctx.obj['CLIENT']).invoke())
@task.command(name='show')
@click.option('--task-id',
'-t',
help='The required task id')
@click.pass_context
def task_show(ctx, task_id=None):
""" show a task's details
"""
if not task_id:
ctx.fail('The task id must be specified by --task-id')
click.echo(TaskShow(ctx.obj['CLIENT'],
task_id=task_id).invoke())

View File

@ -186,7 +186,7 @@ class DrydockClient(object):
resp = self.session.post(endpoint, data=task_dict)
if resp.status_code == 201:
return resp.json().get('id')
return resp.json().get('task_id')
elif resp.status_code == 400:
raise errors.ClientError("Invalid inputs, received a %d: %s" % (resp.status_code, resp.text),
code=resp.status_code)

View File

@ -44,6 +44,7 @@ setup(name='drydock_provisioner',
'drydock_provisioner.cli',
'drydock_provisioner.cli.design',
'drydock_provisioner.cli.part',
'drydock_provisioner.cli.task',
'drydock_provisioner.drydock_client'],
install_requires=[
'PyYAML',