diff options
author | elijah <elijah@riseup.net> | 2012-11-28 20:14:05 -0800 |
---|---|---|
committer | elijah <elijah@riseup.net> | 2012-11-28 20:14:05 -0800 |
commit | e5ed1ba2df6f735e32de35d9171d572dce322b7f (patch) | |
tree | 1a9120599adc7215edee5cf36ef27511823dd819 | |
parent | e2c31618b6f70d86c55c348436dd600b2e4ace21 (diff) | |
download | leap_cli-e5ed1ba2df6f735e32de35d9171d572dce322b7f.tar.gz leap_cli-e5ed1ba2df6f735e32de35d9171d572dce322b7f.tar.bz2 |
new system for how directory paths work. now there is a file Leapfile that manages this, instead of it always being ../leap_platform
-rw-r--r-- | README.md | 34 | ||||
-rw-r--r-- | lib/leap_cli.rb | 2 | ||||
-rw-r--r-- | lib/leap_cli/commands/node.rb | 5 | ||||
-rw-r--r-- | lib/leap_cli/commands/pre.rb | 24 | ||||
-rw-r--r-- | lib/leap_cli/commands/project.rb | 121 | ||||
-rw-r--r-- | lib/leap_cli/init.rb | 74 | ||||
-rw-r--r-- | lib/leap_cli/leapfile.rb | 43 | ||||
-rw-r--r-- | lib/leap_cli/path.rb | 83 | ||||
-rw-r--r-- | lib/leap_cli/util.rb | 21 |
9 files changed, 204 insertions, 203 deletions
@@ -27,31 +27,32 @@ Run `leap help` for a usage instructions. Here is an example usage: - leap new-provider provider + mkdir provider cd provider - edit configuration files (see below) + leap init --domain example.org . + leap node add vpn1 --service openvpn leap compile Directories and Files ================================= -The general structure of leap project looks like this: +A leap project consistents of two directories: - my_leap_project/ # your project directory - leap_platform/ # a clone of the leap_platform puppet recipes - provider/ # your provider-specific configurations +* provider directory: this is the directory where all your configurations live. By definition, a provider directory contains a file named Leapfile. +* platform directory: this is the directory where the puppet recipes live. The path to this directory is specified in the Leapfile. Typically, the platform directory will be a clone or branch of git://leap.se/leap_platform. -The "leap" command should be run from within the "provider" directory. +The "leap" command must always be run under provider directory (or one of its children). -Within the "provider" directory: +Within the provider directory: - nodes/ # one configuration file per node (i.e. server) - services/ # nodes inherit from these files if specified in node config. - tags/ # nodes inherit from these files if specified in node config. - files/ # text and binary files needed for services and nodes, including keypairs - users/ # crypto key material for sysadmins - common.yaml # all nodes inherit these options - provider.yaml # global service provider definition + nodes/ # one configuration file per node (i.e. server) + services/ # nodes inherit from these files if specified in node config. + tags/ # nodes inherit from these files if specified in node config. + files/ # text and binary files needed for services and nodes, including keypairs + users/ # crypto key material for sysadmins + hiera/ # compile yaml files that contain everything needed to deploy a particular node. + common.yaml # all nodes inherit these options + provider.yaml # global service provider definition Configuration Files ================================= @@ -101,8 +102,7 @@ The following methods are available to the evaluated ruby: * global.tags -- A list of all tags. * file(file_path) -- Inserts the full contents of the file. If the file is an erb - template, it is rendered. The file is searched for by first checking platform - and then provider/files, + template, it is rendered. * variable -- Any variable inherited by a particular node is available by just referencing it using either hash notation or object notation diff --git a/lib/leap_cli.rb b/lib/leap_cli.rb index 3f35cd4..f65f131 100644 --- a/lib/leap_cli.rb +++ b/lib/leap_cli.rb @@ -2,13 +2,13 @@ module LeapCli; end require 'leap_cli/version.rb' require 'leap_cli/requirements.rb' +require 'leap_cli/leapfile.rb' require 'core_ext/hash' require 'core_ext/boolean' require 'core_ext/nil' require 'core_ext/string' require 'leap_cli/log' -require 'leap_cli/init' require 'leap_cli/path' require 'leap_cli/util' require 'leap_cli/util/secret' diff --git a/lib/leap_cli/commands/node.rb b/lib/leap_cli/commands/node.rb index 678bebd..aa9610f 100644 --- a/lib/leap_cli/commands/node.rb +++ b/lib/leap_cli/commands/node.rb @@ -6,11 +6,13 @@ module LeapCli; module Commands ## ## COMMANDS ## + desc 'Node management' command :node do |c| c.desc 'Create a new configuration file for a node' c.command :add do |c| c.action do |global_options,options,args| + log 'not yet implemented' end end @@ -34,6 +36,7 @@ module LeapCli; module Commands c.desc 'Renames a node file, and all its related files' c.command :mv do |c| c.action do |global_options,options,args| + log 'not yet implemented' end end @@ -41,7 +44,7 @@ module LeapCli; module Commands c.arg_name '<node-name>', :optional => false, :multiple => false c.command :rm do |c| c.action do |global_options,options,args| - remove_file!() + log 'not yet implemented' end end end diff --git a/lib/leap_cli/commands/pre.rb b/lib/leap_cli/commands/pre.rb index dce01eb..cae787e 100644 --- a/lib/leap_cli/commands/pre.rb +++ b/lib/leap_cli/commands/pre.rb @@ -10,11 +10,6 @@ module LeapCli default_value '1' flag [:v, :verbose] - desc 'Specify the root directory' - arg_name 'path' - default_value Path.root - flag [:root] - desc 'Display version number and exit' switch :version, :negatable => false @@ -30,17 +25,18 @@ module LeapCli end # - # require a root directory + # load Leapfile # - if global[:root] - Path.set_root(global[:root]) + unless LeapCli.leapfile.load + bail! { log :missing, 'Leapfile in directory tree' } end - if Path.ok? - true - else - bail! do - log :error, "- Could not find the root directory. Change current working directory or try --root" - end + Path.set_platform_path(LeapCli.leapfile.platform_directory_path) + Path.set_provider_path(LeapCli.leapfile.provider_directory_path) + if !Path.provider || !File.directory?(Path.provider) + bail! { log :missing, "provider directory '#{Path.provider}'" } + end + if !Path.platform || !File.directory?(Path.platform) + bail! { log :missing, "platform directory '#{Path.platform}'" } end # diff --git a/lib/leap_cli/commands/project.rb b/lib/leap_cli/commands/project.rb index c748128..2f36bc5 100644 --- a/lib/leap_cli/commands/project.rb +++ b/lib/leap_cli/commands/project.rb @@ -1,25 +1,106 @@ -module LeapCli - module Commands - - desc 'Creates a new provider directory.' - arg_name '<directory>' - skips_pre - command :'init-provider' do |c| - c.action do |global_options,options,args| - directory = args.first - unless directory && directory.any? - help! "Directory name is required." - end - directory = File.expand_path(directory) - if File.exists?(directory) - raise "#{directory} already exists." - end - if agree("Create directory '#{directory}'? ") - LeapCli.init(directory) +require 'fileutils' + +module LeapCli; module Commands + + desc 'Initializes a new LEAP provider in the specified directory.' + arg_name 'directory-path' + skips_pre + command :init do |c| + c.flag 'name', :desc => "The name of the provider", :default_value => 'Example' + c.flag 'domain', :desc => "The primary domain of the provider", :default_value => 'example.org' + c.flag 'platform', :desc => "File path of the leap_platform directory", :default_value => '../leap_platform' + c.action do |global_options, options, args| + directory = args.first + unless directory && directory.any? + help! "Directory name is required." + end + directory = File.expand_path(directory) + unless File.exists?(directory) + bail! { log :missing, "directory #{directory}" } + end + create_initial_provider_files(directory, options) + end + end + + private + + DEFAULT_REPO = 'git://leap.se/leap_platform' # TODO: use https + + # + # creates new provider directory + # + def create_initial_provider_files(directory, options) + Path.set_provider_path(directory) + Dir.chdir(directory) do + assert_files_missing! 'provider.json', 'common.json', 'Leapfile', :base => directory + + platform_dir = File.expand_path(options[:platform]) + + unless File.symlink?(platform_dir) || File.directory?(platform_dir) + if agree("The platform directory \"#{options[:platform]}\" does not exist.\nDo you want me to create it by cloning from the\ngit repository #{DEFAULT_REPO}? ") + assert_bin! 'git' + ensure_dir platform_dir + Dir.chdir(platform_dir) do + log :cloning, "leap_platform into #{platform_dir}" + pty_run "git clone --branch develop #{DEFAULT_REPO} ." + pty_run 'git submodule update --init' + end else - puts "OK, bye." + bail! end end + write_file! '.gitignore', GITIGNORE_CONTENT + write_file! 'provider.json', provider_content(options) + write_file! 'common.json', COMMON_CONTENT + write_file! 'Leapfile', leapfile_content(options) + ["nodes", "services", "tags"].each do |dir| + ensure_dir dir + end + log :completed, 'initialization' end end -end
\ No newline at end of file + + def leapfile_content(options) + %[@platform_directory_path = "#{options[:platform]}" +] + # leap_version = "#{LeapCli::VERSION}" + # platform_version = "" + end + + GITIGNORE_CONTENT = <<EOS +test/Vagrantfile +test/.vagrant +test/openvpn +test/cert +EOS + + def provider_content(options) + %[# +# General service provider configuration. +# +{ + "domain": "#{options[:domain]}", + "name": { + "en": "#{options[:name]}" + }, + "description": { + "en": "You really should change this text" + }, + "languages": ["en"], + "default_language": "en", + "enrollment_policy": "open" +} +] + end + + COMMON_CONTENT = <<EOS +# +# Options put here are inherited by all nodes. +# +{ +} +EOS + +end; end + + diff --git a/lib/leap_cli/init.rb b/lib/leap_cli/init.rb deleted file mode 100644 index bebede7..0000000 --- a/lib/leap_cli/init.rb +++ /dev/null @@ -1,74 +0,0 @@ -require 'fileutils' - -module LeapCli - # - # creates new provider directory - # - def self.init(directory) - dirs = [directory] - mkdirs(dirs, false, false) - - Dir.chdir(directory) do - dirs = ["nodes", "services", "keys", "tags"] - mkdirs(dirs, false, false) - - #puts "Creating .provider" - #FileUtils.touch('.provider') - - mkfile("provider.json", PROVIDER_CONTENT) - mkfile("common.json", COMMON_CONTENT) - end - end - - def self.mkfile(filename, content) - puts "Creating #{filename}" - File.open(filename, 'w') do |f| - f.write content - end - end - - def self.mkdirs(dirs,force,dry_run) - exists = false - if !force - dirs.each do |dir| - if File.exist? dir - raise "#{dir} exists; use --force to override" - exists = true - end - end - end - if !exists - dirs.each do |dir| - puts "Creating #{dir}/" - if dry_run - puts "dry-run; #{dir} not created" - else - FileUtils.mkdir_p dir - end - end - else - puts "Exiting..." - return false - end - true - end - - PROVIDER_CONTENT = <<EOS -# -# Global provider definition file. -# -{ - "domain": "example.org" -} -EOS - - COMMON_CONTENT = <<EOS -# -# Options put here are inherited by all nodes. -# -{ - "domain": "example.org" -} -EOS - -end diff --git a/lib/leap_cli/leapfile.rb b/lib/leap_cli/leapfile.rb new file mode 100644 index 0000000..2559864 --- /dev/null +++ b/lib/leap_cli/leapfile.rb @@ -0,0 +1,43 @@ +# +# The Leapfile is the bootstrap configuration file for a LEAP provider. +# +# It is akin to a Gemfile, Rakefile, or Capfile (e.g. it is a ruby file that gets eval'ed) +# + +module LeapCli + def self.leapfile + @leapfile ||= Leapfile.new + end + + class Leapfile + attr_accessor :platform_directory_path + attr_accessor :provider_directory_path + + def load + directory = File.expand_path(find_in_directory_tree('Leapfile')) + if directory == '/' + return nil + else + self.provider_directory_path = directory + leapfile = directory + '/Leapfile' + instance_eval(File.read(leapfile), leapfile) + self.platform_directory_path = File.expand_path(self.platform_directory_path || '../leap_platform', self.provider_directory_path) + return true + end + end + + private + + def find_in_directory_tree(filename) + search_dir = Dir.pwd + while search_dir != "/" + Dir.foreach(search_dir) do |f| + return search_dir if f == filename + end + search_dir = File.dirname(search_dir) + end + return search_dir + end + end +end + diff --git a/lib/leap_cli/path.rb b/lib/leap_cli/path.rb index 27ffcce..20994f4 100644 --- a/lib/leap_cli/path.rb +++ b/lib/leap_cli/path.rb @@ -53,35 +53,8 @@ module LeapCli; module Path :test_client_openvpn_template => 'test/openvpn/client.ovpn.erb' } - # - # required file structure - # - # Option 1 -- A project directory with platform and provider directories - # - # -: $root - # :-- leap_platform - # '-: provider - # '-- provider.json - # - # $root can be any name - # - # Option 2 -- A stand alone provider directory - # - # -: $provider - # '-- provider.json - # - # $provider can be any name. Some commands are not available. - # - # In either case, the 'leap' command must be run from inside the provider directory or - # you must specify root directory with --root=dir. - # - - def self.root - @root ||= File.expand_path("#{provider}/..") - end - def self.platform - @platform ||= File.expand_path("#{root}/leap_platform") + @platform end def self.provider_base @@ -93,42 +66,17 @@ module LeapCli; module Path end def self.provider - @provider ||= if @root - File.expand_path("#{root}/provider") - else - find_in_directory_tree('provider.json') - end + @provider end - def self.ok? - provider != '/' + def self.set_provider_path(provider) + @provider = provider end - - def self.set_root(root_path) - @root = File.expand_path(root_path) - raise "No such directory '#{@root}'" unless File.directory?(@root) + def self.set_platform_path(platform) + @platform = platform end # - # all the places we search for a file when using find_file. - # this is perhaps too many places. - # - # def self.search_path - # @search_path ||= begin - # search_path = [] - # [Path.provider_base, Path.provider].each do |provider| - # #files_dir = named_path(:files_dir, provider) - # search_path << provider - # #search_path << named_path(:files_dir, provider) - # #search_path << named_path(:nodes_dir, files_dir) - # #search_path << named_path(:services_dir, files_dir) - # #search_path << named_path(:tags_dir, files_dir) - # end - # search_path - # end - # end - - # # tries to find a file somewhere # def self.find_file(arg) @@ -174,22 +122,9 @@ module LeapCli; module Path File.exists?(named_path(name, provider_dir)) end - def self.relative_path(path) - path = named_path(path) - path.sub(/^#{Regexp.escape(provider)}\//,'') - end - - private - - def self.find_in_directory_tree(filename) - search_dir = Dir.pwd - while search_dir != "/" - Dir.foreach(search_dir) do |f| - return search_dir if f == filename - end - search_dir = File.dirname(search_dir) - end - return search_dir + def self.relative_path(path, provider_dir=Path.provider) + path = named_path(path, provider_dir) + path.sub(/^#{Regexp.escape(provider_dir)}\//,'') end end; end diff --git a/lib/leap_cli/util.rb b/lib/leap_cli/util.rb index 967acca..98c3002 100644 --- a/lib/leap_cli/util.rb +++ b/lib/leap_cli/util.rb @@ -2,6 +2,7 @@ require 'digest/md5' require 'paint' require 'fileutils' require 'erb' +require 'pty' module LeapCli module Util @@ -84,9 +85,10 @@ module LeapCli def assert_files_missing!(*files) options = files.last.is_a?(Hash) ? files.pop : {} + base = options[:base] || Path.provider file_list = files.collect { |file_path| - file_path = Path.named_path(file_path) - File.exists?(file_path) ? Path.relative_path(file_path) : nil + file_path = Path.named_path(file_path, base) + File.exists?(file_path) ? Path.relative_path(file_path, base) : nil }.compact if file_list.length > 1 bail! do @@ -280,6 +282,21 @@ module LeapCli STDOUT.puts end + # + # runs a command in a pseudo terminal + # + def pty_run(cmd) + PTY.spawn(cmd) do |output, input, pid| + begin + while line = output.gets do + puts line + end + rescue Errno::EIO + end + end + rescue PTY::ChildExited + end + ## ## ERB ## |