123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- # 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 os
- import yaml
- from OpenSSL import crypto
- from time import time
- from packstack.installer import basedefs
- from packstack.installer import utils
- from packstack.installer.setup_controller import Controller
- controller = Controller()
- PUPPET_DIR = os.path.join(basedefs.DIR_PROJECT_DIR, "puppet")
- PUPPET_TEMPLATE_DIR = os.path.join(PUPPET_DIR, "templates")
- HIERA_COMMON_YAML = os.path.join(basedefs.HIERADATA_DIR, "common.yaml")
- # For compatibility with hiera < 3.0
- HIERA_DEFAULTS_YAML = os.path.join(basedefs.HIERADATA_DIR, "defaults.yaml")
- class ManifestFiles(object):
- def __init__(self):
- self.filelist = []
- self.data = {}
- # continuous manifest file that have the same marker can be
- # installed in parallel, if on different servers
- def addFile(self, filename, marker, data=''):
- self.data[filename] = self.data.get(filename, '') + '\n' + data
- for f, p in self.filelist:
- if f == filename:
- return
- self.filelist.append((filename, marker))
- def prependFile(self, filename, marker, data=''):
- self.data[filename] = data + '\n' + self.data.get(filename, '')
- for f, p in self.filelist:
- if f == filename:
- return
- self.filelist.append((filename, marker))
- def getFiles(self):
- return [f for f in self.filelist]
- def writeManifests(self):
- """
- Write out the manifest data to disk, this should only be called once
- write before the puppet manifests are copied to the various servers
- """
- os.mkdir(basedefs.PUPPET_MANIFEST_DIR, 0o700)
- for fname, data in self.data.items():
- path = os.path.join(basedefs.PUPPET_MANIFEST_DIR, fname)
- fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
- with os.fdopen(fd, 'w') as fp:
- fp.write(data)
- manifestfiles = ManifestFiles()
- def getManifestTemplate(template_name):
- if not template_name.endswith(".pp"):
- template_name += ".pp"
- with open(os.path.join(PUPPET_TEMPLATE_DIR, template_name)) as fp:
- return fp.read() % controller.CONF
- def appendManifestFile(manifest_name, data, marker=''):
- manifestfiles.addFile(manifest_name, marker, data)
- def generateHieraDataFile():
- os.mkdir(basedefs.HIERADATA_DIR, 0o700)
- with open(HIERA_COMMON_YAML, 'w') as outfile:
- outfile.write(yaml.dump(controller.CONF,
- explicit_start=True,
- default_flow_style=False))
- os.symlink(os.path.basename(HIERA_COMMON_YAML), HIERA_DEFAULTS_YAML)
- def generate_ssl_cert(config, host, service, ssl_key_file, ssl_cert_file):
- """
- Wrapper on top of openssl
- """
- # We have to check whether the certificate already exists
- cert_dir = os.path.join(config['CONFIG_SSL_CERT_DIR'], 'certs')
- local_cert_name = host + os.path.basename(ssl_cert_file)
- local_cert_path = os.path.join(cert_dir, local_cert_name)
- if not os.path.exists(local_cert_path):
- ca_file = open(config['CONFIG_SSL_CACERT_FILE'], 'rt').read()
- ca_key_file = open(config['CONFIG_SSL_CACERT_KEY_FILE'], 'rt').read()
- ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, ca_key_file)
- ca = crypto.load_certificate(crypto.FILETYPE_PEM, ca_file)
- k = crypto.PKey()
- k.generate_key(crypto.TYPE_RSA, 4096)
- mail = config['CONFIG_SSL_CERT_SUBJECT_MAIL']
- hostinfo = config['HOST_DETAILS'][host]
- fqdn = hostinfo['fqdn']
- cert = crypto.X509()
- subject = cert.get_subject()
- subject.C = config['CONFIG_SSL_CERT_SUBJECT_C']
- subject.ST = config['CONFIG_SSL_CERT_SUBJECT_ST']
- subject.L = config['CONFIG_SSL_CERT_SUBJECT_L']
- subject.O = config['CONFIG_SSL_CERT_SUBJECT_O']
- subject.OU = config['CONFIG_SSL_CERT_SUBJECT_OU']
- subject.CN = "%s/%s" % (service, fqdn)
- subject.emailAddress = mail
- cert.add_extensions([
- crypto.X509Extension(
- "keyUsage".encode('ascii'),
- False,
- "nonRepudiation,digitalSignature,keyEncipherment".encode('ascii')),
- crypto.X509Extension(
- "extendedKeyUsage".encode('ascii'),
- False,
- "clientAuth,serverAuth".encode('ascii')),
- ])
- cert.gmtime_adj_notBefore(0)
- cert.gmtime_adj_notAfter(315360000)
- cert.set_issuer(ca.get_subject())
- cert.set_pubkey(k)
- serial = int(time())
- cert.set_serial_number(serial)
- cert.sign(ca_key, 'sha1')
- final_cert = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
- final_key = crypto.dump_privatekey(crypto.FILETYPE_PEM, k)
- deliver_ssl_file(ca_file, config['CONFIG_SSL_CACERT'], host)
- deliver_ssl_file(final_cert, ssl_cert_file, host)
- deliver_ssl_file(final_key, ssl_key_file, host)
- with open(local_cert_path, 'w') as f:
- f.write(final_cert)
- def deliver_ssl_file(content, path, host):
- server = utils.ScriptRunner(host)
- server.append("grep -- '{content}' {path} || "
- "echo '{content}' > {path} ".format(
- content=content,
- path=path))
- server.execute()
- def gethostlist(CONF):
- hosts = []
- for key, value in CONF.items():
- if key.endswith("_HOST"):
- value = value.split('/')[0]
- if value and value not in hosts:
- hosts.append(value)
- if key.endswith("_HOSTS"):
- for host in value.split(","):
- host = host.strip()
- host = host.split('/')[0]
- if host and host not in hosts:
- hosts.append(host)
- return hosts
|