def salt_master_config(config): project = config.data['project'] master_project_path = os.path.join( Filesystem.project_path(project), 'master') master_env_path = os.path.join( Filesystem.current_env(), 'master' ) merged_master = Filesystem.load_file(master_project_path, master_env_path) return merged_master
def run(config, argv): args = docopt(__doc__, argv=argv) active_env = config.environment env = args["<environment>"] if not env: local_path = os.path.join(Filesystem.local_path()) dirs = (x for x in next(os.walk(local_path))[1] if x != "current") for d in dirs: if active_env == d: sys.stdout.write("* {0}\n".format(d)) else: sys.stdout.write(" {0}\n".format(d)) return env_path = Filesystem.local_env_path(env) if env == active_env: sys.stdout.write("Already on '{0}'\n".format(env)) elif os.path.isdir(env_path): config.activate_environment(env) sys.stdout.write("Switched to environment '{0}'\n".format(env)) else: sys.stdout.write("Environment '{0}' does not exist\n".format(env))
def master_config_data(self, data=None, files=None): master = salt.config.DEFAULT_MASTER_OPTS.copy() master.update( log_level='info', log_level_logfile='info' ) if files: master.update(Filesystem.load_file(*files)) try: master.update(data) except TypeError: pass return master
def run(config, argv): args = docopt(__doc__, argv=argv) profile_name = args['--profile-name'] state = args['--state'] data = {'salt': {}} master = config.master_config_data(files=['/etc/salt/master']) instance_name = instances.instance_name_for_state(state, config) instance_id = instance_name.rsplit('-')[-1] minion_id = '{0}{1}'.format(state, instance_id) pem, pub = salt.gen_keys() client = LocalClient() grains = client.cmd('master', 'grains.item', ['fqdn']) try: master_fqdn = grains['master']['fqdn'] except KeyError: return minion_data = { 'master': master_fqdn, 'id': minion_id } profile = config.profile_for_key(profile_name) minion_data.update(profile.get('minion', {})) data['salt']['minion_pub'] = pub data['salt']['minion_pem'] = pem data['salt']['minion'] = Filesystem.encode( config.minion_config_data(minion_data)) salt.accept_key(master['pki_dir'], pub, minion_id) instances.create_instance( config=config, profile_name=profile_name, state=state, data=data, instance_name=instance_name)
def _master_data(config): profiles = config.profile providers = _providers_for_config(config) config_obj = config.data.copy() config_obj['master'] = 'localhost' ssh_keys_data = _ssh_keys_for_providers(providers) profiles_data = Filesystem.encode(profiles) providers_data = Filesystem.encode(providers) config_data = Filesystem.encode(config_obj) project = config.data['project'] master_project_path = os.path.join( Filesystem.project_path(project), 'master' ) master_env_path = os.path.join( Filesystem.current_env(), 'master' ) master = Filesystem.encode(config.master_config_data( files=[master_project_path, master_env_path])) minion = Filesystem.encode(config.minion_config_data({ 'id': 'master', 'master': 'localhost', 'grains': {'roles': ['master']} })) salt_data = { 'master': master, 'minion': minion} cloudseed_data = { 'profiles': profiles_data, 'providers': providers_data, 'config': config_data, 'ssh_keys': ssh_keys_data} return { 'salt': salt_data, 'cloudseed': cloudseed_data }
def run(config, argv): args = docopt(__doc__, argv=argv) # this is what makes up the above profile = config.profile['master'] identity = None hostname = None username = None try: provider = config.provider_for_profile(profile) except UnknownConfigProvider as e: sys.stdout.write( 'Unknown config provider \'{0}\', unable to continue.\n'\ .format(e.message)) return with profile_key_error(): username = profile['ssh_username'] with config_key_error(): hostname = config.data['master'] identity = profile.get('ssh_password', provider.ssh_identity()) if not identity: log.error('No identity specificed.\n\ Please set ssh_password on the master profile or provide a private_key \ in your provider for this master') return current_env = config.environment if not current_env: sys.stdout.write('No environment available.\n') sys.stdout.write('Have you run \'cloudseed init env <environment>\'?\n') return sys.stdout.write('Syncing states for \'{0}\'\n'.format(current_env)) env_path = Filesystem.local_env_path(current_env) states_path = os.path.join(env_path, 'states') if not os.path.isdir(states_path): sys.stdout.write('States dir not found at \'%s\'\n', states_path) return master_config = salt_master_config(config) sys.stdout.write('Archiving contents at \'{0}\'\n'.format(states_path)) tmp = tempfile.NamedTemporaryFile(delete=False) archive = tarfile.open(fileobj=tmp, mode='w:gz') archive.add(states_path, '.') archive.close() tmp.close() log.debug('Archive created at %s', tmp.name) try: remote_path = master_config['file_roots']['base'][0] except KeyError: remote_path = '/srv/salt' remote_file = os.path.join('/tmp', os.path.basename(tmp.name)) log.debug('Initializing SSH Client') with ssh_client_error(): ssh_client = ssh.master_client_with_config(config) log.debug('Initializing SFTP Client') sftp_client = sftp.connect( hostname=hostname, username=username, identity=identity) log.debug( 'Remotely Executing: sudo sh -c "mkdir -p %s; chown -R root:root %s"', remote_path, remote_path) ssh.run( ssh_client, 'sudo sh -c "mkdir -p {0}; chown -R root:root {0}"'.format(remote_path)) sys.stdout.write('Transferring archive to \'{0}\'\n'.format(hostname)) sftp.put(sftp_client, tmp.name, remote_file) sys.stdout.write('Unpacking archive to \'{0}\'\n'.format(remote_path)) log.debug( 'Remotely Executing: sudo sh -c "tar -C %s -xvf %s; chwon -R root:root %s"', remote_path, remote_file, remote_path) ssh.run(ssh_client, 'sudo sh -c "tar -C {0} -xvf {1}; chown -R root:root {0}"'\ .format(remote_path, remote_file)) log.debug( 'Remotely Executing: rm -rf %s', remote_file) ssh.run(ssh_client, 'rm -f {0}'\ .format(remote_file)) os.unlink(tmp.name) # debugging command only ssh.run(ssh_client, 'sudo sh -c "salt \'master\' state.highstate --async"') sys.stdout.write('Sync complete\n')
def init_cloudseed_environment(config, args): env_name = args['<environment>'] # project_name = config.data['project'] write_file = Filesystem.write_file env_dir = Filesystem.local_env_path(env_name) states_dir = os.path.join(env_dir, 'states') profile_path = os.path.join(env_dir, 'profile') master_path = os.path.join(env_dir, 'master') config_path = os.path.join(env_dir, 'config') # project_env_dir = Filesystem.project_env_path(project_name, env_name) profile = { 'master': { 'image': '<server image>', 'size': '<server size>', 'script': '<bootstrap script>', 'ssh_username': '******', 'provider': '<provider_name>' }, 'minion': { 'image': '<server image>', 'size': '<server size>', 'script': '<bootstrap script>', 'ssh_username': '******', 'provider': '<provider_name>' } } master = { 'fileserver_backend': [ 'roots', 'git' ], 'gitfs_remotes': [ 'git://github.com/cloudseed-project/cloudseed-states.git' ], 'file_roots': { 'base': ['/srv/salt'] } } if not os.path.isdir(env_dir): log.debug('Creating directory %s', env_dir) os.mkdir(env_dir) if not os.path.isdir(states_dir): log.debug('Creating directory %s', states_dir) os.mkdir(states_dir) if os.path.exists(profile_path): log.debug('%s already exists, will not overwrite', profile_path) else: write_file(profile_path, profile) if os.path.exists(config_path): log.debug('%s already exists, will not overwrite', config_path) else: open(config_path, 'w').close() if os.path.exists(master_path): log.debug('%s already exists, will not overwrite', master_path) else: write_file(master_path, master)
def init_cloudseed_project(config, args): write_file = Filesystem.write_file project_name = args['<project>'] user_dir = Filesystem.user_path() local_dir = Filesystem.local_path() project_dir = Filesystem.project_path(project_name) local_config_path = os.path.join(local_dir, 'config') local_providers_path = os.path.join(local_dir, 'providers') local_data = { 'project': project_name, } if not os.path.isdir(user_dir): log.debug('Creating directory %s', user_dir) os.mkdir(user_dir) # make empty global level config global_config = os.path.join(user_dir, 'config') log.debug('Creating empty config %s', global_config) open(global_config, 'w').close() if not os.path.isdir(project_dir): log.debug('Creating directory %s', project_dir) os.mkdir(project_dir) # make empty project level config project_config = os.path.join(project_dir, 'config') master_config = os.path.join(project_dir, 'master') profile_config = os.path.join(project_dir, 'profile') providers_config = os.path.join(project_dir, 'providers') states_dir = os.path.join(project_dir, 'states') log.debug('Creating empty config %s', project_config) open(project_config, 'w').close() log.debug('Creating empty providers %s', project_config) open(providers_config, 'w').close() log.debug('Creating empty salt master config %s', master_config) open(master_config, 'w').close() log.debug('Creating empty profile %s', profile_config) open(profile_config, 'w').close() if not os.path.isdir(states_dir): log.debug('Creating directory %s', states_dir) os.mkdir(states_dir) if not os.path.isdir(local_dir): log.debug('Creating directory %s', local_dir) os.mkdir(local_dir) if not os.path.isfile(local_config_path): log.debug('Creating empty local config %s', local_config_path) write_file(local_config_path, local_data) if not os.path.isfile(local_providers_path): log.debug('Creating empty local providers %s', local_providers_path) open(local_providers_path, 'w').close()