Add commands to support parts in the cli

Updated the setup of the session for the api client to use more
standard fields and make less assumptions.
Moved url parsing to cli code
This commit is contained in:
Bryan Strassner 2017-07-17 17:45:02 -05:00 committed by Scott Hussey
parent 7eddaf13a7
commit c09b86c213
5 changed files with 192 additions and 11 deletions

View File

@ -11,15 +11,17 @@
# 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.
""" The entrypoint for the cli commands
""" The entry point for the cli commands
"""
import os
import logging
import click
from urllib.parse import urlparse
import click
from drydock_provisioner.drydock_client.session import DrydockSession
from drydock_provisioner.drydock_client.client import DrydockClient
from .design import commands as design
from .part import commands as part
@click.group()
@click.option('--debug/--no-debug',
@ -43,12 +45,12 @@ def drydock(ctx, debug, token, url):
ctx.obj['DEBUG'] = debug
if not token:
ctx.fail("Error: Token must be specified either by "
"--token or DD_TOKEN from the environment")
ctx.fail('Error: Token must be specified either by '
'--token or DD_TOKEN from the environment')
if not url:
ctx.fail("Error: URL must be specified either by "
"--url or DD_URL from the environment")
ctx.fail('Error: URL must be specified either by '
'--url or DD_URL from the environment')
# setup logging for the CLI
# Setup root logger
@ -63,7 +65,13 @@ def drydock(ctx, debug, token, url):
logger.debug('logging for cli initialized')
# setup the drydock client using the passed parameters.
ctx.obj['CLIENT'] = DrydockClient(DrydockSession(host=url,
url_parse_result = urlparse(url)
logger.debug(url_parse_result)
if not url_parse_result.scheme:
ctx.fail('URL must specify a scheme and hostname, optionally a port')
ctx.obj['CLIENT'] = DrydockClient(DrydockSession(scheme=url_parse_result.scheme,
host=url_parse_result.netloc,
token=token))
drydock.add_command(design.design)
drydock.add_command(part.part)

View File

@ -0,0 +1,87 @@
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" Actions related to part command
"""
from drydock_provisioner.cli.action import CliAction
class PartBase(CliAction): # pylint: disable=too-few-public-methods
""" base class to set up part actions requiring a design_id
"""
def __init__(self, api_client, design_id):
super().__init__(api_client)
self.design_id = design_id
self.logger.debug('Initializing a Part action with design_id=%s', design_id)
class PartList(PartBase): # pylint: disable=too-few-public-methods
""" Action to list parts of a design
"""
def __init__(self, api_client, design_id):
"""
:param DrydockClient api_client: The api client used for invocation.
:param string design_id: The UUID of the design for which to list parts
"""
super().__init__(api_client, design_id)
self.logger.debug('PartList action initialized')
def invoke(self):
#TODO: change the api call
#return self.api_client.get_design_ids()
pass
class PartCreate(PartBase): # pylint: disable=too-few-public-methods
""" Action to create parts of a design
"""
def __init__(self, api_client, design_id, yaml):
"""
:param DrydockClient api_client: The api client used for invocation.
:param string design_id: The UUID of the design for which to create a part
:param yaml: The file containing the specification of the part
"""
super().__init__(api_client, design_id)
self.yaml = yaml
self.logger.debug('PartCreate action initialized with yaml=%s', yaml[:100])
def invoke(self):
return self.api_client.load_parts(self.design_id, self.yaml)
class PartShow(PartBase): # pylint: disable=too-few-public-methods
""" Action to show a part of a design.
"""
def __init__(self, api_client, design_id, kind, key, source='designed'):
"""
:param DrydockClient api_client: The api client used for invocation.
:param string design_id: the UUID of the design containing this part
:param string kind: the string represesnting the 'kind' of the document to return
:param string key: the string representing the key of the document to return.
:param string source: 'designed' (default) if this is the designed version,
'compiled' if the compiled version (after merging)
"""
super().__init__(api_client, design_id)
self.kind = kind
self.key = key
self.source = source
self.logger.debug('DesignShow action initialized for design_id=%s,'
' kind=%s, key=%s, source=%s',
design_id,
kind,
key,
source)
def invoke(self):
return self.api_client.get_part(design_id=self.design_id,
kind=self.kind,
key=self.key,
source=self.source)

View File

@ -0,0 +1,81 @@
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" cli.part.commands
Contains commands related to parts of designs
"""
import click
from drydock_provisioner.cli.part.actions import PartList
from drydock_provisioner.cli.part.actions import PartShow
from drydock_provisioner.cli.part.actions import PartCreate
@click.group()
@click.option('--design-id',
'-d',
help='The id of the design containing the target parts')
@click.pass_context
def part(ctx, design_id=None):
""" Drydock part commands
"""
if not design_id:
ctx.fail('Error: Design id must be specified using --design-id')
ctx.obj['DESIGN_ID'] = design_id
@part.command(name='create')
@click.option('--file',
'-f',
help='The file name containing the part to create')
@click.pass_context
def part_create(ctx, file=None):
""" Create a part
"""
if not file:
ctx.fail('A file to create a part is required using --file')
with open(file, 'r') as file_input:
file_contents = file_input.read()
# here is where some yaml validation could be done
click.echo(PartCreate(ctx.obj['CLIENT'],
design_id=ctx.obj['DESIGN_ID'],
yaml=file_contents).invoke())
@part.command(name='list')
@click.pass_context
def part_list(ctx):
""" List parts of a design
"""
click.echo(PartList(ctx.obj['CLIENT'], design_id=ctx.obj['DESIGN_ID']).invoke())
@part.command(name='show')
@click.option('--source',
'-s',
help='designed | compiled')
@click.option('--kind',
'-k',
help='The kind value of the document to show')
@click.option('--key',
'-i',
help='The key value of the document to show')
@click.pass_context
def part_show(ctx, source, kind, key):
""" show a part of a design
"""
if not kind:
ctx.fail('The kind must be specified by --kind')
if not key:
ctx.fail('The key must be specified by --key')
click.echo(PartShow(ctx.obj['CLIENT'], design_id=ctx.obj['DESIGN_ID'], kind=kind, key=key, source=source).invoke())

View File

@ -23,15 +23,19 @@ class DrydockSession(object):
:param string marker: (optional) external context marker
"""
def __init__(self, host, *, port=None, token=None, marker=None):
def __init__(self, host, *, port=None, scheme='http', token=None, marker=None):
self.__session = requests.Session()
self.__session.headers.update({'X-Auth-Token': token, 'X-Context-Marker': marker})
self.host = host
self.port = port
self.scheme = scheme
if port:
self.base_url = "http://%s:%d/api/" % (host, port)
self.port = port
self.base_url = "%s://%s:%s/api/" % (self.scheme, self.host, self.port)
else:
self.base_url = "http://%s/api/" % (host)
#assume default port for scheme
self.base_url = "%s://%s/api/" % (self.scheme, self.host)
self.token = token
self.marker = marker

View File

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