Add moniker-manage commands for maintaining servers and TSIG keys
Change-Id: Ic8b6892dbaca3ce643c5ec8e6b81a6a7a0d1aeb2
This commit is contained in:
parent
c7f060d0e0
commit
92896f85f0
|
@ -0,0 +1,83 @@
|
|||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 abc
|
||||
from cliff.command import Command as CliffCommand
|
||||
from cliff.lister import Lister
|
||||
from cliff.show import ShowOne
|
||||
from moniker import utils
|
||||
from moniker.context import MonikerContext
|
||||
|
||||
|
||||
class Command(CliffCommand):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
def run(self, parsed_args):
|
||||
self.context = MonikerContext.get_admin_context()
|
||||
|
||||
return super(Command, self).run(parsed_args)
|
||||
|
||||
@abc.abstractmethod
|
||||
def execute(self, parsed_args):
|
||||
"""
|
||||
Execute something, this is since we overload self.take_action()
|
||||
in order to format the data
|
||||
|
||||
This method __NEEDS__ to be overloaded!
|
||||
|
||||
:param parsed_args: The parsed args that are given by take_action()
|
||||
"""
|
||||
|
||||
def post_execute(self, data):
|
||||
"""
|
||||
Format the results locally if needed, by default we just return data
|
||||
|
||||
:param data: Whatever is returned by self.execute()
|
||||
"""
|
||||
return data
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
# TODO: Common Exception Handling Here
|
||||
results = self.execute(parsed_args)
|
||||
return self.post_execute(results)
|
||||
|
||||
|
||||
class ListCommand(Command, Lister):
|
||||
def post_execute(self, results):
|
||||
if len(results) > 0:
|
||||
columns = utils.get_columns(results)
|
||||
data = [utils.get_item_properties(i, columns) for i in results]
|
||||
return columns, data
|
||||
else:
|
||||
return [], ()
|
||||
|
||||
|
||||
class GetCommand(Command, ShowOne):
|
||||
def post_execute(self, results):
|
||||
return results.keys(), results.values()
|
||||
|
||||
|
||||
class CreateCommand(Command, ShowOne):
|
||||
def post_execute(self, results):
|
||||
return results.keys(), results.values()
|
||||
|
||||
|
||||
class UpdateCommand(Command, ShowOne):
|
||||
def post_execute(self, results):
|
||||
return results.keys(), results.values()
|
||||
|
||||
|
||||
class DeleteCommand(Command):
|
||||
pass
|
|
@ -0,0 +1,115 @@
|
|||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 moniker.openstack.common import log as logging
|
||||
from moniker.manage import base
|
||||
from moniker.central import api as central_api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ListServersCommand(base.ListCommand):
|
||||
""" List Servers """
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return central_api.get_servers(self.context)
|
||||
|
||||
|
||||
class GetServerCommand(base.GetCommand):
|
||||
""" Get Server """
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GetServerCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Server ID")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return central_api.get_server(self.context, parsed_args.id)
|
||||
|
||||
|
||||
class CreateServerCommand(base.CreateCommand):
|
||||
""" Create Server """
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateServerCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--name', help="Server Name", required=True)
|
||||
parser.add_argument('--ipv4', help="Server IPv4 Address")
|
||||
parser.add_argument('--ipv6', help="Server IPv6 Address")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
server = dict(
|
||||
name=parsed_args.name,
|
||||
ipv4=parsed_args.ipv4,
|
||||
ipv6=parsed_args.ipv6,
|
||||
)
|
||||
|
||||
return central_api.create_server(self.context, server)
|
||||
|
||||
|
||||
class UpdateServerCommand(base.UpdateCommand):
|
||||
""" Update Server """
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateServerCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Server ID")
|
||||
parser.add_argument('--name', help="Server Name")
|
||||
|
||||
ipv4_group = parser.add_mutually_exclusive_group()
|
||||
ipv4_group.add_argument('--ipv4', help="Server IPv4 Address")
|
||||
ipv4_group.add_argument('--no-ipv4', action='store_true')
|
||||
|
||||
ipv6_group = parser.add_mutually_exclusive_group()
|
||||
ipv6_group.add_argument('--ipv6', help="Server IPv6 Address")
|
||||
ipv6_group.add_argument('--no-ipv6', action='store_true')
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
server = {}
|
||||
|
||||
if parsed_args.name:
|
||||
server['name'] = parsed_args.name
|
||||
|
||||
if parsed_args.no_ipv4:
|
||||
server['ipv4'] = None
|
||||
elif parsed_args.ipv4:
|
||||
server['ipv4'] = parsed_args.ipv4
|
||||
|
||||
if parsed_args.no_ipv6:
|
||||
server['ipv6'] = None
|
||||
elif parsed_args.ipv6:
|
||||
server['ipv6'] = parsed_args.ipv6
|
||||
|
||||
return central_api.update_server(self.context, parsed_args.id, server)
|
||||
|
||||
|
||||
class DeleteServerCommand(base.DeleteCommand):
|
||||
""" Delete Server """
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteServerCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Server ID")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return central_api.delete_server(self.context, parsed_args.id)
|
|
@ -0,0 +1,107 @@
|
|||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 moniker.openstack.common import log as logging
|
||||
from moniker.manage import base
|
||||
from moniker.central import api as central_api
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ListTsigKeysCommand(base.ListCommand):
|
||||
""" List TsigKeys """
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return central_api.get_tsigkeys(self.context)
|
||||
|
||||
|
||||
class GetTsigKeyCommand(base.GetCommand):
|
||||
""" Get TsigKey """
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GetTsigKeyCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="TSIG Key ID")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return central_api.get_tsigkey(self.context, parsed_args.id)
|
||||
|
||||
|
||||
class CreateTsigKeyCommand(base.CreateCommand):
|
||||
""" Create TsigKey """
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateTsigKeyCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--name', help="TSIG Key Name", required=True)
|
||||
parser.add_argument('--algorithm', help="TSIG Key Algorithm",
|
||||
required=True)
|
||||
parser.add_argument('--secret', help="TSIG Key Secret", required=True)
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
tsigkey = dict(
|
||||
name=parsed_args.name,
|
||||
algorithm=parsed_args.algorithm,
|
||||
secret=parsed_args.secret,
|
||||
)
|
||||
|
||||
return central_api.create_tsigkey(self.context, tsigkey)
|
||||
|
||||
|
||||
class UpdateTsigKeyCommand(base.UpdateCommand):
|
||||
""" Update TsigKey """
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateTsigKeyCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="TSIG Key ID")
|
||||
parser.add_argument('--name', help="TSIG Key Name")
|
||||
parser.add_argument('--algorithm', help="TSIG Key Algorithm")
|
||||
parser.add_argument('--secret', help="TSIG Key Secret")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
tsigkey = {}
|
||||
|
||||
if parsed_args.name:
|
||||
tsigkey['name'] = parsed_args.name
|
||||
|
||||
if parsed_args.algorithm:
|
||||
tsigkey['algorithm'] = parsed_args.algorithm
|
||||
|
||||
if parsed_args.secret:
|
||||
tsigkey['secret'] = parsed_args.secret
|
||||
|
||||
return central_api.update_tsigkey(self.context, parsed_args.id,
|
||||
tsigkey)
|
||||
|
||||
|
||||
class DeleteTsigKeyCommand(base.DeleteCommand):
|
||||
""" Delete TsigKey """
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteTsigKeyCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="TSIG Key ID")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return central_api.delete_tsigkey(self.context, parsed_args.id)
|
|
@ -126,3 +126,49 @@ def execute(*cmd, **kw):
|
|||
run_as_root = kw.pop('run_as_root', True)
|
||||
return processutils.execute(*cmd, run_as_root=run_as_root,
|
||||
root_helper=root_helper, **kw)
|
||||
|
||||
|
||||
def get_item_properties(item, fields, mixed_case_fields=[], formatters={}):
|
||||
"""Return a tuple containing the item properties.
|
||||
|
||||
:param item: a single item resource (e.g. Server, Tenant, etc)
|
||||
:param fields: tuple of strings with the desired field names
|
||||
:param mixed_case_fields: tuple of field names to preserve case
|
||||
:param formatters: dictionary mapping field names to callables
|
||||
to format the values
|
||||
"""
|
||||
row = []
|
||||
|
||||
for field in fields:
|
||||
if field in formatters:
|
||||
row.append(formatters[field](item))
|
||||
else:
|
||||
if field in mixed_case_fields:
|
||||
field_name = field.replace(' ', '_')
|
||||
else:
|
||||
field_name = field.lower().replace(' ', '_')
|
||||
if not hasattr(item, field_name) and \
|
||||
(isinstance(item, dict) and field_name in item):
|
||||
data = item[field_name]
|
||||
else:
|
||||
data = getattr(item, field_name, '')
|
||||
if data is None:
|
||||
data = ''
|
||||
row.append(data)
|
||||
return tuple(row)
|
||||
|
||||
|
||||
def get_columns(data):
|
||||
"""
|
||||
Some row's might have variable count of columns, ensure that we have the
|
||||
same.
|
||||
|
||||
:param data: Results in [{}, {]}]
|
||||
"""
|
||||
columns = set()
|
||||
|
||||
def _seen(col):
|
||||
columns.add(str(col))
|
||||
|
||||
map(lambda item: map(_seen, item.keys()), data)
|
||||
return list(columns)
|
||||
|
|
12
setup.py
12
setup.py
|
@ -76,6 +76,18 @@ setup(
|
|||
database-sync = moniker.manage.database:SyncCommand
|
||||
powerdns database-init = moniker.manage.powerdns:DatabaseInitCommand
|
||||
powerdns database-sync = moniker.manage.powerdns:DatabaseSyncCommand
|
||||
|
||||
server-list = moniker.manage.servers:ListServersCommand
|
||||
server-get = moniker.manage.servers:GetServerCommand
|
||||
server-create = moniker.manage.servers:CreateServerCommand
|
||||
server-update = moniker.manage.servers:UpdateServerCommand
|
||||
server-delete = moniker.manage.servers:DeleteServerCommand
|
||||
|
||||
tsigkey-list = moniker.manage.tsigkeys:ListTsigKeysCommand
|
||||
tsigkey-get = moniker.manage.tsigkeys:GetTsigKeyCommand
|
||||
tsigkey-create = moniker.manage.tsigkeys:CreateTsigKeyCommand
|
||||
tsigkey-update = moniker.manage.tsigkeys:UpdateTsigKeyCommand
|
||||
tsigkey-delete = moniker.manage.tsigkeys:DeleteTsigKeyCommand
|
||||
"""),
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
|
|
Loading…
Reference in New Issue