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)
|
run_as_root = kw.pop('run_as_root', True)
|
||||||
return processutils.execute(*cmd, run_as_root=run_as_root,
|
return processutils.execute(*cmd, run_as_root=run_as_root,
|
||||||
root_helper=root_helper, **kw)
|
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
|
database-sync = moniker.manage.database:SyncCommand
|
||||||
powerdns database-init = moniker.manage.powerdns:DatabaseInitCommand
|
powerdns database-init = moniker.manage.powerdns:DatabaseInitCommand
|
||||||
powerdns database-sync = moniker.manage.powerdns:DatabaseSyncCommand
|
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=[
|
classifiers=[
|
||||||
'Development Status :: 3 - Alpha',
|
'Development Status :: 3 - Alpha',
|
||||||
|
|
Loading…
Reference in New Issue