CLI for Shipyard API
-Added cli folder -Utilizes click to process commands -commands can be found at https://github.com/att-comdev/shipyard/blob/master/docs/CLI.md -also, running the command 'shipyard' will give you a brief description of the commands available -Contains actions.py that calls Client API -Added tests folder -Unit tests for commands -Negative unit tests are also included for commands -Unit tests for actions Change-Id: Ie3e4d1f18aa935a311f332fba5c8a4d239183469
This commit is contained in:
parent
2b4866f6cb
commit
d679696ec0
@ -31,3 +31,6 @@ requests==2.18.4
|
||||
SQLAlchemy==1.1.13
|
||||
ulid==1.1
|
||||
uwsgi==2.0.15
|
||||
click==6.7
|
||||
click-default-group==1.2
|
||||
pyyaml==3.12
|
||||
|
@ -17,12 +17,15 @@ classifier =
|
||||
[files]
|
||||
packages =
|
||||
shipyard_airflow
|
||||
shipyard_client
|
||||
|
||||
[entry_points]
|
||||
oslo.config.opts =
|
||||
shipyard_airflow = shipyard_airflow.conf.opts:list_opts
|
||||
oslo.policy.policies =
|
||||
shipyard_airflow = shipyard_airflow.policy:list_policies
|
||||
console_scripts =
|
||||
shipyard = shipyard_client.cli.commands:shipyard
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = docs/source
|
||||
|
@ -116,9 +116,8 @@ class ShipyardClient(BaseClient):
|
||||
"""
|
||||
action_data = {"name": name, "parameters": parameters}
|
||||
url = ApiPaths.POST_GET_ACTIONS.value.format(self.shipyard_url)
|
||||
return self.post_resp(url,
|
||||
data=json.dumps(action_data),
|
||||
content_type='application/json')
|
||||
return self.post_resp(
|
||||
url, data=json.dumps(action_data), content_type='application/json')
|
||||
|
||||
def get_action_detail(self, action_id=None):
|
||||
"""
|
||||
|
@ -32,6 +32,7 @@ class ShipyardClientContext:
|
||||
:param dict keystone_auth: auth_url, password, project_domain_name,
|
||||
project_name, username, user_domain_name
|
||||
"""
|
||||
|
||||
self.debug = debug
|
||||
self.keystone_auth = keystone_auth
|
||||
# the service type will for now just be shipyard will change later
|
||||
|
0
shipyard_client/cli/__init__.py
Normal file
0
shipyard_client/cli/__init__.py
Normal file
72
shipyard_client/cli/action.py
Normal file
72
shipyard_client/cli/action.py
Normal file
@ -0,0 +1,72 @@
|
||||
# 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.
|
||||
|
||||
# Base classes for cli actions intended to invoke the api
|
||||
|
||||
import logging
|
||||
|
||||
from shipyard_client.api_client.shipyard_api_client import ShipyardClient
|
||||
from shipyard_client.api_client.shipyardclient_context import \
|
||||
ShipyardClientContext
|
||||
from shipyard_client.api_client.client_error import ClientError
|
||||
from shipyard_client.cli.input_checks import validate_auth_vars
|
||||
|
||||
|
||||
class CliAction(object):
|
||||
"""Action base for CliActions"""
|
||||
|
||||
def __init__(self, ctx):
|
||||
"""Sets api_client"""
|
||||
self.logger = logging.getLogger('shipyard_cli')
|
||||
self.api_parameters = ctx.obj['API_PARAMETERS']
|
||||
self.resp_txt = ""
|
||||
self.needs_credentials = False
|
||||
|
||||
auth_vars = self.api_parameters['auth_vars']
|
||||
context_marker = self.api_parameters['context_marker']
|
||||
debug = self.api_parameters['debug']
|
||||
|
||||
validate_auth_vars(self, ctx)
|
||||
|
||||
self.logger.debug("Passing environment varibles to the API client")
|
||||
try:
|
||||
shipyard_client_context = ShipyardClientContext(
|
||||
auth_vars, context_marker, debug)
|
||||
self.api_client = ShipyardClient(shipyard_client_context)
|
||||
except ClientError as e:
|
||||
self.logger.debug("The shipyard Client Context could not be set.")
|
||||
ctx.fail('Client Error: %s.' % str(e))
|
||||
|
||||
def invoke_and_return_resp(self):
|
||||
"""
|
||||
calls the invoke method in the approiate actions.py and returns the
|
||||
formatted response
|
||||
"""
|
||||
|
||||
self.logger.debug("Inoking action.")
|
||||
env_vars = self.api_parameters['auth_vars']
|
||||
|
||||
try:
|
||||
self.invoke()
|
||||
except ClientError as e:
|
||||
self.resp_txt = "Client Error: %s." % str(e)
|
||||
except Exception as e:
|
||||
self.resp_txt = "Error: Unable to invoke action because %s." % str(
|
||||
e)
|
||||
|
||||
return self.resp_txt
|
||||
|
||||
def invoke(self):
|
||||
"""Default invoke"""
|
||||
self.resp_txt = "Error: Invoke method is not defined for this action."
|
137
shipyard_client/cli/commands.py
Normal file
137
shipyard_client/cli/commands.py
Normal file
@ -0,0 +1,137 @@
|
||||
# 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-1.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.
|
||||
|
||||
import click
|
||||
import logging
|
||||
|
||||
from click_default_group import DefaultGroup
|
||||
|
||||
from .commit import commands as commit
|
||||
from .control import commands as control
|
||||
from .create import commands as create
|
||||
from .describe import commands as describe
|
||||
from .get import commands as get
|
||||
from .help import commands as help
|
||||
from shipyard_client.cli.input_checks import check_control_action, check_id
|
||||
|
||||
|
||||
@click.group(cls=DefaultGroup, default='shipyard_default')
|
||||
# Shipyard Command Options
|
||||
@click.option(
|
||||
'--context-marker',
|
||||
'context_marker',
|
||||
help='Specifies a UUID (8-4-4-4-12 format) that will be used to correlate'
|
||||
' logs, transactions, etc. in downstream activities triggered by this'
|
||||
' interaction. If not specified, Shipyard will supply a new UUID to serve'
|
||||
' as this marker. (optional)',
|
||||
required=False)
|
||||
@click.option('--debug/--no-debug', default=False, help='Turn Debug on.')
|
||||
@click.option(
|
||||
'--output-format',
|
||||
'output_format',
|
||||
required=False,
|
||||
type=click.Choice(['format', 'raw']))
|
||||
# Supported Environment Variables
|
||||
@click.option(
|
||||
'--os_project_domain_name',
|
||||
envvar='OS_PROJECT_DOMAIN_NAME',
|
||||
required=False)
|
||||
@click.option(
|
||||
'--os_user_domain_name', envvar='OS_USER_DOMAIN_NAME', required=False)
|
||||
@click.option('--os_project_name', envvar='OS_PROJECT_NAME', required=False)
|
||||
@click.option('--os_username', envvar='OS_USERNAME', required=False)
|
||||
@click.option('--os_password', envvar='OS_PASSWORD', required=False)
|
||||
# os_auth_url is required for all command except help, please see shipyard def
|
||||
@click.option(
|
||||
'--os_auth_url', envvar='OS_AUTH_URL', required=False)
|
||||
# Allows context (ctx) to be passed
|
||||
@click.pass_context
|
||||
def shipyard(ctx, context_marker, debug, os_project_domain_name,
|
||||
os_user_domain_name, os_project_name, os_username, os_password,
|
||||
os_auth_url, output_format):
|
||||
"""
|
||||
COMMAND: shipyard \n
|
||||
DESCRIPTION: The base shipyard command supports options that determine
|
||||
cross-CLI behaviors. These options are positioned immediately following
|
||||
the shipyard command. \n
|
||||
FORMAT: shipyard [--context-marker=<uuid>] [--os_{various}=<value>]
|
||||
[--debug/--no-debug] [--output-format=<json,yaml,raw] <subcommands> \n
|
||||
"""
|
||||
|
||||
if not ctx.obj:
|
||||
ctx.obj = {}
|
||||
|
||||
ctx.obj['DEBUG'] = debug
|
||||
|
||||
# setup logging for the CLI
|
||||
# set up root logger
|
||||
logger = logging.getLogger('shipyard_cli')
|
||||
|
||||
logger.setLevel(logging.DEBUG if debug else logging.INFO)
|
||||
logging_handler = logging.StreamHandler()
|
||||
logger.addHandler(logging_handler)
|
||||
logger.debug('logging for cli initialized')
|
||||
|
||||
auth_vars = {
|
||||
'project_domain_name': os_project_domain_name,
|
||||
'user_domain_name': os_user_domain_name,
|
||||
'project_name': os_project_name,
|
||||
'username': os_username,
|
||||
'password': os_password,
|
||||
'auth_url': os_auth_url
|
||||
}
|
||||
|
||||
ctx.obj['API_PARAMETERS'] = {
|
||||
'auth_vars': auth_vars,
|
||||
'context_marker': context_marker,
|
||||
'debug': debug
|
||||
}
|
||||
|
||||
ctx.obj['FORMAT'] = output_format
|
||||
|
||||
|
||||
shipyard.add_command(commit.commit)
|
||||
shipyard.add_command(control.control)
|
||||
shipyard.add_command(create.create)
|
||||
shipyard.add_command(describe.describe)
|
||||
shipyard.add_command(get.get)
|
||||
shipyard.add_command(help.help)
|
||||
|
||||
|
||||
# To Invoke Control Commands
|
||||
# Since control is not a command used in the CLI, the control commands
|
||||
# pause, unpause, and stop are invoked here.
|
||||
@shipyard.command(name='shipyard_default', short_help="")
|
||||
@click.pass_context
|
||||
@click.argument('action')
|
||||
@click.argument('target_type', metavar='[TYPE]')
|
||||
@click.argument('id', required=False)
|
||||
def control_command(ctx, action, target_type, id):
|
||||
"""
|
||||
For more information on the control commands (pause, unpause, stop), please
|
||||
enter 'shipyard control <control command> --help.'
|
||||
"""
|
||||
|
||||
check_control_action(ctx, action)
|
||||
|
||||
if id:
|
||||
check_id(ctx, id)
|
||||
ctx.invoke(
|
||||
getattr(control, 'control_' + action),
|
||||
target_type=target_type,
|
||||
id=id)
|
||||
|
||||
else:
|
||||
ctx.invoke(
|
||||
getattr(control, 'control_' + action), target_type=target_type)
|
0
shipyard_client/cli/commit/__init__.py
Normal file
0
shipyard_client/cli/commit/__init__.py
Normal file
35
shipyard_client/cli/commit/actions.py
Normal file
35
shipyard_client/cli/commit/actions.py
Normal file
@ -0,0 +1,35 @@
|
||||
# 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.
|
||||
|
||||
from shipyard_client.cli.action import CliAction
|
||||
from shipyard_client.cli.output_formatting import output_formatting
|
||||
|
||||
|
||||
class CommitConfigdocs(CliAction):
|
||||
"""Actions to Commit Configdocs"""
|
||||
|
||||
def __init__(self, ctx, force):
|
||||
"""Initializes api_client, sets parameters, and sets output_format"""
|
||||
super().__init__(ctx)
|
||||
self.force = force
|
||||
self.output_format = ctx.obj['FORMAT']
|
||||
self.logger.debug("CommitConfigdocs action initialized with force=%s",
|
||||
force)
|
||||
|
||||
def invoke(self):
|
||||
"""Calls API Client and formats response from API Client"""
|
||||
self.logger.debug("Calling API Client commit_configdocs.")
|
||||
self.resp_txt = output_formatting(
|
||||
self.output_format,
|
||||
self.api_client.commit_configdocs(force=self.force))
|
54
shipyard_client/cli/commit/commands.py
Normal file
54
shipyard_client/cli/commit/commands.py
Normal file
@ -0,0 +1,54 @@
|
||||
# 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.
|
||||
|
||||
# Commit command
|
||||
|
||||
import click
|
||||
|
||||
from shipyard_client.cli.commit.actions import CommitConfigdocs
|
||||
|
||||
|
||||
@click.group()
|
||||
@click.pass_context
|
||||
def commit(ctx):
|
||||
"""
|
||||
Commits confidocs. \n
|
||||
For more information on commit commands
|
||||
please enter the commit command followed by '--help' \n
|
||||
Example: shipyard commit configdocs --help
|
||||
"""
|
||||
|
||||
|
||||
DESC_CONFIGDOCS = """
|
||||
COMMAND: configdocs \n
|
||||
DESCRIPTION: Attempts to commit the Shipyard Buffer documents, first
|
||||
invoking validation by downstream components. \n
|
||||
FORMAT: shipyard commit configdocs [--force] \n
|
||||
EXAMPLE: shipyard commit configdocs
|
||||
"""
|
||||
|
||||
SHORT_DESC_CONFIGDOCS = ("Attempts to commit the Shipyard Buffer documents, "
|
||||
"first invoking validation by downstream components.")
|
||||
|
||||
|
||||
@commit.command(
|
||||
name='configdocs', help=DESC_CONFIGDOCS, short_help=SHORT_DESC_CONFIGDOCS)
|
||||
@click.option(
|
||||
'--force',
|
||||
'-f',
|
||||
flag_value=True,
|
||||
help='Force the commit to occur, even if validations fail.')
|
||||
@click.pass_context
|
||||
def commit_configdocs(ctx, force):
|
||||
click.echo(CommitConfigdocs(ctx, force).invoke_and_return_resp())
|
0
shipyard_client/cli/control/__init__.py
Normal file
0
shipyard_client/cli/control/__init__.py
Normal file
34
shipyard_client/cli/control/actions.py
Normal file
34
shipyard_client/cli/control/actions.py
Normal file
@ -0,0 +1,34 @@
|
||||
# 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.
|
||||
|
||||
from shipyard_client.cli.action import CliAction
|
||||
from shipyard_client.cli.output_formatting import output_formatting
|
||||
|
||||
|
||||
class Control(CliAction):
|
||||
"""Action to Pause Process"""
|
||||
|
||||
def __init__(self, ctx, control_verb, action_id):
|
||||
"""Initializes api_client, sets parameters, and sets output_format"""
|
||||
super().__init__(ctx)
|
||||
self.action_id = action_id
|
||||
self.control_verb = control_verb
|
||||
self.output_format = ctx.obj['FORMAT']
|
||||
self.logger.debug("ControlPause action initialized")
|
||||
|
||||
def invoke(self):
|
||||
"""Calls API Client and formats response from API Client"""
|
||||
self.logger.debug("Calling API Client post_control_action.")
|
||||
self.resp_txt = output_formatting(self.output_format,
|
||||
self.api_client.post_control_action(
|
||||
action_id=self.action_id,
|
||||
control_verb=self.control_verb))
|
110
shipyard_client/cli/control/commands.py
Normal file
110
shipyard_client/cli/control/commands.py
Normal file
@ -0,0 +1,110 @@
|
||||
# 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.
|
||||
|
||||
# Control command
|
||||
|
||||
import click
|
||||
|
||||
from shipyard_client.cli.control.actions import Control
|
||||
|
||||
|
||||
@click.group()
|
||||
@click.pass_context
|
||||
def control(ctx):
|
||||
"""
|
||||
Pause, unpause, or stop something in progress. \n
|
||||
For more information on control commands
|
||||
please enter the control command followed by '--help' \n
|
||||
Example: shipyard control pause --help
|
||||
"""
|
||||
|
||||
|
||||
DESC_PAUSE = """
|
||||
COMMAND: pause \n
|
||||
DESCRIPTION: Pause something in progress. \n
|
||||
FORMAT: shipyard pause [<type> <id>] | [<qualified name>] \n
|
||||
EXAMPLE: shipyard pause action 01BTG32JW87G0YKA1K29TKNAFX | shipyard pause
|
||||
action/01BTG32JW87G0YKA1K29TKNAFX
|
||||
"""
|
||||
|
||||
SHORT_DESC_PAUSE = "Pause something in progress."
|
||||
|
||||
|
||||
@control.command(name='pause', help=DESC_PAUSE, short_help=SHORT_DESC_PAUSE)
|
||||
@click.argument(
|
||||
'target_type', metavar='[TYPE]', required=True) # type or qualified name
|
||||
@click.argument('id', required=False)
|
||||
@click.pass_context
|
||||
def control_pause(ctx, target_type, id=None):
|
||||
|
||||
control_handler(ctx, target_type, 'pause', id)
|
||||
|
||||
|
||||
DESC_UNPAUSE = """
|
||||
COMMAND: unpause \n
|
||||
DESCRIPTION: Unpause something in progress. \n
|
||||
FORMAT: shipyard unpause [<type> <id>] | [<qualified name>] \n
|
||||
EXAMPLE: shipyard unpause action 01BTG32JW87G0YKA1K29TKNAFX | shipyard
|
||||
unpause action/01BTG32JW87G0YKA1K29TKNAFX
|
||||
"""
|
||||
|
||||
SHORT_DESC_UNPAUSE = "Unpause something in progress."
|
||||
|
||||
|
||||
@control.command(
|
||||
name='unpause', help=DESC_UNPAUSE, short_help=SHORT_DESC_UNPAUSE)
|
||||
@click.argument(
|
||||
'target_type', metavar='[TYPE]', required=True) # type or qualified name
|
||||
@click.argument('id', required=False)
|
||||
@click.pass_context
|
||||
def control_unpause(ctx, target_type, id=None):
|
||||
|
||||
control_handler(ctx, target_type, 'unpause', id)
|
||||
|
||||
|
||||
DESC_STOP = """
|
||||
COMMAND: stop \n
|
||||
DESCRIPTION: Stop an executing or paused item. \n
|
||||
FORMAT: shipyard stop [<type> <id>] | [<qualified name>] \n
|
||||
EXAMPLE: shipyard stop action 01BTG32JW87G0YKA1K29TKNAFX | shipyard stop
|
||||
action/01BTG32JW87G0YKA1K29TKNAFX
|
||||
"""
|
||||
|
||||
SHORT_DESC_STOP = "Stop an executing or paused item."
|
||||
|
||||
|
||||
@control.command(name='stop', help=DESC_STOP, short_help=SHORT_DESC_STOP)
|
||||
@click.argument(
|
||||
'target_type', metavar='[TYPE]', required=True) # type or qualified name
|
||||
@click.argument('id', required=False)
|
||||
@click.pass_context
|
||||
def control_stop(ctx, target_type, id=None):
|
||||
|
||||
control_handler(ctx, target_type, 'stop', id)
|
||||
|
||||
|
||||
def control_handler(ctx, target_type, control_verb, id):
|
||||
"""
|
||||
Handles spliting the qualified_name if needed and passes to actions.py
|
||||
"""
|
||||
|
||||
# if id is not entered, then qualified name is entered
|
||||
if id is None:
|
||||
name = target_type.split("/")
|
||||
if len(name) == 2:
|
||||
target_type, id = name
|
||||
else:
|
||||
ctx.fail('A type and id must be entered.')
|
||||
|
||||
click.echo(Control(ctx, control_verb, id).invoke_and_return_resp())
|
0
shipyard_client/cli/create/__init__.py
Normal file
0
shipyard_client/cli/create/__init__.py
Normal file
59
shipyard_client/cli/create/actions.py
Normal file
59
shipyard_client/cli/create/actions.py
Normal file
@ -0,0 +1,59 @@
|
||||
# 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.
|
||||
|
||||
from shipyard_client.cli.action import CliAction
|
||||
from shipyard_client.cli.output_formatting import output_formatting
|
||||
|
||||
|
||||
class CreateAction(CliAction):
|
||||
"""Action to Create Action"""
|
||||
|
||||
def __init__(self, ctx, action_name, param):
|
||||
"""Initializes api_client, sets parameters, and sets output_format"""
|
||||
super().__init__(ctx)
|
||||
self.logger.debug("CreateAction action initialized with action command"
|
||||
"%s and parameters %s", action_name, param)
|
||||
self.action_name = action_name
|
||||
self.param = param
|
||||
self.output_format = ctx.obj['FORMAT']
|
||||
|
||||
def invoke(self):
|
||||
"""Calls API Client and formats response from API Client"""
|
||||
self.logger.debug("Calling API Client post_actions.")
|
||||
self.resp_txt = output_formatting(self.output_format,
|
||||
self.api_client.post_actions(
|
||||
name=self.action_name,
|
||||
parameters=self.param))
|
||||
|
||||
|
||||
class CreateConfigdocs(CliAction):
|
||||
"""Action to Create Configdocs"""
|
||||
|
||||
def __init__(self, ctx, collection, buffer, data):
|
||||
"""Initializes api_client, sets parameters, and sets output_format"""
|
||||
super().__init__(ctx)
|
||||
self.logger.debug("CreateConfigdocs action initialized with" +
|
||||
" collection=%s,buffer=%s and data=%s", collection,
|
||||
buffer, str(data))
|
||||
self.collection = collection
|
||||
self.buffer = buffer
|
||||
self.data = data
|
||||
self.output_format = ctx.obj['FORMAT']
|
||||
|
||||
def invoke(self):
|
||||
"""Calls API Client and formats response from API Client"""
|
||||
self.logger.debug("Calling API Client post_configdocs.")
|
||||
self.resp_txt = output_formatting(self.output_format,
|
||||
self.api_client.post_configdocs(
|
||||
collection_id=self.collection,
|
||||
buffer_mode=self.buffer,
|
||||
document_data=self.data))
|
147
shipyard_client/cli/create/commands.py
Normal file
147
shipyard_client/cli/create/commands.py
Normal file
@ -0,0 +1,147 @@
|
||||
# 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.
|
||||
|
||||
# Create command
|
||||
|
||||
import click
|
||||
import os
|
||||
import yaml
|
||||
|
||||
from shipyard_client.cli.create.actions import CreateAction, CreateConfigdocs
|
||||
from shipyard_client.cli.input_checks import check_action_command, \
|
||||
check_reformat_parameter
|
||||
|
||||
|
||||
@click.group()
|
||||
@click.pass_context
|
||||
def create(ctx):
|
||||
"""
|
||||
Create configdocs or an action. \n
|
||||
For more information on create commands
|
||||
please enter the create command followed by '--help' \n
|
||||
Example: shipyard create action --help
|
||||
"""
|
||||
|
||||
|
||||
DESC_ACTION = """
|
||||
COMMAND: action \n
|
||||
DESCRIPTION: Invokes the specified workflow through Shipyard. Returns the
|
||||
id of the action invoked so that it can be queried subsequently. \n
|
||||
FORMAT: shipyard create action <action command> --param=<parameter>
|
||||
(repeatable) \n
|
||||
EXAMPLE: shipyard create action redeploy_server --param="server-name=mcp"
|
||||
"""
|
||||
|
||||
SHORT_DESC_ACTION = (
|
||||
"Invokes the specified workflow through Shipyard. Returns "
|
||||
"the id of the action invoked so that it can be queried "
|
||||
"subsequently.")
|
||||
|
||||
|
||||
@create.command(name='action', help=DESC_ACTION, short_help=SHORT_DESC_ACTION)
|
||||
@click.argument('action_name')
|
||||
@click.option(
|
||||
'--param',
|
||||
multiple=True,
|
||||
help="A parameter to be provided to the action being invoked.(Repeatable)")
|
||||
@click.pass_context
|
||||
def create_action(ctx, action_name, param):
|
||||
check_action_command(ctx, action_name)
|
||||
|
||||
if not param and action_name is 'redeploy_server':
|
||||
ctx.fail('At least one parameter must be specified using '
|
||||
'--param="<parameter>" with action redeploy_server')
|
||||
else:
|
||||
param = check_reformat_parameter(ctx, param)
|
||||
click.echo(
|
||||
CreateAction(ctx, action_name, param).invoke_and_return_resp())
|
||||
|
||||
|
||||
DESC_CONFIGDOCS = """
|
||||
COMMAND: configdocs \n
|
||||
DESCRIPTION: Load documents into the Shipyard Buffer. \n
|
||||
FORMAT: shipyard create configdocs <collection> [--append | --replace]
|
||||
[--filename=<filename> (repeatable) | --directory=<directory] \n
|
||||
EXAMPLE: shipyard create configdocs design --append
|
||||
--filename=site_design.yaml
|
||||
"""
|
||||
|
||||
SHORT_DESC_CONFIGDOCS = "Load documents into the Shipyard Buffer."
|
||||
|
||||
|
||||
@create.command(
|
||||
name='configdocs', help=DESC_CONFIGDOCS, short_help=SHORT_DESC_CONFIGDOCS)
|
||||
@click.argument('collection')
|
||||
@click.option(
|
||||
'--append',
|
||||
flag_value=True,
|
||||
help='Add the collection to the Shipyard Buffer. ')
|
||||
@click.option(
|
||||
'--replace',
|
||||
flag_value=True,
|
||||
help='Clear the Shipyard Buffer and replace it with the specified '
|
||||
'contents. ')
|
||||
@click.option(
|
||||
'--filename',
|
||||
multiple=True,
|
||||
type=click.Path(exists=True),
|
||||
help='The file name to use as the contents of the collection. '
|
||||
'(Repeatable). ')
|
||||
@click.option(
|
||||
'--directory',
|
||||
type=click.Path(exists=True),
|
||||
help='A directory containing documents that will be joined and loaded as '
|
||||
'a collection.')
|
||||
@click.pass_context
|
||||
def create_configdocs(ctx, collection, filename, directory, append, replace):
|
||||
|
||||
if (append and replace):
|
||||
ctx.fail('Either append or replace may be selected but not both')
|
||||
if (not filename and not directory) or (filename and directory):
|
||||
ctx.fail('Please specify one or more filenames using '
|
||||
'--filename="<filename>" OR a directory using '
|
||||
'--directory="<directory>"')
|
||||
if append:
|
||||
create_buffer = 'append'
|
||||
elif replace:
|
||||
create_buffer = 'replace'
|
||||
else:
|
||||
create_buffer = None
|
||||
|
||||
if directory:
|
||||
filename += tuple(
|
||||
[each for each in os.listdir(directory) if each.endswith('.yaml')])
|
||||
if filename is None:
|
||||
ctx.fail('The directory does not contain any YAML files. Please '
|
||||
'enter one or more YAML files or a directory that '
|
||||
'contains one or more YAML files.')
|
||||
docs = []
|
||||
|
||||
for file in filename:
|
||||
with open(file, 'r') as stream:
|
||||
if file.endswith(".yaml"):
|
||||
try:
|
||||
docs += list(yaml.safe_load_all(stream))
|
||||
except yaml.YAMLError as exc:
|
||||
ctx.fail('YAML file {} is invalid because {}'
|
||||
.format(file, exc))
|
||||
else:
|
||||
ctx.fail('The file {} is not a YAML file. Please enter '
|
||||
'only YAML files.'.format(file))
|
||||
|
||||
data = yaml.safe_dump_all(docs)
|
||||
|
||||
click.echo(
|
||||
CreateConfigdocs(ctx, collection, create_buffer, data)
|
||||
.invoke_and_return_resp())
|
0
shipyard_client/cli/describe/__init__.py
Normal file
0
shipyard_client/cli/describe/__init__.py
Normal file
77
shipyard_client/cli/describe/actions.py
Normal file
77
shipyard_client/cli/describe/actions.py
Normal file
@ -0,0 +1,77 @@
|
||||
# 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.
|
||||
|
||||
from shipyard_client.cli.action import CliAction
|
||||
from shipyard_client.cli.output_formatting import output_formatting
|
||||
|
||||
|
||||
class DescribeAction(CliAction):
|
||||
"""Action to Describe Action"""
|
||||
|
||||
def __init__(self, ctx, action_id):
|
||||
"""Initializes api_client, sets parameters, and sets output_format"""
|
||||
super().__init__(ctx)
|
||||
self.logger.debug(
|
||||
"DescribeAction action initialized with action_id=%s", action_id)
|
||||
self.action_id = action_id
|
||||
self.output_format = ctx.obj['FORMAT']
|
||||
|
||||
def invoke(self):
|
||||
"""Calls API Client and formats response from API Client"""
|
||||
self.logger.debug("Calling API Client get_action_detail.")
|
||||
self.resp_txt = output_formatting(
|
||||
self.output_format,
|
||||
self.api_client.get_action_detail(action_id=self.action_id))
|
||||
|
||||
|
||||
class DescribeStep(CliAction):
|
||||
"""Action to Describe Step"""
|
||||
|
||||
def __init__(self, ctx, action_id, step_id):
|
||||
"""Initializes api_client, sets parameters, and sets output_format"""
|
||||
super().__init__(ctx)
|
||||
self.logger.debug(
|
||||
"DescribeStep action initialized with action_id=%s and step_id=%s",
|
||||
action_id, step_id)
|
||||
self.action_id = action_id
|
||||
self.step_id = step_id
|
||||
self.output_format = ctx.obj['FORMAT']
|
||||
|
||||
def invoke(self):
|
||||
"""Calls API Client and formats response from API Client"""
|
||||
self.logger.debug("Calling API Client get_step_detail.")
|
||||
self.resp_txt = output_formatting(self.output_format,
|
||||
self.api_client.get_step_detail(
|
||||
action_id=self.action_id,
|
||||
step_id=self.step_id))
|
||||
|
||||
|
||||
class DescribeValidation(CliAction):
|
||||
"""Action to Describe Validation"""
|
||||
|
||||
def __init__(self, ctx, action_id, validation_id):
|
||||
"""Initializes api_client, sets parameters, and sets output_format"""
|
||||
super().__init__(ctx)
|
||||
self.logger.debug(
|
||||
'DescribeValidation action initialized with action_id=%s'
|
||||
'and validation_id=%s', action_id, validation_id)
|
||||
self.validation_id = validation_id
|
||||
self.action_id = action_id
|
||||
self.output_format = ctx.obj['FORMAT']
|
||||
|
||||
def invoke(self):
|
||||
"""Calls API Client and formats response from API Client"""
|
||||
self.logger.debug("Calling API Client get_validation_detail.")
|
||||
self.resp_txt = output_formatting(
|
||||
self.output_format,
|
||||
self.api_client.get_validation_detail(
|
||||
action_id=self.action_id, validation_id=self.validation_id))
|
153
shipyard_client/cli/describe/commands.py
Normal file
153
shipyard_client/cli/describe/commands.py
Normal file
@ -0,0 +1,153 @@
|
||||
# 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.
|
||||
|
||||
# Describe command
|
||||
|
||||
import click
|
||||
|
||||
from click_default_group import DefaultGroup
|
||||
|
||||
from shipyard_client.cli.describe.actions import DescribeAction
|
||||
from shipyard_client.cli.describe.actions import DescribeStep
|
||||
from shipyard_client.cli.describe.actions import DescribeValidation
|
||||
from shipyard_client.cli.input_checks import check_id
|
||||
|
||||
|
||||
@click.group(cls=DefaultGroup, default='describe_default_command')
|
||||
@click.pass_context
|
||||
def describe(ctx):
|
||||
"""
|
||||
Describe the action, step, or validation. \n
|
||||
For more information on describe commands
|
||||
please enter the describe command followed by '--help' \n
|
||||
Example: shipyard describe action --help \n
|
||||
|
||||
FOR NAMESPACE ENTRIES: \n
|
||||
COMMAND: (no sub command) \n
|
||||
DESCRIPTION: Retrieves the detailed information about the supplied
|
||||
namespaced item. \n
|
||||
FORMAT: shipyard describe <namespace item> \n
|
||||
EXAMPLE: shipyard describe action/01BTG32JW87G0YKA1K29TKNAFX | shipyard
|
||||
describe step/01BTG32JW87G0YKA1K29TKNAFX/preflight | shipyard describe
|
||||
validation/01BTG32JW87G0YKA1K29TKNAFX/01BTG3PKBS15KCKFZ56XXXBGF2
|
||||
"""
|
||||
|
||||
|
||||
@describe.command('describe_default_command', short_help="")
|
||||
@click.argument('namespace_item')
|
||||
@click.pass_context
|
||||
def describe_default_command(ctx, namespace_item):
|
||||
|
||||
try:
|
||||
namespace = namespace_item.split("/")
|
||||
if (namespace[0] == 'action'):
|
||||
ctx.invoke(describe_action, action_id=namespace[1])
|
||||
elif (namespace[0] == 'step'):
|
||||
ctx.invoke(
|
||||
describe_step, step_id=namespace[2], action=namespace[1])
|
||||
elif (namespace[0] == 'validation'):
|
||||
ctx.invoke(
|
||||
describe_validation,
|
||||
validation_id=namespace[1],
|
||||
action=namespace[2])
|
||||
else:
|
||||
raise
|
||||
except:
|
||||
ctx.fail("Invalid namespace item. Please utilize one of the following"
|
||||
" formats for the namespace item. \n"
|
||||
"action: action/action id \n"
|
||||
"step: step/action id/step id \n"
|
||||
"validation: validation/validation id/action id")
|
||||
|
||||
|
||||
DESC_ACTION = """
|
||||
COMMAND: describe action \n
|
||||
DESCRIPTION: Retrieves the detailed information about the supplied action
|
||||
id. \n
|
||||
FORMAT: shipyard describe action <action id> \n
|
||||
EXAMPLE: shipyard describe action 01BTG32JW87G0YKA1K29TKNAFX
|
||||
"""
|
||||
|
||||
SHORT_DESC_ACTION = ("Retrieves the detailed information about the supplied"
|
||||
"action id.")
|
||||
|
||||
|
||||
@describe.command('action', help=DESC_ACTION, short_help=SHORT_DESC_ACTION)
|
||||
@click.argument('action_id')
|
||||
@click.pass_context
|
||||
def describe_action(ctx, action_id):
|
||||
|
||||
if not action_id:
|
||||
click.fail("An action id argument must be passed.")
|
||||
|
||||
check_id(ctx, action_id)
|
||||
|
||||
click.echo(DescribeAction(ctx, action_id).invoke_and_return_resp())
|
||||
|
||||
|
||||
DESC_STEP = """
|
||||
COMMAND: describe step \n
|
||||
DESCRIPTION: Retrieves the step details associated with an action and step. \n
|
||||
FORMAT: shipyard describe step <step id> --action=<action id> \n
|
||||
EXAMPLE: shipyard describe step preflight
|
||||
--action=01BTG32JW87G0YKA1K29TKNAFX 786d416c-bf70-4705-a9bd-6670a4d7bb60
|
||||
"""
|
||||
|
||||
SHORT_DESC_STEP = ("Retrieves the step details associated with an action and "
|
||||
"step.")
|
||||
|
||||
|
||||
@describe.command('step', help=DESC_STEP, short_help=SHORT_DESC_STEP)
|
||||
@click.argument('step_id')
|
||||
@click.option(
|
||||
'--action',
|
||||
'-a',
|
||||
help='The action id that provides the context for this step')
|
||||
@click.pass_context
|
||||
def describe_step(ctx, step_id, action):
|
||||
|
||||
check_id(ctx, action)
|
||||
|
||||
click.echo(DescribeStep(ctx, action, step_id).invoke_and_return_resp())
|
||||
|
||||
|
||||
DESC_VALIDATION = """
|
||||
COMMAND: describe validation \n
|
||||
DESCRIPTION: Retrieves the validation details assocaited with an action and
|
||||
validation id. \n
|
||||
FORMAT: shipyard describe validation <validation id> --action=<action id>\n
|
||||
EXAMPLE: shipyard describe validation 01BTG3PKBS15KCKFZ56XXXBGF2
|
||||
--action=01BTG32JW87G0YKA1K29TKNAFX
|
||||
"""
|
||||
|
||||
SHORT_DESC_VALIDATION = ("Retrieves the validation details assocaited with an "
|
||||
"action and validation id.")
|
||||
|
||||
|
||||
@describe.command(
|
||||
'validation', help=DESC_VALIDATION, short_help=SHORT_DESC_VALIDATION)
|
||||
@click.argument('validation_id')
|
||||
@click.option(
|
||||
'--action',
|
||||
'-a',
|
||||
help='The action id that provides the context for this validation')
|
||||
@click.pass_context
|
||||
def describe_validation(ctx, validation_id, action):
|
||||
|
||||
check_id(ctx, validation_id)
|
||||
check_id(ctx, action)
|
||||
|
||||
click.echo(
|
||||
DescribeValidation(ctx, validation_id, action)
|
||||
.invoke_and_return_resp())
|
0
shipyard_client/cli/get/__init__.py
Normal file
0
shipyard_client/cli/get/__init__.py
Normal file
70
shipyard_client/cli/get/actions.py
Normal file
70
shipyard_client/cli/get/actions.py
Normal file
@ -0,0 +1,70 @@
|
||||
# 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.
|
||||
|
||||
from shipyard_client.cli.action import CliAction
|
||||
from shipyard_client.cli.output_formatting import output_formatting
|
||||
|
||||
|
||||
class GetActions(CliAction):
|
||||
"""Action to Get Actions"""
|
||||
|
||||
def __init__(self, ctx):
|
||||
"""Initializes api_client, sets parameters, and sets output_format"""
|
||||
super().__init__(ctx)
|
||||
self.logger.debug("GetActions action initialized.")
|
||||
self.output_format = ctx.obj['FORMAT']
|
||||
|
||||
def invoke(self):
|
||||
"""Calls API Client and formats response from API Client"""
|
||||
self.logger.debug("Calling API Client get_actions.")
|
||||
self.resp_txt = output_formatting(self.output_format,
|
||||
self.api_client.get_actions())
|
||||
|
||||
|
||||
class GetConfigdocs(CliAction):
|
||||
"""Action to Get Configdocs"""
|
||||
|
||||
def __init__(self, ctx, collection, version):
|
||||
"""Initializes api_client, sets parameters, and sets output_format"""
|
||||
super().__init__(ctx)
|
||||
self.logger.debug(
|
||||
"GetConfigdocs action initialized with collection=%s and "
|
||||
"version=%s" % (collection, version))
|
||||
self.collection = collection
|
||||
self.version = version
|
||||
self.output_format = ctx.obj['FORMAT']
|
||||
|
||||
def invoke(self):
|
||||
"""Calls API Client and formats response from API Client"""
|
||||
self.logger.debug("Calling API Client get_configdocs.")
|
||||
self.resp_txt = output_formatting(self.output_format,
|
||||
self.api_client.get_configdocs(
|
||||
collection_id=self.collection,
|
||||
version=self.version))
|
||||
|
||||
|
||||
class GetRenderedConfigdocs(CliAction):
|
||||
"""Action to Get Rendered Configdocs"""
|
||||
|
||||
def __init__(self, ctx, version):
|
||||
"""Initializes api_client, sets parameters, and sets output_format"""
|
||||
super().__init__(ctx)
|
||||
self.logger.debug("GetRenderedConfigdocs action initialized")
|
||||
self.version = version
|
||||
self.output_format = ctx.obj['FORMAT']
|
||||
|
||||
def invoke(self):
|
||||
"""Calls API Client and formats response from API Client"""
|
||||
self.logger.debug("Calling API Client get_rendereddocs.")
|
||||
self.resp_txt = output_formatting(
|
||||
self.output_format,
|
||||
self.api_client.get_rendereddocs(version=self.version))
|
143
shipyard_client/cli/get/commands.py
Normal file
143
shipyard_client/cli/get/commands.py
Normal file
@ -0,0 +1,143 @@
|
||||
# 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.
|
||||
|
||||
# Get command
|
||||
|
||||
import click
|
||||
|
||||
from shipyard_client.cli.get.actions import GetActions
|
||||
from shipyard_client.cli.get.actions import GetConfigdocs
|
||||
from shipyard_client.cli.get.actions import GetRenderedConfigdocs
|
||||
|
||||
|
||||
@click.group()
|
||||
@click.pass_context
|
||||
def get(ctx):
|
||||
"""
|
||||
Get the actions, confidocs, or renderedconfigdocs. \n
|
||||
For more information on get commands
|
||||
please enter the get command followed by '--help' \n
|
||||
Example: shipyard get actions --help
|
||||
"""
|
||||
|
||||
|
||||
DESC_ACTIONS = """
|
||||
COMMAND: actions \n
|
||||
DESCRIPTION: Lists the actions that have been invoked. \n
|
||||
FORMAT: shipyard get actions \n
|
||||
EXAMPLE: shipyard get actions
|
||||
"""
|
||||
|
||||
SHORT_DESC_ACTIONS = "Lists the actions that have been invoked."
|
||||
|
||||
|
||||
@get.command(name='actions', help=DESC_ACTIONS, short_help=SHORT_DESC_ACTIONS)
|
||||
@click.pass_context
|
||||
def get_actions(ctx):
|
||||
|
||||
click.echo(GetActions(ctx).invoke_and_return_resp())
|
||||
|
||||
|
||||
DESC_CONFIGDOCS = """
|
||||
COMMAND: configdocs \n
|
||||
DESCRIPTION: Retrieve documents loaded into Shipyard, either committed or
|
||||
from the Shipyard Buffer. \n
|
||||
FORMAT: shipyard get configdocs <collection> [--committed | --buffer] \n
|
||||
EXAMPLE: shipyard get configdocs design
|
||||
"""
|
||||
|
||||
SHORT_DESC_CONFIGDOCS = ("Retrieve documents loaded into Shipyard, either "
|
||||
"committed or from the Shipyard Buffer.")
|
||||
|
||||
|
||||
@get.command(
|
||||
name='configdocs', help=DESC_CONFIGDOCS, short_help=SHORT_DESC_CONFIGDOCS)
|
||||
@click.argument('collection')
|
||||
@click.option(
|
||||
'--committed',
|
||||
'-c',
|
||||
flag_value='committed',
|
||||
help='Retrieve the documents that have last been committed for this '
|
||||
'collection')
|
||||
@click.option(
|
||||
'--buffer',
|
||||
'-b',
|
||||
flag_value='buffer',
|
||||
help='Retrive the documents that have been loaded into Shipyard since the '
|
||||
'prior commit. If no documents have been loaded into the buffer for this '
|
||||
'collection, this will return an empty response (default)')
|
||||
@click.pass_context
|
||||
def get_configdocs(ctx, collection, buffer, committed):
|
||||
|
||||
if buffer and committed:
|
||||
ctx.fail(
|
||||
'You must choose whether to retrive the committed OR from the '
|
||||
'Shipyard Buffer with --committed or --buffer. ')
|
||||
|
||||
if (not buffer and not committed) or buffer:
|
||||
version = 'buffer'
|
||||
|
||||
if committed:
|
||||
version = 'committed'
|
||||
|
||||
click.echo(
|
||||
GetConfigdocs(ctx, collection, version).invoke_and_return_resp())
|
||||
|
||||
|
||||
DESC_RENDEREDCONFIGDOCS = """
|
||||
COMMAND: renderedconfigdocs \n
|
||||
DESCRIPTION: Retrieve the rendered version of documents loaded into
|
||||
Shipyard. Rendered documents are the "final" version of the documents after
|
||||
applying Deckhand layering and substitution. \n
|
||||
FORMAT: shipyard get renderedconfigdocs [--committed | --buffer] \n
|
||||
EXAMPLE: shipyard get renderedconfigdocs
|
||||
"""
|
||||
|
||||
SHORT_DESC_RENDEREDCONFIGDOCS = (
|
||||
"Retrieve the rendered version of documents "
|
||||
"loaded into Shipyard. Rendered documents are "
|
||||
"the 'final' version of the documents after "
|
||||
"applying Deckhand layering and substitution.")
|
||||
|
||||
|
||||
@get.command(
|
||||
name='renderedconfigdocs',
|
||||
help=DESC_RENDEREDCONFIGDOCS,
|
||||
short_help=SHORT_DESC_RENDEREDCONFIGDOCS)
|
||||
@click.option(
|
||||
'--committed',
|
||||
'-c',
|
||||
flag_value='committed',
|
||||
help='Retrieve the documents that have last been committed.')
|
||||
@click.option(
|
||||
'--buffer',
|
||||
'-b',
|
||||
flag_value='buffer',
|
||||
help='Retrieve the documents that have been loaded into Shipyard since the'
|
||||
' prior commit. (default)')
|
||||
@click.pass_context
|
||||
def get_renderedconfigdocs(ctx, buffer, committed):
|
||||
|
||||
if buffer and committed:
|
||||
ctx.fail(
|
||||
'You must choose whether to retrive the committed documents OR the'
|
||||
' docutments in the Shipyard Buffer with --committed or --buffer.')
|
||||
|
||||
if committed:
|
||||
version = 'committed'
|
||||
|
||||
else:
|
||||
version = 'buffer'
|
||||
|
||||
click.echo(GetRenderedConfigdocs(ctx, version).invoke_and_return_resp())
|
0
shipyard_client/cli/help/__init__.py
Normal file
0
shipyard_client/cli/help/__init__.py
Normal file
49
shipyard_client/cli/help/commands.py
Normal file
49
shipyard_client/cli/help/commands.py
Normal file
@ -0,0 +1,49 @@
|
||||
# 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.
|
||||
|
||||
# help command
|
||||
|
||||
import click
|
||||
|
||||
from shipyard_client.cli.help.output import default, actions, configdocs
|
||||
|
||||
|
||||
@click.group()
|
||||
def help():
|
||||
"""Shipyard Help Command"""
|
||||
pass
|
||||
|
||||
|
||||
@help.command(name='help')
|
||||
@click.argument('topic', required=False)
|
||||
@click.pass_context
|
||||
def help(ctx, topic=None):
|
||||
"""
|
||||
Display detailed information on topics. \n
|
||||
COMMAND: help \n
|
||||
DESCRIPTION: Provides topical help for Shipyard. Note that --help will
|
||||
provide more specific command help. \n
|
||||
FORMAT: shipyard help <topic> \n
|
||||
EXAMPLE: shipyard help configdocs \n
|
||||
"""
|
||||
|
||||
if topic is None:
|
||||
click.echo(default())
|
||||
elif topic == 'actions':
|
||||
click.echo(actions())
|
||||
elif topic == 'configdocs':
|
||||
click.echo(configdocs())
|
||||
else:
|
||||
ctx.fail("Invalid topic. Run command 'shipyard help' for a list of "
|
||||
" available topics.")
|
64
shipyard_client/cli/help/output.py
Normal file
64
shipyard_client/cli/help/output.py
Normal file
@ -0,0 +1,64 @@
|
||||
# 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.
|
||||
|
||||
|
||||
def default():
|
||||
return '''THE SHIPYARD COMMAND
|
||||
The base shipyard command supports options that determine cross-CLI behaviors.
|
||||
|
||||
FORMAT
|
||||
shipyard [--context-marker=<uuid>] [--os_{various}=<value>]
|
||||
[--debug/--no-debug] [--output-format] <subcommands>
|
||||
|
||||
Please Note: --os_auth_url is required for every command except shipyard help
|
||||
<topic>.
|
||||
|
||||
TOPICS
|
||||
For information of the following topics, run shipyard help <topic>
|
||||
actions
|
||||
configdocs'''
|
||||
|
||||
|
||||
def actions():
|
||||
return '''ACTIONS
|
||||
|
||||
|
||||
Supported Actions
|
||||
No supported actions at this time.
|
||||
|
||||
|
||||
Actions Under Development
|
||||
|
||||
deploy_site: Triggers the initial deployment of a site using the latest
|
||||
committed configuration documents.
|
||||
|
||||
update_site: Triggers the initial deployment of a site, using the latest
|
||||
committed configuration documents.
|
||||
Steps:
|
||||
(same as deploy_site)
|
||||
|
||||
redeploy_server: Using parameters to indicate which server(s), triggers a
|
||||
redeployment of server to the last known good design and
|
||||
secrets.
|
||||
'''
|
||||
|
||||
|
||||
def configdocs():
|
||||
return '''CONFIGDOCS
|
||||
The Shipyard Buffer Documents
|
||||
|
||||
Supported Commands:
|
||||
shipyard commit configdocs
|
||||
shipyard create configdocs
|
||||
shipyard get configdocs'''
|
67
shipyard_client/cli/input_checks.py
Normal file
67
shipyard_client/cli/input_checks.py
Normal file
@ -0,0 +1,67 @@
|
||||
# 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-1.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.
|
||||
|
||||
|
||||
def check_action_command(ctx, action_command):
|
||||
"""verifies the action command is valid"""
|
||||
if (action_command != "deploy_site") and (
|
||||
action_command != "update_site") and (action_command !=
|
||||
"redeploy_server"):
|
||||
ctx.fail('Invalid action command. The action commands available are '
|
||||
'deploy_site, update_site, and redeploy_server.')
|
||||
|
||||
|
||||
def check_control_action(ctx, action):
|
||||
"""verifies the control action is valid"""
|
||||
if (action != 'pause') and (action != 'unpause') and (action != 'stop'):
|
||||
ctx.fail('Invalid action. Please enter pause, unpause, or stop.')
|
||||
|
||||
|
||||
def check_id(ctx, id):
|
||||
"""verifies the id is valid"""
|
||||
if (len(id) != 26):
|
||||
ctx.fail('Invalid ID. ID can only be 26 characters.')
|
||||
if not id.isalnum():
|
||||
ctx.fail('Invalid ID. ID can only contain letters and numbers.')
|
||||
|
||||
|
||||
def validate_auth_vars(self, ctx):
|
||||
""" Checks that the required authurization varible have been entered """
|
||||
|
||||
required_auth_vars = ['auth_url']
|
||||
auth_vars = self.api_parameters['auth_vars']
|
||||
for var in required_auth_vars:
|
||||
if auth_vars[var] is None:
|
||||
self.resp_txt += (
|
||||
'Missing the required authorization variable: ' + var + '\n')
|
||||
if self.resp_txt is not "":
|
||||
self.resp_txt += ('\nMissing the following additional authorization '
|
||||
'options: ')
|
||||
for var in auth_vars:
|
||||
if auth_vars[var] is None and var not in required_auth_vars:
|
||||
self.resp_txt += '\n--os_' + var
|
||||
ctx.fail(self.resp_txt)
|
||||
|
||||
|
||||
def check_reformat_parameter(ctx, param):
|
||||
param_dictionary = {}
|
||||
try:
|
||||
for p in param:
|
||||
values = p.split('=')
|
||||
param_dictionary[values[0]] = values[1]
|
||||
except:
|
||||
ctx.fail(
|
||||
"Invalid parameter or parameter format for " + p +
|
||||
". Please utilize the format: <parameter name>=<parameter value>")
|
||||
return param_dictionary
|
47
shipyard_client/cli/output_formatting.py
Normal file
47
shipyard_client/cli/output_formatting.py
Normal file
@ -0,0 +1,47 @@
|
||||
# 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-1.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.
|
||||
|
||||
import json
|
||||
import yaml
|
||||
|
||||
|
||||
def output_formatting(output_format, response):
|
||||
"""formats response from api_client"""
|
||||
if output_format == 'raw':
|
||||
return response.text
|
||||
else: # assume formatted
|
||||
return formatted(response)
|
||||
|
||||
|
||||
def formatted(response):
|
||||
"""Formats either json or yaml depending on call"""
|
||||
call = response.headers['Content-Type']
|
||||
if 'json' in call:
|
||||
try:
|
||||
input = response.json()
|
||||
return (json.dumps(input, sort_keys=True, indent=4))
|
||||
except ValueError:
|
||||
return ("This is not json and could not be printed as such. \n " +
|
||||
response.text)
|
||||
|
||||
else: # all others should be yaml
|
||||
try:
|
||||
return (yaml.dump_all(
|
||||
yaml.safe_load_all(response.content),
|
||||
width=79,
|
||||
indent=4,
|
||||
default_flow_style=False))
|
||||
except ValueError:
|
||||
return ("This is not yaml and could not be printed as such.\n " +
|
||||
response.text)
|
@ -116,8 +116,7 @@ def test_commit_configs(*args):
|
||||
def test_get_actions(*args):
|
||||
shipyard_client = get_api_client()
|
||||
result = shipyard_client.get_actions()
|
||||
assert result['url'] == '{}/actions'.format(
|
||||
shipyard_client.shipyard_url)
|
||||
assert result['url'] == '{}/actions'.format(shipyard_client.shipyard_url)
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@ -129,8 +128,7 @@ def test_post_actions(*args):
|
||||
parameters = {'hello': 'world'}
|
||||
result = shipyard_client.post_actions(name, parameters)
|
||||
data = json.loads(result['data'])
|
||||
assert result['url'] == '{}/actions'.format(
|
||||
shipyard_client.shipyard_url)
|
||||
assert result['url'] == '{}/actions'.format(shipyard_client.shipyard_url)
|
||||
assert data['name'] == name
|
||||
assert data['parameters']['hello'] == 'world'
|
||||
|
||||
@ -154,9 +152,8 @@ def test_get_val_details(*args):
|
||||
action_id = 'GoodAction'
|
||||
validation_id = 'Validation'
|
||||
result = shipyard_client.get_validation_detail(action_id, validation_id)
|
||||
assert result[
|
||||
'url'] == '{}/actions/{}/validationdetails/{}'.format(
|
||||
shipyard_client.shipyard_url, action_id, validation_id)
|
||||
assert result['url'] == '{}/actions/{}/validationdetails/{}'.format(
|
||||
shipyard_client.shipyard_url, action_id, validation_id)
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@ -190,8 +187,8 @@ def test_get_workflows(*args):
|
||||
shipyard_client = get_api_client()
|
||||
since_mode = 'TestSince'
|
||||
result = shipyard_client.get_workflows(since_mode)
|
||||
assert result['url'] == '{}/workflows'.format(
|
||||
shipyard_client.shipyard_url, since_mode)
|
||||
assert result['url'] == '{}/workflows'.format(shipyard_client.shipyard_url,
|
||||
since_mode)
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
|
0
shipyard_client/tests/unit/cli/__init__.py
Normal file
0
shipyard_client/tests/unit/cli/__init__.py
Normal file
66
shipyard_client/tests/unit/cli/commit/test_commit_actions.py
Normal file
66
shipyard_client/tests/unit/cli/commit/test_commit_actions.py
Normal file
@ -0,0 +1,66 @@
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
|
||||
from shipyard_client.cli.commit.actions import CommitConfigdocs
|
||||
from shipyard_client.api_client.base_client import BaseClient
|
||||
from shipyard_client.tests.unit.cli.replace_api_client import \
|
||||
replace_base_constructor, replace_post_rep, replace_get_resp, \
|
||||
replace_output_formatting
|
||||
from shipyard_client.tests.unit.cli.utils import temporary_context
|
||||
from shipyard_client.api_client.shipyardclient_context import \
|
||||
ShipyardClientContext
|
||||
|
||||
auth_vars = {
|
||||
'project_domain_name': 'projDomainTest',
|
||||
'user_domain_name': 'userDomainTest',
|
||||
'project_name': 'projectTest',
|
||||
'username': 'usernameTest',
|
||||
'password': 'passwordTest',
|
||||
'auth_url': 'urlTest'
|
||||
}
|
||||
|
||||
api_parameters = {
|
||||
'auth_vars': auth_vars,
|
||||
'context_marker': 'UUID',
|
||||
'debug': False
|
||||
}
|
||||
|
||||
|
||||
class MockCTX():
|
||||
pass
|
||||
|
||||
|
||||
ctx = MockCTX()
|
||||
ctx.obj = {}
|
||||
ctx.obj['API_PARAMETERS'] = api_parameters
|
||||
ctx.obj['FORMAT'] = 'format'
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@mock.patch.object(BaseClient, 'post_resp', replace_post_rep)
|
||||
@mock.patch.object(BaseClient, 'get_resp', replace_get_resp)
|
||||
@mock.patch.object(ShipyardClientContext, '__init__', temporary_context)
|
||||
@mock.patch(
|
||||
'shipyard_client.cli.commit.actions.output_formatting',
|
||||
side_effect=replace_output_formatting)
|
||||
def test_CommitConfigdocs(*args):
|
||||
response = CommitConfigdocs(ctx, True).invoke_and_return_resp()
|
||||
# test correct function was called
|
||||
url = response.get('url')
|
||||
assert 'commitconfigdocs' in url
|
||||
# test function was called with correct parameters
|
||||
params = response.get('params')
|
||||
assert params.get('force') is True
|
@ -0,0 +1,44 @@
|
||||
# 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.
|
||||
from click.testing import CliRunner
|
||||
from mock import patch, ANY
|
||||
|
||||
from shipyard_client.cli.commit.actions import CommitConfigdocs
|
||||
from shipyard_client.cli.commands import shipyard
|
||||
|
||||
auth_vars = ('--os_project_domain_name=OS_PROJECT_DOMAIN_NAME_test '
|
||||
'--os_user_domain_name=OS_USER_DOMAIN_NAME_test '
|
||||
'--os_project_name=OS_PROJECT_NAME_test '
|
||||
'--os_username=OS_USERNAME_test --os_password=OS_PASSWORD_test '
|
||||
'--os_auth_url=OS_AUTH_URL_test')
|
||||
|
||||
|
||||
def test_commit_configdocs(*args):
|
||||
"""test commit_configdocs"""
|
||||
runner = CliRunner()
|
||||
with patch.object(CommitConfigdocs, '__init__') as mock_method:
|
||||
results = runner.invoke(shipyard, [auth_vars, 'commit', 'configdocs'])
|
||||
mock_method.assert_called_once_with(ANY, False)
|
||||
|
||||
|
||||
def test_commit_configdocs_negative():
|
||||
"""
|
||||
negative unit test for commit configdocs command
|
||||
verifies invalid argument results in error
|
||||
"""
|
||||
invalid_arg = 'invalid'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(shipyard,
|
||||
[auth_vars, 'commit', 'configdocs', invalid_arg])
|
||||
assert 'Error' in results.output
|
@ -0,0 +1,69 @@
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
|
||||
from shipyard_client.cli.control.actions import Control
|
||||
from shipyard_client.api_client.base_client import BaseClient
|
||||
from shipyard_client.tests.unit.cli.replace_api_client import \
|
||||
replace_base_constructor, replace_post_rep, replace_get_resp, \
|
||||
replace_output_formatting
|
||||
from shipyard_client.tests.unit.cli.utils import temporary_context
|
||||
from shipyard_client.api_client.shipyardclient_context import \
|
||||
ShipyardClientContext
|
||||
|
||||
auth_vars = {
|
||||
'project_domain_name': 'projDomainTest',
|
||||
'user_domain_name': 'userDomainTest',
|
||||
'project_name': 'projectTest',
|
||||
'username': 'usernameTest',
|
||||
'password': 'passwordTest',
|
||||
'auth_url': 'urlTest'
|
||||
}
|
||||
|
||||
api_parameters = {
|
||||
'auth_vars': auth_vars,
|
||||
'context_marker': 'UUID',
|
||||
'debug': False
|
||||
}
|
||||
|
||||
|
||||
class MockCTX():
|
||||
pass
|
||||
|
||||
|
||||
ctx = MockCTX()
|
||||
ctx.obj = {}
|
||||
ctx.obj['API_PARAMETERS'] = api_parameters
|
||||
ctx.obj['FORMAT'] = 'format'
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@mock.patch.object(BaseClient, 'post_resp', replace_post_rep)
|
||||
@mock.patch.object(BaseClient, 'get_resp', replace_get_resp)
|
||||
@mock.patch.object(ShipyardClientContext, '__init__', temporary_context)
|
||||
@mock.patch(
|
||||
'shipyard_client.cli.control.actions.output_formatting',
|
||||
side_effect=replace_output_formatting)
|
||||
def test_Control(*args):
|
||||
control_verb = 'pause'
|
||||
id = '01BTG32JW87G0YKA1K29TKNAFX'
|
||||
response = Control(ctx, control_verb, id).invoke_and_return_resp()
|
||||
# test correct function was called
|
||||
url = response.get('url')
|
||||
assert 'control' in url
|
||||
|
||||
# test function was called with correct parameters
|
||||
assert control_verb in url
|
||||
assert id in url
|
123
shipyard_client/tests/unit/cli/control/test_control_commands.py
Normal file
123
shipyard_client/tests/unit/cli/control/test_control_commands.py
Normal file
@ -0,0 +1,123 @@
|
||||
# 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.
|
||||
|
||||
from click.testing import CliRunner
|
||||
from mock import patch, ANY
|
||||
|
||||
from shipyard_client.cli.control.actions import Control
|
||||
from shipyard_client.cli.commands import shipyard
|
||||
|
||||
auth_vars = ('--os_project_domain_name=OS_PROJECT_DOMAIN_NAME_test '
|
||||
'--os_user_domain_name=OS_USER_DOMAIN_NAME_test '
|
||||
'--os_project_name=OS_PROJECT_NAME_test '
|
||||
'--os_username=OS_USERNAME_test --os_password=OS_PASSWORD_test '
|
||||
'--os_auth_url=OS_AUTH_URL_test')
|
||||
|
||||
|
||||
def test_control_pause(*args):
|
||||
"""check that control_pause works for both type & id, or qaulified name"""
|
||||
target_type = 'action'
|
||||
id = '01BTG32JW87G0YKA1K29TKNAFX'
|
||||
runner = CliRunner()
|
||||
with patch.object(Control, '__init__') as mock_method:
|
||||
results = runner.invoke(shipyard,
|
||||
[auth_vars, 'pause', target_type, id])
|
||||
mock_method.assert_called_once_with(ANY, 'pause', id)
|
||||
|
||||
qualified_name = target_type + "/" + id
|
||||
with patch.object(Control, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [auth_vars, 'pause', qualified_name])
|
||||
mock_method.assert_called_once_with(ANY, 'pause', id)
|
||||
|
||||
|
||||
def test_control_pause_negative(*args):
|
||||
"""
|
||||
negative unit test for control pause command
|
||||
verifies invalid id and qualified name results in error
|
||||
"""
|
||||
target_type = 'action'
|
||||
id = 'invalid id'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(shipyard, [auth_vars, 'pause', target_type, id])
|
||||
assert 'Error' in results.output
|
||||
|
||||
qualified_name = 'invalid qualified name'
|
||||
results = runner.invoke(shipyard, [auth_vars, 'pause', qualified_name])
|
||||
assert 'Error' in results.output
|
||||
|
||||
|
||||
def test_control_unpause(*args):
|
||||
"""
|
||||
check that control_unpause works for both type & id, or qaulified name
|
||||
"""
|
||||
target_type = 'action'
|
||||
id = '01BTG32JW87G0YKA1K29TKNAFX'
|
||||
runner = CliRunner()
|
||||
with patch.object(Control, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [auth_vars, 'unpause', target_type, id])
|
||||
mock_method.assert_called_once_with(ANY, 'unpause', id)
|
||||
|
||||
qualified_name = target_type + "/" + id
|
||||
with patch.object(Control, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [auth_vars, 'unpause', qualified_name])
|
||||
mock_method.assert_called_once_with(ANY, 'unpause', id)
|
||||
|
||||
|
||||
def test_control_unpause_negative(*args):
|
||||
"""
|
||||
negative unit test for control unpause command
|
||||
verifies invalid id and qualified name results in error
|
||||
"""
|
||||
|
||||
target_type = 'action'
|
||||
id = 'invalid id'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(shipyard, [auth_vars, 'unpause', target_type, id])
|
||||
assert 'Error' in results.output
|
||||
|
||||
qualified_name = 'invalid qualified name'
|
||||
results = runner.invoke(shipyard, [auth_vars, 'unpause', qualified_name])
|
||||
assert 'Error' in results.output
|
||||
|
||||
|
||||
def test_control_stop(*args):
|
||||
"""check that control_stop works for both type & id, or qaulified name"""
|
||||
|
||||
target_type = 'action'
|
||||
id = '01BTG32JW87G0YKA1K29TKNAFX'
|
||||
runner = CliRunner()
|
||||
with patch.object(Control, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [auth_vars, 'stop', target_type, id])
|
||||
mock_method.assert_called_once_with(ANY, 'stop', id)
|
||||
|
||||
qualified_name = target_type + "/" + id
|
||||
with patch.object(Control, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [auth_vars, 'stop', qualified_name])
|
||||
mock_method.assert_called_once_with(ANY, 'stop', id)
|
||||
|
||||
|
||||
def test_control_stop_negative(*args):
|
||||
"""
|
||||
negative unit test for control stop command
|
||||
verifies invalid id and qualified name results in error
|
||||
"""
|
||||
target_type = 'action'
|
||||
id = 'invalid id'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(shipyard, [auth_vars, 'stop', target_type, id])
|
||||
assert 'Error' in results.output
|
||||
|
||||
qualified_name = 'invalid qualified name'
|
||||
results = runner.invoke(shipyard, [auth_vars, 'stop', qualified_name])
|
||||
assert 'Error' in results.output
|
@ -0,0 +1,4 @@
|
||||
env_description:
|
||||
color : red
|
||||
candy : crunch
|
||||
food : strawberry
|
@ -0,0 +1,9 @@
|
||||
summer:
|
||||
sport : tennis
|
||||
vacation : Florida
|
||||
temperature : 90F
|
||||
---
|
||||
fall:
|
||||
holiday : Thanksgiving
|
||||
food : pumpkin
|
||||
color : orange
|
95
shipyard_client/tests/unit/cli/create/test_create_actions.py
Normal file
95
shipyard_client/tests/unit/cli/create/test_create_actions.py
Normal file
@ -0,0 +1,95 @@
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
import yaml
|
||||
|
||||
from shipyard_client.cli.create.actions import CreateAction, CreateConfigdocs
|
||||
from shipyard_client.api_client.base_client import BaseClient
|
||||
from shipyard_client.tests.unit.cli.replace_api_client import \
|
||||
replace_base_constructor, replace_post_rep, replace_get_resp, \
|
||||
replace_output_formatting
|
||||
from shipyard_client.tests.unit.cli.utils import temporary_context
|
||||
from shipyard_client.api_client.shipyardclient_context import \
|
||||
ShipyardClientContext
|
||||
|
||||
auth_vars = {
|
||||
'project_domain_name': 'projDomainTest',
|
||||
'user_domain_name': 'userDomainTest',
|
||||
'project_name': 'projectTest',
|
||||
'username': 'usernameTest',
|
||||
'password': 'passwordTest',
|
||||
'auth_url': 'urlTest'
|
||||
}
|
||||
|
||||
api_parameters = {
|
||||
'auth_vars': auth_vars,
|
||||
'context_marker': 'UUID',
|
||||
'debug': False
|
||||
}
|
||||
|
||||
|
||||
class MockCTX():
|
||||
pass
|
||||
|
||||
|
||||
ctx = MockCTX()
|
||||
ctx.obj = {}
|
||||
ctx.obj['API_PARAMETERS'] = api_parameters
|
||||
ctx.obj['FORMAT'] = 'format'
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@mock.patch.object(BaseClient, 'post_resp', replace_post_rep)
|
||||
@mock.patch.object(BaseClient, 'get_resp', replace_get_resp)
|
||||
@mock.patch.object(ShipyardClientContext, '__init__', temporary_context)
|
||||
@mock.patch(
|
||||
'shipyard_client.cli.create.actions.output_formatting',
|
||||
side_effect=replace_output_formatting)
|
||||
def test_CreateAction(*args):
|
||||
action_name = 'redeploy_server'
|
||||
param = {'server-name': 'mcp'}
|
||||
response = CreateAction(ctx, action_name, param).invoke_and_return_resp()
|
||||
# test correct function was called
|
||||
url = response.get('url')
|
||||
assert 'actions' in url
|
||||
# test function was called with correct parameters
|
||||
data = response.get('data')
|
||||
assert '"name": "redeploy_server"' in data
|
||||
assert '"parameters": {"server-name": "mcp"}' in data
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@mock.patch.object(BaseClient, 'post_resp', replace_post_rep)
|
||||
@mock.patch.object(BaseClient, 'get_resp', replace_get_resp)
|
||||
@mock.patch.object(ShipyardClientContext, '__init__', temporary_context)
|
||||
@mock.patch(
|
||||
'shipyard_client.cli.create.actions.output_formatting',
|
||||
side_effect=replace_output_formatting)
|
||||
def test_CreateConfigdocs(*args):
|
||||
collection = 'design'
|
||||
filename = 'shipyard_client/tests/unit/cli/create/sample_yaml/sample.yaml'
|
||||
document_data = yaml.dump_all(filename)
|
||||
buffer = 'append'
|
||||
response = CreateConfigdocs(ctx, collection, buffer,
|
||||
document_data).invoke_and_return_resp()
|
||||
# test correct function was called
|
||||
url = response.get('url')
|
||||
assert 'configdocs' in url
|
||||
# test function was called with correct parameters
|
||||
assert collection in url
|
||||
data = response.get('data')
|
||||
assert document_data in data
|
||||
params = response.get('params')
|
||||
assert params.get('buffermode') == buffer
|
@ -0,0 +1,83 @@
|
||||
# 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.
|
||||
from click.testing import CliRunner
|
||||
from mock import patch, ANY
|
||||
|
||||
from shipyard_client.cli.create.actions import CreateAction, CreateConfigdocs
|
||||
from shipyard_client.cli.commands import shipyard
|
||||
|
||||
auth_vars = ('--os_project_domain_name=OS_PROJECT_DOMAIN_NAME_test '
|
||||
'--os_user_domain_name=OS_USER_DOMAIN_NAME_test '
|
||||
'--os_project_name=OS_PROJECT_NAME_test '
|
||||
'--os_username=OS_USERNAME_test --os_password=OS_PASSWORD_test '
|
||||
'--os_auth_url=OS_AUTH_URL_test')
|
||||
|
||||
|
||||
def test_create_action():
|
||||
"""test create_action works with action id and param input"""
|
||||
|
||||
action_name = 'redeploy_server'
|
||||
param = '--param="server-name=mcp"'
|
||||
runner = CliRunner()
|
||||
with patch.object(CreateAction, '__init__') as mock_method:
|
||||
runner.invoke(shipyard,
|
||||
[auth_vars, 'create', 'action', action_name, param])
|
||||
mock_method.assert_called_once_with(ANY, action_name,
|
||||
{'"server-name': 'mcp"'})
|
||||
|
||||
|
||||
def test_create_action_negative():
|
||||
"""
|
||||
negative unit test for create action command
|
||||
verifies invalid action command results in error
|
||||
"""
|
||||
|
||||
action_command = 'invalid_action_command'
|
||||
param = '--param="test"'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(
|
||||
shipyard, [auth_vars, 'create', 'action', action_command, param])
|
||||
assert 'Error' in results.output
|
||||
|
||||
|
||||
def test_create_configdocs():
|
||||
"""test create configdocs"""
|
||||
|
||||
collection = 'design'
|
||||
filename = 'shipyard_client/tests/unit/cli/create/sample_yaml/sample.yaml'
|
||||
append = 'append'
|
||||
runner = CliRunner()
|
||||
with patch.object(CreateConfigdocs, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [
|
||||
auth_vars, 'create', 'configdocs', collection, '--' + append,
|
||||
'--filename=' + filename
|
||||
])
|
||||
mock_method.assert_called_once_with(ANY, collection, 'append', ANY)
|
||||
|
||||
|
||||
def test_create_configdocs_negative():
|
||||
"""
|
||||
negative unit test for create configdocs command
|
||||
verifies invalid filename results in error
|
||||
"""
|
||||
|
||||
collection = 'design'
|
||||
filename = 'invalid.yaml'
|
||||
append = 'append'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(shipyard, [
|
||||
auth_vars, 'create', 'configdocs', collection, '--' + append,
|
||||
'--filename=' + filename
|
||||
])
|
||||
assert 'Error' in results.output
|
@ -0,0 +1,99 @@
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
|
||||
from shipyard_client.cli.describe.actions import \
|
||||
DescribeAction, DescribeStep, DescribeValidation
|
||||
from shipyard_client.api_client.base_client import BaseClient
|
||||
from shipyard_client.tests.unit.cli.replace_api_client import \
|
||||
replace_base_constructor, replace_post_rep, replace_get_resp, \
|
||||
replace_output_formatting
|
||||
from shipyard_client.tests.unit.cli.utils import temporary_context
|
||||
from shipyard_client.api_client.shipyardclient_context import \
|
||||
ShipyardClientContext
|
||||
|
||||
auth_vars = {
|
||||
'project_domain_name': 'projDomainTest',
|
||||
'user_domain_name': 'userDomainTest',
|
||||
'project_name': 'projectTest',
|
||||
'username': 'usernameTest',
|
||||
'password': 'passwordTest',
|
||||
'auth_url': 'urlTest'
|
||||
}
|
||||
|
||||
api_parameters = {
|
||||
'auth_vars': auth_vars,
|
||||
'context_marker': 'UUID',
|
||||
'debug': False
|
||||
}
|
||||
|
||||
|
||||
class MockCTX():
|
||||
pass
|
||||
|
||||
|
||||
ctx = MockCTX()
|
||||
ctx.obj = {}
|
||||
ctx.obj['API_PARAMETERS'] = api_parameters
|
||||
ctx.obj['FORMAT'] = 'format'
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@mock.patch.object(BaseClient, 'post_resp', replace_post_rep)
|
||||
@mock.patch.object(BaseClient, 'get_resp', replace_get_resp)
|
||||
@mock.patch.object(ShipyardClientContext, '__init__', temporary_context)
|
||||
@mock.patch(
|
||||
'shipyard_client.cli.describe.actions.output_formatting',
|
||||
side_effect=replace_output_formatting)
|
||||
def test_DescribeAction(*args):
|
||||
response = DescribeAction(
|
||||
ctx, '01BTG32JW87G0YKA1K29TKNAFX').invoke_and_return_resp()
|
||||
# test correct function was called
|
||||
url = response.get('url')
|
||||
assert 'actions/01BTG32JW87G0YKA1K29TKNAFX' in url
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@mock.patch.object(BaseClient, 'post_resp', replace_post_rep)
|
||||
@mock.patch.object(BaseClient, 'get_resp', replace_get_resp)
|
||||
@mock.patch.object(ShipyardClientContext, '__init__', temporary_context)
|
||||
@mock.patch(
|
||||
'shipyard_client.cli.describe.actions.output_formatting',
|
||||
side_effect=replace_output_formatting)
|
||||
def test_DescribeStep(*args):
|
||||
response = DescribeStep(ctx, '01BTG32JW87G0YKA1K29TKNAFX',
|
||||
'preflight').invoke_and_return_resp()
|
||||
# test correct function was called
|
||||
url = response.get('url')
|
||||
assert 'actions/01BTG32JW87G0YKA1K29TKNAFX/steps/preflight' in url
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@mock.patch.object(BaseClient, 'post_resp', replace_post_rep)
|
||||
@mock.patch.object(BaseClient, 'get_resp', replace_get_resp)
|
||||
@mock.patch.object(ShipyardClientContext, '__init__', temporary_context)
|
||||
@mock.patch(
|
||||
'shipyard_client.cli.describe.actions.output_formatting',
|
||||
side_effect=replace_output_formatting)
|
||||
def test_DescribeValidation(*args):
|
||||
response = DescribeValidation(
|
||||
ctx, '01BTG32JW87G0YKA1K29TKNAFX',
|
||||
'01BTG3PKBS15KCKFZ56XXXBGF2').invoke_and_return_resp()
|
||||
# test correct function was called
|
||||
url = response.get('url')
|
||||
assert 'actions' in url
|
||||
assert '01BTG32JW87G0YKA1K29TKNAFX' in url
|
||||
assert 'validationdetails' in url
|
||||
assert '01BTG3PKBS15KCKFZ56XXXBGF2' in url
|
@ -0,0 +1,117 @@
|
||||
# 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.
|
||||
|
||||
from click.testing import CliRunner
|
||||
from mock import patch, ANY
|
||||
|
||||
from shipyard_client.cli.describe.actions import DescribeAction
|
||||
from shipyard_client.cli.describe.actions import DescribeStep
|
||||
from shipyard_client.cli.describe.actions import DescribeValidation
|
||||
from shipyard_client.cli.commands import shipyard
|
||||
|
||||
auth_vars = ('--os_project_domain_name=OS_PROJECT_DOMAIN_NAME_test '
|
||||
'--os_user_domain_name=OS_USER_DOMAIN_NAME_test '
|
||||
'--os_project_name=OS_PROJECT_NAME_test '
|
||||
'--os_username=OS_USERNAME_test --os_password=OS_PASSWORD_test '
|
||||
'--os_auth_url=OS_AUTH_URL_test')
|
||||
|
||||
|
||||
def test_describe_action():
|
||||
"""test describe_action"""
|
||||
|
||||
action_id = '01BTG32JW87G0YKA1K29TKNAFX'
|
||||
runner = CliRunner()
|
||||
with patch.object(DescribeAction, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [auth_vars, 'describe', 'action', action_id])
|
||||
mock_method.assert_called_once_with(ANY, action_id)
|
||||
|
||||
|
||||
def test_describe_action_negative():
|
||||
"""
|
||||
negative unit test for describe action command
|
||||
verifies invalid action id results in error
|
||||
"""
|
||||
|
||||
action_id = 'invalid action id'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(shipyard,
|
||||
[auth_vars, 'describe', 'action', action_id])
|
||||
assert 'Error' in results.output
|
||||
|
||||
|
||||
def test_describe_step():
|
||||
"""test describe_step"""
|
||||
|
||||
step_id = 'preflight'
|
||||
action_id = '01BTG32JW87G0YKA1K29TKNAFX'
|
||||
runner = CliRunner()
|
||||
with patch.object(DescribeStep, '__init__') as mock_method:
|
||||
results = runner.invoke(shipyard, [
|
||||
auth_vars, 'describe', 'step', step_id, '--action=' + action_id
|
||||
])
|
||||
mock_method.assert_called_once_with(ANY, action_id, step_id)
|
||||
|
||||
|
||||
def test_describe_step_negative():
|
||||
"""
|
||||
negative unit test for describe step command
|
||||
verifies invalid action id results in error
|
||||
"""
|
||||
|
||||
step_id = 'preflight'
|
||||
action_id = 'invalid action id'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(shipyard, [
|
||||
auth_vars, 'describe', 'step', step_id, '--action=' + action_id
|
||||
])
|
||||
assert 'Error' in results.output
|
||||
|
||||
|
||||
def test_describe_validation():
|
||||
"""test describe_validation"""
|
||||
|
||||
validation_id = '01BTG3PKBS15KCKFZ56XXXBGF2'
|
||||
action_id = '01BTG32JW87G0YKA1K29TKNAFX'
|
||||
runner = CliRunner()
|
||||
with patch.object(DescribeValidation, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [
|
||||
auth_vars, 'describe', 'validation', '01BTG3PKBS15KCKFZ56XXXBGF2',
|
||||
'--action=' + action_id
|
||||
])
|
||||
mock_method.assert_called_once_with(ANY, validation_id, action_id)
|
||||
|
||||
|
||||
def test_describe_validation_negative():
|
||||
"""
|
||||
negative unit test for describe validation command
|
||||
verifies invalid validation id and action id results in error
|
||||
"""
|
||||
|
||||
validation_id = 'invalid validation id'
|
||||
action_id = '01BTG32JW87G0YKA1K29TKNAFX'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(shipyard, [
|
||||
auth_vars, 'describe', 'validation', validation_id,
|
||||
'--action=' + action_id
|
||||
])
|
||||
assert 'Error' in results.output
|
||||
|
||||
validation_id = '01BTG3PKBS15KCKFZ56XXXBGF2'
|
||||
action_id = 'invalid action id'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(shipyard, [
|
||||
auth_vars, 'describe', 'validation', validation_id,
|
||||
'--action=' + action_id
|
||||
])
|
||||
assert 'Error' in results.output
|
97
shipyard_client/tests/unit/cli/get/test_get_actions.py
Normal file
97
shipyard_client/tests/unit/cli/get/test_get_actions.py
Normal file
@ -0,0 +1,97 @@
|
||||
# Copyright 2017 AT&T Intellectual Property. replace_shipyard 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.
|
||||
|
||||
import mock
|
||||
|
||||
from shipyard_client.cli.get.actions import GetActions, GetConfigdocs, \
|
||||
GetRenderedConfigdocs
|
||||
from shipyard_client.api_client.base_client import BaseClient
|
||||
from shipyard_client.tests.unit.cli.replace_api_client import \
|
||||
replace_base_constructor, replace_post_rep, replace_get_resp, \
|
||||
replace_output_formatting
|
||||
from shipyard_client.tests.unit.cli.utils import temporary_context
|
||||
from shipyard_client.api_client.shipyardclient_context import \
|
||||
ShipyardClientContext
|
||||
|
||||
auth_vars = {
|
||||
'project_domain_name': 'projDomainTest',
|
||||
'user_domain_name': 'userDomainTest',
|
||||
'project_name': 'projectTest',
|
||||
'username': 'usernameTest',
|
||||
'password': 'passwordTest',
|
||||
'auth_url': 'urlTest'
|
||||
}
|
||||
api_parameters = {
|
||||
'auth_vars': auth_vars,
|
||||
'context_marker': 'UUID',
|
||||
'debug': False
|
||||
}
|
||||
|
||||
|
||||
class MockCTX():
|
||||
pass
|
||||
|
||||
|
||||
ctx = MockCTX()
|
||||
ctx.obj = {}
|
||||
ctx.obj['API_PARAMETERS'] = api_parameters
|
||||
ctx.obj['FORMAT'] = 'format'
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@mock.patch.object(BaseClient, 'post_resp', replace_post_rep)
|
||||
@mock.patch.object(BaseClient, 'get_resp', replace_get_resp)
|
||||
@mock.patch.object(ShipyardClientContext, '__init__', temporary_context)
|
||||
@mock.patch(
|
||||
'shipyard_client.cli.get.actions.output_formatting',
|
||||
side_effect=replace_output_formatting)
|
||||
def test_GetActions(*args):
|
||||
response = GetActions(ctx).invoke_and_return_resp()
|
||||
# test correct function was called
|
||||
url = response.get('url')
|
||||
assert 'actions' in url
|
||||
assert response.get('params') == {}
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@mock.patch.object(BaseClient, 'post_resp', replace_post_rep)
|
||||
@mock.patch.object(BaseClient, 'get_resp', replace_get_resp)
|
||||
@mock.patch.object(ShipyardClientContext, '__init__', temporary_context)
|
||||
@mock.patch(
|
||||
'shipyard_client.cli.get.actions.output_formatting',
|
||||
side_effect=replace_output_formatting)
|
||||
def test_GetConfigdocs(*args):
|
||||
response = GetConfigdocs(ctx, 'design', 'buffer').invoke_and_return_resp()
|
||||
# test correct function was called
|
||||
url = response.get('url')
|
||||
assert 'configdocs/design' in url
|
||||
params = response.get('params')
|
||||
assert params.get('version') == 'buffer'
|
||||
|
||||
|
||||
@mock.patch.object(BaseClient, '__init__', replace_base_constructor)
|
||||
@mock.patch.object(BaseClient, 'post_resp', replace_post_rep)
|
||||
@mock.patch.object(BaseClient, 'get_resp', replace_get_resp)
|
||||
@mock.patch.object(ShipyardClientContext, '__init__', temporary_context)
|
||||
@mock.patch(
|
||||
'shipyard_client.cli.get.actions.output_formatting',
|
||||
side_effect=replace_output_formatting)
|
||||
def test_GetRenderedConfigdocs(*args):
|
||||
response = GetRenderedConfigdocs(ctx, 'buffer').invoke_and_return_resp()
|
||||
# test correct function was called
|
||||
url = response.get('url')
|
||||
assert 'renderedconfigdocs' in url
|
||||
params = response.get('params')
|
||||
assert params.get('version') == 'buffer'
|
94
shipyard_client/tests/unit/cli/get/test_get_commands.py
Normal file
94
shipyard_client/tests/unit/cli/get/test_get_commands.py
Normal file
@ -0,0 +1,94 @@
|
||||
# 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.
|
||||
|
||||
from click.testing import CliRunner
|
||||
from mock import patch, ANY
|
||||
|
||||
from shipyard_client.cli.get.actions import (GetActions, GetConfigdocs,
|
||||
GetRenderedConfigdocs)
|
||||
from shipyard_client.cli.commands import shipyard
|
||||
|
||||
auth_vars = ('--os_project_domain_name=OS_PROJECT_DOMAIN_NAME_test '
|
||||
'--os_user_domain_name=OS_USER_DOMAIN_NAME_test '
|
||||
'--os_project_name=OS_PROJECT_NAME_test '
|
||||
'--os_username=OS_USERNAME_test --os_password=OS_PASSWORD_test '
|
||||
'--os_auth_url=OS_AUTH_URL_test')
|
||||
|
||||
|
||||
def test_get_actions(*args):
|
||||
"""test get_actions"""
|
||||
|
||||
runner = CliRunner()
|
||||
with patch.object(GetActions, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [auth_vars, 'get', 'actions'])
|
||||
mock_method.assert_called_once_with(ANY)
|
||||
|
||||
|
||||
def test_get_actions_negative(*args):
|
||||
"""
|
||||
negative unit test for get actions command
|
||||
verifies invalid argument results in error
|
||||
"""
|
||||
|
||||
invalid_arg = 'invalid'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(shipyard,
|
||||
[auth_vars, 'get', 'actions', invalid_arg])
|
||||
assert 'Error' in results.output
|
||||
|
||||
|
||||
def test_get_configdocs(*args):
|
||||
"""test get_configdocs"""
|
||||
|
||||
collection = 'design'
|
||||
runner = CliRunner()
|
||||
with patch.object(GetConfigdocs, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [auth_vars, 'get', 'configdocs', collection])
|
||||
mock_method.assert_called_once_with(ANY, collection, 'buffer')
|
||||
|
||||
|
||||
def test_get_configdocs_negative(*args):
|
||||
"""
|
||||
negative unit test for get actions command
|
||||
verifies invalid argument results in error
|
||||
"""
|
||||
|
||||
collection = 'design'
|
||||
invalid_arg = 'invalid'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(
|
||||
shipyard, [auth_vars, 'get', 'configdocs', collection, invalid_arg])
|
||||
assert 'Error' in results.output
|
||||
|
||||
|
||||
def test_get_renderedconfigdocs(*args):
|
||||
"""test get_rendereddocs"""
|
||||
|
||||
runner = CliRunner()
|
||||
with patch.object(GetRenderedConfigdocs, '__init__') as mock_method:
|
||||
runner.invoke(shipyard, [auth_vars, 'get', 'renderedconfigdocs'])
|
||||
mock_method.assert_called_once_with(ANY, 'buffer')
|
||||
|
||||
|
||||
def test_get_renderedconfigdocs_negative(*args):
|
||||
"""
|
||||
negative unit test for get actions command
|
||||
verfies invalid argument results in error
|
||||
"""
|
||||
|
||||
invalid_arg = 'invalid'
|
||||
runner = CliRunner()
|
||||
results = runner.invoke(
|
||||
shipyard, [auth_vars, 'get', 'renderedconfigdocs', invalid_arg])
|
||||
assert 'Error' in results.output
|
0
shipyard_client/tests/unit/cli/help/__init__.py
Normal file
0
shipyard_client/tests/unit/cli/help/__init__.py
Normal file
45
shipyard_client/tests/unit/cli/help/test_help_commands.py
Normal file
45
shipyard_client/tests/unit/cli/help/test_help_commands.py
Normal file
@ -0,0 +1,45 @@
|
||||
# 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.
|
||||
|
||||
from click.testing import CliRunner
|
||||
|
||||
from shipyard_client.cli.help.commands import help
|
||||
|
||||
|
||||
def test_help():
|
||||
"""test help with all options"""
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(help)
|
||||
assert 'THE SHIPYARD COMMAND' in result.output
|
||||
|
||||
topic = 'actions'
|
||||
result = runner.invoke(help, [topic])
|
||||
assert 'ACTIONS' in result.output
|
||||
|
||||
topic = 'configdocs'
|
||||
result = runner.invoke(help, [topic])
|
||||
assert 'CONFIGDOCS' in result.output
|
||||
|
||||
|
||||
def test_help_negative():
|
||||
"""
|
||||
negative unit test for help command
|
||||
verfies invalid topic results in error
|
||||
"""
|
||||
|
||||
invalid_topic = 'invalid'
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(help, [invalid_topic])
|
||||
assert 'Error' in result.output
|
49
shipyard_client/tests/unit/cli/replace_api_client.py
Normal file
49
shipyard_client/tests/unit/cli/replace_api_client.py
Normal file
@ -0,0 +1,49 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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.
|
||||
|
||||
# For testing purposes only
|
||||
|
||||
|
||||
class TemporaryContext(object):
|
||||
def __init__(self):
|
||||
self.debug = True
|
||||
self.keystone_Auth = {}
|
||||
self.token = 'abcdefgh'
|
||||
self.service_type = 'http://shipyard'
|
||||
self.shipyard_endpoint = 'http://shipyard/api/v1.0'
|
||||
self.context_marker = '123456'
|
||||
|
||||
|
||||
def replace_post_rep(self, url, query_params={}, data={}, content_type=''):
|
||||
"""
|
||||
replaces call to shipyard client
|
||||
:returns: dict with url and parameters
|
||||
"""
|
||||
return {'url': url, 'params': query_params, 'data': data}
|
||||
|
||||
|
||||
def replace_get_resp(self, url, query_params={}, json=False):
|
||||
"""
|
||||
replaces call to shipyard client
|
||||
:returns: dict with url and parameters
|
||||
"""
|
||||
return {'url': url, 'params': query_params}
|
||||
|
||||
|
||||
def replace_base_constructor(self, context):
|
||||
pass
|
||||
|
||||
|
||||
def replace_output_formatting(format, response):
|
||||
return response
|
56
shipyard_client/tests/unit/cli/test_output_formatting.py
Normal file
56
shipyard_client/tests/unit/cli/test_output_formatting.py
Normal file
@ -0,0 +1,56 @@
|
||||
# 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.
|
||||
|
||||
import json
|
||||
import yaml
|
||||
from mock import patch, ANY
|
||||
from requests.models import Response
|
||||
|
||||
from shipyard_client.cli.output_formatting import output_formatting
|
||||
|
||||
json_response = Response()
|
||||
json_response._content = b'{ "key" : "a" }'
|
||||
json_response.status_code = 200
|
||||
json_response.headers['content-type'] = 'application/json'
|
||||
|
||||
yaml_response = Response()
|
||||
yaml_response._content = b'''Projects:
|
||||
C/C++ Libraries:
|
||||
- libyaml # "C" Fast YAML 1.1
|
||||
- Syck # (dated) "C" YAML 1.0
|
||||
- yaml-cpp # C++ YAML 1.2 implementation
|
||||
Ruby:
|
||||
- psych # libyaml wrapper (in Ruby core for 1.9.2)
|
||||
- RbYaml # YAML 1.1 (PyYAML Port)
|
||||
- yaml4r # YAML 1.0, standard library syck binding
|
||||
Python:
|
||||
- PyYAML # YAML 1.1, pure python and libyaml binding
|
||||
- ruamel.yaml # YAML 1.2, update of PyYAML with round-tripping of comments
|
||||
- PySyck # YAML 1.0, syck binding'''
|
||||
|
||||
yaml_response.headers['content-type'] = 'application/yaml'
|
||||
|
||||
|
||||
def test_output_formatting():
|
||||
"""call output formatting and check correct one was given"""
|
||||
|
||||
with patch.object(json, 'dumps') as mock_method:
|
||||
output_formatting('format', json_response)
|
||||
mock_method.assert_called_once_with(
|
||||
json_response.json(), sort_keys=True, indent=4)
|
||||
|
||||
with patch.object(yaml, 'dump_all') as mock_method:
|
||||
output_formatting('format', yaml_response)
|
||||
mock_method.assert_called_once_with(
|
||||
ANY, width=79, indent=4, default_flow_style=False)
|
50
shipyard_client/tests/unit/cli/test_shipyard_commands.py
Normal file
50
shipyard_client/tests/unit/cli/test_shipyard_commands.py
Normal file
@ -0,0 +1,50 @@
|
||||
# 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.
|
||||
|
||||
from click.testing import CliRunner
|
||||
from mock import patch
|
||||
|
||||
from shipyard_client.cli.commands import shipyard
|
||||
from shipyard_client.api_client.shipyardclient_context import \
|
||||
ShipyardClientContext
|
||||
|
||||
|
||||
def test_shipyard():
|
||||
context_marker = '--context-marker=UUID'
|
||||
debug = '--debug'
|
||||
os_project_domain_name = (
|
||||
'--os_project_domain_name=OS_PROJECT_DOMAIN_NAME_test')
|
||||
os_user_domain_name = '--os_user_domain_name=OS_USER_DOMAIN_NAME_test'
|
||||
os_project_name = '--os_project_name=OS_PROJECT_NAME_test'
|
||||
os_username = '--os_username=OS_USERNAME_test'
|
||||
os_password = '--os_password=OS_PASSWORD_test'
|
||||
os_auth_url = '--os_auth_url=OS_AUTH_URL_test'
|
||||
|
||||
auth_vars = {
|
||||
'project_domain_name': 'OS_PROJECT_DOMAIN_NAME_test',
|
||||
'user_domain_name': 'OS_USER_DOMAIN_NAME_test',
|
||||
'project_name': 'OS_PROJECT_NAME_test',
|
||||
'username': 'OS_USERNAME_test',
|
||||
'password': 'OS_PASSWORD_test',
|
||||
'auth_url': 'OS_AUTH_URL_test'
|
||||
}
|
||||
|
||||
runner = CliRunner()
|
||||
with patch.object(ShipyardClientContext, '__init__') as mock_method:
|
||||
results = runner.invoke(shipyard, [
|
||||
context_marker, os_project_domain_name, os_user_domain_name,
|
||||
os_project_name, os_username, os_password, os_auth_url, debug,
|
||||
'commit', 'configdocs'
|
||||
])
|
||||
mock_method.assert_called_once_with(auth_vars, 'UUID', True)
|
23
shipyard_client/tests/unit/cli/utils.py
Normal file
23
shipyard_client/tests/unit/cli/utils.py
Normal file
@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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.
|
||||
|
||||
# For testing purposes only
|
||||
|
||||
|
||||
def temporary_context(self, keystone_auth, context_marker, debug=False):
|
||||
self.debug = debug
|
||||
self.keystone_Auth = keystone_auth
|
||||
self.service_type = 'shipyard'
|
||||
self.shipyard_endpoint = 'http://shipyard/api/v1.0'
|
||||
self.context_marker = context_marker
|
Loading…
x
Reference in New Issue
Block a user