summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/Admin/Init.py
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2012-10-03 15:27:34 -0400
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2012-10-03 15:27:34 -0400
commit9eb3db849ba11ac49ced872a585f001bad3d8384 (patch)
tree212acba6b612e541f84325c28b48586f68c94f27 /src/lib/Bcfg2/Server/Admin/Init.py
parent1ea86e8f1d59b1c770ee8ae901d221adbbe9c1df (diff)
downloadbcfg2-9eb3db849ba11ac49ced872a585f001bad3d8384.tar.gz
bcfg2-9eb3db849ba11ac49ced872a585f001bad3d8384.tar.bz2
bcfg2-9eb3db849ba11ac49ced872a585f001bad3d8384.zip
prompt for locations of bcfg2 keypair in Init, using sane OS defaults
Diffstat (limited to 'src/lib/Bcfg2/Server/Admin/Init.py')
-rw-r--r--src/lib/Bcfg2/Server/Admin/Init.py219
1 files changed, 100 insertions, 119 deletions
diff --git a/src/lib/Bcfg2/Server/Admin/Init.py b/src/lib/Bcfg2/Server/Admin/Init.py
index 62f150055..5d5888ff2 100644
--- a/src/lib/Bcfg2/Server/Admin/Init.py
+++ b/src/lib/Bcfg2/Server/Admin/Init.py
@@ -1,3 +1,4 @@
+""" Interactively initialize a new repository. """
import getpass
import os
import random
@@ -10,17 +11,17 @@ import subprocess
import Bcfg2.Server.Admin
import Bcfg2.Server.Plugin
import Bcfg2.Options
-from Bcfg2.Compat import input
+from Bcfg2.Compat import input # pylint: disable=W0622
# default config file
-config = '''[server]
+CONFIG = '''[server]
repository = %s
plugins = %s
[statistics]
sendmailpath = %s
#web_debug = False
-#time_zone =
+#time_zone =
[database]
#engine = sqlite3
@@ -48,7 +49,7 @@ bcfg2 = %s
'''
# Default groups
-groups = '''<Groups version='3.0'>
+GROUPS = '''<Groups version='3.0'>
<Group profile='true' public='true' default='true' name='basic'>
<Group name='%s'/>
</Group>
@@ -65,13 +66,13 @@ groups = '''<Groups version='3.0'>
'''
# Default contents of clients.xml
-clients = '''<Clients version="3.0">
+CLIENTS = '''<Clients version="3.0">
<Client profile="basic" name="%s"/>
</Clients>
'''
# Mapping of operating system names to groups
-os_list = [('Red Hat/Fedora/RHEL/RHAS/Centos', 'redhat'),
+OS_LIST = [('Red Hat/Fedora/RHEL/RHAS/Centos', 'redhat'),
('SUSE/SLES', 'suse'),
('Mandrake', 'mandrake'),
('Debian', 'debian'),
@@ -80,43 +81,11 @@ os_list = [('Red Hat/Fedora/RHEL/RHAS/Centos', 'redhat'),
('FreeBSD', 'freebsd'),
('Arch', 'arch')]
-# Complete list of plugins
-plugin_list = ['Account',
- 'Base',
- 'Bundler',
- 'Bzr',
- 'Cfg',
- 'Decisions',
- 'Deps',
- 'Git',
- 'Guppy',
- 'Hg',
- 'Metadata',
- 'NagiosGen',
- 'Ohai',
- 'Packages',
- 'Pkgmgr',
- 'Probes',
- 'Properties',
- 'Rules',
- 'Snapshots',
- 'SSHbase',
- 'SSLCA',
- 'Statistics',
- 'TCheetah',
- 'TGenshi']
-
-# Default list of plugins to use
-default_plugins = Bcfg2.Options.SERVER_PLUGINS.default
-
def gen_password(length):
"""Generates a random alphanumeric password with length characters."""
chars = string.letters + string.digits
- newpasswd = ''
- for i in range(length):
- newpasswd = newpasswd + random.choice(chars)
- return newpasswd
+ return "".join(random.choice(chars) for i in range(length))
def create_key(hostname, keypath, certpath, country, state, location):
@@ -140,7 +109,8 @@ def create_key(hostname, keypath, certpath, country, state, location):
os.chmod(keypath, stat.S_IRUSR | stat.S_IWUSR) # 0600
-def create_conf(confpath, confdata, keypath):
+def create_conf(confpath, confdata):
+ """ create the config file """
# Don't overwrite existing bcfg2.conf file
if os.path.exists(confpath):
result = input("\nWarning: %s already exists. "
@@ -152,14 +122,14 @@ def create_conf(confpath, confdata, keypath):
open(confpath, "w").write(confdata)
os.chmod(confpath, stat.S_IRUSR | stat.S_IWUSR) # 0600
except Exception:
- e = sys.exc_info()[1]
- print("Error %s occured while trying to write configuration "
- "file to '%s'.\n" %
- (e, confpath))
+ err = sys.exc_info()[1]
+ print("Error trying to write configuration file '%s': %s" %
+ (confpath, err))
raise SystemExit(1)
class Init(Bcfg2.Server.Admin.Mode):
+ """Interactively initialize a new repository."""
__shorthelp__ = ("Interactively initialize a new repository.")
__longhelp__ = __shorthelp__ + "\n\nbcfg2-admin init"
__usage__ = "bcfg2-admin init"
@@ -168,24 +138,38 @@ class Init(Bcfg2.Server.Admin.Mode):
'proto': Bcfg2.Options.SERVER_PROTOCOL,
'repo': Bcfg2.Options.SERVER_REPOSITORY,
'sendmail': Bcfg2.Options.SENDMAIL_PATH}
- repopath = ""
- response = ""
- def _set_defaults(self):
+ def __init__(self, setup):
+ Bcfg2.Server.Admin.Mode.__init__(self, setup)
+ self.data = dict()
+ self.plugins = Bcfg2.Options.SERVER_PLUGINS.default
+
+ def _set_defaults(self, opts):
"""Set default parameters."""
- self.configfile = self.opts['configfile']
- self.repopath = self.opts['repo']
- self.password = gen_password(8)
- self.server_uri = "https://%s:6789" % socket.getfqdn()
- self.plugins = default_plugins
+ self.data['configfile'] = opts['configfile']
+ self.data['repopath'] = opts['repo']
+ self.data['password'] = gen_password(8)
+ self.data['server_uri'] = "https://%s:6789" % socket.getfqdn()
+ self.data['sendmail'] = opts['sendmail']
+ self.data['proto'] = opts['proto']
+ if os.path.exists("/etc/pki/tls"):
+ self.data['keypath'] = "/etc/pki/tls/private/bcfg2.key"
+ self.data['certpath'] = "/etc/pki/tls/certs/bcfg2.crt"
+ elif os.path.exists("/etc/ssl"):
+ self.data['keypath'] = "/etc/ssl/bcfg2.key"
+ self.data['certpath'] = "/etc/ssl/bcfg2.crt"
+ else:
+ basepath = os.path.dirname(self.configfile)
+ self.data['keypath'] = os.path.join(basepath, "bcfg2.key")
+ self.data['certpath'] = os.path.join(basepath, 'bcfg2.crt')
def __call__(self, args):
Bcfg2.Server.Admin.Mode.__call__(self, args)
# Parse options
- self.opts = Bcfg2.Options.OptionParser(self.options)
- self.opts.parse(args)
- self._set_defaults()
+ opts = Bcfg2.Options.OptionParser(self.options)
+ opts.parse(args)
+ self._set_defaults(opts)
# Prompt the user for input
self._prompt_config()
@@ -194,7 +178,7 @@ class Init(Bcfg2.Server.Admin.Mode):
self._prompt_hostname()
self._prompt_server()
self._prompt_groups()
- # self._prompt_plugins()
+ self._prompt_keypath()
self._prompt_certificate()
# Initialize the repository
@@ -205,27 +189,27 @@ class Init(Bcfg2.Server.Admin.Mode):
data = input("What is the server's hostname [%s]: " %
socket.getfqdn())
if data != '':
- self.shostname = data
+ self.data['shostname'] = data
else:
- self.shostname = socket.getfqdn()
+ self.data['shostname'] = socket.getfqdn()
def _prompt_config(self):
"""Ask for the configuration file path."""
newconfig = input("Store Bcfg2 configuration in [%s]: " %
self.configfile)
if newconfig != '':
- self.configfile = os.path.abspath(newconfig)
+ self.data['configfile'] = os.path.abspath(newconfig)
def _prompt_repopath(self):
"""Ask for the repository path."""
while True:
newrepo = input("Location of Bcfg2 repository [%s]: " %
- self.repopath)
+ self.data['repopath'])
if newrepo != '':
- self.repopath = os.path.abspath(newrepo)
- if os.path.isdir(self.repopath):
- response = input("Directory %s exists. Overwrite? [y/N]:" \
- % self.repopath)
+ self.data['repopath'] = os.path.abspath(newrepo)
+ if os.path.isdir(self.data['repopath']):
+ response = input("Directory %s exists. Overwrite? [y/N]:" %
+ self.data['repopath'])
if response.lower().strip() == 'y':
break
else:
@@ -237,45 +221,29 @@ class Init(Bcfg2.Server.Admin.Mode):
"Input password used for communication verification "
"(without echoing; leave blank for a random): ").strip()
if len(newpassword) != 0:
- self.password = newpassword
+ self.data['password'] = newpassword
def _prompt_server(self):
"""Ask for the server name."""
newserver = input("Input the server location [%s]: " %
- self.server_uri)
+ self.data['server_uri'])
if newserver != '':
- self.server_uri = newserver
+ self.data['server_uri'] = newserver
def _prompt_groups(self):
"""Create the groups.xml file."""
prompt = '''Input base Operating System for clients:\n'''
- for entry in os_list:
- prompt += "%d: %s\n" % (os_list.index(entry) + 1, entry[0])
+ for entry in OS_LIST:
+ prompt += "%d: %s\n" % (OS_LIST.index(entry) + 1, entry[0])
prompt += ': '
while True:
try:
osidx = int(input(prompt))
- self.os_sel = os_list[osidx - 1][1]
+ self.data['os_sel'] = OS_LIST[osidx - 1][1]
break
except ValueError:
continue
- def _prompt_plugins(self):
- default = input("Use default plugins? (%s) [Y/n]: " %
- ''.join(default_plugins)).lower()
- if default != 'y' or default != '':
- while True:
- plugins_are_valid = True
- plug_str = input("Specify plugins: ")
- plugins = plug_str.split(',')
- for plugin in plugins:
- plugin = plugin.strip()
- if not plugin in plugin_list:
- plugins_are_valid = False
- print("ERROR: Plugin %s not recognized" % plugin)
- if plugins_are_valid:
- break
-
def _prompt_certificate(self):
"""Ask for the key details (country, state, and location)."""
print("The following questions affect SSL certificate generation.")
@@ -283,73 +251,86 @@ class Init(Bcfg2.Server.Admin.Mode):
newcountry = input("Country name (2 letter code) for certificate: ")
if newcountry != '':
if len(newcountry) == 2:
- self.country = newcountry
+ self.data['country'] = newcountry
else:
while len(newcountry) != 2:
newcountry = input("2 letter country code (eg. US): ")
if len(newcountry) == 2:
- self.country = newcountry
+ self.data['country'] = newcountry
break
else:
- self.country = 'US'
+ self.data['country'] = 'US'
- newstate = input("State or Province Name (full name) for certificate: ")
+ newstate = input("State or Province Name (full name) for "
+ "certificate: ")
if newstate != '':
- self.state = newstate
+ self.data['state'] = newstate
else:
- self.state = 'Illinois'
+ self.data['state'] = 'Illinois'
newlocation = input("Locality Name (eg, city) for certificate: ")
if newlocation != '':
- self.location = newlocation
+ self.data['location'] = newlocation
else:
- self.location = 'Argonne'
+ self.data['location'] = 'Argonne'
+
+ def _prompt_keypath(self):
+ """ Ask for the key pair location. Try to use sensible
+ defaults depending on the OS """
+ keypath = input("Path where Bcfg2 server private key will be created "
+ "[%s]: " % self.data['keypath'])
+ if keypath:
+ self.data['keypath'] = keypath
+ certpath = input("Path where Bcfg2 server cert will be created"
+ "[%s]: " % self.data['certpath'])
+ if certpath:
+ self.data['certpath'] = certpath
def _init_plugins(self):
"""Initialize each plugin-specific portion of the repository."""
for plugin in self.plugins:
if plugin == 'Metadata':
Bcfg2.Server.Plugins.Metadata.Metadata.init_repo(
- self.repopath,
- groups_xml=groups % self.os_sel,
- clients_xml=clients % socket.getfqdn())
+ self.data['repopath'],
+ groups_xml=GROUPS % self.data['os_sel'],
+ clients_xml=CLIENTS % socket.getfqdn())
else:
try:
module = __import__("Bcfg2.Server.Plugins.%s" % plugin, '',
'', ["Bcfg2.Server.Plugins"])
cls = getattr(module, plugin)
- cls.init_repo(self.repopath)
- except Exception:
- e = sys.exc_info()[1]
+ cls.init_repo(self.data['repopath'])
+ except: # pylint: disable=W0702
+ err = sys.exc_info()[1]
print("Plugin setup for %s failed: %s\n"
- "Check that dependencies are installed?" % (plugin, e))
+ "Check that dependencies are installed" % (plugin,
+ err))
def init_repo(self):
- """Setup a new repo and create the content of the configuration file."""
- keypath = os.path.dirname(self.configfile)
- kpath = os.path.join(keypath, 'bcfg2.key')
- cpath = os.path.join(keypath, 'bcfg2.crt')
-
- confdata = config % (self.repopath,
+ """Setup a new repo and create the content of the
+ configuration file."""
+ confdata = CONFIG % (self.data['repopath'],
','.join(self.plugins),
- self.opts['sendmail'],
- self.opts['proto'],
- self.password,
- cpath,
- kpath,
- cpath,
- self.server_uri)
+ self.data['sendmail'],
+ self.data['proto'],
+ self.data['password'],
+ self.data['certpath'],
+ self.data['keypath'],
+ self.data['certpath'],
+ self.data['server_uri'])
# Create the configuration file and SSL key
- create_conf(self.configfile, confdata, keypath)
- create_key(self.shostname, kpath, cpath, self.country,
- self.state, self.location)
+ create_conf(self.data['configfile'], confdata)
+ create_key(self.data['shostname'], self.data['keypath'],
+ self.data['certpath'], self.data['country'],
+ self.data['state'], self.data['location'])
# Create the repository
- path = os.path.join(self.repopath, 'etc')
+ path = os.path.join(self.data['repopath'], 'etc')
try:
os.makedirs(path)
self._init_plugins()
- print("Repository created successfuly in %s" % (self.repopath))
+ print("Repository created successfuly in %s" %
+ self.data['repopath'])
except OSError:
print("Failed to create %s." % path)