def upload(filename, repo, message, testing): with chdir(repo): check_call(["bzr", "pull"]) shutil.copy(filename, os.path.join(repo, "common/noarch")) if not testing: with chdir(repo): check_call(["bzr", "commit", "-m", message]) check_call(["bzr", "push"])
def upload(filename, repo, message, testing): with chdir(repo): check_call(['bzr', 'pull']) shutil.copy(filename, os.path.join(repo, 'common/noarch')) if not testing: with chdir(repo): check_call(['bzr', 'commit', '-m', message]) check_call(['bzr', 'push'])
def trigger_puppet(self): # If we can't reverse resolve the hostname (like on azure), support DN # registration by IP address. # NB: determine this *before* updating /etc/hosts below since # gethostbyaddr will not fail if we have an /etc/hosts entry. reverse_dns_bad = False try: socket.gethostbyaddr(utils.resolve_private_address(hookenv.unit_private_ip())) except socket.herror: reverse_dns_bad = True # We know java7 has MAXHOSTNAMELEN of 64 char, so we cannot rely on # java to do a hostname lookup on clouds that have >64 char fqdns # (gce). Force short hostname (< 64 char) into /etc/hosts as workaround. # Better fix may be to move to java8. See http://paste.ubuntu.com/16230171/ # NB: do this before the puppet apply, which may call java stuffs # like format namenode, which will fail if we dont get this fix # down early. short_host = subprocess.check_output(['facter', 'hostname']).strip().decode() private_ip = utils.resolve_private_address(hookenv.unit_private_ip()) if short_host and private_ip: utils.update_kv_host(private_ip, short_host) utils.manage_etc_hosts() charm_dir = hookenv.charm_dir() # TODO JIRA KWM: rm does not need Hdfs_init and will fail rm_patch = Path(charm_dir) / 'resources/patch1_rm_init_hdfs.patch' # TODO JIRA KWM: nm should not *need* mapred role. we could patch it # with nm_patch, or adjust nm charm to include mapred role. for now, # we're doing the latter. todo rfc from dev@bigtop list. # nm_patch = Path(charm_dir) / 'resources/patch2_nm_core-site.patch' # TODO JIRA KWM: client role needs common_yarn for yarn-site.xml client_patch = Path(charm_dir) / 'resources/patch3_client_role_use_common_yarn.patch' with chdir("{}".format(self.bigtop_base)): # rm patch goes first utils.run_as('root', 'patch', '-p1', '-s', '-i', rm_patch) # skip nm_patch for now since nm charm is including mapred role # utils.run_as('root', 'patch', '-p1', '-s', '-i', nm_patch) # client patch goes last utils.run_as('root', 'patch', '-p1', '-s', '-i', client_patch) # TODO FIX ABOVE KWM # puppet apply needs to be ran where recipes were unpacked with chdir("{}".format(self.bigtop_base)): utils.run_as('root', 'puppet', 'apply', '-d', '--modulepath="bigtop-deploy/puppet/modules:/etc/puppet/modules"', 'bigtop-deploy/puppet/manifests/site.pp') # Do any post-puppet config on the generated config files. if reverse_dns_bad: hdfs_site = Path('/etc/hadoop/conf/hdfs-site.xml') with utils.xmlpropmap_edit_in_place(hdfs_site) as props: props['dfs.namenode.datanode.registration.ip-hostname-check'] = 'false'
def create_csr(tls): '''Create a certificate signing request (CSR). Only the followers need to run this operation.''' if not is_leader(): with chdir('easy-rsa/easyrsa3'): # Must remove the path characters from the unit name. path_name = hookenv.local_unit().replace('/', '_') # The reqest will be named with unit_name.req req_file = 'pki/reqs/{0}.req'.format(path_name) # If the request already exists do not generate another one. if os.path.isfile(req_file): remove_state('create certificate signing request') return # The Common Name is the public address of the system. cn = hookenv.unit_public_ip() hookenv.log('Creating the CSR for {0}'.format(path_name)) sans = get_sans() # Create a CSR for this system with the subject and SANs. gen_req = './easyrsa --batch --req-cn={0} --subject-alt-name={1}' \ ' gen-req {2} nopass 2>&1'.format(cn, sans, path_name) check_call(split(gen_req)) # Read the CSR file. with open(req_file, 'r') as fp: csr = fp.read() # Set the CSR on the relation object. tls.set_csr(csr) else: hookenv.log('The leader does not need to create a CSR.')
def install_presentation(): """ Install presentation """ opts = layer.options('git-deploy') # Clone repo hookenv.status_set('maintenance', 'Installing and building the presentation.') # Build and install with chdir(opts.get('target')): with open('requirements.txt', 'r') as f: for i in list(map(lambda b: b.strip('\n'), f.readlines())): pip_install(i) sphinx_build_cmd = 'sphinx-build -b html source %s' % opts.get( 'target') subprocess.call(sphinx_build_cmd.split(), shell=False) present_chown_cmd = 'chown -R www-data:www-data %s' % opts.get('target') subprocess.call(present_chown_cmd.split(), shell=False) # Configure nginx vhost configure_site('present', 'present.vhost', app_path=opts.get('target')) # Open presentation front-end port hookenv.open_port(config['port']) # Set status hookenv.status_set('active', 'Presentation is active on port %s' % config['port']) # Set state set_state('presentation.available')
def import_sign(tls): '''Import and sign the certificate signing request (CSR). Only the leader can sign the requests.''' if is_leader(): hookenv.log('The leader needs to sign the csr requests.') # Get all the requests that are queued up to sign. csr_map = tls.get_csr_map() # Iterate over the unit names related to CSRs. for unit_name, csr in csr_map.items(): with chdir('easy-rsa/easyrsa3'): temp_file = tempfile.NamedTemporaryFile(suffix='.csr') with open(temp_file.name, 'w') as fp: fp.write(csr) # Must remove the path characters from the unit_name. path_name = unit_name.replace('/', '_') if not os.path.isfile('pki/reqs/{0}.req'.format(path_name)): hookenv.log('Importing csr from {0}'.format(path_name)) # Create the command to import the request using path name. import_req = './easyrsa --batch import-req {0} {1} 2>&1' # easy-rsa import-req /tmp/temporary.csr path_name check_call(split(import_req.format(temp_file.name, path_name))) if not os.path.isfile('pki/issued/{0}.crt'.format(path_name)): hookenv.log('Signing csr from {0}'.format(path_name)) # Create a command that signs the request. sign_req = './easyrsa --batch sign-req server {0} 2>&1' check_call(split(sign_req.format(path_name))) # Read in the signed certificate. cert_file = 'pki/issued/{0}.crt'.format(path_name) with open(cert_file, 'r') as fp: certificate = fp.read() hookenv.log('Leader sending signed certificate over relation.') # Send the certificate over the relation. tls.set_cert(unit_name, certificate)
def bundle(cmd): """ Runs bundle Usage: bundle('install') bundle('exec rails s') bundle('rake db:create RAILS_ENV=production') Arguments: cmd: Command to run can be string or list Returns: Will halt on error """ sh = shell('which bundler') if sh.code > 0: gem('install -N bundler') hookenv.status_set('maintenance', 'Running Bundler') with chdir(ruby_dist_dir()): if not isinstance(cmd, str): hookenv.log('{} must be a string'.format(cmd), 'error') sys.exit(1) shell_cmd = set_proxy("bundle {} -j{}".format(cmd, cpu_count())) sh = shell(shell_cmd, record_output=False) if sh.code > 0: hookenv.status_set("blocked", "Ruby error: {}".format(sh.errors())) hookenv.log("Ruby error: {}".format(sh.errors())) sys.exit(1)
def install_presentation(): """ Install presentation """ opts = layer.options('git-deploy') # Clone repo hookenv.status_set('maintenance', 'Installing and building the presentation.') # Build and install with chdir(opts.get('target')): with open('requirements.txt', 'r') as f: for i in list(map(lambda b: b.strip('\n'), f.readlines())): pip_install(i) sphinx_build_cmd = 'sphinx-build -b html source %s' % opts.get('target') subprocess.call(sphinx_build_cmd.split(), shell=False) present_chown_cmd = 'chown -R www-data:www-data %s' % opts.get('target') subprocess.call(present_chown_cmd.split(), shell=False) # Configure nginx vhost configure_site('present', 'present.vhost', app_path=opts.get('target')) # Open presentation front-end port hookenv.open_port(config['port']) # Set status hookenv.status_set('active', 'Presentation is active on port %s' % config['port']) # Set state set_state('presentation.available')
def init_nextcloud(mysql): status_set('maintenance', "Initializing Nextcloud") ctxt = {'dbname': mysql.database(), 'dbuser': mysql.user(), 'dbpass': mysql.password(), 'dbhost': mysql.host(), 'dbport': mysql.port(), 'dbtype': 'mysql', 'admin_username': config().get('admin-username'), 'admin_password': config().get('admin-password'), 'data_dir': Path('/var/www/nextcloud/data'), } nextcloud_init = ("sudo -u www-data /usr/bin/php occ maintenance:install " "--database {dbtype} --database-name {dbname} " "--database-host {dbhost} --database-pass {dbpass} " "--database-user {dbuser} --admin-user {admin_username} " "--admin-pass {admin_password} " "--data-dir {data_dir} ").format(**ctxt) log(nextcloud_init) with chdir('/var/www/nextcloud'): subprocess.call("sudo chown -R www-data:www-data .".split()) subprocess.call(nextcloud_init.split()) Path('/var/www/nextcloud/config/config.php').write_text( Path('/var/www/nextcloud/config/config.php').open().read().replace( "localhost", config().get('fqdn') or unit_public_ip())) set_flag('nextcloud.initdone') status_set('active', "Nextcloud init complete")
def create_certificate_authority(certificate_authority=None): '''Return the CA and server certificates for this system. If the CA is empty, generate a self signged certificate authority.''' # followers are not special, do not generate a ca if not is_leader(): return # Create an absolute path so current directory does not affect the result. easyrsa3_dir = os.path.join(hookenv.charm_dir(), 'easy-rsa/easyrsa3') with chdir(easyrsa3_dir): ca_file = 'pki/ca.crt' # Check if an old CA exists. if os.path.isfile(ca_file): # Initialize easy-rsa (by deleting old pki) so a CA can be created. init = './easyrsa --batch init-pki 2>&1' check_call(split(init)) # When the CA is not None write the CA file. if certificate_authority: # Write the certificate authority from configuration. with open(ca_file, 'w') as fp: fp.write(certificate_authority) else: # The Certificate Authority does not exist build a self signed one. # The Common Name (CN) for a certificate must be an IP or hostname. cn = hookenv.unit_public_ip() # Create a self signed CA with the CN, stored pki/ca.crt build_ca = './easyrsa --batch "--req-cn={0}" build-ca nopass 2>&1' check_call(split(build_ca.format(cn))) # Read the CA so we can return the contents from this method. with open(ca_file, 'r') as fp: certificate_authority = fp.read() set_state('certificate authority available') return certificate_authority
def create_certificate_authority(certificate_authority=None): '''Return the CA and server certificates for this system. If the CA is empty, generate a self signged certificate authority.''' # followers are not special, do not generate a ca if not is_leader(): return with chdir('easy-rsa/easyrsa3'): ca_file = 'pki/ca.crt' # Check if an old CA exists. if os.path.isfile(ca_file): # Initialize easy-rsa (by deleting old pki) so a CA can be created. init = './easyrsa --batch init-pki 2>&1' check_call(split(init)) # When the CA is not None write the CA file. if certificate_authority: # Write the certificate authority from configuration. with open(ca_file, 'w') as fp: fp.write(certificate_authority) else: # The Certificate Authority does not exist build a self signed one. # The Common Name (CN) for a certificate must be an IP or hostname. cn = hookenv.unit_public_ip() # Create a self signed CA with the CN, stored pki/ca.crt build_ca = './easyrsa --batch "--req-cn={0}" build-ca nopass 2>&1' check_call(split(build_ca.format(cn))) # Read the CA so we can return the contents from this method. with open(ca_file, 'r') as fp: certificate_authority = fp.read() set_state('certificate authority available') return certificate_authority
def install(): """ Install Hook """ log('ftb-infinity: install') status_set('maintenance', 'installing FTB modpack') # Add user adduser(FTB_USER) mkdir(FTB_HOME, owner=FTB_USER, group=FTB_USER, perms=0o750) check_call(['usermod', '-s', '/bin/bash', '-d', FTB_HOME, FTB_USER]) # Download ftb ArchiveUrlFetchHandler().install(FTB_DL_URL, FTB_HOME) # Sanitize permissions, zip! chownr(FTB_HOME, FTB_USER, FTB_USER) path = os.path.join(FTB_HOME, 'FTBInstall.sh') s = os.stat(path) os.chmod(path, s.st_mode | stat.S_IXUSR | stat.S_IXGRP) # Accept EULA sed(os.path.join(FTB_HOME, 'eula.txt'), 'eula=false', 'eula=true') # Download minecraft jars with chdir(FTB_HOME): check_call(['sudo', '-u', FTB_USER, '-H', os.path.join(FTB_HOME, 'FTBInstall.sh')]) # Render server.properties ftb_config_server() # Deploy systemd service ftb_systemd_install() set_state(CHARM_STATE_AVAILABLE) status_set('waiting', 'ftb downloaded')
def npm(*cmd): """ Runs npm This layer relies on the use of npm scripts defined in `package.json`, see here https://docs.npmjs.com/misc/scripts for more information. Usage: npm('install') npm('run', 'build') Arguments: cmd: Command to run. The list of all positional args will be passed in as the first arg to `subprocess.run`. Returns: Will halt on error """ dist_dir = node_dist_dir() hookenv.status_set( 'maintenance', 'installing NPM dependencies for {}'.format(dist_dir)) with host.chdir(dist_dir): with Popen(['npm'] + list(cmd), stderr=PIPE) as process: _, errout = process.communicate() retcode = process.poll() if retcode != 0: hookenv.log('NPM error: {}'.format(errout)) hookenv.status_set("blocked", "NPM error: {}".format(errout)) sys.exit(0)
def create_certificate_authority(): '''Return the CA and server certificates for this system. If the CA is empty, generate a self signged certificate authority.''' with chdir(easyrsa_directory): # The Common Name (CN) for a certificate must be an IP or hostname. cn = hookenv.unit_public_ip() # Create a self signed CA with the CN, stored pki/ca.crt build_ca = './easyrsa --batch "--req-cn={0}" build-ca nopass 2>&1' # Build a self signed Certificate Authority. check_call(split(build_ca.format(cn))) ca_file = 'pki/ca.crt' # Read the CA so it can be returned in leader data. with open(ca_file, 'r') as stream: certificate_authority = stream.read() key_file = 'pki/private/ca.key' # Read the private key so it can be set in leader data. with open(key_file, 'r') as stream: ca_key = stream.read() # Set these values on the leadership data. leader_set({'certificate_authority': certificate_authority}) leader_set({'certificate_authority_key': ca_key}) # Install the CA on this system as a trusted CA. install_ca(certificate_authority) # Create a client certificate for this CA. client_cert, client_key = create_client_certificate() # Set the client certificate and key on leadership data. leader_set({'client_certificate': client_cert}) leader_set({'client_key': client_key}) status_set('active', 'Certificiate Authority available') set_state('easyrsa.certificate.authority.available')
def master_kubeconfig(): '''Create the kubernetes configuration for the master unit. The master should create a package with the client credentials so the user can interact securely with the apiserver.''' hookenv.log('Creating Kubernetes configuration for master node.') directory = '/srv/kubernetes' ca = '/srv/kubernetes/ca.crt' key = '/srv/kubernetes/client.key' cert = '/srv/kubernetes/client.crt' # Get the public address of the apiserver so users can access the master. server = 'https://{0}:{1}'.format(hookenv.unit_public_ip(), '6443') # Create the client kubeconfig so users can access the master node. create_kubeconfig(directory, server, ca, key, cert) # Copy the kubectl binary to this directory. cmd = 'cp -v /usr/local/bin/kubectl {0}'.format(directory) check_call(split(cmd)) # Use a context manager to run the tar command in a specific directory. with chdir(directory): # Create a package with kubectl and the files to use it externally. cmd = 'tar -cvzf /home/ubuntu/kubectl_package.tar.gz ca.crt ' \ 'client.key client.crt kubectl kubeconfig' check_call(split(cmd)) # This sets up the client workspace consistently on the leader and nodes. node_kubeconfig() set_state('kubeconfig.created')
def test_clone_functional(self): src = None dst = None try: src = tempfile.mkdtemp() with chdir(src): if self.is_git_version_2_28_plus: subprocess.check_output(['git', 'init', '--initial-branch', 'main']) else: subprocess.check_output(['git', 'init']) subprocess.check_output(['git', 'config', 'user.name', 'Joe']) subprocess.check_output( ['git', 'config', 'user.email', '*****@*****.**']) subprocess.check_output(['touch', 'foo']) subprocess.check_output(['git', 'add', 'foo']) subprocess.check_output(['git', 'commit', '-m', 'test']) dst = tempfile.mkdtemp() os.rmdir(dst) if self.is_git_version_2_28_plus: self.fh.clone(src, dst, "main") assert os.path.exists(os.path.join(dst, '.git')) self.fh.clone(src, dst, "main") # idempotent assert os.path.exists(os.path.join(dst, '.git')) else: self.fh.clone(src, dst) assert os.path.exists(os.path.join(dst, '.git')) self.fh.clone(src, dst) # idempotent assert os.path.exists(os.path.join(dst, '.git')) finally: if src: shutil.rmtree(src, ignore_errors=True) if dst: shutil.rmtree(dst, ignore_errors=True)
def create_server_certificate(name="server"): """Create the server certificate and server key.""" # Use the public ip as the Common Name for the server certificate. cn = hookenv.unit_public_ip() # Create an absolute path so current directory does not affect the result. easyrsa3_dir = os.path.join(hookenv.charm_dir(), "easy-rsa/easyrsa3") with chdir(easyrsa3_dir): server_file = "pki/issued/{0}.crt".format(name) # Get a list of extra sans from the unitdata kv module. extra_sans = unitdata.kv().get("extra_sans") # Get a string compatible with easyrsa for the subject-alt-names. sans = get_sans(extra_sans) # Do not regenerate the server certificate if it already exists. if not os.path.isfile(server_file): # Create a server certificate for the server based on the CN. server = ( "./easyrsa --batch --req-cn={0} --subject-alt-name={1} " "build-server-full {2} nopass 2>&1".format(cn, sans, name) ) check_call(split(server)) # Read the server certificate from the filesystem. with open(server_file, "r") as fp: server_cert = fp.read() # The key name is also used to set the reactive state. set_cert("tls.server.certificate", server_cert)
def create_certificate_authority(certificate_authority=None): """Return the CA and server certificates for this system. If the CA is empty, generate a self signged certificate authority.""" # followers are not special, do not generate a ca if not is_leader(): return # Create an absolute path so current directory does not affect the result. easyrsa3_dir = os.path.join(hookenv.charm_dir(), "easy-rsa/easyrsa3") with chdir(easyrsa3_dir): ca_file = "pki/ca.crt" # Check if an old CA exists. if os.path.isfile(ca_file): # Initialize easy-rsa (by deleting old pki) so a CA can be created. init = "./easyrsa --batch init-pki 2>&1" check_call(split(init)) # When the CA is not None write the CA file. if certificate_authority: # Write the certificate authority from configuration. with open(ca_file, "w") as fp: fp.write(certificate_authority) else: # The Certificate Authority does not exist build a self signed one. # The Common Name (CN) for a certificate must be an IP or hostname. cn = hookenv.unit_public_ip() # Create a self signed CA with the CN, stored pki/ca.crt build_ca = './easyrsa --batch "--req-cn={0}" build-ca nopass 2>&1' check_call(split(build_ca.format(cn))) # Read the CA so we can return the contents from this method. with open(ca_file, "r") as fp: certificate_authority = fp.read() set_state("certificate authority available") return certificate_authority
def patch_dea(job_name): DEA_PATCH = """ --- container.rb 2014-08-01 15:49:04.472289999 +0000 +++ container.rb 2014-07-31 23:31:30.776289999 +0000 @@ -118,7 +118,7 @@ new_container_with_bind_mounts(params[:bind_mounts]) limit_cpu(params[:limit_cpu]) limit_disk(byte: params[:byte], inode: params[:inode]) - limit_memory(params[:limit_memory]) + #limit_memory(params[:limit_memory]) setup_network if params[:setup_network] end end """ version = release_version() with host.chdir('/var/vcap/releases/{}/packages/dea_next/lib/container'.format(version)): current = open('container.rb').read() if "#limit_memory(params" in current: # Already applied return fd, fn = tempfile.mkstemp() os.close(fd) with open(fn, 'w') as fp: print >>fp, DEA_PATCH patch = open(fn) subprocess.check_call(['patch', '-s', '-F4'], stdin=patch) os.unlink(fn)
def create_csr(tls): '''Create a certificate signing request (CSR). Only the followers need to run this operation.''' if not is_leader(): # Create an absolute path to easyrsa3 to change to that directory. easyrsa3_dir = os.path.join(hookenv.charm_dir(), 'easy-rsa/easyrsa3') # Use an absolute path for this context manager. with chdir(easyrsa3_dir): # Must remove the path characters from the unit name. path_name = hookenv.local_unit().replace('/', '_') # The reqest will be named with unit_name.req req_file = 'pki/reqs/{0}.req'.format(path_name) # If the request already exists do not generate another one. if os.path.isfile(req_file): remove_state('create certificate signing request') return # The Common Name is the public address of the system. cn = hookenv.unit_public_ip() hookenv.log('Creating the CSR for {0}'.format(path_name)) sans = get_sans() # Create a CSR for this system with the subject and SANs. gen_req = './easyrsa --batch --req-cn={0} --subject-alt-name={1}' \ ' gen-req {2} nopass 2>&1'.format(cn, sans, path_name) check_call(split(gen_req)) # Read the CSR file. with open(req_file, 'r') as fp: csr = fp.read() # Set the CSR on the relation object. tls.set_csr(csr) else: hookenv.log('The leader does not need to create a CSR.')
def create_server_certificate(cn, san_list, name='server'): '''Return a newly created server certificate and server key from a common name, list of Subject Alternate Names, and the certificate name.''' server_cert = None server_key = None with chdir(easyrsa_directory): # Create the path to the server certificate. cert_file = 'pki/issued/{0}.crt'.format(name) # Create the path to the server key. key_file = 'pki/private/{0}.key'.format(name) # Do not regenerate the server certificate if it already exists. if not os.path.isfile(cert_file) and not os.path.isfile(key_file): # Get a string compatible with easyrsa for the subject-alt-names. sans = get_sans(san_list) # Create a server certificate for the server based on the CN. server = './easyrsa --batch --req-cn={0} --subject-alt-name={1} ' \ 'build-server-full {2} nopass 2>&1'.format(cn, sans, name) check_call(split(server)) # Read the server certificate from the file system. with open(cert_file, 'r') as stream: server_cert = stream.read() # Read the server key from the file system. with open(key_file, 'r') as stream: server_key = stream.read() return server_cert, server_key
def update_status(): ''' Calls occ status and sets version every now and then (update-status). :return: ''' nextcloud_status = "sudo -u www-data /usr/bin/php occ status" with chdir('/var/www/nextcloud'): try: output = subprocess.run( nextcloud_status.split(), stdout=subprocess.PIPE ).stdout.split() version = output[5].decode('UTF-8') install_status = output[2].decode('UTF-8') if install_status == 'true': application_version_set(version) status_set('active', "Nextcloud is OK.") else: status_set('waiting', "Nextcloud install state not OK.") except: status_set('waiting', "Nextcloud install state not OK.")
def setup_insightedge_on_spark(spark): destination = Path('/usr/lib/insightedge') if not destination.exists(): hookenv.status_set('maintenance', 'fetching insightedge') filename = hookenv.resource_get('insightedge') if not filename: hookenv.status_set("blocked", "unable to fetch insightedge resource") hookenv.log("Failed to fetch InsightEdge resource") return hookenv.status_set('maintenance', 'installing insightedge') extracted = Path(fetch.install_remote('file://' + filename)) destination.rmtree_p() # in case doing a re-install extracted.dirs()[0].copytree(destination) # copy nested dir contents hookenv.status_set('maintenance', 'configuring insightedge') with host.chdir(destination): insightedge_jars = subprocess.check_output([ 'bash', '-c', '. {}; get_libs ,'.format( destination / 'sbin' / 'common-insightedge.sh') ], env={ 'INSIGHTEDGE_HOME': destination }).decode('utf8') spark.register_classpaths(insightedge_jars.split(',')) set_state('insightedge.installed')
def update_charm(charm, url, hash, hash_type, filename, message, force, testing): charmname = os.path.basename(charm) with chdir(charm): if not os.path.exists("resources.yaml"): print "Skipping (no resources): {}".format(charmname) return if not force: input = raw_input("Update {}? [Y/n] ".format(charmname)) if input.strip().lower() not in ("", "y", "yes"): print " Skipping" return print " Updating" else: print "Updating: {}".format(charmname) with open("resources.yaml", "r") as fp: resources = ruamel.yaml.load(fp, ruamel.yaml.RoundTripLoader) if "jujubigdata" not in resources["resources"]: print "Skipping (no jujubigdata): {}".format(charm) return resources["resources"]["jujubigdata"].update({"pypi": url, "hash": hash, "hash_type": hash_type}) with open("resources.yaml", "w") as fp: ruamel.yaml.dump(resources, fp, Dumper=ruamel.yaml.RoundTripDumper) for oldfile in glob("resources/jujubigdata-*"): os.remove(oldfile) if testing: shutil.copy(filename, "resources") check_call(["bzr", "add", "resources"]) last_log = check_output(["bzr", "log", "--line", "-l1"]) if "[wip]" in last_log: check_call(["bzr", "uncommit", "--force"]) if testing: message = "[wip] {}".format(message) check_call(["bzr", "commit", "-m", message])
def create_csr(tls): """Create a certificate signing request (CSR). Only the followers need to run this operation.""" if not is_leader(): # Create an absolute path to easyrsa3 to change to that directory. easyrsa3_dir = os.path.join(hookenv.charm_dir(), "easy-rsa/easyrsa3") # Use an absolute path for this context manager. with chdir(easyrsa3_dir): # Must remove the path characters from the unit name. path_name = hookenv.local_unit().replace("/", "_") # The reqest will be named with unit_name.req req_file = "pki/reqs/{0}.req".format(path_name) # If the request already exists do not generate another one. if os.path.isfile(req_file): remove_state("create certificate signing request") return # The Common Name is the public address of the system. cn = hookenv.unit_public_ip() hookenv.log("Creating the CSR for {0}".format(path_name)) sans = get_sans() # Create a CSR for this system with the subject and SANs. gen_req = "./easyrsa --batch --req-cn={0} --subject-alt-name={1}" " gen-req {2} nopass 2>&1".format( cn, sans, path_name ) check_call(split(gen_req)) # Read the CSR file. with open(req_file, "r") as fp: csr = fp.read() # Set the CSR on the relation object. tls.set_csr(csr) else: hookenv.log("The leader does not need to create a CSR.")
def install(self): ''' Fetch resources ''' self.dist_config.add_users() self.dist_config.add_dirs() result = resource_get('tomee') if not result: log("Failed to fetch TomEE resource") return False unitdata.kv().set("tomeetarball", result) log("TomEE tarball path is {}".format(result)) tomee_install_dir = self.dist_config.path('tomee_dir') with chdir(tomee_install_dir): utils.run_as('tomcat', 'tar', '-zxvf', '{}'.format(result)) tomee_dirs = [f for f in os.listdir(tomee_install_dir) if f.startswith('apache-tomee')] catalina_home = os.path.join(tomee_install_dir, tomee_dirs[0]) with utils.environment_edit_in_place('/etc/environment') as env: env['CATALINA_HOME'] = catalina_home unitdata.kv().set("catalina_home", catalina_home) self.open_ports() return True
def upgrade(): """An upgrade has been triggered.""" pki_directory = os.path.join(easyrsa_directory, "pki") if os.path.isdir(pki_directory): # specific handling if the upgrade is from a previous version # where certificate_authority_serial is not set at install serial_file = "serial" with chdir(pki_directory): # if the ca and ca_key are set and serial is not # set this to serial in the pki directory if (os.path.isfile(serial_file) and leader_get("certificate_authority") and leader_get("certificate_authority_key") and not leader_get("certificate_authority_serial")): with open(serial_file, "r") as stream: ca_serial = stream.read() # set the previously unset certificate authority serial leader_set({"certificate_authority_serial": ca_serial}) charm_pki_directory = os.path.join(charm_directory, "pki") # When the charm pki directory exists, it is stale, remove it. if os.path.isdir(charm_pki_directory): shutil.rmtree(charm_pki_directory) # Copy the EasyRSA/pki to the charm pki directory. shutil.copytree(pki_directory, charm_pki_directory, symlinks=True) clear_flag("easyrsa.installed") clear_flag("easyrsa.configured")
def trigger_puppet(self): # TODO need to either manage the apt keys from Juju or # update upstream Puppet recipes to install them along with apt source # puppet apply needs to be ran where recipes were unpacked with chdir("{0}/{1}".format(self.bigtop_dir, self.bigtop_version)): utils.run_as('root', 'puppet', 'apply', '-d', '--modulepath="bigtop-deploy/puppet/modules:/etc/puppet/modules"', 'bigtop-deploy/puppet/manifests/site.pp')
def get_latest(repo): with chdir(repo): check_call(["bzr", "pull"]) filename = glob("common/noarch/jujubigdata-*")[0] with open(filename) as fp: hash = sha256(fp.read()).hexdigest() print "Hash: {}".format(hash) return os.path.abspath(filename), hash
def get_latest(repo): with chdir(repo): check_call(['bzr', 'pull']) filename = glob('common/noarch/jujubigdata-*')[0] with open(filename) as fp: hash = sha256(fp.read()).hexdigest() print "Hash: {}".format(hash) return os.path.abspath(filename), hash
def init_zkrest(self): # Zookeeper user needs to compile the rest contrib server. # So zookeeper needs to: # 1. Have a home dir for ant cache to exist # 2. Write to the /usr/lib/zookeeper chownr(self.dist_config.path('zookeeper'), 'zookeeper', 'zookeeper', chowntopdir=True) with chdir(self.dist_config.path('zookeeper')): utils.run_as('zookeeper', 'ant') unitdata.kv().set('rest.initialised', True)
def install(): '''Install the easy-rsa software that is used by this layer.''' easyrsa_resource = None try: # Try to get the resource from Juju. easyrsa_resource = resource_get('easyrsa') except Exception as e: message = 'An error occurred fetching the easyrsa resource.' hookenv.log(message) hookenv.log(e) hookenv.status_set('blocked', message) return if not easyrsa_resource: hookenv.status_set('blocked', 'The easyrsa resource is missing.') return # Get the filesize in bytes. filesize = os.stat(easyrsa_resource).st_size # When the filesize is less than 10 KB we do not have a real file. if filesize < 10240: hookenv.status_set('blocked', 'The easyrsa resource is not complete.') return # Expand the archive in the charm directory creating an EasyRSA directory. untar = 'tar -xvzf {0} -C {1}'.format(easyrsa_resource, charm_directory) check_call(split(untar)) version = get_version(easyrsa_resource) # Save the version in the key/value store of the charm. unitdata.kv().set('easyrsa-version', version) if os.path.islink(easyrsa_directory): check_call(split('rm -v {0}'.format(easyrsa_directory))) # Link the EasyRSA version directory to a common name. link = 'ln -v -s {0}/EasyRSA-{1} {2}'.format(charm_directory, version, easyrsa_directory) check_call(split(link)) # The charm pki directory contains backup of pki for upgrades. charm_pki_directory = os.path.join(charm_directory, 'pki') if os.path.isdir(charm_pki_directory): new_pki_directory = os.path.join(easyrsa_directory, 'pki') # Only copy the directory if the new_pki_directory does not exist. if not os.path.isdir(new_pki_directory): # Copy the pki to this new directory. shutil.copytree(charm_pki_directory, new_pki_directory, symlinks=True) # We are done with the old charm pki directory, so delete contents. shutil.rmtree(charm_pki_directory) else: # Create new pki. with chdir(easyrsa_directory): check_call(split('./easyrsa --batch init-pki 2>&1')) set_state('easyrsa.installed')
def install(): """Install the easy-rsa software that is used by this layer.""" easyrsa_resource = None try: # Try to get the resource from Juju. easyrsa_resource = resource_get("easyrsa") except Exception as e: message = "An error occurred fetching the easyrsa resource." hookenv.log(message) hookenv.log(e) status.blocked(message) return if not easyrsa_resource: status.blocked("The easyrsa resource is missing.") return # Get the filesize in bytes. filesize = os.stat(easyrsa_resource).st_size # When the filesize is less than 10 KB we do not have a real file. if filesize < 10240: status.blocked("The easyrsa resource is not complete.") return # Expand the archive in the charm directory creating an EasyRSA directory. untar = "tar -xvzf {0} -C {1}".format(easyrsa_resource, charm_directory) check_call(split(untar)) version = get_version(easyrsa_resource) # Save the version in the key/value store of the charm. unitdata.kv().set("easyrsa-version", version) if islink(easyrsa_directory): check_call(split("rm -v {0}".format(easyrsa_directory))) # Link the EasyRSA version directory to a common name. link = "ln -v -s {0}/EasyRSA-{1} {2}".format(charm_directory, version, easyrsa_directory) check_call(split(link)) # The charm pki directory contains backup of pki for upgrades. charm_pki_directory = os.path.join(charm_directory, "pki") if os.path.isdir(charm_pki_directory): new_pki_directory = os.path.join(easyrsa_directory, "pki") # Only copy the directory if the new_pki_directory does not exist. if not os.path.isdir(new_pki_directory): # Copy the pki to this new directory. shutil.copytree(charm_pki_directory, new_pki_directory, symlinks=True) # We are done with the old charm pki directory, so delete contents. shutil.rmtree(charm_pki_directory) else: # Create new pki. with chdir(easyrsa_directory): check_call(split("./easyrsa --batch init-pki 2>&1")) set_flag("easyrsa.installed")
def maintenance_mode(on_off): on = "sudo -u www-data /usr/bin/php occ maintenance:mode --on" off = "sudo -u www-data /usr/bin/php occ maintenance:mode --off" with chdir('/var/www/nextcloud'): if on_off: subprocess.call(on.split()) else: subprocess.call(off.split())
def install(): '''Install the easy-rsa software that is required for this layer.''' apt = 'apt-get install -y git openssl' check_call(split(apt)) if os.path.isdir('easy-rsa'): shutil.rmtree('easy-rsa') git = 'git clone https://github.com/OpenVPN/easy-rsa.git' hookenv.log(git) check_call(split(git)) with chdir('easy-rsa/easyrsa3'): check_call(split('./easyrsa --batch init-pki 2>&1')) set_state('easyrsa installed')
def run_smoke_tests(self, smoke_components=None, smoke_env=None): """ Run the Bigtop smoke tests for given components using the gradle wrapper script. :param list smoke_components: Bigtop components to smoke test :param list smoke_env: Dict of required environment variables (merged with /etc/environment) """ if not is_state('bigtop.available'): hookenv.log('Bigtop is not ready to run smoke tests') return None if not smoke_components: hookenv.log('Missing Bigtop smoke test component list') return None # We always need TERM and JAVA_HOME; merge with any user provided dict subprocess_env = {'TERM': 'dumb', 'JAVA_HOME': java_home()} if isinstance(smoke_env, dict): subprocess_env.update(smoke_env) # Ensure the base dir is owned by ubuntu so we can create a .gradle dir. chownr(self.bigtop_base, 'ubuntu', 'ubuntu', chowntopdir=True) # Gradle doesn't honor env proxies; check for either http* or HTTP* and # set cli args as needed. http_url = os.environ.get('http_proxy', os.environ.get('HTTP_PROXY')) https_url = os.environ.get('https_proxy', os.environ.get('HTTPS_PROXY')) proxy_args = [] if http_url: parsed_url = urlparse(http_url) proxy_args += ['-Dhttp.proxyHost={}'.format(parsed_url.hostname), '-Dhttp.proxyPort={}'.format(parsed_url.port)] if https_url: parsed_url = urlparse(https_url) proxy_args += ['-Dhttps.proxyHost={}'.format(parsed_url.hostname), '-Dhttps.proxyPort={}'.format(parsed_url.port)] # Bigtop can run multiple smoke tests at once; construct the right args. comp_args = ['bigtop-tests:smoke-tests:%s:test' % c for c in smoke_components] gradlew_args = ['-Psmoke.tests', '--info'] + proxy_args + comp_args hookenv.log('Bigtop smoke test environment: {}'.format(subprocess_env)) hookenv.log('Bigtop smoke test args: {}'.format(gradlew_args)) with chdir(self.bigtop_base): try: utils.run_as('ubuntu', './gradlew', *gradlew_args, env=subprocess_env) smoke_out = 'success' except subprocess.CalledProcessError as e: smoke_out = e.output return smoke_out
def install(): '''Install the easy-rsa software that is required for this layer.''' # Create an absolute path to easy-rsa that is not affected by cwd. easy_rsa_directory = os.path.join(hookenv.charm_dir(), 'easy-rsa') if os.path.isdir(easy_rsa_directory): shutil.rmtree(easy_rsa_directory) git = 'git clone https://github.com/OpenVPN/easy-rsa.git' hookenv.log(git) check_call(split(git)) # Create an absolute path to the easyrsa3 directory. easyrsa3_directory = os.path.join(easy_rsa_directory, 'easyrsa3') with chdir(easyrsa3_directory): check_call(split('./easyrsa --batch init-pki 2>&1')) set_state('easyrsa installed')
def install(): """Install the easy-rsa software that is required for this layer.""" # Create an absolute path to easy-rsa that is not affected by cwd. easy_rsa_directory = os.path.join(hookenv.charm_dir(), "easy-rsa") if os.path.isdir(easy_rsa_directory): shutil.rmtree(easy_rsa_directory) git = "git clone https://github.com/OpenVPN/easy-rsa.git" hookenv.log(git) check_call(split(git)) # Create an absolute path to the easyrsa3 directory. easyrsa3_directory = os.path.join(easy_rsa_directory, "easyrsa3") with chdir(easyrsa3_directory): check_call(split("./easyrsa --batch init-pki 2>&1")) set_state("easyrsa installed")
def install_whelp(): ''' Reactive hook to install whelp ''' hookenv.status_set('maintenance', 'Installing whelp') whelp = Whelp() whelp_tar = hookenv.resource_get('webapp') hookenv.status_set('maintenance', 'installing webapp') # Extract tar resource tar = tarfile.open(whelp_tar) tar.extractall(WHELP_HOME) # Install pip3 reqs with chdir('/srv/whelp/whelp'): with open('requirements.txt', 'r') as f: for i in list(map(lambda b: b.strip('\n'), f.readlines())): pip_install(i) # Set permissions chownr(WHELP_HOME, 'www-data', 'www-data') # Get state files for whelp to run whelp.get_whelp_bucket_files() # Configure NGINX configure_site('whelp', 'whelp.vhost', port=config['port'], whelp_port=config['whelp-port']) # Start Supervisor subprocess.call('supervisord -c /etc/supervisor/supervisord.conf'.split(), shell=False) # Render whelp supervisor.conf whelp.render_whelp_supervisor_conf() # Open port 80 hookenv.open_port(config['port']) # Set status to active hookenv.status_set('active', 'Whelp is active on port %s' % config['port']) # Set whelp.available state set_state('whelp.installed')
def create_client_certificate(name='client'): '''Create the client certificate and client key.''' with chdir('easy-rsa/easyrsa3'): client_file = 'pki/issued/{0}.crt'.format(name) # Do not regenerate the client certificate if it already exists. if not os.path.isfile(client_file): # Create a client certificate and key. client = './easyrsa build-client-full {0} nopass 2>&1'.format(name) check_call(split(client)) # Read the client certificate from the filesystem. with open(client_file, 'r') as fp: client_cert = fp.read() # The key name is also used to set the reactive state. set_cert('tls.client.certificate', client_cert) set_state('client certificate available')
def extract_ruby(): if os.path.exists(WORKDIR): rmtree(WORKDIR) os.makedirs(WORKDIR) with chdir('/tmp'): cmd = ('tar xf ruby.tar.gz -C {} --strip-components=1'.format(WORKDIR)) sh = shell(cmd) if sh.code > 0: hookenv.status_set( 'blocked', 'Problem extracting ruby: {}:{}'.format(cmd, sh.errors())) hookenv.log('Problem extracting ruby: {}:{}'.format(cmd, sh.errors())) sys.exit(1)
def configure_insightedge_spark(): hookenv.status_set('maintenance', 'configuring insightedge') dc = get_dist_config() destination = dc.path('spark') spark = Spark(dc) with host.chdir(destination): insightedge_jars = subprocess.check_output([ 'bash', '-c', '. {}; get_libs ,'.format( destination / 'sbin' / 'common-insightedge.sh') ], env={ 'INSIGHTEDGE_HOME': destination }).decode('utf8') spark.register_classpaths(insightedge_jars.split(',')) set_state('insightedge-spark.configured')
def start(self): """ Override start to use InsightEdge's wrapper. """ # Start if we're not already running. We currently dont have any # runtime config options, so no need to restart when hooks fire. if not utils.jps("zeppelin"): ie_home = self.dist_config.path('insightedge') zeppelin_home = self.dist_config.path('zeppelin') # chdir here because things like zepp tutorial think ZEPPELIN_HOME # is wherever the daemon was started from. with host.chdir(zeppelin_home): utils.run_as('ubuntu', '{}/sbin/start-zeppelin.sh'.format(ie_home)) # wait up to 30s for API to start, lest requests fail self.wait_for_api(30)
def install(): '''Install the easy-rsa software that is used by this layer.''' easyrsa_resource = None try: # Try to get the resource from Juju. easyrsa_resource = resource_get('easyrsa') except Exception as e: message = 'An error occurred fetching the easyrsa resource.' hookenv.log(message) hookenv.log(e) hookenv.status_set('blocked', message) return if not easyrsa_resource: hookenv.status_set('blocked', 'The easyrsa resource is missing.') return # Get the filesize in bytes. filesize = os.stat(easyrsa_resource).st_size # When the filesize is less than 10 KB we do not have a real file. if filesize < 10240: hookenv.status_set('blocked', 'The easyrsa resource is not complete.') return # Expand the archive in the charm directory creating an EasyRSA directory. untar = 'tar -xvzf {0} -C {1}'.format(easyrsa_resource, charm_directory) check_call(split(untar)) version = get_version(easyrsa_resource) # Save the version in the key/value store of the charm. unitdata.kv().set('easyrsa-version', version) # Link the EasyRSA version directory to a common name. link = 'ln -v -s {0}/EasyRSA-{1} {2}'.format(charm_directory, version, easyrsa_directory) check_call(split(link)) charm_pki_directory = os.path.join(charm_directory, 'pki') if os.path.isdir(charm_pki_directory): new_pki_directory = os.path.join(easyrsa_directory, 'pki') # Copy the pki in this new directory. shutil.copytree(charm_pki_directory, new_pki_directory, symlinks=True) else: # Create new pki. with chdir(easyrsa_directory): check_call(split('./easyrsa --batch init-pki 2>&1')) set_state('easyrsa.installed')
def create_client_certificate(name='client'): '''Create the client certificate and client key.''' # Create an absolute path so current directory does not affect the result. easyrsa3_dir = os.path.join(hookenv.charm_dir(), 'easy-rsa/easyrsa3') with chdir(easyrsa3_dir): client_file = 'pki/issued/{0}.crt'.format(name) # Do not regenerate the client certificate if it already exists. if not os.path.isfile(client_file): # Create a client certificate and key. client = './easyrsa build-client-full {0} nopass 2>&1'.format(name) check_call(split(client)) # Read the client certificate from the filesystem. with open(client_file, 'r') as fp: client_cert = fp.read() # The key name is also used to set the reactive state. set_cert('tls.client.certificate', client_cert) set_state('client certificate available')
def render_backup(): ''' Backup existing data in the event of restoration on a dirty unit. ''' if not os.path.isdir(ETCD_DATA_DIR) and SKIP_BACKUP: msg = "Backup set to True, but no data found to backup" action_set({'backup.error': msg}) if not os.path.isdir(ETCD_DATA_DIR): return with chdir(ETCD_DATA_DIR): if not SKIP_BACKUP: log('Backing up existing data found in {}'.format(ETCD_DATA_DIR)) archive_path = "{}/{}".format(TARGET_PATH, ARCHIVE) cmd = 'tar cvf {0} {1}'.format(archive_path, '.') check_call(split(cmd)) backup_sum = shasum_file(archive_path) action_set({'backup.path': archive_path, 'backup.sha256sum': backup_sum})
def create_client_certificate(name="client"): """Create the client certificate and client key.""" # Create an absolute path so current directory does not affect the result. easyrsa3_dir = os.path.join(hookenv.charm_dir(), "easy-rsa/easyrsa3") with chdir(easyrsa3_dir): client_file = "pki/issued/{0}.crt".format(name) # Do not regenerate the client certificate if it already exists. if not os.path.isfile(client_file): # Create a client certificate and key. client = "./easyrsa build-client-full {0} nopass 2>&1".format(name) check_call(split(client)) # Read the client certificate from the filesystem. with open(client_file, "r") as fp: client_cert = fp.read() # The key name is also used to set the reactive state. set_cert("tls.client.certificate", client_cert) set_state("client certificate available")
def compile_ruby(): with chdir(WORKDIR): cmds = [ 'env RUBY_CFLAGS="-O3" ./configure --prefix=/usr ' '--disable-install-rdoc', 'make -j{}'.format(cpu_count()), 'make install' ] for cmd in cmds: hookenv.log('Running compile command: {}'.format(cmd)) sh = shell(cmd, record_output=False) if sh.code > 0: hookenv.status_set('blocked', 'Problem with Ruby: {}'.format(sh.errors())) hookenv.log("Problem with Ruby: {}".format(sh.errors())) sys.exit(1) hookenv.status_set('maintenance', 'Installing Ruby completed.')
def create_client_certificate(name="client"): """Return a newly created client certificate and client key, by name.""" with chdir(easyrsa_directory): # Create a path to the client certificate. cert_file = "pki/issued/{0}.crt".format(name) # Create a path to the client key. key_file = "pki/private/{0}.key".format(name) # Do not regenerate the client certificate if it already exists. if not os.path.isfile(cert_file) and not os.path.isfile(key_file): # Create a client certificate and key. check_call(["./easyrsa", "build-client-full", name, "nopass"]) # Read the client certificate from the file system. with open(cert_file, "r") as stream: client_cert = stream.read() # Read the client key from the file system. with open(key_file, "r") as stream: client_key = stream.read() return client_cert, client_key
def stop(self): """ Override start to use InsightEdge's wrapper. """ # Start if we're not already running. We currently dont have any # runtime config options, so no need to restart when hooks fire. if not utils.jps("zeppelin"): ie_home = self.dist_config.path('insightedge') zeppelin_home = self.dist_config.path('zeppelin') # chdir here because things like zepp tutorial think ZEPPELIN_HOME # is wherever the daemon was started from. with host.chdir(zeppelin_home): utils.run_as('ubuntu', '{}/sbin/stop-zeppelin.sh'.format(ie_home)) # wait for the process to stop, since issuing a start while the # process is still running (i.e., restart) could cause it to not # start up again self.wait_for_stop(30)
def install_fiche(): """ Install Fiche """ status_set('maintenance', 'Installing and configuring Fiche.') # Build fiche with chdir(options('git-deploy').get('target')): subprocess.call('make', shell=False) subprocess.call('make install PREFIX=/usr/local/bin'.split(), shell=False) subprocess.call('rm -rf /srv/fiche/*'.split(), shell=False) # Get uid for www-data and chown /srv/fiche uid = pwd.getpwnam('www-data').pw_uid os.chown(options('git-deploy').get('target'), uid, -1) set_state('fiche.installed')
def trigger_puppet(self): """ Trigger Puppet to install the desired components. """ java_version = unitdata.kv().get('java_version', '') if java_version.startswith('1.7.') and len(get_fqdn()) > 64: # We know java7 has MAXHOSTNAMELEN of 64 char, so we cannot rely on # java to do a hostname lookup on clouds that have >64 char FQDNs # (e.g., gce). Attempt to work around this by putting the (hopefully # short) hostname into /etc/hosts so that it will (hopefully) be # used instead (see http://paste.ubuntu.com/16230171/). # NB: do this before the puppet apply, which may call java stuffs # like format namenode, which will fail if we dont get this fix # down early. short_host = subprocess.check_output(['facter', 'hostname']).strip().decode() private_ip = utils.resolve_private_address(hookenv.unit_private_ip()) if short_host and private_ip: utils.update_kv_host(private_ip, short_host) utils.manage_etc_hosts() # puppet args are bigtop-version depedent if self.bigtop_version == '1.1.0': puppet_args = [ '-d', '--modulepath="bigtop-deploy/puppet/modules:/etc/puppet/modules"', 'bigtop-deploy/puppet/manifests/site.pp' ] else: puppet_args = [ '-d', '--parser=future', '--modulepath="bigtop-deploy/puppet/modules:/etc/puppet/modules"', 'bigtop-deploy/puppet/manifests' ] # puppet apply runs from the root of the bigtop release source with chdir(self.bigtop_base): utils.run_as('root', 'puppet', 'apply', *puppet_args) # Do any post-puppet config on the generated config files. utils.re_edit_in_place('/etc/default/bigtop-utils', { r'(# )?export JAVA_HOME.*': 'export JAVA_HOME={}'.format( java_home()), })
def create_server_certificate(cn, san_list, name=None): '''Return a newly created server certificate and server key from a common name, list of Subject Alternate Names, and the certificate name.''' if name is None: name = 'server' server_cert = None server_key = None with chdir(easyrsa_directory): # Create the path to the server certificate. cert_file = 'pki/issued/{0}.crt'.format(name) # Create the path to the server key. key_file = 'pki/private/{0}.key'.format(name) # Create the path to the request file req_file = 'pki/reqs/{0}.req'.format(name) # Get a string compatible with easyrsa for the subject-alt-names. sans = get_sans(san_list) sans_arg = '--subject-alt-name={}'.format(sans) if sans else '' this_cert = {'sans': sans, 'cn': cn, 'name': name} changed = data_changed('server_cert.' + name, this_cert) cert_exists = os.path.isfile(cert_file) and os.path.isfile(key_file) # Do not regenerate the server certificate if it already exists # and the data hasn't changed. if changed and cert_exists: # We need to revoke the existing cert and regenerate it revoke = './easyrsa --batch revoke {0}'.format(name) check_call(split(revoke)) # nuke old files if they exist remove_file_if_exists(cert_file) remove_file_if_exists(key_file) remove_file_if_exists(req_file) if changed or not cert_exists: # Create a server certificate for the server based on the CN. server = './easyrsa --batch --req-cn={0} {1} ' \ 'build-server-full {2} nopass 2>&1'.format(cn, sans_arg, name) check_call(split(server)) # Read the server certificate from the file system. with open(cert_file, 'r') as stream: server_cert = stream.read() # Read the server key from the file system. with open(key_file, 'r') as stream: server_key = stream.read() return server_cert, server_key
def create_client_certificate(name='client'): '''Return a newly created client certificate and client key, by name.''' client_cert = None client_key = None with chdir(easyrsa_directory): # Create a path to the client certificate. cert_file = 'pki/issued/{0}.crt'.format(name) # Create a path to the client key. key_file = 'pki/private/{0}.key'.format(name) # Do not regenerate the client certificate if it already exists. if not os.path.isfile(cert_file) and not os.path.isfile(key_file): # Create a client certificate and key. client = './easyrsa build-client-full {0} nopass 2>&1'.format(name) check_call(split(client)) # Read the client certificate from the file system. with open(cert_file, 'r') as stream: client_cert = stream.read() # Read the client key from the file system. with open(key_file, 'r') as stream: client_key = stream.read() return client_cert, client_key