kerberos infra deployment impl
this change implements support of deploying kerberos infrastucture, including kdc server and setting up clients. can be tested on fake plugin. Partially-implements bp: initial-kerberos-integration Change-Id: I328c3ecbbc712b3a9d48a6a7248ec28477ec0f5c
This commit is contained in:
parent
bed07565e5
commit
758f38a1f6
@ -17,6 +17,7 @@ from sahara import context
|
|||||||
from sahara.i18n import _
|
from sahara.i18n import _
|
||||||
from sahara.plugins import exceptions as pex
|
from sahara.plugins import exceptions as pex
|
||||||
from sahara.plugins.fake import edp_engine
|
from sahara.plugins.fake import edp_engine
|
||||||
|
from sahara.plugins import kerberos as krb
|
||||||
from sahara.plugins import provisioning as p
|
from sahara.plugins import provisioning as p
|
||||||
from sahara.plugins import utils as plugin_utils
|
from sahara.plugins import utils as plugin_utils
|
||||||
|
|
||||||
@ -49,11 +50,12 @@ class FakePluginProvider(p.ProvisioningPluginBase):
|
|||||||
return {
|
return {
|
||||||
"HDFS": ["namenode", "datanode"],
|
"HDFS": ["namenode", "datanode"],
|
||||||
"MapReduce": ["tasktracker", "jobtracker"],
|
"MapReduce": ["tasktracker", "jobtracker"],
|
||||||
|
"Kerberos": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_configs(self, hadoop_version):
|
def get_configs(self, hadoop_version):
|
||||||
# no need to expose any configs, it could be checked using real plugins
|
# returning kerberos configs
|
||||||
return []
|
return krb.get_config_list()
|
||||||
|
|
||||||
def configure_cluster(self, cluster):
|
def configure_cluster(self, cluster):
|
||||||
with context.ThreadGroup() as tg:
|
with context.ThreadGroup() as tg:
|
||||||
@ -62,11 +64,23 @@ class FakePluginProvider(p.ProvisioningPluginBase):
|
|||||||
self._write_ops, instance)
|
self._write_ops, instance)
|
||||||
|
|
||||||
def start_cluster(self, cluster):
|
def start_cluster(self, cluster):
|
||||||
|
self.deploy_kerberos(cluster)
|
||||||
with context.ThreadGroup() as tg:
|
with context.ThreadGroup() as tg:
|
||||||
for instance in plugin_utils.get_instances(cluster):
|
for instance in plugin_utils.get_instances(cluster):
|
||||||
tg.spawn('fake-check-%s' % instance.id,
|
tg.spawn('fake-check-%s' % instance.id,
|
||||||
self._check_ops, instance)
|
self._check_ops, instance)
|
||||||
|
|
||||||
|
def deploy_kerberos(self, cluster):
|
||||||
|
all_instances = plugin_utils.get_instances(cluster)
|
||||||
|
namenodes = plugin_utils.get_instances(cluster, 'namenode')
|
||||||
|
server = None
|
||||||
|
if len(namenodes) > 0:
|
||||||
|
server = namenodes[0]
|
||||||
|
elif len(all_instances) > 0:
|
||||||
|
server = all_instances[0]
|
||||||
|
if server:
|
||||||
|
krb.deploy_infrastructure(cluster, server)
|
||||||
|
|
||||||
def scale_cluster(self, cluster, instances):
|
def scale_cluster(self, cluster, instances):
|
||||||
with context.ThreadGroup() as tg:
|
with context.ThreadGroup() as tg:
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
|
345
sahara/plugins/kerberos.py
Normal file
345
sahara/plugins/kerberos.py
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
# 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 oslo_config import cfg
|
||||||
|
from oslo_log import log as logging
|
||||||
|
from oslo_utils import uuidutils as uuid
|
||||||
|
|
||||||
|
from sahara import conductor as cond
|
||||||
|
from sahara import context
|
||||||
|
from sahara import exceptions as exc
|
||||||
|
from sahara.i18n import _
|
||||||
|
from sahara.plugins import provisioning as base
|
||||||
|
from sahara.plugins import utils as pl_utils
|
||||||
|
from sahara.service.castellan import utils as key_manager
|
||||||
|
from sahara.utils import cluster as cl_utils
|
||||||
|
from sahara.utils import cluster_progress_ops as cpo
|
||||||
|
from sahara.utils import files
|
||||||
|
|
||||||
|
|
||||||
|
conductor = cond.API
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
CONF = cfg.CONF
|
||||||
|
POLICY_FILES_DIR = '/tmp/UnlimitedPolicy'
|
||||||
|
|
||||||
|
|
||||||
|
class KDCInstallationFailed(exc.SaharaException):
|
||||||
|
code = 'KDC_INSTALL_FAILED'
|
||||||
|
message_template = _('KDC installation failed by reason: {reason}')
|
||||||
|
|
||||||
|
def __init__(self, reason):
|
||||||
|
message = self.message_template.format(reason=reason)
|
||||||
|
super(KDCInstallationFailed, self).__init__(message)
|
||||||
|
|
||||||
|
|
||||||
|
def _config(**kwargs):
|
||||||
|
return base.Config(
|
||||||
|
applicable_target='Kerberos', priority=1,
|
||||||
|
is_optional=True, scope='cluster', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
enable_kerberos = _config(
|
||||||
|
name='Enable Kerberos Security', config_type='bool',
|
||||||
|
default_value=False)
|
||||||
|
use_existing_kdc = _config(
|
||||||
|
name='Existing KDC', config_type='bool',
|
||||||
|
default_value=False)
|
||||||
|
kdc_server_ip = _config(
|
||||||
|
name='Server IP of KDC', config_type='string',
|
||||||
|
default_value='192.168.0.1',
|
||||||
|
description=_('Server IP of KDC server when using existing KDC'))
|
||||||
|
realm_name = _config(
|
||||||
|
name='Realm Name', config_type='string',
|
||||||
|
default_value='SAHARA-KDC',
|
||||||
|
description=_('The name of realm to be used'))
|
||||||
|
admin_principal = _config(
|
||||||
|
name='Admin principal', config_type='string',
|
||||||
|
default_value='sahara/admin',
|
||||||
|
description=_('Admin principal for existing KDC server'))
|
||||||
|
admin_password = _config(
|
||||||
|
name='Admin password', config_type='string', default_value='')
|
||||||
|
policy_url = _config(
|
||||||
|
name="JCE libraries", config_type='string',
|
||||||
|
default_value='http://sahara-files.mirantis.com/kerberos-artifacts',
|
||||||
|
description=_('Java Cryptography Extension (JCE) '
|
||||||
|
'Unlimited Strength Jurisdiction Policy Files location')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_config_list():
|
||||||
|
return [
|
||||||
|
enable_kerberos,
|
||||||
|
use_existing_kdc,
|
||||||
|
kdc_server_ip,
|
||||||
|
realm_name,
|
||||||
|
admin_principal,
|
||||||
|
admin_password,
|
||||||
|
policy_url,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_kdc_host(cluster, server):
|
||||||
|
if using_existing_kdc(cluster):
|
||||||
|
return "server.%s" % CONF.node_domain
|
||||||
|
return server.fqdn()
|
||||||
|
|
||||||
|
|
||||||
|
def is_kerberos_security_enabled(cluster):
|
||||||
|
return pl_utils.get_config_value_or_default(
|
||||||
|
cluster=cluster, config=enable_kerberos)
|
||||||
|
|
||||||
|
|
||||||
|
def using_existing_kdc(cluster):
|
||||||
|
return pl_utils.get_config_value_or_default(
|
||||||
|
cluster=cluster, config=use_existing_kdc)
|
||||||
|
|
||||||
|
|
||||||
|
def get_kdc_server_ip(cluster):
|
||||||
|
return pl_utils.get_config_value_or_default(
|
||||||
|
cluster=cluster, config=kdc_server_ip)
|
||||||
|
|
||||||
|
|
||||||
|
def get_realm_name(cluster):
|
||||||
|
return pl_utils.get_config_value_or_default(
|
||||||
|
cluster=cluster, config=realm_name)
|
||||||
|
|
||||||
|
|
||||||
|
def get_admin_principal(cluster):
|
||||||
|
return pl_utils.get_config_value_or_default(
|
||||||
|
cluster=cluster, config=admin_principal)
|
||||||
|
|
||||||
|
|
||||||
|
def get_admin_password(cluster):
|
||||||
|
# TODO(vgridnev): support in follow-up improved secret storage for
|
||||||
|
# configs
|
||||||
|
return pl_utils.get_config_value_or_default(
|
||||||
|
cluster=cluster, config=admin_password)
|
||||||
|
|
||||||
|
|
||||||
|
def get_policy_url(cluster):
|
||||||
|
return pl_utils.get_config_value_or_default(
|
||||||
|
cluster=cluster, config=policy_url)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_clients(cluster, server=None, instances=None):
|
||||||
|
if not instances:
|
||||||
|
instances = cl_utils.get_instances(cluster)
|
||||||
|
server_ip = None
|
||||||
|
cpo.add_provisioning_step(
|
||||||
|
cluster.id, _("Setting Up Kerberos clients"), len(instances))
|
||||||
|
|
||||||
|
if not server:
|
||||||
|
server_ip = get_kdc_server_ip(cluster)
|
||||||
|
with context.ThreadGroup() as tg:
|
||||||
|
for instance in instances:
|
||||||
|
tg.spawn('setup-client-%s' % instance.instance_name,
|
||||||
|
_setup_client_node, cluster, instance,
|
||||||
|
server, server_ip)
|
||||||
|
|
||||||
|
|
||||||
|
def prepare_policy_files(cluster, instances=None):
|
||||||
|
if instances is None:
|
||||||
|
instances = pl_utils.get_instances(cluster)
|
||||||
|
|
||||||
|
remote_url = get_policy_url(cluster)
|
||||||
|
cpo.add_provisioning_step(
|
||||||
|
cluster.id, _("Preparing policy files"), len(instances))
|
||||||
|
with context.ThreadGroup() as tg:
|
||||||
|
for inst in instances:
|
||||||
|
tg.spawn(
|
||||||
|
'policy-files',
|
||||||
|
_prepare_policy_files, inst, remote_url)
|
||||||
|
|
||||||
|
|
||||||
|
def deploy_infrastructure(cluster, server=None):
|
||||||
|
if not is_kerberos_security_enabled(cluster):
|
||||||
|
LOG.debug("Kerberos security disabled for cluster")
|
||||||
|
return
|
||||||
|
if not using_existing_kdc(cluster):
|
||||||
|
deploy_kdc_server(cluster, server)
|
||||||
|
|
||||||
|
setup_clients(cluster, server)
|
||||||
|
|
||||||
|
|
||||||
|
def _execute_script(client, script):
|
||||||
|
with client.remote() as remote:
|
||||||
|
script_path = '/tmp/%s' % uuid.generate_uuid()[:8]
|
||||||
|
remote.write_file_to(script_path, script)
|
||||||
|
remote.execute_command('chmod +x %s' % script_path)
|
||||||
|
remote.execute_command('bash %s' % script_path)
|
||||||
|
remote.execute_command('rm -rf %s' % script_path)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kdc_config(cluster, os):
|
||||||
|
if os == "ubuntu":
|
||||||
|
data = files.get_file_text('plugins/resources/kdc_conf')
|
||||||
|
else:
|
||||||
|
data = files.get_file_text('plugins/resources/kdc_conf_redhat')
|
||||||
|
return data % {
|
||||||
|
'realm_name': get_realm_name(cluster)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _get_krb5_config(cluster, server_fqdn):
|
||||||
|
data = files.get_file_text('plugins/resources/krb5_config')
|
||||||
|
return data % {
|
||||||
|
'realm_name': get_realm_name(cluster),
|
||||||
|
'server': server_fqdn,
|
||||||
|
'node_domain': CONF.node_domain,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _get_short_uuid():
|
||||||
|
return "%s%s" % (uuid.generate_uuid()[:8], uuid.generate_uuid()[:8])
|
||||||
|
|
||||||
|
|
||||||
|
def get_server_password(cluster):
|
||||||
|
if using_existing_kdc(cluster):
|
||||||
|
return get_admin_password(cluster)
|
||||||
|
ctx = context.ctx()
|
||||||
|
cluster = conductor.cluster_get(ctx, cluster)
|
||||||
|
extra = cluster.extra.to_dict() if cluster.extra else {}
|
||||||
|
passwd_key = 'admin-passwd-kdc'
|
||||||
|
if passwd_key not in extra:
|
||||||
|
passwd = _get_short_uuid()
|
||||||
|
key_id = key_manager.store_secret(passwd, ctx)
|
||||||
|
extra[passwd_key] = key_id
|
||||||
|
cluster = conductor.cluster_update(ctx, cluster, {'extra': extra})
|
||||||
|
passwd = key_manager.get_secret(extra.get(passwd_key), ctx)
|
||||||
|
return passwd
|
||||||
|
|
||||||
|
|
||||||
|
def _get_configs_dir(os):
|
||||||
|
if os == "ubuntu":
|
||||||
|
return "/etc/krb5kdc"
|
||||||
|
return "/var/kerberos/krb5kdc"
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kdc_conf_path(os):
|
||||||
|
return "%s/kdc.conf" % _get_configs_dir(os)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_realm_create_command(os):
|
||||||
|
if os == 'ubuntu':
|
||||||
|
return "krb5_newrealm"
|
||||||
|
return "kdb5_util create -s"
|
||||||
|
|
||||||
|
|
||||||
|
def _get_acl_config_path(os):
|
||||||
|
return "%s/kadm5.acl" % _get_configs_dir(os)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_acl_config():
|
||||||
|
return "*/admin * "
|
||||||
|
|
||||||
|
|
||||||
|
def _get_start_command(os, version):
|
||||||
|
if os == "ubuntu":
|
||||||
|
return ("sudo service krb5-kdc restart && "
|
||||||
|
"sudo service krb5-admin-server restart")
|
||||||
|
|
||||||
|
if version.startswith('6'):
|
||||||
|
return ("sudo /etc/rc.d/init.d/krb5kdc start "
|
||||||
|
"&& sudo /etc/rc.d/init.d/kadmin start")
|
||||||
|
|
||||||
|
if version.startswith('7'):
|
||||||
|
return ("sudo systemctl start krb5kdc &&"
|
||||||
|
"sudo systemctl start kadmin")
|
||||||
|
|
||||||
|
raise ValueError(
|
||||||
|
_("Unable to get kdc server start command"))
|
||||||
|
|
||||||
|
|
||||||
|
def _get_server_installation_script(cluster, server_fqdn, os, version):
|
||||||
|
data = files.get_file_text(
|
||||||
|
'plugins/resources/mit-kdc-server-init.sh.template')
|
||||||
|
return data % {
|
||||||
|
'kdc_conf': _get_kdc_config(cluster, os),
|
||||||
|
'kdc_conf_path': _get_kdc_conf_path(os),
|
||||||
|
'acl_conf': _get_acl_config(),
|
||||||
|
'acl_conf_path': _get_acl_config_path(os),
|
||||||
|
'realm_create': _get_realm_create_command(os),
|
||||||
|
'krb5_conf': _get_krb5_config(cluster, server_fqdn),
|
||||||
|
'admin_principal': get_admin_principal(cluster),
|
||||||
|
'password': get_server_password(cluster),
|
||||||
|
'os': os,
|
||||||
|
'start_command': _get_start_command(os, version),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@cpo.event_wrapper(True, step=_("Deploy KDC server"), param=('cluster', 0))
|
||||||
|
def deploy_kdc_server(cluster, server):
|
||||||
|
with server.remote() as r:
|
||||||
|
os = r.get_os_distrib()
|
||||||
|
version = r.get_os_version()
|
||||||
|
script = _get_server_installation_script(
|
||||||
|
cluster, server.fqdn(), os, version)
|
||||||
|
_execute_script(server, script)
|
||||||
|
|
||||||
|
|
||||||
|
def _push_etc_hosts_entry(client, entry):
|
||||||
|
with client.remote() as r:
|
||||||
|
r.execute_command('echo %s | sudo tee -a /etc/hosts' % entry)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_client_installation_script(cluster, server_fqdn, os):
|
||||||
|
data = files.get_file_text('plugins/resources/krb-client-init.sh.template')
|
||||||
|
return data % {
|
||||||
|
'os': os,
|
||||||
|
'krb5_conf': _get_krb5_config(cluster, server_fqdn),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@cpo.event_wrapper(True, param=('client', 1))
|
||||||
|
def _setup_client_node(cluster, client, server=None, server_ip=None):
|
||||||
|
if server:
|
||||||
|
server_fqdn = server.fqdn()
|
||||||
|
elif server_ip:
|
||||||
|
server_fqdn = "server." % CONF.node_domain
|
||||||
|
_push_etc_hosts_entry(
|
||||||
|
client, "%s %s %s" % (server_ip, server_fqdn, server))
|
||||||
|
else:
|
||||||
|
raise KDCInstallationFailed(_('Server or server ip are not provided'))
|
||||||
|
with client.remote() as r:
|
||||||
|
os = r.get_os_distrib()
|
||||||
|
script = _get_client_installation_script(cluster, server_fqdn, os)
|
||||||
|
_execute_script(client, script)
|
||||||
|
|
||||||
|
|
||||||
|
@cpo.event_wrapper(True)
|
||||||
|
def _prepare_policy_files(instance, remote_url):
|
||||||
|
with instance.remote() as r:
|
||||||
|
cmd = 'cut -f2 -d \"=\" /etc/profile.d/99-java.sh | head -1'
|
||||||
|
exit_code, java_home = r.execute_command(cmd)
|
||||||
|
java_home = java_home.strip()
|
||||||
|
results = [
|
||||||
|
r.execute_command(
|
||||||
|
"ls %s/local_policy.jar" % POLICY_FILES_DIR,
|
||||||
|
raise_when_error=False)[0] != 0,
|
||||||
|
r.execute_command(
|
||||||
|
"ls %s/US_export_policy.jar" % POLICY_FILES_DIR,
|
||||||
|
raise_when_error=False)[0] != 0
|
||||||
|
]
|
||||||
|
# a least one exit code is not zero
|
||||||
|
if any(results):
|
||||||
|
r.execute_command('mkdir %s' % POLICY_FILES_DIR)
|
||||||
|
r.execute_command(
|
||||||
|
"sudo curl %s/local_policy.jar -o %s/local_policy.jar" % (
|
||||||
|
remote_url, POLICY_FILES_DIR))
|
||||||
|
r.execute_command(
|
||||||
|
"sudo curl %s/US_export_policy.jar -o "
|
||||||
|
"%s/US_export_policy.jar" % (
|
||||||
|
remote_url, POLICY_FILES_DIR))
|
||||||
|
r.execute_command(
|
||||||
|
'sudo cp %s/*.jar %s/lib/security/'
|
||||||
|
% (POLICY_FILES_DIR, java_home))
|
16
sahara/plugins/resources/kdc_conf
Normal file
16
sahara/plugins/resources/kdc_conf
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[kdcdefaults]
|
||||||
|
kdc_ports = 750,88
|
||||||
|
|
||||||
|
[realms]
|
||||||
|
%(realm_name)s = {
|
||||||
|
database_name = /var/lib/krb5kdc/principal
|
||||||
|
admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab
|
||||||
|
acl_file = /etc/krb5kdc/kadm5.acl
|
||||||
|
key_stash_file = /etc/krb5kdc/stash
|
||||||
|
kdc_ports = 750,88
|
||||||
|
max_life = 10h 0m 0s
|
||||||
|
max_renewable_life = 7d 0h 0m 0s
|
||||||
|
master_key_type = des3-hmac-sha1
|
||||||
|
supported_enctypes = aes256-cts:normal arcfour-hmac:normal des3-hmac-sha1:normal des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3
|
||||||
|
default_principal_flags = +preauth, +renewable, +forwardable
|
||||||
|
}
|
13
sahara/plugins/resources/kdc_conf_redhat
Normal file
13
sahara/plugins/resources/kdc_conf_redhat
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[kdcdefaults]
|
||||||
|
kdc_ports = 88
|
||||||
|
kdc_tcp_ports = 88
|
||||||
|
|
||||||
|
[realms]
|
||||||
|
%(realm_name)s = {
|
||||||
|
#master_key_type = aes256-cts
|
||||||
|
acl_file = /var/kerberos/krb5kdc/kadm5.acl
|
||||||
|
dict_file = /usr/share/dict/words
|
||||||
|
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
|
||||||
|
supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal
|
||||||
|
default_principal_flags = +preauth, +renewable, +forwardable
|
||||||
|
}
|
14
sahara/plugins/resources/krb-client-init.sh.template
Normal file
14
sahara/plugins/resources/krb-client-init.sh.template
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -xe
|
||||||
|
export SAHARA_SCRIPT_BASE_OS=%(os)s
|
||||||
|
if [ "$SAHARA_SCRIPT_BASE_OS" = "ubuntu" ]; then
|
||||||
|
|
||||||
|
sudo dpkg -s krb5-user || sudo DEBIAN_FRONTEND=noninteractive apt-get install -y krb5-user
|
||||||
|
sudo dpkg -s libpam-krb5 || sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libpam-krb5
|
||||||
|
sudo dpkg -s ldap-utils || sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ldap-utils
|
||||||
|
|
||||||
|
else
|
||||||
|
sudo rpm -q krb5-workstation || sudo yum install -y krb5-workstation
|
||||||
|
fi
|
||||||
|
sudo echo "%(krb5_conf)s" | sudo tee /etc/krb5.conf
|
11
sahara/plugins/resources/krb5_config
Normal file
11
sahara/plugins/resources/krb5_config
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[libdefaults]
|
||||||
|
default_realm = %(realm_name)s
|
||||||
|
forwardable = true
|
||||||
|
proxiable = true
|
||||||
|
[realms]
|
||||||
|
%(realm_name)s = {
|
||||||
|
kdc = %(server)s
|
||||||
|
admin_server = %(server)s
|
||||||
|
}
|
||||||
|
[domain_realm]
|
||||||
|
.%(node_domain)s = %(realm_name)s
|
34
sahara/plugins/resources/mit-kdc-server-init.sh.template
Normal file
34
sahara/plugins/resources/mit-kdc-server-init.sh.template
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -xe
|
||||||
|
export SAHARA_SCRIPT_BASE_OS=%(os)s
|
||||||
|
if [ "$SAHARA_SCRIPT_BASE_OS" = "ubuntu" ]; then
|
||||||
|
sudo dpkg -s krb5-admin-server || sudo DEBIAN_FRONTEND=noninteractive apt-get install -y krb5-admin-server
|
||||||
|
sudo dpkg -s rng-tools || sudo apt-get install rng-tools -y
|
||||||
|
else
|
||||||
|
sudo rpm -q krb5-server || sudo yum install -y krb5-server
|
||||||
|
sudo rpm -q krb5-libs || sudo yum install -y krb5-libs
|
||||||
|
sudo rpm -q krb5-workstation || sudo yum install -y krb5-workstation
|
||||||
|
sudo rpm -q rng-tools || sudo yum install -y rng-tools
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo rngd -r /dev/urandom -W 4096
|
||||||
|
|
||||||
|
sudo echo "%(krb5_conf)s" | sudo tee /etc/krb5.conf
|
||||||
|
sudo echo "%(kdc_conf)s" | sudo tee %(kdc_conf_path)s
|
||||||
|
sudo echo "%(acl_conf)s" | sudo tee %(acl_conf_path)s
|
||||||
|
|
||||||
|
|
||||||
|
sudo %(realm_create)s <<EOF
|
||||||
|
%(password)s
|
||||||
|
%(password)s
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo kadmin.local <<EOF
|
||||||
|
addprinc %(admin_principal)s
|
||||||
|
%(password)s
|
||||||
|
%(password)s
|
||||||
|
exit
|
||||||
|
EOF
|
||||||
|
|
||||||
|
%(start_command)s
|
@ -77,7 +77,21 @@ def start_process_event_message(process):
|
|||||||
process=process)
|
process=process)
|
||||||
|
|
||||||
|
|
||||||
def get_config_value_or_default(service, name, cluster):
|
def get_config_value_or_default(
|
||||||
|
service=None, name=None, cluster=None, config=None):
|
||||||
|
if not config:
|
||||||
|
if not service or not name:
|
||||||
|
raise RuntimeError(_("Unable to retrieve config details"))
|
||||||
|
default_value = None
|
||||||
|
else:
|
||||||
|
service = config.applicable_target
|
||||||
|
name = config.name
|
||||||
|
default_value = config.default_value
|
||||||
|
|
||||||
|
cluster_configs = cluster.cluster_configs
|
||||||
|
if cluster_configs.get(service, {}).get(name, None) is not None:
|
||||||
|
return cluster_configs.get(service, {}).get(name, None)
|
||||||
|
|
||||||
# Try getting config from the cluster.
|
# Try getting config from the cluster.
|
||||||
for ng in cluster.node_groups:
|
for ng in cluster.node_groups:
|
||||||
if (ng.configuration().get(service) and
|
if (ng.configuration().get(service) and
|
||||||
@ -85,6 +99,8 @@ def get_config_value_or_default(service, name, cluster):
|
|||||||
return ng.configuration()[service][name]
|
return ng.configuration()[service][name]
|
||||||
|
|
||||||
# Find and return the default
|
# Find and return the default
|
||||||
|
if default_value is not None:
|
||||||
|
return default_value
|
||||||
|
|
||||||
plugin = plugins_base.PLUGINS.get_plugin(cluster.plugin_name)
|
plugin = plugins_base.PLUGINS.get_plugin(cluster.plugin_name)
|
||||||
configs = plugin.get_all_configs(cluster.hadoop_version)
|
configs = plugin.get_all_configs(cluster.hadoop_version)
|
||||||
|
93
sahara/tests/unit/plugins/test_kerberos.py
Normal file
93
sahara/tests/unit/plugins/test_kerberos.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# 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 mock
|
||||||
|
|
||||||
|
from sahara import context
|
||||||
|
from sahara.plugins import kerberos as krb
|
||||||
|
from sahara.tests.unit import base
|
||||||
|
|
||||||
|
|
||||||
|
class FakeObject(dict):
|
||||||
|
def __init__(self, dict):
|
||||||
|
self._dict = dict
|
||||||
|
super(FakeObject, self).__init__(**dict)
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return self._dict
|
||||||
|
|
||||||
|
|
||||||
|
class TestKerberosBase(base.SaharaTestCase):
|
||||||
|
def test_list_configs(self):
|
||||||
|
self.assertEqual(7, len(krb.get_config_list()))
|
||||||
|
|
||||||
|
@mock.patch('sahara.conductor.API.cluster_update')
|
||||||
|
@mock.patch('sahara.conductor.API.cluster_get')
|
||||||
|
@mock.patch('sahara.service.castellan.utils.store_secret')
|
||||||
|
@mock.patch('sahara.service.castellan.utils.get_secret')
|
||||||
|
def test_get_server_password(
|
||||||
|
self, get_secret, store_secret, cluster_get_mock,
|
||||||
|
cluster_update_mock):
|
||||||
|
cl = mock.Mock(
|
||||||
|
node_groups=[], cluster_configs={}, extra={})
|
||||||
|
ctx = context.ctx()
|
||||||
|
cluster_get_mock.return_value = cl
|
||||||
|
store_secret.return_value = 'secret-id'
|
||||||
|
krb.get_server_password(cl)
|
||||||
|
|
||||||
|
self.assertEqual(1, cluster_get_mock.call_count)
|
||||||
|
self.assertEqual(1, cluster_update_mock.call_count)
|
||||||
|
self.assertEqual([
|
||||||
|
mock.call(ctx, cl, {'extra': {'admin-passwd-kdc': 'secret-id'}})],
|
||||||
|
cluster_update_mock.call_args_list)
|
||||||
|
|
||||||
|
self.assertEqual(1, get_secret.call_count)
|
||||||
|
self.assertEqual(1, store_secret.call_count)
|
||||||
|
|
||||||
|
cl = mock.Mock(
|
||||||
|
node_groups=[], cluster_configs={},
|
||||||
|
extra=FakeObject({'admin-passwd-kdc': 'secret-id'}))
|
||||||
|
cluster_get_mock.return_value = cl
|
||||||
|
krb.get_server_password(cl)
|
||||||
|
|
||||||
|
self.assertEqual(2, get_secret.call_count)
|
||||||
|
self.assertEqual(1, store_secret.call_count)
|
||||||
|
self.assertEqual(1, cluster_update_mock.call_count)
|
||||||
|
|
||||||
|
cl = mock.Mock(
|
||||||
|
node_groups=[], cluster_configs=FakeObject({
|
||||||
|
'Existing KDC': True, 'Admin password': 'THE BEST EVER'}),
|
||||||
|
extra=FakeObject({'admin-passwd-kdc': 'secret-id'}))
|
||||||
|
cluster_get_mock.return_value = cl
|
||||||
|
get_secret.return_value = 'THE BEST EVER'
|
||||||
|
self.assertEqual('THE BEST EVER', krb.get_server_password(cl))
|
||||||
|
|
||||||
|
def test_base_configs(self):
|
||||||
|
cluster = mock.Mock(
|
||||||
|
cluster_configs={'Kerberos': {'Enable Kerberos Security': True}},
|
||||||
|
node_groups=[],
|
||||||
|
)
|
||||||
|
self.assertTrue(krb.is_kerberos_security_enabled(cluster))
|
||||||
|
|
||||||
|
cluster = mock.Mock(
|
||||||
|
cluster_configs={'Kerberos': {'Enable Kerberos Security': False}},
|
||||||
|
node_groups=[],
|
||||||
|
)
|
||||||
|
self.assertFalse(krb.is_kerberos_security_enabled(cluster))
|
||||||
|
|
||||||
|
@mock.patch('sahara.plugins.kerberos.get_server_password')
|
||||||
|
def test_get_server_installation_script(self, get):
|
||||||
|
cluster = mock.Mock(node_groups=[], cluster_configs={})
|
||||||
|
get.return_value = 'password'
|
||||||
|
krb._get_server_installation_script(
|
||||||
|
cluster, 'server.novalocal', 'centos', '6.7')
|
@ -357,13 +357,13 @@ def _get_os_distrib():
|
|||||||
return _execute_command(
|
return _execute_command(
|
||||||
('printf "import platform\nprint(platform.linux_distribution('
|
('printf "import platform\nprint(platform.linux_distribution('
|
||||||
'full_distribution_name=0)[0])" | python'),
|
'full_distribution_name=0)[0])" | python'),
|
||||||
run_as_root=False)[1].lower()
|
run_as_root=False)[1].lower().strip()
|
||||||
|
|
||||||
|
|
||||||
def _get_os_version():
|
def _get_os_version():
|
||||||
return _execute_command(
|
return _execute_command(
|
||||||
('printf "import platform\nprint(platform.linux_distribution()[1])"'
|
('printf "import platform\nprint(platform.linux_distribution()[1])"'
|
||||||
' | python'), run_as_root=False)
|
' | python'), run_as_root=False)[1].strip()
|
||||||
|
|
||||||
|
|
||||||
def _install_packages(packages):
|
def _install_packages(packages):
|
||||||
@ -838,6 +838,9 @@ class InstanceInteropHelper(remote.Remote):
|
|||||||
def get_os_distrib(self, timeout=None):
|
def get_os_distrib(self, timeout=None):
|
||||||
return self._run_s(_get_os_distrib, timeout, "get_os_distrib")
|
return self._run_s(_get_os_distrib, timeout, "get_os_distrib")
|
||||||
|
|
||||||
|
def get_os_version(self, timeout=None):
|
||||||
|
return self._run_s(_get_os_version, timeout, "get_os_version")
|
||||||
|
|
||||||
def install_packages(self, packages, timeout=None):
|
def install_packages(self, packages, timeout=None):
|
||||||
description = _('Installing packages "%s"') % list(packages)
|
description = _('Installing packages "%s"') % list(packages)
|
||||||
self._log_command(description)
|
self._log_command(description)
|
||||||
|
Loading…
Reference in New Issue
Block a user