mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Provide ipa-advise tool
Provides a pluggable framework for generating configuration scriptlets and instructions for various machine setups and use cases. Creates a new ipa-advise command, available to root user on the IPA server. Also provides an example configuration plugin, config-fedora-authconfig. https://fedorahosted.org/freeipa/ticket/3670
This commit is contained in:
committed by
Martin Kosek
parent
2a9be92855
commit
c81849712f
22
ipaserver/advise/__init__.py
Normal file
22
ipaserver/advise/__init__.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# Authors: Tomas Babej <tbabej@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2013 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
"""
|
||||
Base subpackage for ipa-advise related code.
|
||||
"""
|
||||
169
ipaserver/advise/base.py
Normal file
169
ipaserver/advise/base.py
Normal file
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/python
|
||||
# Authors: Tomas Babej <tbabej@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2013 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import os
|
||||
from ipalib import api
|
||||
from ipalib.errors import ValidationError
|
||||
from ipapython import admintool
|
||||
|
||||
|
||||
"""
|
||||
To add configuration instructions for a new use case, define a new class that
|
||||
inherits from Advice class.
|
||||
|
||||
You should create a plugin file for it in ipaserver/advise/plugins folder.
|
||||
|
||||
The class can run any arbitrary code or IPA command via api.Command['command']()
|
||||
calls. It needs to override get_info() method, which returns the formatted
|
||||
advice string.
|
||||
|
||||
>>> class sample_advice(Advice):
|
||||
>>> description = 'Instructions for machine with SSSD 1.0 setup.'
|
||||
|
||||
Description provided shows itself as a header and in the list of all advices
|
||||
currently available via ipa-advise.
|
||||
|
||||
Optionally, you can require root privileges for your plugin:
|
||||
|
||||
>>> require_root = True
|
||||
|
||||
The following method should be implemented in your plugin:
|
||||
|
||||
>>>.....def get_info():
|
||||
>>> self.log.debug('Entering execute() method')
|
||||
>>> self.log.comment('Providing useful advice just for you')
|
||||
>>> self.log.command('yum update sssd -y')
|
||||
|
||||
As you can see, Advice's log has 3 different levels. Debug lines are printed
|
||||
out with '# DEBUG:' prefix if --verbose had been used. Comment lines utilize
|
||||
'# ' prefix and command lines are printed raw.
|
||||
|
||||
As a result, you can redirect the advice's output directly to a script file.
|
||||
|
||||
# ipa-advise sample-advice > script.sh
|
||||
# ./script.sh
|
||||
|
||||
Important! Do not forget to register the class to the API.
|
||||
|
||||
>>> api.register(sample_advice)
|
||||
"""
|
||||
|
||||
|
||||
class IpaAdvise(admintool.AdminTool):
|
||||
"""
|
||||
Admin tool that given systems's configuration provides instructions how to
|
||||
configure the systems for various use cases.
|
||||
"""
|
||||
|
||||
command_name = 'ipa-advise'
|
||||
usage = "%prog ADVICE"
|
||||
description = "Provides configuration advice for various use cases. To "\
|
||||
"see the list of possible ADVICEs, run ipa-advise without "\
|
||||
"any arguments."
|
||||
|
||||
def __init__(self, options, args):
|
||||
super(IpaAdvise, self).__init__(options, args)
|
||||
|
||||
@classmethod
|
||||
def add_options(cls, parser):
|
||||
super(IpaAdvise, cls).add_options(parser)
|
||||
|
||||
def validate_options(self):
|
||||
super(IpaAdvise, self).validate_options(needs_root=False)
|
||||
|
||||
if len(self.args) > 1:
|
||||
raise self.option_parser.error("You can only provide one "
|
||||
"positional argument.")
|
||||
|
||||
def log_success(self):
|
||||
pass
|
||||
|
||||
def print_config_list(self):
|
||||
self.print_header('List of available advices')
|
||||
|
||||
max_keyword_len = max((len(keyword) for keyword in api.Advice))
|
||||
|
||||
for keyword in api.Advice:
|
||||
advice = getattr(api.Advice, keyword, '')
|
||||
description = getattr(advice, 'description', '')
|
||||
keyword = keyword.replace('_', '-')
|
||||
|
||||
# Compute the number of spaces needed for the table to be aligned
|
||||
offset = max_keyword_len - len(keyword)
|
||||
print(" {key} {off}: {desc}".format(key=keyword,
|
||||
desc=description,
|
||||
off=' ' * offset))
|
||||
|
||||
def print_header(self, header, print_shell=False):
|
||||
header_size = len(header)
|
||||
|
||||
prefix = ''
|
||||
if print_shell:
|
||||
prefix = '# '
|
||||
print '#!/bin/sh'
|
||||
|
||||
# Do not print out empty header
|
||||
if header_size > 0:
|
||||
print(prefix + '-' * (header_size - len(prefix)))
|
||||
print(prefix + header)
|
||||
print(prefix + '-' * (header_size - len(prefix)))
|
||||
|
||||
def print_advice(self, keyword):
|
||||
advice = getattr(api.Advice, keyword, None)
|
||||
|
||||
# Ensure that Configuration class for given --setup option value exists
|
||||
if advice is None:
|
||||
raise ValidationError(
|
||||
name="advice",
|
||||
error="No instructions are available for '{con}'. "
|
||||
"See the list of available configuration "
|
||||
"by invoking the ipa-advise command with no argument."
|
||||
.format(con=keyword.replace('_', '-')))
|
||||
|
||||
# Check whether root privileges are needed
|
||||
if advice.require_root and os.getegid() != 0:
|
||||
raise admintool.ScriptError(
|
||||
'Must be root to get advice for {adv}'
|
||||
.format(adv=keyword.replace('_', '-')), 1)
|
||||
|
||||
# Print out nicely formatted header
|
||||
self.print_header(advice.description, print_shell=True)
|
||||
|
||||
# Set options so that plugin can use verbose/quiet options
|
||||
advice.set_options(self.options)
|
||||
|
||||
# Print out the actual advice
|
||||
advice.get_info()
|
||||
for line in advice.log.content:
|
||||
print line
|
||||
|
||||
def run(self):
|
||||
super(IpaAdvise, self).run()
|
||||
|
||||
api.bootstrap(in_server=False, context='advise')
|
||||
api.finalize()
|
||||
|
||||
# With no argument, print the list out and exit
|
||||
if not self.args:
|
||||
self.print_config_list()
|
||||
return
|
||||
else:
|
||||
keyword = self.args[0].replace('-', '_')
|
||||
self.print_advice(keyword)
|
||||
22
ipaserver/advise/plugins/__init__.py
Normal file
22
ipaserver/advise/plugins/__init__.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# Authors: Tomas Babej <tbabej@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2013 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
"""
|
||||
Provides a separate api for ipa-advise plugins.
|
||||
"""
|
||||
41
ipaserver/advise/plugins/fedora_authconfig.py
Normal file
41
ipaserver/advise/plugins/fedora_authconfig.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# Authors: Tomas Babej <tbabej@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2013 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from ipalib import api
|
||||
from ipalib.frontend import Advice
|
||||
|
||||
|
||||
class config_fedora_authconfig(Advice):
|
||||
"""
|
||||
Provides client configuration instructions using authconfig.
|
||||
"""
|
||||
|
||||
description = 'Authconfig instructions for configuring Fedora 18/19 '\
|
||||
'client with IPA server without use of SSSD.'
|
||||
|
||||
def get_info(self):
|
||||
self.log.debug("Hostname obtained via api.env.host")
|
||||
self.log.comment("Run the following command as a root:")
|
||||
template = "/sbin/authconfig --enableldap --ldapserver={server} "\
|
||||
"--enablerfc2307bis --enablekrb5"
|
||||
advice = template.format(server=api.env.host)
|
||||
self.log.command(advice)
|
||||
|
||||
|
||||
api.register(config_fedora_authconfig)
|
||||
Reference in New Issue
Block a user